mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
test: Add stickies tests (#5413)
* test: Add tests for stickies * test: add sticky basic test * test: add size dragging tests * test: add delete sticky test * test: add editing test * test: update editing text * test: add expansion tests * test: add more tests * test: clean up tests * refactor: update dragging tests to make sense * refactor: upate drag right test * test: add shrink from right test * test: refactor some more * test: fix all tests * test: clean up * test: update number * test: add z-index tests * test: address comments * test: fix mistake * test: wait on save * test: try button instead
This commit is contained in:
parent
dc2a7a307a
commit
649389edad
262
cypress/e2e/25-stickies.cy.ts
Normal file
262
cypress/e2e/25-stickies.cy.ts
Normal file
|
@ -0,0 +1,262 @@
|
|||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||
|
||||
const workflowPage = new WorkflowPageClass();
|
||||
|
||||
function checkStickiesStyle( top: number, left: number, height: number, width: number, zIndex?: number) {
|
||||
workflowPage.getters.stickies().should(($el) => {
|
||||
expect($el).to.have.css('top', `${top}px`);
|
||||
expect($el).to.have.css('left', `${left}px`);
|
||||
expect($el).to.have.css('height', `${height}px`);
|
||||
expect($el).to.have.css('width', `${width}px`);
|
||||
if (zIndex) {
|
||||
expect($el).to.have.css('z-index', `${zIndex}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('Canvas Actions', () => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
workflowPage.actions.visit();
|
||||
|
||||
cy.window().then(
|
||||
(win) => {
|
||||
// @ts-ignore
|
||||
win.preventNodeViewBeforeUnload = true;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('adds sticky to canvas with default text and position', () => {
|
||||
workflowPage.getters.addStickyButton().should('not.be.visible');
|
||||
|
||||
addDefaultSticky()
|
||||
workflowPage.getters.stickies().eq(0)
|
||||
.should('have.text', 'I’m a note\nDouble click to edit me. Guide\n')
|
||||
.find('a').contains('Guide').should('have.attr', 'href');
|
||||
});
|
||||
|
||||
it('drags sticky around to top left corner', () => {
|
||||
// used to caliberate move sticky function
|
||||
addDefaultSticky();
|
||||
moveSticky({ top: 0, left: 0 });
|
||||
});
|
||||
|
||||
it('drags sticky around and position/size are saved correctly', () => {
|
||||
addDefaultSticky();
|
||||
moveSticky({ top: 500, left: 500 });
|
||||
|
||||
workflowPage.actions.saveWorkflowOnButtonClick();
|
||||
cy.wait('@createWorkflow');
|
||||
|
||||
cy.reload();
|
||||
cy.waitForLoad();
|
||||
|
||||
stickyShouldBePositionedCorrectly({ top: 500, left: 500 });
|
||||
});
|
||||
|
||||
it('deletes sticky', () => {
|
||||
workflowPage.actions.addSticky();
|
||||
workflowPage.getters.stickies().should('have.length', 1)
|
||||
|
||||
workflowPage.actions.deleteSticky();
|
||||
|
||||
workflowPage.getters.stickies().should('have.length', 0)
|
||||
});
|
||||
|
||||
it('edits sticky and updates content as markdown', () => {
|
||||
workflowPage.actions.addSticky();
|
||||
|
||||
workflowPage.getters.stickies()
|
||||
.should('have.text', 'I’m a note\nDouble click to edit me. Guide\n')
|
||||
|
||||
workflowPage.getters.stickies().dblclick();
|
||||
workflowPage.actions.editSticky('# hello world \n ## text text');
|
||||
workflowPage.getters.stickies().find('h1').should('have.text', 'hello world');
|
||||
workflowPage.getters.stickies().find('h2').should('have.text', 'text text');
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the right edge', () => {
|
||||
addDefaultSticky();
|
||||
|
||||
moveSticky({ top: 200, left: 200 });
|
||||
|
||||
dragRightEdge({ left: 200, top: 200, height: 160, width: 240 }, 100);
|
||||
dragRightEdge({ left: 200, top: 200, height: 160, width: 240 }, -50);
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the left edge', () => {
|
||||
addDefaultSticky();
|
||||
|
||||
moveSticky({ left: 600, top: 200 });
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="left"]', [100, 100]);
|
||||
checkStickiesStyle(140, 510, 160, 150);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="left"]', [-50, -50]);
|
||||
checkStickiesStyle(140, 466, 160, 194);
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the top edge', () => {
|
||||
workflowPage.actions.addSticky();
|
||||
cy.drag('[data-test-id="sticky"]', [100, 100]); // move away from canvas button
|
||||
checkStickiesStyle(360, 620, 160, 240);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="top"]', [100, 100]);
|
||||
checkStickiesStyle(440, 620, 80, 240);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="top"]', [-50, -50]);
|
||||
checkStickiesStyle(384, 620, 136, 240);
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the bottom edge', () => {
|
||||
workflowPage.actions.addSticky();
|
||||
cy.drag('[data-test-id="sticky"]', [100, 100]); // move away from canvas button
|
||||
checkStickiesStyle(360, 620, 160, 240);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="bottom"]', [100, 100]);
|
||||
checkStickiesStyle(360, 620, 254, 240);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="bottom"]', [-50, -50]);
|
||||
checkStickiesStyle(360, 620, 198, 240);
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the bottom right edge', () => {
|
||||
workflowPage.actions.addSticky();
|
||||
cy.drag('[data-test-id="sticky"]', [-100, -100]); // move away from canvas button
|
||||
checkStickiesStyle(160, 420, 160, 240);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="bottomRight"]', [100, 100]);
|
||||
checkStickiesStyle(160, 420, 254, 346);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="bottomRight"]', [-50, -50]);
|
||||
checkStickiesStyle(160, 420, 198, 302);
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the top right edge', () => {
|
||||
addDefaultSticky();
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="topRight"]', [100, 100]);
|
||||
checkStickiesStyle(420, 400, 80, 346);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="topRight"]', [-50, -50]);
|
||||
checkStickiesStyle(364, 400, 136, 302);
|
||||
});
|
||||
|
||||
it('expands/shrinks sticky from the top left edge, and reach min height/width', () => {
|
||||
addDefaultSticky();
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="topLeft"]', [100, 100]);
|
||||
checkStickiesStyle(420, 490, 80, 150);
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="topLeft"]', [-150, -150]);
|
||||
checkStickiesStyle(264, 346, 236, 294);
|
||||
});
|
||||
|
||||
it('sets sticky behind node', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('Manual Trigger');
|
||||
addDefaultSticky();
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="topLeft"]', [-150, -150]);
|
||||
checkStickiesStyle(184, 256, 316, 384, -121);
|
||||
|
||||
workflowPage.getters.canvasNodes().eq(0)
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('z-index', 'auto');
|
||||
});
|
||||
|
||||
workflowPage.actions.addSticky();
|
||||
workflowPage.getters.stickies().eq(0)
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('z-index', '-121');
|
||||
});
|
||||
workflowPage.getters.stickies().eq(1)
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('z-index', '-38');
|
||||
});
|
||||
|
||||
cy.drag('[data-test-id="sticky"] [data-dir="topLeft"]', [-200, -200], { index: 1 });
|
||||
workflowPage.getters.stickies().eq(0)
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('z-index', '-121');
|
||||
});
|
||||
|
||||
workflowPage.getters.stickies().eq(1)
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('z-index', '-158');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
type Position = {
|
||||
top: number;
|
||||
left: number;
|
||||
};
|
||||
|
||||
type BoundingBox = {
|
||||
height: number;
|
||||
width: number;
|
||||
top: number;
|
||||
left: number;
|
||||
}
|
||||
|
||||
function dragRightEdge(curr: BoundingBox, move: number) {
|
||||
workflowPage.getters.stickies().first().then(($el) => {
|
||||
const { left, top, height, width } = curr;
|
||||
cy.drag(`[data-test-id="sticky"] [data-dir="right"]`, [left + width + move, 0], { abs: true });
|
||||
stickyShouldBePositionedCorrectly({ top, left });
|
||||
stickyShouldHaveCorrectSize([height, width * 1.5 + move]);
|
||||
});
|
||||
}
|
||||
|
||||
function shouldHaveOneSticky() {
|
||||
workflowPage.getters.stickies().should('have.length', 1);
|
||||
}
|
||||
|
||||
function shouldBeInDefaultLocation() {
|
||||
workflowPage.getters.stickies().eq(0).should(($el) => {
|
||||
expect($el).to.have.css('height', '160px');
|
||||
expect($el).to.have.css('width', '240px');
|
||||
})
|
||||
}
|
||||
|
||||
function shouldHaveDefaultSize() {
|
||||
workflowPage.getters.stickies().should(($el) => {
|
||||
expect($el).to.have.css('height', '160px');
|
||||
expect($el).to.have.css('width', '240px');
|
||||
})
|
||||
}
|
||||
|
||||
function addDefaultSticky() {
|
||||
workflowPage.actions.addSticky();
|
||||
shouldHaveOneSticky();
|
||||
shouldHaveDefaultSize();
|
||||
shouldBeInDefaultLocation();
|
||||
}
|
||||
|
||||
function stickyShouldBePositionedCorrectly(position: Position) {
|
||||
const yOffset = -60;
|
||||
const xOffset = -180;
|
||||
workflowPage.getters.stickies()
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('top', `${yOffset + position.top}px`);
|
||||
expect($el).to.have.css('left', `${xOffset + position.left}px`);
|
||||
});
|
||||
}
|
||||
|
||||
function stickyShouldHaveCorrectSize(size: [number, number]) {
|
||||
const yOffset = 0;
|
||||
const xOffset = 0;
|
||||
workflowPage.getters.stickies()
|
||||
.should(($el) => {
|
||||
expect($el).to.have.css('height', `${yOffset + size[0]}px`);
|
||||
expect($el).to.have.css('width', `${xOffset + size[1]}px`);
|
||||
});
|
||||
}
|
||||
|
||||
function moveSticky(target: Position) {
|
||||
cy.drag('[data-test-id="sticky"]', [target.left, target.top], { abs: true });
|
||||
stickyShouldBePositionedCorrectly(target);
|
||||
}
|
|
@ -106,6 +106,8 @@ export class WorkflowPage extends BasePage {
|
|||
cy.get(
|
||||
`.connection-actions[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`,
|
||||
),
|
||||
addStickyButton: () => cy.getByTestId('add-sticky-button'),
|
||||
stickies: () => cy.getByTestId('sticky'),
|
||||
editorTabButton: () => cy.getByTestId('radio-button-workflow'),
|
||||
};
|
||||
actions = {
|
||||
|
@ -167,11 +169,13 @@ export class WorkflowPage extends BasePage {
|
|||
this.getters.shareButton().click();
|
||||
},
|
||||
saveWorkflowOnButtonClick: () => {
|
||||
cy.intercept('POST', '/rest/workflows').as('createWorkflow');
|
||||
this.getters.saveButton().should('contain', 'Save');
|
||||
this.getters.saveButton().click();
|
||||
this.getters.saveButton().should('contain', 'Saved');
|
||||
},
|
||||
saveWorkflowUsingKeyboardShortcut: () => {
|
||||
cy.intercept('POST', '/rest/workflows').as('createWorkflow');
|
||||
cy.get('body').type('{meta}', { release: false }).type('s');
|
||||
},
|
||||
deleteNode: (name: string) => {
|
||||
|
@ -257,6 +261,24 @@ export class WorkflowPage extends BasePage {
|
|||
.first()
|
||||
.click({ force: true });
|
||||
},
|
||||
addSticky: () => {
|
||||
this.getters.nodeCreatorPlusButton().realHover();
|
||||
this.getters.addStickyButton().click();
|
||||
},
|
||||
deleteSticky: () => {
|
||||
this.getters.stickies().eq(0)
|
||||
.realHover()
|
||||
.find('[data-test-id="delete-sticky"]')
|
||||
.click();
|
||||
},
|
||||
editSticky: (content: string) => {
|
||||
this.getters.stickies()
|
||||
.dblclick()
|
||||
.find('textarea')
|
||||
.clear()
|
||||
.type(content)
|
||||
.type('{esc}');
|
||||
},
|
||||
turnOnManualExecutionSaving: () => {
|
||||
this.getters.workflowMenu().click();
|
||||
this.getters.workflowMenuItemSettings().click();
|
||||
|
|
|
@ -232,18 +232,19 @@ Cypress.Commands.add('paste', { prevSubject: true }, (selector, pastePayload) =>
|
|||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('drag', (selector, pos) => {
|
||||
Cypress.Commands.add('drag', (selector, pos, options) => {
|
||||
const index = options?.index || 0;
|
||||
const [xDiff, yDiff] = pos;
|
||||
const element = cy.get(selector);
|
||||
const element = cy.get(selector).eq(index);
|
||||
element.should('exist');
|
||||
|
||||
const originalLocation = Cypress.$(selector)[0].getBoundingClientRect();
|
||||
const originalLocation = Cypress.$(selector)[index].getBoundingClientRect();
|
||||
|
||||
element.trigger('mousedown');
|
||||
element.trigger('mousemove', {
|
||||
which: 1,
|
||||
pageX: originalLocation.right + xDiff,
|
||||
pageY: originalLocation.top + yDiff,
|
||||
pageX: options?.abs? xDiff: originalLocation.right + xDiff,
|
||||
pageY: options?.abs? yDiff: originalLocation.top + yDiff,
|
||||
force: true,
|
||||
});
|
||||
element.trigger('mouseup', { force: true });
|
||||
|
|
|
@ -47,7 +47,7 @@ declare global {
|
|||
grantBrowserPermissions(...permissions: string[]): void;
|
||||
readClipboard(): Chainable<string>;
|
||||
paste(pastePayload: string): void;
|
||||
drag(selector: string, target: [number, number]): void;
|
||||
drag(selector: string, target: [number, number], options?: {abs?: true, index?: number}): void;
|
||||
draganddrop(draggableSelector: string, droppableSelector: string): void;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<div
|
||||
:class="[$style.addStickyButton, showStickyButton ? $style.visibleButton : '']"
|
||||
@click="addStickyNote"
|
||||
data-test-id="add-sticky-button"
|
||||
>
|
||||
<n8n-icon-button
|
||||
size="medium"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
:ref="data.name"
|
||||
:style="stickyPosition"
|
||||
:data-name="data.name"
|
||||
data-test-id="sticky"
|
||||
>
|
||||
<div
|
||||
:class="{
|
||||
|
@ -41,7 +42,12 @@
|
|||
</div>
|
||||
|
||||
<div v-show="showActions" class="sticky-options no-select-on-click">
|
||||
<div v-touch:tap="deleteNode" class="option" :title="$locale.baseText('node.deleteNode')">
|
||||
<div
|
||||
v-touch:tap="deleteNode"
|
||||
class="option"
|
||||
data-test-id="delete-sticky"
|
||||
:title="$locale.baseText('node.deleteNode')"
|
||||
>
|
||||
<font-awesome-icon icon="trash" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue