225 lines
7.7 KiB
JavaScript
225 lines
7.7 KiB
JavaScript
/// <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);
|
|
});
|
|
});
|
|
});
|