From 9d386abb2aa299a94955d33751e258380b26c1c0 Mon Sep 17 00:00:00 2001
From: Peter
Date: Mon, 30 Oct 2023 13:24:25 +0100
Subject: [PATCH] tests(svelte) WIP added some e2e tests and edges example
---
.../src/routes/tests/edges/+page.svelte | 9 +
.../svelte/src/routes/tests/edges/Flow.svelte | 12 ++
.../src/routes/tests/edges/nodesAndEdges.ts | 157 ++++++++++++++++++
tests/playwright/e2e/edges.spec.ts | 120 +++++++++++++
tests/playwright/e2e/nodes.spec.ts | 1 +
5 files changed, 299 insertions(+)
create mode 100644 examples/svelte/src/routes/tests/edges/+page.svelte
create mode 100644 examples/svelte/src/routes/tests/edges/Flow.svelte
create mode 100644 examples/svelte/src/routes/tests/edges/nodesAndEdges.ts
create mode 100644 tests/playwright/e2e/edges.spec.ts
diff --git a/examples/svelte/src/routes/tests/edges/+page.svelte b/examples/svelte/src/routes/tests/edges/+page.svelte
new file mode 100644
index 00000000..12dec33c
--- /dev/null
+++ b/examples/svelte/src/routes/tests/edges/+page.svelte
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/examples/svelte/src/routes/tests/edges/Flow.svelte b/examples/svelte/src/routes/tests/edges/Flow.svelte
new file mode 100644
index 00000000..6686c907
--- /dev/null
+++ b/examples/svelte/src/routes/tests/edges/Flow.svelte
@@ -0,0 +1,12 @@
+
+
+
diff --git a/examples/svelte/src/routes/tests/edges/nodesAndEdges.ts b/examples/svelte/src/routes/tests/edges/nodesAndEdges.ts
new file mode 100644
index 00000000..6e0d969a
--- /dev/null
+++ b/examples/svelte/src/routes/tests/edges/nodesAndEdges.ts
@@ -0,0 +1,157 @@
+import { MarkerType, type Edge, type 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 }
+ },
+ {
+ id: '4',
+ data: { label: '4' },
+ position: { x: -100, y: 200 }
+ },
+ {
+ id: '5',
+ data: { label: '5' },
+ position: { x: 100, y: 200 }
+ },
+ {
+ id: '6',
+ data: { label: '6' },
+ position: { x: -100, y: 300 }
+ },
+ {
+ id: '7',
+ data: { label: '7' },
+ position: { x: 100, y: 300 }
+ },
+ {
+ id: '8',
+ data: { label: '8' },
+ position: { x: -100, y: 400 }
+ },
+ {
+ id: '9',
+ data: { label: '9' },
+ position: { x: 100, y: 400 }
+ },
+ {
+ id: '10',
+ data: { label: '10' },
+ position: { x: -100, y: 500 }
+ },
+ {
+ id: '11',
+ data: { label: '11' },
+ position: { x: 100, y: 500 }
+ },
+ {
+ id: '12',
+ data: { label: '12' },
+ position: { x: -100, y: 600 }
+ },
+ {
+ id: '13',
+ data: { label: '13' },
+ position: { x: 100, y: 600 }
+ }
+];
+
+export const initialEdges: Edge[] = [
+ {
+ id: 'edge-with-class',
+ source: '1',
+ target: '2',
+ class: 'edge-class-test'
+ },
+ {
+ id: 'edge-with-style',
+ source: '1',
+ target: '3',
+ style: 'stroke: red;'
+ },
+ {
+ id: 'hidden-edge',
+ source: '2',
+ target: '4',
+ label: 'hidden',
+ hidden: true
+ },
+ {
+ id: 'animated-edge',
+ source: '3',
+ target: '5',
+ label: 'animated',
+ animated: true
+ },
+ {
+ id: 'not-selectable-edge',
+ source: '4',
+ target: '6',
+ label: 'not-selectable',
+ selectable: false
+ },
+ {
+ id: 'not-deletable',
+ source: '5',
+ target: '7',
+ label: 'not-deletable',
+ deletable: false
+ },
+ {
+ id: 'z-index',
+ source: '6',
+ target: '8',
+ label: 'z-index',
+ zIndex: 3141592
+ },
+ {
+ id: 'aria-label',
+ source: '7',
+ target: '9',
+ label: 'aria-label',
+ ariaLabel: 'aria-label-test'
+ },
+ {
+ id: 'interaction-width',
+ source: '8',
+ target: '10',
+ label: 'interaction-width',
+ interactionWidth: 42
+ },
+ {
+ id: 'markers',
+ source: '9',
+ target: '11',
+ label: 'markers',
+ markerEnd: { type: MarkerType.Arrow },
+ markerStart: { type: MarkerType.ArrowClosed }
+ }
+ // {
+ // id: 'updatable',
+ // source: '9',
+ // target: '11',
+ // label: 'focusable',
+ // updatable: true
+ // },
+ // {
+ // id: 'not-focusable',
+ //
+ // source: '5',
+ // target: '7',
+ // label: 'not-focusable',
+ // focusable: false
+ // },
+];
diff --git a/tests/playwright/e2e/edges.spec.ts b/tests/playwright/e2e/edges.spec.ts
new file mode 100644
index 00000000..da5a3feb
--- /dev/null
+++ b/tests/playwright/e2e/edges.spec.ts
@@ -0,0 +1,120 @@
+import { test, expect } from '@playwright/test';
+
+import { FRAMEWORK } from './constants';
+
+test.describe('EDGES', () => {
+ test.beforeEach(async ({ page }) => {
+ // Go to the starting url before each test.
+ await page.goto('/tests/edges');
+
+ // Timeout get's ignored and tests timeout after 200ms ???
+ // page.waitForSelector('[data-id="edge-with-class"]', { timeout: 5000 });
+ });
+
+ test.describe('selection', () => {
+ test('selecting an edge by click', async ({ page }) => {
+ const edge = page.locator('.svelte-flow__edge').and(page.locator('[data-id="edge-with-class"]'));
+
+ await expect(edge).toBeAttached();
+ await edge.click();
+ await expect(edge).toHaveClass(/selected/);
+ });
+
+ // test('selecting multiple edges by meta-click', async ({ page }) => {
+ // const edge1 = page.locator('[data-id="edge-with-class"]');
+ // const edge2 = page.locator('[data-id="edge-with-style"]');
+
+ // await expect(edge1).toBeAttached();
+ // await expect(edge2).toBeAttached();
+
+ // await edge1.click();
+ // await page.keyboard.down('Meta');
+ // await edge2.click();
+
+ // await expect(edge1).toHaveClass(/selected/);
+ // await expect(edge2).toHaveClass(/selected/);
+ // });
+ });
+
+ test.describe('properties', () => {
+ test('classes get applied', async ({ page }) => {
+ const edge = page.locator('[data-id="edge-with-class"]');
+
+ await expect(edge).toHaveClass(/edge-class-test/);
+ });
+
+ test('styles get applied', async ({ page }) => {
+ const edge = page.locator('#edge-with-style');
+
+ await expect(edge).toHaveCSS('stroke', 'rgb(255, 0, 0)');
+ });
+
+ test('hidden=true hides edge', async ({ page }) => {
+ const edge = page.locator('#hidden-edge');
+
+ await expect(edge).not.toBeVisible();
+ });
+
+ test('animated=true add "animated" class', async ({ page }) => {
+ const edge = page.locator('[data-id="animated-edge"]');
+
+ await expect(edge).toHaveClass(/animated/);
+ });
+
+ test('selectable=false prevents selecting of edges', async ({ page }) => {
+ const edge = page.locator('[data-id="not-selectable-edge"]');
+
+ await expect(edge).toBeAttached();
+ await expect(edge).not.toHaveClass(/selected/);
+
+ // For some reason these commands do not work
+ // await expect(edge).toBeInViewport();
+ // await edge.click();
+
+ const edgeBox = await edge.boundingBox();
+
+ await page.mouse.move(edgeBox!.x + edgeBox!.width * 0.5, edgeBox!.y + edgeBox!.height * 0.5);
+ await page.mouse.down();
+ await page.mouse.up();
+
+ await expect(edge).not.toHaveClass(/selected/);
+ });
+
+ test('deleting edges is possible', async ({ page }) => {
+ const edge = page.locator('[data-id="edge-with-class"]');
+
+ await expect(edge).toBeAttached();
+
+ const edgeBox = await edge.boundingBox();
+
+ await edge.click();
+ await expect(edge).toHaveClass(/selected/);
+
+ await page.keyboard.press('Backspace');
+
+ await expect(edge).not.toBeAttached();
+ });
+
+ test('deletable=false prevents deleting of edges', async ({ page }) => {
+ const edge = page.locator('[data-id="not-deletable"]');
+
+ await expect(edge).toBeAttached();
+
+ // For some reason these commands do not work
+ // await expect(edge).toBeInViewport();
+ // await edge.click();
+
+ const edgeBox = await edge.boundingBox();
+
+ await page.mouse.move(edgeBox!.x + edgeBox!.width * 0.5, edgeBox!.y + edgeBox!.height * 0.5);
+ await page.mouse.down();
+ await page.mouse.up();
+
+ // TODO: times out on webkit
+ await expect(edge).toHaveClass(/selected/);
+
+ await page.keyboard.press('Backspace');
+ await expect(edge).toBeAttached();
+ });
+ });
+});
diff --git a/tests/playwright/e2e/nodes.spec.ts b/tests/playwright/e2e/nodes.spec.ts
index 2136c3f1..697cefa6 100644
--- a/tests/playwright/e2e/nodes.spec.ts
+++ b/tests/playwright/e2e/nodes.spec.ts
@@ -137,6 +137,7 @@ test.describe('NODES', () => {
expect(edges).toHaveLength(0);
});
+ // TODO: pressing backspace creates problems on webkit
test('deletable=false prevents deletion', async ({ page }) => {
const node = page.locator(`.${FRAMEWORK}-flow__node`).and(page.locator('[data-id="notDeletable"]'));