Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Add stickies tests #5413

Merged
merged 27 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
97725ba
test: Add tests for stickies
mutdmour Feb 8, 2023
9eb55a2
test: add sticky basic test
mutdmour Feb 8, 2023
7b81b75
test: add size dragging tests
mutdmour Feb 8, 2023
39bc218
test: add delete sticky test
mutdmour Feb 8, 2023
29520af
test: add editing test
mutdmour Feb 8, 2023
2c5ad36
test: update editing text
mutdmour Feb 8, 2023
ddb1943
test: add expansion tests
mutdmour Feb 8, 2023
6e2424d
test: add more tests
mutdmour Feb 8, 2023
7bae279
test: clean up tests
mutdmour Feb 8, 2023
64bcb84
chore: merge in master
mutdmour Feb 10, 2023
abb7610
refactor: update dragging tests to make sense
mutdmour Feb 10, 2023
f385aa1
refactor: upate drag right test
mutdmour Feb 10, 2023
630ec54
chore: merge in master
mutdmour Feb 13, 2023
a5eeccc
test: add shrink from right test
mutdmour Feb 13, 2023
b16c86f
test: refactor some more
mutdmour Feb 13, 2023
14ddc94
chore: merge in masteR
mutdmour Mar 24, 2023
ee1098b
test: fix all tests
mutdmour Mar 24, 2023
0ecc3cb
test: clean up
mutdmour Mar 24, 2023
d70001b
test: update number
mutdmour Mar 24, 2023
0b822f7
test: add z-index tests
mutdmour Mar 24, 2023
5df4660
Merge branch 'master' of github.com:n8n-io/n8n into n8n-6040-stickies
mutdmour Mar 27, 2023
06dc9af
Merge branch 'master' of github.com:n8n-io/n8n into n8n-6040-stickies
mutdmour Apr 21, 2023
a609451
test: address comments
mutdmour Apr 21, 2023
71f6d3a
test: fix mistake
mutdmour Apr 21, 2023
33ae79d
Merge branch 'master' of github.com:n8n-io/n8n into n8n-6040-stickies
mutdmour Apr 21, 2023
5dab15a
test: wait on save
mutdmour Apr 21, 2023
ce5f1e3
test: try button instead
mutdmour Apr 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 262 additions & 0 deletions cypress/e2e/25-stickies.cy.ts
Original file line number Diff line number Diff line change
@@ -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);
}
22 changes: 22 additions & 0 deletions cypress/pages/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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();
Expand Down
11 changes: 6 additions & 5 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
2 changes: 1 addition & 1 deletion cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/editor-ui/src/components/Node/NodeCreation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<div
:class="[$style.addStickyButton, showStickyButton ? $style.visibleButton : '']"
@click="addStickyNote"
data-test-id="add-sticky-button"
>
<n8n-icon-button
size="medium"
Expand Down
8 changes: 7 additions & 1 deletion packages/editor-ui/src/components/Sticky.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:ref="data.name"
:style="stickyPosition"
:data-name="data.name"
data-test-id="sticky"
>
<div
:class="{
Expand Down Expand Up @@ -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>
Expand Down