Skip to content

Commit

Permalink
Merge with dev
Browse files Browse the repository at this point in the history
  • Loading branch information
josemitoribio committed Nov 5, 2024
2 parents 08b3ada + 24699c2 commit 0c4d463
Show file tree
Hide file tree
Showing 184 changed files with 3,099 additions and 648 deletions.
111 changes: 111 additions & 0 deletions e2e/canvas/move-shape-using-keyboard.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { test, expect } from '@playwright/test';
import {
dragAndDrop,
getLocatorPosition,
getByShapeType,
getShapePosition,
moveSelected,
} from '../helpers';
import { Group } from 'konva/lib/Group';

const numShifts: number = 10;

test('move shape with the keyboard - left', async ({ page }) => {
await page.goto('');

const component = page.getByAltText('Input', { exact: true });
const position = await getLocatorPosition(component);

await dragAndDrop(page, position, {
x: position.x + 500,
y: position.y - 240,
});

const inputShape = (await getByShapeType(page, 'input')) as Group;
expect(inputShape).toBeDefined();

const draggedPosition = await getShapePosition(inputShape);

moveSelected(page, 'ArrowLeft', numShifts);

const inputShapeMoved = (await getByShapeType(page, 'input')) as Group;
const movedPosition = await getShapePosition(inputShapeMoved);

expect(movedPosition.x === draggedPosition.x - numShifts * 2).toBeTruthy();
expect(movedPosition.y === draggedPosition.y).toBeTruthy();
});

test('move shape with the keyboard - up', async ({ page }) => {
await page.goto('');

const component = page.getByAltText('Input', { exact: true });
const position = await getLocatorPosition(component);

await dragAndDrop(page, position, {
x: position.x + 500,
y: position.y - 240,
});

const inputShape = (await getByShapeType(page, 'input')) as Group;
expect(inputShape).toBeDefined();

const draggedPosition = await getShapePosition(inputShape);

moveSelected(page, 'ArrowUp', numShifts);

const inputShapeMoved = (await getByShapeType(page, 'input')) as Group;
const movedPosition = await getShapePosition(inputShapeMoved);

expect(movedPosition.x === draggedPosition.x).toBeTruthy();
expect(movedPosition.y === draggedPosition.y - numShifts * 2).toBeTruthy();
});

test('move shape with the keyboard - down', async ({ page }) => {
await page.goto('');

const component = page.getByAltText('Input', { exact: true });
const position = await getLocatorPosition(component);

await dragAndDrop(page, position, {
x: position.x + 500,
y: position.y - 240,
});

const inputShape = (await getByShapeType(page, 'input')) as Group;
expect(inputShape).toBeDefined();

const draggedPosition = await getShapePosition(inputShape);

moveSelected(page, 'ArrowDown', numShifts);

const inputShapeMoved = (await getByShapeType(page, 'input')) as Group;
const movedPosition = await getShapePosition(inputShapeMoved);

expect(movedPosition.x === draggedPosition.x).toBeTruthy();
expect(movedPosition.y === draggedPosition.y + numShifts * 2).toBeTruthy();
});

test('move shape with the keyboard - right', async ({ page }) => {
await page.goto('');

const component = page.getByAltText('Input', { exact: true });
const position = await getLocatorPosition(component);

await dragAndDrop(page, position, {
x: position.x + 500,
y: position.y - 240,
});

const inputShape = (await getByShapeType(page, 'input')) as Group;
expect(inputShape).toBeDefined();

const draggedPosition = await getShapePosition(inputShape);

moveSelected(page, 'ArrowRight', numShifts);

const inputShapeMoved = (await getByShapeType(page, 'input')) as Group;
const movedPosition = await getShapePosition(inputShapeMoved);

expect(movedPosition.x === draggedPosition.x + numShifts * 2).toBeTruthy();
expect(movedPosition.y === draggedPosition.y).toBeTruthy();
});
59 changes: 59 additions & 0 deletions e2e/helpers/konva-testing.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Page } from '@playwright/test';
import { Layer } from 'konva/lib/Layer';
import { Shape } from 'konva/lib/Shape';
import { Group } from 'konva/lib/Group';
import { E2E_CanvasItemKeyAttrs } from './types/e2e-types';
import { getCanvasBoundingBox } from './position.helpers';

