init the awkward code
91
static/html/jspaint/cypress/cypress-image-snapshot-viewer.js
Normal file
@@ -0,0 +1,91 @@
|
||||
// ==UserScript==
|
||||
// @name Cypress Image Snapshot Viewer
|
||||
// @namespace https://github.com/1j01/
|
||||
// @version 0.1
|
||||
// @description Show diffs of screenshots within the Cypress Dashboard. Works with images from cypress-image-snapshot. To use, press D in the gallery, and then move the mouse over and out of the image.
|
||||
// @author Isaiah Odhner
|
||||
// @match https://dashboard.cypress.io/*
|
||||
// @grant none
|
||||
// @noframes
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
let cleanUp = null;
|
||||
|
||||
function showDiffView(originalImg) {
|
||||
if (cleanUp) { cleanUp(); }
|
||||
|
||||
var screenshotWidth = originalImg.naturalWidth / 3;
|
||||
var screenshotHeight = originalImg.naturalHeight;
|
||||
originalImg.style.opacity = "0";
|
||||
var img = document.createElement("img");
|
||||
img.src = originalImg.src;
|
||||
img.style.position = "absolute";
|
||||
img.style.left = "0";
|
||||
img.style.pointerEvents = "all";
|
||||
img.draggable = false;
|
||||
img.addEventListener("mouseenter", () => {
|
||||
img.style.left = `${-2 * screenshotWidth}px`;
|
||||
});
|
||||
img.addEventListener("mouseleave", () => {
|
||||
img.style.left = "0";
|
||||
});
|
||||
var container = document.createElement("div");
|
||||
container.style.width = `${screenshotWidth}px`;
|
||||
container.style.height = `${screenshotHeight}px`;
|
||||
container.style.position = "relative";
|
||||
container.style.overflow = "hidden";
|
||||
container.style.margin = "auto";
|
||||
var outerContainer = document.createElement("div");
|
||||
outerContainer.style.position = "fixed";
|
||||
outerContainer.style.display = "flex";
|
||||
outerContainer.style.left = "0";
|
||||
outerContainer.style.right = "0";
|
||||
outerContainer.style.top = "0";
|
||||
outerContainer.style.bottom = "0";
|
||||
outerContainer.style.zIndex = "100000";
|
||||
outerContainer.style.pointerEvents = "none";
|
||||
|
||||
outerContainer.appendChild(container);
|
||||
container.appendChild(img);
|
||||
document.body.appendChild(outerContainer);
|
||||
|
||||
cleanUp = () => {
|
||||
originalImg.style.opacity = "";
|
||||
container.style.transformOrigin = "center center";
|
||||
container.style.transition = "opacity 0.2s ease, transform 0.2s ease";
|
||||
container.style.opacity = 0;
|
||||
container.style.transform = "scale(0.9)";
|
||||
setTimeout(() => {
|
||||
outerContainer.remove();
|
||||
}, 500);
|
||||
cleanUp = null;
|
||||
};
|
||||
}
|
||||
|
||||
addEventListener("keydown", e => {
|
||||
if (e.key === "d") {
|
||||
if (cleanUp) {
|
||||
cleanUp();
|
||||
} else {
|
||||
var originalImg = document.elementFromPoint(innerWidth / 2, innerHeight / 2);
|
||||
if (!originalImg || !originalImg.matches("img")) {
|
||||
console.warn("Didn't find an image in the middle of the page. Found", originalImg);
|
||||
return;
|
||||
}
|
||||
showDiffView(originalImg);
|
||||
}
|
||||
} else if (e.key === "Escape") {
|
||||
if (cleanUp) { cleanUp(); }
|
||||
}
|
||||
});
|
||||
|
||||
// mousedown is TAKEN - with stopPropagation, presumably
|
||||
// (useCapture doesn't help)
|
||||
addEventListener("pointerdown", (e) => {
|
||||
if (cleanUp) { cleanUp(); }
|
||||
});
|
||||
|
||||
}());
|
||||
5
static/html/jspaint/cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
224
static/html/jspaint/cypress/integration/tool-tests.spec.js
Normal file
@@ -0,0 +1,224 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('tool tests', () => {
|
||||
// @TODO: make rounded tools render consistently across platforms
|
||||
const roundedToolsCompareOptions = {
|
||||
failureThreshold: 13,
|
||||
failureThresholdType: 'pixel'
|
||||
};
|
||||
|
||||
// beforeAll isn't a thing, and beforeEach applies also to tests declared above it,
|
||||
// so do this fake test + flag hack in order to execute some steps before the first test
|
||||
let before_first_real_test = true;
|
||||
it(`(fake test for setup)`, () => {
|
||||
cy.visit('/')
|
||||
cy.setResolution([800, 500]);
|
||||
cy.window().should('have.property', 'selected_colors'); // wait for app to be loaded
|
||||
before_first_real_test = false;
|
||||
});
|
||||
beforeEach(() => {
|
||||
if (before_first_real_test) return;
|
||||
cy.window().then({ timeout: 60000 }, async (win) => {
|
||||
win.selected_colors.foreground = "#000";
|
||||
win.selected_colors.background = "#fff";
|
||||
win.brush_shape = win.default_brush_shape;
|
||||
win.brush_size = win.default_brush_size
|
||||
win.eraser_size = win.default_eraser_size;
|
||||
win.airbrush_size = win.default_airbrush_size;
|
||||
win.pencil_size = win.default_pencil_size;
|
||||
win.stroke_size = win.default_stroke_size;
|
||||
win.clear();
|
||||
});
|
||||
});
|
||||
|
||||
const simulateGesture = (win, { start, end, shift, shiftToggleChance = 0.01, secondary, secondaryToggleChance, target }) => {
|
||||
target = target || win.$(".main-canvas")[0];
|
||||
let startWithinRect = target.getBoundingClientRect();
|
||||
let canvasAreaRect = win.$(".canvas-area")[0].getBoundingClientRect();
|
||||
|
||||
let startMinX = Math.max(startWithinRect.left, canvasAreaRect.left);
|
||||
let startMaxX = Math.min(startWithinRect.right, canvasAreaRect.right);
|
||||
let startMinY = Math.max(startWithinRect.top, canvasAreaRect.top);
|
||||
let startMaxY = Math.min(startWithinRect.bottom, canvasAreaRect.bottom);
|
||||
let startPointX = startMinX + start.x * (startMaxX - startMinX);
|
||||
let startPointY = startMinY + start.y * (startMaxY - startMinY);
|
||||
let endPointX = startMinX + end.x * (startMaxX - startMinX);
|
||||
let endPointY = startMinY + end.y * (startMaxY - startMinY);
|
||||
|
||||
const $cursor = win.$(`<img src="images/cursors/default.png" class="user-cursor"/>`);
|
||||
$cursor.css({
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
top: 0,
|
||||
opacity: 0,
|
||||
zIndex: 5, // @#: z-index
|
||||
pointerEvents: "none",
|
||||
transition: "opacity 0.5s",
|
||||
});
|
||||
$cursor.appendTo(".jspaint");
|
||||
let triggerMouseEvent = (type, point) => {
|
||||
|
||||
const clientX = point.x;
|
||||
const clientY = point.y;
|
||||
// const el_over = win.document.elementFromPoint(clientX, clientY);
|
||||
const do_nothing = false;//!type.match(/move/) && (!el_over || !el_over.closest(".canvas-area"));
|
||||
$cursor.css({
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
left: clientX,
|
||||
top: clientY,
|
||||
opacity: do_nothing ? 0.5 : 1,
|
||||
});
|
||||
if (do_nothing) {
|
||||
return;
|
||||
}
|
||||
|
||||
let event = new win.$.Event(type, {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX,
|
||||
clientY,
|
||||
screenX: clientX,
|
||||
screenY: clientY,
|
||||
offsetX: point.x,
|
||||
offsetY: point.y,
|
||||
button: secondary ? 2 : 0,
|
||||
buttons: secondary ? 2 : 1,
|
||||
shiftKey: shift,
|
||||
});
|
||||
win.$(target).trigger(event);
|
||||
};
|
||||
|
||||
let t = 0;
|
||||
const stepsInGesture = 3;
|
||||
let pointForTime = (t) => {
|
||||
return {
|
||||
x: startPointX + (endPointX - startPointX) * t,
|
||||
y: startPointY + (endPointY - startPointY) * Math.pow(t, 0.3),
|
||||
};
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
triggerMouseEvent("pointerenter", pointForTime(t)); // so dynamic cursors follow the simulation cursor
|
||||
triggerMouseEvent("pointerdown", pointForTime(t));
|
||||
let move = () => {
|
||||
t += 1 / stepsInGesture;
|
||||
// if (seededRandom() < shiftToggleChance) {
|
||||
// shift = !shift;
|
||||
// }
|
||||
// if (seededRandom() < secondaryToggleChance) {
|
||||
// secondary = !secondary;
|
||||
// }
|
||||
if (t > 1) {
|
||||
triggerMouseEvent("pointerup", pointForTime(t));
|
||||
|
||||
$cursor.remove();
|
||||
|
||||
resolve();
|
||||
} else {
|
||||
triggerMouseEvent("pointermove", pointForTime(t));
|
||||
/*gestureTimeoutID =*/ setTimeout(move, 10);
|
||||
}
|
||||
};
|
||||
triggerMouseEvent("pointerleave", pointForTime(t));
|
||||
move();
|
||||
});
|
||||
};
|
||||
|
||||
// const gesture = (points) => {
|
||||
// const options = { secondary: false, shift: false };
|
||||
// // @TODO: while loop
|
||||
// trigger("pointerenter", points[0].x, points[0].y, options);
|
||||
// trigger("pointerdown", points[0].x, points[0].y, options);
|
||||
// let i = 0;
|
||||
// for (; i < points.length; i++) {
|
||||
// trigger("pointermove", points[i].x, points[i].y, options);
|
||||
// }
|
||||
// i--;
|
||||
// trigger("pointerup", points[i].x, points[i].y, options);
|
||||
// };
|
||||
|
||||
// it('brush tool', () => {
|
||||
// cy.get(".tool[title='Brush']").click();
|
||||
// // gesture([{ x: 50, y: 50 }, { x: 100, y: 100 }]);
|
||||
// cy.get(".swatch:nth-child(21)").rightclick();
|
||||
// cy.window().then({ timeout: 8000 }, async (win) => {
|
||||
// for (let secondary = 0; secondary <= 1; secondary++) {
|
||||
// for (let b = 0; b < 12; b++) {
|
||||
// win.$(`.chooser > :nth-child(${b + 1})`).click();
|
||||
// const start = { x: 0.05 + b * 0.05, y: 0.1 + 0.1 * secondary };
|
||||
// const end = { x: start.x + 0.04, y: start.y + 0.04 };
|
||||
// await simulateGesture(win, { shift: false, secondary: !!secondary, start, end });
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// cy.matchImageSnapshot();
|
||||
// });
|
||||
|
||||
// @TODO: test transparent document mode
|
||||
it(`eraser tool`, () => {
|
||||
cy.get(`.tool[title='Eraser/Color Eraser']`).click();
|
||||
// gesture([{ x: 50, y: 50 }, { x: 100, y: 100 }]);
|
||||
cy.window().then({ timeout: 60000 }, async (win) => {
|
||||
for (let row = 0; row < 4; row++) {
|
||||
const secondary = !!(row % 2);
|
||||
const increaseSize = row >= 2;
|
||||
let $options = win.$(`.chooser > *`);
|
||||
for (let o = 0; o < $options.length; o++) {
|
||||
$options[o].click();
|
||||
if (increaseSize) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
win.$('body').trigger(new win.$.Event("keydown", { key: "NumpadPlus", keyCode: 107, which: 107 }));
|
||||
}
|
||||
}
|
||||
win.selected_colors.background = "#f0f";
|
||||
const start = { x: 0.05 + o * 0.05, y: 0.1 + 0.1 * row };
|
||||
const end = { x: start.x + 0.04, y: start.y + 0.04 };
|
||||
await simulateGesture(win, { shift: false, secondary: false, start, end });
|
||||
if (secondary) {
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
win.selected_colors.background = "#ff0";
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
win.selected_colors.foreground = "#f0f";
|
||||
const start = { x: 0.04 + o * 0.05, y: 0.11 + 0.1 * row };
|
||||
const end = { x: start.x + 0.03, y: start.y + 0.02 };
|
||||
await simulateGesture(win, { shift: false, secondary: true, start, end });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
cy.get(".main-canvas").matchImageSnapshot();
|
||||
});
|
||||
|
||||
["Brush", "Pencil", "Rectangle", "Rounded Rectangle", "Ellipse", "Line"].forEach((toolName) => {
|
||||
it(`${toolName.toLowerCase()} tool`, () => {
|
||||
cy.get(`.tool[title='${toolName}']`).click();
|
||||
// gesture([{ x: 50, y: 50 }, { x: 100, y: 100 }]);
|
||||
cy.get(".swatch:nth-child(22)").rightclick();
|
||||
cy.window().then({ timeout: 60000 }, async (win) => {
|
||||
for (let row = 0; row < 4; row++) {
|
||||
const secondary = !!(row % 2);
|
||||
const increaseSize = row >= 2;
|
||||
let $options = win.$(`.chooser > *`);
|
||||
// Pencil has no options
|
||||
if ($options.length === 0) {
|
||||
$options = win.$("<dummy>");
|
||||
}
|
||||
for (let o = 0; o < $options.length; o++) {
|
||||
$options[o].click();
|
||||
if (increaseSize && (o === 0 || toolName === "Brush" || toolName === "Line")) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
win.$('body').trigger(new win.$.Event("keydown", { key: "NumpadPlus", keyCode: 107, which: 107 }));
|
||||
}
|
||||
}
|
||||
const start = { x: 0.05 + o * 0.05, y: 0.1 + 0.1 * row };
|
||||
const end = { x: start.x + 0.04, y: start.y + 0.04 };
|
||||
await simulateGesture(win, { shift: false, secondary: !!secondary, start, end });
|
||||
}
|
||||
}
|
||||
});
|
||||
cy.get(".main-canvas").matchImageSnapshot(toolName.match(/Rounded Rectangle|Ellipse/) ? roundedToolsCompareOptions : undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
181
static/html/jspaint/cypress/integration/visual-tests.spec.js
Normal file
@@ -0,0 +1,181 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('visual tests', () => {
|
||||
|
||||
const withTextCompareOptions = {
|
||||
failureThreshold: 0.05,
|
||||
failureThresholdType: 'percent' // not actually percent - fraction
|
||||
};
|
||||
const withMuchTextCompareOptions = {
|
||||
failureThreshold: 0.08,
|
||||
failureThresholdType: 'percent' // not actually percent - fraction
|
||||
};
|
||||
const toolboxCompareOptions = {
|
||||
failureThreshold: 40,
|
||||
failureThresholdType: 'pixel'
|
||||
};
|
||||
|
||||
const selectTheme = (themeName) => {
|
||||
cy.contains(".menu-button", "Extras").click();
|
||||
cy.contains(".menu-item", "Theme").click();
|
||||
cy.contains(".menu-item", themeName).click();
|
||||
cy.get(".status-text").click(); // close menu (@TODO: menus should probably always be closed when you select a menu item)
|
||||
cy.wait(1000); // give a bit of time for theme to load
|
||||
};
|
||||
|
||||
it('main screenshot', () => {
|
||||
cy.visit('/');
|
||||
cy.setResolution([760, 490]);
|
||||
cy.window().should('have.property', 'get_tool_by_id'); // wait for app to be loaded
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
it('brush selected', () => {
|
||||
cy.get('.tool[title="Brush"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
it('select selected', () => {
|
||||
cy.get('.tool[title="Select"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
it('magnifier selected', () => {
|
||||
cy.get('.tool[title="Magnifier"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
it('airbrush selected', () => {
|
||||
cy.get('.tool[title="Airbrush"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
it('eraser selected', () => {
|
||||
cy.get('.tool[title="Eraser/Color Eraser"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
it('line selected', () => {
|
||||
cy.get('.tool[title="Line"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
it('rectangle selected', () => {
|
||||
cy.get('.tool[title="Rectangle"]').click();
|
||||
cy.get('.tools-component').matchImageSnapshot(toolboxCompareOptions);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
if (Cypress.$('.window:visible')[0]) {
|
||||
cy.get('.window:visible .window-close-button').click();
|
||||
cy.get('.window').should('not.be.visible');
|
||||
}
|
||||
});
|
||||
|
||||
it('image attributes window', () => {
|
||||
cy.get('body').type('{ctrl}e');
|
||||
cy.get('.window:visible').matchImageSnapshot(withMuchTextCompareOptions);
|
||||
});
|
||||
|
||||
it('flip and rotate window', () => {
|
||||
// @TODO: make menus more testable, with IDs
|
||||
cy.get('.menus > .menu-container:nth-child(4) > .menu-button > .menu-hotkey').click();
|
||||
cy.get('.menus > .menu-container:nth-child(4) > .menu-popup > table > tr:nth-child(1)').click();
|
||||
cy.get('.window:visible').matchImageSnapshot(withMuchTextCompareOptions);
|
||||
});
|
||||
|
||||
it('stretch and skew window', () => {
|
||||
// @TODO: make menus more testable, with IDs
|
||||
cy.get('.menus > .menu-container:nth-child(4) > .menu-button > .menu-hotkey').click();
|
||||
cy.get('.menus > .menu-container:nth-child(4) > .menu-popup > table > tr:nth-child(2)').click();
|
||||
// @TODO: wait for images to load and include images?
|
||||
cy.get('.window:visible').matchImageSnapshot(Object.assign({}, withTextCompareOptions, { blackout: ["img"] }));
|
||||
});
|
||||
|
||||
it('help window', () => {
|
||||
// @TODO: make menus more testable, with IDs
|
||||
cy.get('.menus > .menu-container:nth-child(6) > .menu-button > .menu-hotkey').click();
|
||||
cy.get('.menus > .menu-container:nth-child(6) > .menu-popup > table > tr:nth-child(1)').click();
|
||||
cy.get('.window:visible .folder', { timeout: 10000 }); // wait for sidebar contents to load
|
||||
// @TODO: wait for iframe to load
|
||||
cy.get('.window:visible').matchImageSnapshot(Object.assign({}, withTextCompareOptions, { blackout: ["iframe"] }));
|
||||
});
|
||||
|
||||
it('about window', () => {
|
||||
// @TODO: make menus more testable, with IDs
|
||||
cy.get('.menus > .menu-container:nth-child(6) > .menu-button > .menu-hotkey').click();
|
||||
cy.get('.menus > .menu-container:nth-child(6) > .menu-popup > table > tr:nth-child(3)').click();
|
||||
cy.get('.window:visible').matchImageSnapshot(Object.assign({}, withMuchTextCompareOptions, { blackout: ["img", "#maybe-outdated-line"] }));
|
||||
});
|
||||
|
||||
it('eye gaze mode', () => {
|
||||
cy.get('.tool[title="Select"]').click();
|
||||
cy.contains(".menu-button", "Extras").click();
|
||||
cy.contains(".menu-item", "Eye Gaze Mode").click();
|
||||
cy.wait(100);
|
||||
// cy.contains(".menu-button", "View").click();
|
||||
// cy.get("body").trigger("pointermove", { clientX: 200, clientY: 150 });
|
||||
cy.get(".status-text").click();
|
||||
cy.wait(100);
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
it('modern theme eye gaze mode', () => {
|
||||
selectTheme("Modern");
|
||||
// cy.contains(".menu-button", "View").click();
|
||||
// cy.get("body").trigger("pointermove", { clientX: 200, clientY: 150 });
|
||||
cy.wait(100);
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
it('modern theme', () => {
|
||||
cy.contains(".menu-button", "Extras").click();
|
||||
cy.contains(".menu-item", "Eye Gaze Mode").click();
|
||||
cy.wait(100);
|
||||
// cy.contains(".menu-button", "View").click();
|
||||
// cy.get("body").trigger("pointermove", { clientX: 200, clientY: 150 });
|
||||
cy.get(".status-text").click();
|
||||
cy.wait(100);
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
const test_edit_colors_dialog = (expand = true) => {
|
||||
cy.contains(".menu-button", "Colors").click();
|
||||
cy.contains(".menu-item", "Edit Colors").click();
|
||||
cy.wait(100);
|
||||
if (expand) {
|
||||
cy.contains("button", "Define Custom Colors >>").click();
|
||||
}
|
||||
cy.get('.window:visible').matchImageSnapshot(Object.assign({}, withTextCompareOptions));
|
||||
};
|
||||
it('modern theme edit colors dialog (expanded)', test_edit_colors_dialog);
|
||||
|
||||
it('winter theme', () => {
|
||||
selectTheme("Winter");
|
||||
// cy.contains(".menu-button", "View").click();
|
||||
// cy.get("body").trigger("pointermove", { clientX: 200, clientY: 150 });
|
||||
cy.wait(100);
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
it('winter theme edit colors dialog (expanded)', test_edit_colors_dialog);
|
||||
|
||||
it('winter theme vertical color box', () => {
|
||||
cy.wait(500);
|
||||
cy.contains(".menu-button", "Extras").click();
|
||||
cy.contains(".menu-item", "Vertical Color Box").click();
|
||||
cy.wait(500);
|
||||
cy.get(".status-text").click();
|
||||
cy.wait(100);
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
it('classic theme vertical color box', () => {
|
||||
selectTheme("Classic");
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
it('classic theme edit colors dialog', () => {
|
||||
test_edit_colors_dialog(false);
|
||||
});
|
||||
|
||||
it('modern theme vertical color box', () => {
|
||||
selectTheme("Modern");
|
||||
cy.matchImageSnapshot(withTextCompareOptions);
|
||||
});
|
||||
|
||||
});
|
||||
11
static/html/jspaint/cypress/plugins/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
const {
|
||||
addMatchImageSnapshotPlugin,
|
||||
} = require("cypress-image-snapshot/plugin");
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
addMatchImageSnapshotPlugin(on, config);
|
||||
};
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 31 KiB |
14
static/html/jspaint/cypress/support/commands.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
|
||||
addMatchImageSnapshotCommand({
|
||||
failureThreshold: 0,
|
||||
failureThresholdType: 'pixel',
|
||||
customDiffConfig: { threshold: 0 },
|
||||
capture: 'viewport',
|
||||
});
|
||||
Cypress.Commands.add("setResolution", (size) => {
|
||||
if (Cypress._.isArray(size)) {
|
||||
cy.viewport(size[0], size[1]);
|
||||
} else {
|
||||
cy.viewport(size);
|
||||
}
|
||||
})
|
||||
7
static/html/jspaint/cypress/support/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// ***********************************************************
|
||||
// This support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// https://on.cypress.io/configuration
|
||||
|
||||
import './commands'
|
||||