tests(svelte) WIP added some e2e tests and edges example
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { SvelteFlowProvider } from '@xyflow/svelte';
|
||||||
|
|
||||||
|
import Flow from './Flow.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SvelteFlowProvider>
|
||||||
|
<Flow />
|
||||||
|
</SvelteFlowProvider>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
import { initialNodes, initialEdges } from './nodesAndEdges';
|
||||||
|
import { SvelteFlow } from '@xyflow/svelte';
|
||||||
|
|
||||||
|
import '@xyflow/svelte/dist/style.css';
|
||||||
|
|
||||||
|
const nodes = writable(initialNodes);
|
||||||
|
const edges = writable(initialEdges);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SvelteFlow {nodes} {edges} fitView />
|
||||||
@@ -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
|
||||||
|
// },
|
||||||
|
];
|
||||||
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -137,6 +137,7 @@ test.describe('NODES', () => {
|
|||||||
expect(edges).toHaveLength(0);
|
expect(edges).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: pressing backspace creates problems on webkit
|
||||||
test('deletable=false prevents deletion', async ({ page }) => {
|
test('deletable=false prevents deletion', async ({ page }) => {
|
||||||
const node = page.locator(`.${FRAMEWORK}-flow__node`).and(page.locator('[data-id="notDeletable"]'));
|
const node = page.locator(`.${FRAMEWORK}-flow__node`).and(page.locator('[data-id="notDeletable"]'));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user