const getLayer = async (page: Page): Promise<Layer> =>
await page.evaluate(() => {
Expand Down Expand Up @@ -59,3 +61,60 @@ export const getTransformer = async (page: Page): Promise<any> => {
});
return transformer;
};

export const getWithinCanvasItemList = async (
page: Page
): Promise<Group['attrs'][]> => {
const items = await page.evaluate(() => {
return window.__TESTING_KONVA_LAYER__.find(
(c: any) => c.getType('Group') && (c.attrs['data-id'] as Group)
);
});
return items.map(it => it.attrs);
};

export const clickOnCanvasItem = async (
page: Page,
item: E2E_CanvasItemKeyAttrs
) => {
const { x, y } = item;
const stageCanvas = await page.locator('#konva-stage canvas').first();
const canvasWindowPos = await stageCanvas.boundingBox();
if (!canvasWindowPos) throw new Error('Canvas is not loaded on ui');
await page.mouse.move(
canvasWindowPos?.x + x + 20,
canvasWindowPos?.y + y + 20
);

await page.mouse.down();
await page.mouse.up();

return item;
};

export const dbClickOnCanvasItem = async (
page: Page,
item: E2E_CanvasItemKeyAttrs
) => {
const { x, y } = item;
const canvasWindowPos = await getCanvasBoundingBox(page);
await page.mouse.dblclick(
canvasWindowPos?.x + x + 20,
canvasWindowPos?.y + y + 20
);
return item;
};

export const ctrlClickOverCanvasItems = async (
page: Page,
itemList: E2E_CanvasItemKeyAttrs[]
) => {
if (!itemList.length)
throw new Error('Please, add an array with at least one canvas Item');
// NOTE: The keyboard entry 'ControlOrMeta' is the way to simulate both 'Ctrl' or 'Command' key
await page.keyboard.down('ControlOrMeta');
for (const item of itemList) {
await clickOnCanvasItem(page, item);
}
await page.keyboard.up('ControlOrMeta');
};
29 changes: 28 additions & 1 deletion e2e/helpers/position.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Locator, Page } from '@playwright/test';
import { Group } from 'konva/lib/Group';

