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:
Mutasem Aldmour 2023-04-21 15:37:09 +02:00 committed by GitHub
parent dc2a7a307a
commit 649389edad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 299 additions and 7 deletions

View 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', 'Im 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', 'Im 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);
}

View file

@ -106,6 +106,8 @@ export class WorkflowPage extends BasePage {
cy.get( cy.get(
`.connection-actions[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`, `.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'), editorTabButton: () => cy.getByTestId('radio-button-workflow'),
}; };
actions = { actions = {
@ -167,11 +169,13 @@ export class WorkflowPage extends BasePage {
this.getters.shareButton().click(); this.getters.shareButton().click();
}, },
saveWorkflowOnButtonClick: () => { saveWorkflowOnButtonClick: () => {
cy.intercept('POST', '/rest/workflows').as('createWorkflow');
this.getters.saveButton().should('contain', 'Save'); this.getters.saveButton().should('contain', 'Save');
this.getters.saveButton().click(); this.getters.saveButton().click();
this.getters.saveButton().should('contain', 'Saved'); this.getters.saveButton().should('contain', 'Saved');
}, },
saveWorkflowUsingKeyboardShortcut: () => { saveWorkflowUsingKeyboardShortcut: () => {
cy.intercept('POST', '/rest/workflows').as('createWorkflow');
cy.get('body').type('{meta}', { release: false }).type('s'); cy.get('body').type('{meta}', { release: false }).type('s');
}, },
deleteNode: (name: string) => { deleteNode: (name: string) => {
@ -257,6 +261,24 @@ export class WorkflowPage extends BasePage {
.first() .first()
.click({ force: true }); .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: () => { turnOnManualExecutionSaving: () => {
this.getters.workflowMenu().click(); this.getters.workflowMenu().click();
this.getters.workflowMenuItemSettings().click(); this.getters.workflowMenuItemSettings().click();

View file

@ -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 [xDiff, yDiff] = pos;
const element = cy.get(selector); const element = cy.get(selector).eq(index);
element.should('exist'); element.should('exist');
const originalLocation = Cypress.$(selector)[0].getBoundingClientRect(); const originalLocation = Cypress.$(selector)[index].getBoundingClientRect();
element.trigger('mousedown'); element.trigger('mousedown');
element.trigger('mousemove', { element.trigger('mousemove', {
which: 1, which: 1,
pageX: originalLocation.right + xDiff, pageX: options?.abs? xDiff: originalLocation.right + xDiff,
pageY: originalLocation.top + yDiff, pageY: options?.abs? yDiff: originalLocation.top + yDiff,
force: true, force: true,
}); });
element.trigger('mouseup', { force: true }); element.trigger('mouseup', { force: true });

View file

@ -47,7 +47,7 @@ declare global {
grantBrowserPermissions(...permissions: string[]): void; grantBrowserPermissions(...permissions: string[]): void;
readClipboard(): Chainable<string>; readClipboard(): Chainable<string>;
paste(pastePayload: string): void; 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; draganddrop(draggableSelector: string, droppableSelector: string): void;
} }
} }

View file

@ -17,6 +17,7 @@
<div <div
:class="[$style.addStickyButton, showStickyButton ? $style.visibleButton : '']" :class="[$style.addStickyButton, showStickyButton ? $style.visibleButton : '']"
@click="addStickyNote" @click="addStickyNote"
data-test-id="add-sticky-button"
> >
<n8n-icon-button <n8n-icon-button
size="medium" size="medium"

View file

@ -5,6 +5,7 @@
:ref="data.name" :ref="data.name"
:style="stickyPosition" :style="stickyPosition"
:data-name="data.name" :data-name="data.name"
data-test-id="sticky"
> >
<div <div
:class="{ :class="{
@ -41,7 +42,12 @@
</div> </div>
<div v-show="showActions" class="sticky-options no-select-on-click"> <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" /> <font-awesome-icon icon="trash" />
</div> </div>
</div> </div>