Svelte NodeToolbar with E2E (#3643)

* Added NodeToolbar

* Added comments & fixed default behaviour in svelte

* Added e2e-tests for NodeToolbar component & added data-id to react NodeToolbar

* refactor(svelte/NodeToolbar): cleanup

* refactor(node-toolbar): add system utils

---------

Co-authored-by: moklick <info@moritzklack.com>
This commit is contained in:
peterkogo
2023-11-20 18:40:43 +01:00
committed by GitHub
parent b659443507
commit b8affc1c82
22 changed files with 564 additions and 71 deletions

View File

@@ -0,0 +1,93 @@
import { test, expect, Locator } from '@playwright/test';
import { FRAMEWORK } from './constants';
type Position = 'top' | 'right' | 'bottom' | 'left';
const positions: Position[] = ['top', 'right', 'bottom', 'left'];
type Alignment = 'start' | 'center' | 'end';
const alignments: Alignment[] = ['start', 'center', 'end'];
type Permutation = {
id: string;
position: Position;
align: Alignment;
};
const permutations: Permutation[] = [];
positions.forEach((position) => {
alignments.forEach((align) => {
permutations.push({
id: `node-${align}-${position}`,
position,
align,
});
});
});
test.describe('Node Toolbar', async () => {
test.beforeEach(async ({ page }) => {
// Go to the starting url before each test.
await page.goto('/tests/generic/node-toolbar/general');
// Wait till the edges are rendered
await page.waitForSelector('[data-id="first-edge"]', { timeout: 5000 });
});
test('all toolbars are positioned correctly', async ({ page }) => {
permutations.forEach(async (permutation) => {
const toolbar = page
.locator(`[data-id="${permutation.id}"]`)
.and(page.locator(`.${FRAMEWORK}-flow__node-toolbar`));
const node = page.locator(`[data-id="${permutation.id}"]`).and(page.locator(`.${FRAMEWORK}-flow__node`));
await expect(toolbar).toBeAttached();
await expect(node).toBeAttached();
const toolbarBox = await toolbar.boundingBox();
const nodeBox = await node.boundingBox();
switch (permutation.position) {
case 'top':
expect(toolbarBox!.y).toBeLessThan(nodeBox!.y);
break;
case 'right':
expect(toolbarBox!.x).toBeGreaterThan(nodeBox!.x);
break;
case 'bottom':
expect(toolbarBox!.y).toBeGreaterThan(nodeBox!.y);
break;
case 'left':
expect(toolbarBox!.x).toBeLessThan(nodeBox!.x);
break;
}
const dimension = permutation.position === 'top' || permutation.position === 'bottom' ? 'x' : 'y';
const extent = permutation.position === 'top' || permutation.position === 'bottom' ? 'width' : 'height';
switch (permutation.align) {
case 'start':
expect(Math.floor(toolbarBox![dimension])).toBe(Math.floor(nodeBox![dimension]));
break;
case 'center':
expect(Math.floor(toolbarBox![dimension] + toolbarBox![extent] * 0.5)).toBe(
Math.floor(nodeBox![dimension] + nodeBox![extent] * 0.5)
);
break;
case 'end':
expect(Math.floor(toolbarBox![dimension] + toolbarBox![extent])).toBe(
Math.floor(nodeBox![dimension] + nodeBox![extent])
);
break;
}
});
});
test('toolbar default behaviour', async ({ page }) => {
const node = page.locator('[data-id="default-node"]').and(page.locator(`.${FRAMEWORK}-flow__node`));
const toolbar = page.locator('[data-id="default-node"]').and(page.locator(`.${FRAMEWORK}-flow__node-toolbar`));
await expect(node).toBeAttached();
await expect(toolbar).not.toBeAttached();
await node.click();
await expect(toolbar).toBeAttached();
});
});

View File

@@ -1,23 +1,7 @@
import { test, expect } from '@playwright/test';
import { FRAMEWORK } from './constants';
const MATCH_ALL_NUMBERS = /[\d\.]+/g;
// Type "Locator" not exported...
async function getTransform(element) {
const transformString = await element.evaluate((el) => {
return el.style.transform;
});
// 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]),
};
}
import { getTransform } from './utils';
test.describe('PANE DEFAULT', () => {
test.beforeEach(async ({ page }) => {

View File

@@ -0,0 +1,16 @@
const MATCH_ALL_NUMBERS = /[\d\.]+/g;
// Type "Locator" not exported...
export async function getTransform(element) {
const transformString = await element.evaluate((el) => {
return el.style.transform;
});
// 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]),
};
}