From 0b7613c64eb1bff80491f1db686f9a5c0fd0d80f Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 2 Nov 2023 16:29:22 +0100 Subject: [PATCH] Added tests for pane --- .../tests/pane/{ => default}/+page.svelte | 0 .../tests/pane/{ => default}/Flow.svelte | 2 +- .../tests/pane/{ => default}/nodesAndEdges.ts | 10 +- .../tests/pane/non-default/+page.svelte | 9 + .../routes/tests/pane/non-default/Flow.svelte | 19 ++ .../tests/pane/non-default/nodesAndEdges.ts | 33 ++++ tests/playwright/e2e/pane.spec.ts | 182 ++++++++++++++++-- 7 files changed, 233 insertions(+), 22 deletions(-) rename examples/svelte/src/routes/tests/pane/{ => default}/+page.svelte (100%) rename examples/svelte/src/routes/tests/pane/{ => default}/Flow.svelte (82%) rename examples/svelte/src/routes/tests/pane/{ => default}/nodesAndEdges.ts (75%) create mode 100644 examples/svelte/src/routes/tests/pane/non-default/+page.svelte create mode 100644 examples/svelte/src/routes/tests/pane/non-default/Flow.svelte create mode 100644 examples/svelte/src/routes/tests/pane/non-default/nodesAndEdges.ts diff --git a/examples/svelte/src/routes/tests/pane/+page.svelte b/examples/svelte/src/routes/tests/pane/default/+page.svelte similarity index 100% rename from examples/svelte/src/routes/tests/pane/+page.svelte rename to examples/svelte/src/routes/tests/pane/default/+page.svelte diff --git a/examples/svelte/src/routes/tests/pane/Flow.svelte b/examples/svelte/src/routes/tests/pane/default/Flow.svelte similarity index 82% rename from examples/svelte/src/routes/tests/pane/Flow.svelte rename to examples/svelte/src/routes/tests/pane/default/Flow.svelte index 6686c907..ae2093ed 100644 --- a/examples/svelte/src/routes/tests/pane/Flow.svelte +++ b/examples/svelte/src/routes/tests/pane/default/Flow.svelte @@ -9,4 +9,4 @@ const edges = writable(initialEdges); - + diff --git a/examples/svelte/src/routes/tests/pane/nodesAndEdges.ts b/examples/svelte/src/routes/tests/pane/default/nodesAndEdges.ts similarity index 75% rename from examples/svelte/src/routes/tests/pane/nodesAndEdges.ts rename to examples/svelte/src/routes/tests/pane/default/nodesAndEdges.ts index 81e88cc4..7d2e0522 100644 --- a/examples/svelte/src/routes/tests/pane/nodesAndEdges.ts +++ b/examples/svelte/src/routes/tests/pane/default/nodesAndEdges.ts @@ -21,15 +21,13 @@ export const initialNodes: Node[] = [ export const initialEdges: Edge[] = [ { - id: 'edge-with-class', + id: 'first-edge', source: '1', - target: '2', - class: 'edge-class-test' + target: '2' }, { - id: 'edge-with-style', + id: 'second-edge', source: '1', - target: '3', - style: 'stroke: red;' + target: '3' } ]; diff --git a/examples/svelte/src/routes/tests/pane/non-default/+page.svelte b/examples/svelte/src/routes/tests/pane/non-default/+page.svelte new file mode 100644 index 00000000..12dec33c --- /dev/null +++ b/examples/svelte/src/routes/tests/pane/non-default/+page.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/examples/svelte/src/routes/tests/pane/non-default/Flow.svelte b/examples/svelte/src/routes/tests/pane/non-default/Flow.svelte new file mode 100644 index 00000000..d06a8de3 --- /dev/null +++ b/examples/svelte/src/routes/tests/pane/non-default/Flow.svelte @@ -0,0 +1,19 @@ + + + diff --git a/examples/svelte/src/routes/tests/pane/non-default/nodesAndEdges.ts b/examples/svelte/src/routes/tests/pane/non-default/nodesAndEdges.ts new file mode 100644 index 00000000..7d2e0522 --- /dev/null +++ b/examples/svelte/src/routes/tests/pane/non-default/nodesAndEdges.ts @@ -0,0 +1,33 @@ +import type { Edge, Node } from '@xyflow/svelte'; + +export const initialNodes: Node[] = [ + { + id: '1', + data: { label: '1' }, + position: { x: 0, y: 0 }, + type: 'input' + }, + { + id: '2', + data: { label: '2' }, + position: { x: -100, y: 100 } + }, + { + id: '3', + data: { label: '3' }, + position: { x: 100, y: 100 } + } +]; + +export const initialEdges: Edge[] = [ + { + id: 'first-edge', + source: '1', + target: '2' + }, + { + id: 'second-edge', + source: '1', + target: '3' + } +]; diff --git a/tests/playwright/e2e/pane.spec.ts b/tests/playwright/e2e/pane.spec.ts index c3899f12..fab03bdb 100644 --- a/tests/playwright/e2e/pane.spec.ts +++ b/tests/playwright/e2e/pane.spec.ts @@ -1,15 +1,36 @@ import { test, expect } from '@playwright/test'; import { FRAMEWORK } from './constants'; +import { transform } from 'typescript'; -test.describe('PANE', () => { - test.beforeEach(async ({ page }) => { - // Go to the starting url before each test. - await page.goto('/tests/pane'); +const MATCH_ALL_NUMBERS = /[\d\.]+/g; + +// Type "Locator" not exported... +async function getTransform(element) { + const transformString = await element.evaluate((el) => { + return el.style.transform; }); - test.describe('pan', () => { - test('panning the pane', async ({ page }) => { + // Parses all numbers in f.ex "translate(590px, 324px) scale(2)"" + const transforms = transformString.match(MATCH_ALL_NUMBERS); + return { + translateX: parseFloat(transforms![0]), + translateY: parseFloat(transforms![1]), + scale: parseFloat(transforms![2]), + }; +} + +test.describe('PANE DEFAULT', () => { + test.beforeEach(async ({ page }) => { + // Go to the starting url before each test. + await page.goto('/tests/pane/default'); + + // Wait till the edges are rendered + await page.waitForSelector('#first-edge', { timeout: 5000 }); + }); + + test.describe('pan & zoom', () => { + test('panning the pane moves it', async ({ page }) => { const pane = page.locator(`.${FRAMEWORK}-flow__pane`); const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); @@ -17,20 +38,151 @@ test.describe('PANE', () => { const paneBox = await pane.boundingBox(); - const viewportTransformBeforePan = await viewport.evaluate((element) => { - return element.style.transform; - }); + const transformsBefore = await getTransform(viewport); await pane.hover(); await page.mouse.down(); - await page.mouse.move(paneBox!.x + 150, paneBox!.y + 100); - await page.mouse.up(); + // Move pane by 100, 100 + await page.mouse.move(paneBox!.x + paneBox!.width * 0.5 + 100, paneBox!.y + paneBox!.height * 0.5 + 100); - const viewportTransformAfterPan = await viewport.evaluate((element) => { - return element.style.transform; - }); + const transformsAfter = await getTransform(viewport); - expect(viewportTransformBeforePan).toBe(viewportTransformAfterPan); + expect(transformsAfter.translateX - transformsBefore.translateX).toBe(100); + expect(transformsAfter.translateY - transformsBefore.translateY).toBe(100); + }); + + test('scrolling the default pane zooms it', async ({ page }) => { + const pane = page.locator(`.${FRAMEWORK}-flow__pane`); + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + + await expect(pane).toBeAttached(); + + const transformsBefore = await getTransform(viewport); + + await pane.hover(); + await page.mouse.wheel(0, 100); + + const transformsAfter = await getTransform(viewport); + + expect(transformsAfter.scale).not.toBe(transformsBefore.scale); + }); + }); + + test.describe('minZoom & maxZoom', () => { + test('minZoom works as intended', async ({ page }) => { + const pane = page.locator(`.${FRAMEWORK}-flow__pane`); + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + + await expect(pane).toBeAttached(); + + await pane.hover(); + + // Zoom out + await page.mouse.wheel(5000, 5000); + + const transformsMinZoom = await getTransform(viewport); + expect(transformsMinZoom.scale).toBe(0.25); + }); + + test('maxZoom works as intended', async ({ page }) => { + const pane = page.locator(`.${FRAMEWORK}-flow__pane`); + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + + await expect(pane).toBeAttached(); + + await pane.hover(); + + // Zoom in + await page.mouse.wheel(-5000, -5000); + + const transformsMaxZoom = await getTransform(viewport); + expect(transformsMaxZoom.scale).toBe(4); + }); + }); + + test.describe('autoPan', () => { + test('autoPanOnNodeDrag works as intended', async ({ page }) => { + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + const node = page.locator('[data-id="1"]'); + + await expect(node).toBeAttached(); + + const transformBefore = await getTransform(viewport); + + await node.hover(); + await page.mouse.down(); + await page.mouse.move(0, 0); + await page.waitForTimeout(500); + await page.mouse.move(100, 100); + + const transformAfter = await getTransform(viewport); + + await expect(transformAfter.translateX).toBeGreaterThan(transformBefore.translateX); + await expect(transformAfter.translateY).toBeGreaterThan(transformBefore.translateY); + }); + + test('autoPanOnConnect works as intended', async ({ page }) => { + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + const handle = page.locator('[data-id="1"] .svelte-flow__handle'); + + await expect(handle).toBeAttached(); + + const transformBefore = await getTransform(viewport); + + await handle.hover(); + await page.mouse.down(); + await page.mouse.move(0, 0); + await page.waitForTimeout(500); + await page.mouse.move(100, 100); + + const transformAfter = await getTransform(viewport); + + await expect(transformAfter.translateX).toBeGreaterThan(transformBefore.translateX); + await expect(transformAfter.translateY).toBeGreaterThan(transformBefore.translateY); }); }); }); + +test.describe('PANE NON-DEFAULT', () => { + test.beforeEach(async ({ page }) => { + // Go to the starting url before each test. + await page.goto('/tests/pane/non-default'); + + // Wait till the edges are rendered + await page.waitForSelector('#first-edge', { timeout: 5000 }); + }); + + test.describe('pan & zoom', () => { + test('panOnScroll pans the pane on scrolling', async ({ page }) => { + const pane = page.locator(`.${FRAMEWORK}-flow__pane`); + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + + await expect(pane).toBeAttached(); + + const transformsBefore = await getTransform(viewport); + + await pane.hover(); + await page.mouse.wheel(100, 100); + + const transformsAfter = await getTransform(viewport); + + expect(transformsAfter.translateX).not.toBe(transformsBefore.translateX); + expect(transformsAfter.translateY).not.toBe(transformsBefore.translateY); + }); + + test('intialViewport', async ({ page }) => { + const pane = page.locator(`.${FRAMEWORK}-flow__pane`); + const viewport = page.locator(`.${FRAMEWORK}-flow__viewport`); + + await expect(pane).toBeAttached(); + + const viewportTransform = await getTransform(viewport); + + expect(viewportTransform.translateX).toBe(1.23); + expect(viewportTransform.translateY).toBe(9.87); + expect(viewportTransform.scale).toBe(1.234); + }); + }); +}); + +//TODO: Inverse: Not zooming/panning when disabled