From 5aa94e2e13492330dc1fdae57f489d4b7f40d38a Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Thu, 13 Oct 2022 18:56:00 +0200 Subject: [PATCH] tests: add `tryAssertion` command to replace `cy.wait` --- .../1-store/edges/addSelectedEdges.cy.ts | 10 ++--- .../1-store/edges/removeSelectedEdges.cy.ts | 4 +- .../elements/removeSelectedElements.cy.ts | 4 +- .../1-store/nodes/addSelectedNodes.cy.ts | 4 +- .../1-store/nodes/removeSelectedNodes.cy.ts | 4 +- .../1-store/viewpane/deleteKeyCode.cy.ts | 4 +- .../1-store/viewpane/selectionKeyCode.cy.ts | 6 +-- .../component/2-vue-flow/updateEdge.cy.ts | 4 +- .../component/2-vue-flow/viewpane.cy.ts | 39 +++++++++++++++++++ e2e/cypress/component/2-vue-flow/viewpane.ts | 20 ---------- e2e/cypress/support/component.ts | 21 ++++++++++ 11 files changed, 78 insertions(+), 42 deletions(-) create mode 100644 e2e/cypress/component/2-vue-flow/viewpane.cy.ts delete mode 100644 e2e/cypress/component/2-vue-flow/viewpane.ts diff --git a/e2e/cypress/component/1-store/edges/addSelectedEdges.cy.ts b/e2e/cypress/component/1-store/edges/addSelectedEdges.cy.ts index 5f3d41cd..35b00265 100644 --- a/e2e/cypress/component/1-store/edges/addSelectedEdges.cy.ts +++ b/e2e/cypress/component/1-store/edges/addSelectedEdges.cy.ts @@ -20,7 +20,7 @@ describe('Store Action: `addSelectedEdges`', () => { }) it('adds selected edges to store', () => { - expect(store.getSelectedEdges.value).to.have.length(randomNumber) + cy.tryAssertion(() => expect(store.getSelectedEdges.value).to.have.length(randomNumber)) }) it('adds `selected` class to edges', () => { @@ -33,14 +33,10 @@ describe('Store Action: `addSelectedEdges`', () => { if (index < randomNumber) { expect(!!storedEdge?.selected).to.eq(true) - cy.wait(1).then(() => { - expect(edge).to.have.class('selected') - }) + cy.tryAssertion(() => expect(edge).to.have.class('selected')) } else { expect(!!storedEdge?.selected).to.eq(false) - cy.wait(1).then(() => { - expect(edge).to.not.have.class('selected') - }) + cy.tryAssertion(() => expect(edge).to.not.have.class('selected')) } }) }) diff --git a/e2e/cypress/component/1-store/edges/removeSelectedEdges.cy.ts b/e2e/cypress/component/1-store/edges/removeSelectedEdges.cy.ts index e43cd583..bcbf8f69 100644 --- a/e2e/cypress/component/1-store/edges/removeSelectedEdges.cy.ts +++ b/e2e/cypress/component/1-store/edges/removeSelectedEdges.cy.ts @@ -36,12 +36,12 @@ describe('Store Action: `removeSelectedEdges`', () => { if (index >= randomNumber2 && index < randomNumber) { expect(!!storedEdge?.selected).to.eq(true) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(edge).to.have.class('selected') }) } else { expect(!!storedEdge?.selected).to.eq(false) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(edge).to.not.have.class('selected') }) } diff --git a/e2e/cypress/component/1-store/elements/removeSelectedElements.cy.ts b/e2e/cypress/component/1-store/elements/removeSelectedElements.cy.ts index 70a37adc..e8bfdfd9 100644 --- a/e2e/cypress/component/1-store/elements/removeSelectedElements.cy.ts +++ b/e2e/cypress/component/1-store/elements/removeSelectedElements.cy.ts @@ -35,7 +35,7 @@ describe('Store Action: `removeSelectedElements`', () => { ), ) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(store.getSelectedElements.value).to.have.length(randomNumber - randomNumber2) }) }) @@ -45,7 +45,7 @@ describe('Store Action: `removeSelectedElements`', () => { store.addSelectedElements(Array.from({ length: randomNumber }, (_, i) => store.getElements.value[i])) store.removeSelectedElements() - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(store.getSelectedElements.value).to.have.length(0) }) }) diff --git a/e2e/cypress/component/1-store/nodes/addSelectedNodes.cy.ts b/e2e/cypress/component/1-store/nodes/addSelectedNodes.cy.ts index 4133109d..2b915d70 100644 --- a/e2e/cypress/component/1-store/nodes/addSelectedNodes.cy.ts +++ b/e2e/cypress/component/1-store/nodes/addSelectedNodes.cy.ts @@ -33,12 +33,12 @@ describe('Store Action: `addSelectedNodes`', () => { if (index < randomNumber) { expect(!!storedNode?.selected).to.eq(true) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(node).to.have.class('selected') }) } else { expect(!!storedNode?.selected).to.eq(false) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(node).to.not.have.class('selected') }) } diff --git a/e2e/cypress/component/1-store/nodes/removeSelectedNodes.cy.ts b/e2e/cypress/component/1-store/nodes/removeSelectedNodes.cy.ts index 5b4530e3..508c98e6 100644 --- a/e2e/cypress/component/1-store/nodes/removeSelectedNodes.cy.ts +++ b/e2e/cypress/component/1-store/nodes/removeSelectedNodes.cy.ts @@ -36,12 +36,12 @@ describe('Store Action: `removeSelectedNodes`', () => { if (index >= randomNumber2 && index < randomNumber) { expect(!!storedNode?.selected).to.eq(true) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(node).to.have.class('selected') }) } else { expect(!!storedNode?.selected).to.eq(false) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(node).to.not.have.class('selected') }) } diff --git a/e2e/cypress/component/1-store/viewpane/deleteKeyCode.cy.ts b/e2e/cypress/component/1-store/viewpane/deleteKeyCode.cy.ts index a7ba29c1..91d813f4 100644 --- a/e2e/cypress/component/1-store/viewpane/deleteKeyCode.cy.ts +++ b/e2e/cypress/component/1-store/viewpane/deleteKeyCode.cy.ts @@ -19,7 +19,7 @@ describe('Store State: `deleteKeyCode`', () => { cy.get('body').trigger('keydown', { key: 'Backspace' }) - cy.wait(1).then(() => { + cy.tryAssertion(() => { cy.get(`[data-id="${nodes[0].id}"]`).should('not.exist') expect(store.nodes.value.some((node) => node.id === nodes[0].id)).to.equal(false) }) @@ -33,7 +33,7 @@ describe('Store State: `deleteKeyCode`', () => { cy.get('body').trigger('keydown', { key: 'Delete' }) - cy.wait(1).then(() => { + cy.tryAssertion(() => { cy.get(`[data-id="${nodes[0].id}"]`).should('not.exist') expect(store.nodes.value.some((node) => node.id === nodes[0].id)).to.equal(false) }) diff --git a/e2e/cypress/component/1-store/viewpane/selectionKeyCode.cy.ts b/e2e/cypress/component/1-store/viewpane/selectionKeyCode.cy.ts index 42b5351d..78d91283 100644 --- a/e2e/cypress/component/1-store/viewpane/selectionKeyCode.cy.ts +++ b/e2e/cypress/component/1-store/viewpane/selectionKeyCode.cy.ts @@ -33,7 +33,7 @@ describe('Store State: `selectionKeyCode`', () => { cy.get('body').trigger('keyup', { key: 'Shift', release: true }) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(store.getSelectedElements.value).to.not.have.length(0) }) }) @@ -60,7 +60,7 @@ describe('Store State: `selectionKeyCode`', () => { cy.get('body').trigger('keyup', { key: 'Control', release: true }) - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(store.getSelectedElements.value).to.not.have.length(0) }) }) @@ -84,7 +84,7 @@ describe('Store State: `selectionKeyCode`', () => { }) .click() - cy.wait(1).then(() => { + cy.tryAssertion(() => { expect(store.getSelectedElements.value).to.not.have.length(0) }) }) diff --git a/e2e/cypress/component/2-vue-flow/updateEdge.cy.ts b/e2e/cypress/component/2-vue-flow/updateEdge.cy.ts index 9cdef0ab..16ca5f76 100644 --- a/e2e/cypress/component/2-vue-flow/updateEdge.cy.ts +++ b/e2e/cypress/component/2-vue-flow/updateEdge.cy.ts @@ -39,7 +39,7 @@ describe('Check if edges are updatable', () => { const edgeAnchor = cy.get('.vue-flow__edgeupdater[data-type="target"]') const targetTargetHandle = cy.get(`[data-nodeid="3"].target`) - targetTargetHandle.then((handle) => { + targetTargetHandle.then(async (handle) => { const target = handle[0] const { x, y } = target.getBoundingClientRect() @@ -61,7 +61,7 @@ describe('Check if edges are updatable', () => { view: win, }) - cy.wait(100).then(() => { + await cy.tryAssertion(() => { const storedEdges = store.edges.value expect(storedEdges).to.have.length(1) expect(storedEdges[0].target).to.equal('3') diff --git a/e2e/cypress/component/2-vue-flow/viewpane.cy.ts b/e2e/cypress/component/2-vue-flow/viewpane.cy.ts new file mode 100644 index 00000000..f758eee8 --- /dev/null +++ b/e2e/cypress/component/2-vue-flow/viewpane.cy.ts @@ -0,0 +1,39 @@ +import { useVueFlow } from '@vue-flow/core' +import { getElements } from '../../utils' + +const { nodes } = getElements() + +describe('Viewpane drag / zoom', () => { + const store = useVueFlow({ id: 'test' }) + beforeEach(() => { + cy.vueFlow({ + nodes, + }) + }) + + it('drags pane', () => { + cy.window().then(async (win) => { + const initialViewport = store.viewport.value + cy.get('.vue-flow__pane') + .should('be.visible') + .trigger('mousedown', 'center', { force: true, view: win }) + .trigger('mousemove', { + force: true, + clientX: -(store.dimensions.value.width / 10), + clientY: store.dimensions.value.height / 2, + view: win, + }) + .trigger('mouseup', { force: true, view: win }) + + await cy.tryAssertion(() => { + cy.get('.vue-flow__transformationpane') + .should('be.visible') + .should( + 'have.css', + 'transform', + `matrix(${store.viewport.value.zoom}, 0, 0, ${store.viewport.value.zoom}, ${store.viewport.value.x}, ${store.viewport.value.y})`, + ) + }) + }) + }) +}) diff --git a/e2e/cypress/component/2-vue-flow/viewpane.ts b/e2e/cypress/component/2-vue-flow/viewpane.ts deleted file mode 100644 index 85b18f4f..00000000 --- a/e2e/cypress/component/2-vue-flow/viewpane.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getElements } from '../../utils' - -const { nodes } = getElements() - -describe('Viewpane drag / zoom', () => { - beforeEach(() => { - cy.vueFlow({ - nodes, - }) - }) - - it('drag pane', () => { - cy.window().then((win) => { - cy.get('.vue-flow__pane') - .trigger('mousedown', 'center', { force: true, view: win }) - .trigger('mousemove', { force: true, clientX: 500, clientY: 250, view: win }) - .trigger('mouseup', { force: true, view: win }) - }) - }) -}) diff --git a/e2e/cypress/support/component.ts b/e2e/cypress/support/component.ts index b03a66fc..7b354d15 100644 --- a/e2e/cypress/support/component.ts +++ b/e2e/cypress/support/component.ts @@ -49,6 +49,24 @@ const useViewPort = () => cy.get('.vue-flow__viewport') const useTransformationPane = () => cy.get('.vue-flow__transformationpane') +const retry = (assertion: Function, { interval = 20, timeout = 1000 } = {}) => { + return new Promise((resolve, reject) => { + const startTime = Date.now() + + const tryAgain = () => { + setTimeout(() => { + try { + resolve(assertion()) + } catch (err) { + Date.now() - startTime > timeout ? reject(err) : tryAgain() + } + }, interval) + } + + tryAgain() + }) +} + // Augment the Cypress namespace to include type definitions for // your custom command. // Alternatively, can be defined in cypress/support/component.d.ts @@ -60,6 +78,7 @@ declare global { vueFlow: typeof mountVueFlow viewPort: typeof useViewPort transformationPane: typeof useTransformationPane + tryAssertion: typeof retry } } } @@ -72,5 +91,7 @@ Cypress.Commands.add('viewPort', useViewPort) Cypress.Commands.add('transformationPane', useTransformationPane) +Cypress.Commands.add('tryAssertion', retry) + // Example use: // cy.mount(MyComponent)