interface Position {
x: number;
Expand All @@ -8,6 +9,7 @@ interface Position {
export const getLocatorPosition = async (
locator: Locator
): Promise<Position> => {
await locator.scrollIntoViewIfNeeded();
const box = (await locator.boundingBox()) || {
x: 0,
y: 0,
Expand All @@ -17,6 +19,17 @@ export const getLocatorPosition = async (
return { x: box.x + box.width / 2, y: box.y + box.height / 2 };
};

export const getCanvasBoundingBox = async (page: Page) => {
const canvasWindowPos = await page
.locator('#konva-stage canvas')
.boundingBox();
if (canvasWindowPos) {
return canvasWindowPos;
} else {
throw new Error('Canvas is not loaded on ui');
}
};

export const dragAndDrop = async (
page: Page,
aPosition: Position,
Expand All @@ -32,11 +45,13 @@ export const addComponentsToCanvas = async (
page: Page,
components: string[]
) => {
const canvasPosition = await page.locator('canvas').boundingBox();
const stageCanvas = await page.locator('#konva-stage canvas').first();
const canvasPosition = await stageCanvas.boundingBox();
if (!canvasPosition) throw new Error('No canvas found');

for await (const [index, c] of components.entries()) {
const component = page.getByAltText(c, { exact: true });
await component.scrollIntoViewIfNeeded();
const position = await getLocatorPosition(component);

const targetPosition = (
Expand All @@ -53,3 +68,15 @@ export const addComponentsToCanvas = async (
await dragAndDrop(page, position, targetPosition(120, index));
}
};

export const getShapePosition = async (shape: Group): Promise<Position> => {
return { x: shape?.attrs.x, y: shape?.attrs.y };
};

export const moveSelected = (
page: Page,
direction: string,
numShifts: number
) => {
for (let i: number = 0; i < numShifts; i++) page.keyboard.down(direction);
};
8 changes: 8 additions & 0 deletions e2e/helpers/types/e2e-types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface E2E_CanvasItemKeyAttrs {
x: number;
y: number;
['data-id']: string;
width: number;
height: number;
shapeType: string;
}
13 changes: 13 additions & 0 deletions e2e/helpers/ui-buttons.helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Page } from '@playwright/test';

export const clickUndoUiButton = async (page: Page) =>
await page.getByRole('button', { name: 'Undo' }).click();

export const clickRedoUiButton = async (page: Page) =>
await page.getByRole('button', { name: 'Redo' }).click();

export const clickCopyUiButton = async (page: Page) =>
await page.getByRole('button', { name: 'Copy' }).click();

export const clickPasteUiButton = async (page: Page) =>
await page.getByRole('button', { name: 'Paste' }).click();
121 changes: 121 additions & 0 deletions e2e/inline-edit/multiple-line-inline-edit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { test, expect } from '@playwright/test';
import { Group } from 'konva/lib/Group';
import { dragAndDrop, getByShapeType, getLocatorPosition } from '../helpers';

test('can add textarea to canvas, edit content, and verify shape text', async ({
page,
}) => {
await page.goto('');
const component = page.getByAltText('Textarea');
await component.scrollIntoViewIfNeeded();

const position = await getLocatorPosition(component);
const targetPosition = {
x: position.x + 500,
y: position.y - 240,
};
await dragAndDrop(page, position, targetPosition);
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
const textarea = page.getByRole('textbox').first();
const textareaContent = await textarea.inputValue();
expect(textareaContent).toEqual('Your text here...');

const textContent = 'Hello';
await textarea.fill(textContent);
await page.mouse.click(800, 130);
const textareaShape = (await getByShapeType(page, 'textarea')) as Group;

expect(textareaShape).toBeDefined();
const textShape = textareaShape.children.find(
child => child.attrs.text === textContent
);
expect(textShape).toBeDefined();
});

test('cancels textarea edit on Escape and verifies original shape text', async ({
page,
}) => {
await page.goto('');
const component = page.getByAltText('Textarea');
await component.scrollIntoViewIfNeeded();

const position = await getLocatorPosition(component);
const targetPosition = {
x: position.x + 500,
y: position.y - 240,
};
await dragAndDrop(page, position, targetPosition);
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
const textarea = page.getByRole('textbox').first();

const textContent = 'Hello';
await textarea.fill(textContent);
await page.keyboard.press('Escape');
const originalTextContent = 'Your text here...';
const textareaShape = (await getByShapeType(page, 'textarea')) as Group;

expect(textareaShape).toBeDefined();
const textShape = textareaShape.children.find(
child => child.attrs.text === originalTextContent
);
expect(textShape).toBeDefined();
});

test('can add and edit input, and delete last letter', async ({ page }) => {
await page.goto('');
const component = page.getByAltText('Textarea');
await component.scrollIntoViewIfNeeded();

const position = await getLocatorPosition(component);
const targetPosition = {
x: position.x + 500,
y: position.y - 240,
};
await dragAndDrop(page, position, targetPosition);
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
const textarea = page.getByRole('textbox').first();

const textContent = 'World';
await textarea.fill(textContent);
await page.keyboard.press('Backspace');
const updatedTextareaContent = await textarea.inputValue();
expect(updatedTextareaContent).toEqual('Worl');

await page.mouse.click(800, 130);

const textareaShape = (await getByShapeType(page, 'textarea')) as Group;
expect(textareaShape).toBeDefined();
const textShape = textareaShape.children.find(
child => child.attrs.text === 'Worl'
);
expect(textShape).toBeDefined();
});

test('adds multi-line text to textarea on canvas and verifies shape text', async ({
page,
}) => {
await page.goto('');
const component = page.getByAltText('Textarea');
await component.scrollIntoViewIfNeeded();

const position = await getLocatorPosition(component);
const targetPosition = {
x: position.x + 500,
y: position.y - 240,
};
await dragAndDrop(page, position, targetPosition);
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
const textarea = page.getByRole('textbox').first();

const textContent = 'Line 1\nLine 2';
await textarea.fill(textContent);

await page.mouse.click(800, 130);

const textareaShape = (await getByShapeType(page, 'textarea')) as Group;
expect(textareaShape).toBeDefined();
const textShape = textareaShape.children.find(
child => child.attrs.text === textContent
);
expect(textShape).toBeDefined();
});
Loading

0 comments on commit 0c4d463

Please sign in to comment.