Skip to content

Commit 3e96f47

Browse files
authored
Merge pull request #556 from Lemoncode/dev
Deployment
2 parents a7396d3 + 6642cd5 commit 3e96f47

File tree

219 files changed

+3914
-507
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

219 files changed

+3914
-507
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,17 @@ Team members participating in this project
125125
<a href="https://github.com/Pableras90">
126126
<kbd><img src="https://github.com/Pableras90.png" alt="Pablo Reinaldo" width="50" height="50" style="border-radius: 50%;"></kbd>
127127
</a>
128+
129+
<a href="https://github.com/Alber-Writer">
130+
<kbd><img src="https://github.com/Alber-Writer.png" alt="Alberto Escribano" width="50" height="50" style="border-radius: 50%;"></kbd>
131+
</a>
132+
<a href="https://github.com/El-Mito-de-Giralda">
133+
<kbd><img src="https://github.com/El-Mito-de-Giralda.png" alt="Jorge Miranda de la quintana" width="50" height="50" style="border-radius: 50%;"></kbd>
134+
</a>
135+
<a href="https://github.com/josemitoribio">
136+
<kbd><img src="https://github.com/josemitoribio.png" alt="Josemi Toribio" width="50" height="50" style="border-radius: 50%;"></kbd>
137+
</a>
138+
128139
<a href="https://github.com/IonutGabi">
129140
<kbd><img src="https://github.com/IonutGabi.png" alt="Gabi Birsan" width="50" height="50" style="border-radius: 50%;"></kbd>
130141
</a>

e2e/helpers/konva-testing.helpers.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Layer } from 'konva/lib/Layer';
33
import { Shape } from 'konva/lib/Shape';
44
import { Group } from 'konva/lib/Group';
55
import { E2E_CanvasItemKeyAttrs } from './types/e2e-types';
6+
import { getCanvasBoundingBox } from './position.helpers';
67

78
const getLayer = async (page: Page): Promise<Layer> =>
89
await page.evaluate(() => {
@@ -77,7 +78,8 @@ export const clickOnCanvasItem = async (
7778
item: E2E_CanvasItemKeyAttrs
7879
) => {
7980
const { x, y } = item;
80-
const canvasWindowPos = await page.locator('canvas').boundingBox();
81+
const stageCanvas = await page.locator('#konva-stage canvas').first();
82+
const canvasWindowPos = await stageCanvas.boundingBox();
8183
if (!canvasWindowPos) throw new Error('Canvas is not loaded on ui');
8284
await page.mouse.move(
8385
canvasWindowPos?.x + x + 20,
@@ -90,6 +92,19 @@ export const clickOnCanvasItem = async (
9092
return item;
9193
};
9294

95+
export const dbClickOnCanvasItem = async (
96+
page: Page,
97+
item: E2E_CanvasItemKeyAttrs
98+
) => {
99+
const { x, y } = item;
100+
const canvasWindowPos = await getCanvasBoundingBox(page);
101+
await page.mouse.dblclick(
102+
canvasWindowPos?.x + x + 20,
103+
canvasWindowPos?.y + y + 20
104+
);
105+
return item;
106+
};
107+
93108
export const ctrlClickOverCanvasItems = async (
94109
page: Page,
95110
itemList: E2E_CanvasItemKeyAttrs[]

e2e/helpers/position.helpers.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface Position {
99
export const getLocatorPosition = async (
1010
locator: Locator
1111
): Promise<Position> => {
12+
await locator.scrollIntoViewIfNeeded();
1213
const box = (await locator.boundingBox()) || {
1314
x: 0,
1415
y: 0,
@@ -18,6 +19,17 @@ export const getLocatorPosition = async (
1819
return { x: box.x + box.width / 2, y: box.y + box.height / 2 };
1920
};
2021

22+
export const getCanvasBoundingBox = async (page: Page) => {
23+
const canvasWindowPos = await page
24+
.locator('#konva-stage canvas')
25+
.boundingBox();
26+
if (canvasWindowPos) {
27+
return canvasWindowPos;
28+
} else {
29+
throw new Error('Canvas is not loaded on ui');
30+
}
31+
};
32+
2133
export const dragAndDrop = async (
2234
page: Page,
2335
aPosition: Position,
@@ -33,7 +45,8 @@ export const addComponentsToCanvas = async (
3345
page: Page,
3446
components: string[]
3547
) => {
36-
const canvasPosition = await page.locator('canvas').boundingBox();
48+
const stageCanvas = await page.locator('#konva-stage canvas').first();
49+
const canvasPosition = await stageCanvas.boundingBox();
3750
if (!canvasPosition) throw new Error('No canvas found');
3851

3952
for await (const [index, c] of components.entries()) {

e2e/helpers/ui-buttons.helpers.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Page } from '@playwright/test';
2+
3+
export const clickUndoUiButton = async (page: Page) =>
4+
await page.getByRole('button', { name: 'Undo' }).click();
5+
6+
export const clickRedoUiButton = async (page: Page) =>
7+
await page.getByRole('button', { name: 'Redo' }).click();
8+
9+
export const clickCopyUiButton = async (page: Page) =>
10+
await page.getByRole('button', { name: 'Copy' }).click();
11+
12+
export const clickPasteUiButton = async (page: Page) =>
13+
await page.getByRole('button', { name: 'Paste' }).click();
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { test, expect } from '@playwright/test';
2+
import { Group } from 'konva/lib/Group';
3+
import { dragAndDrop, getByShapeType, getLocatorPosition } from '../helpers';
4+
5+
test('can add textarea to canvas, edit content, and verify shape text', async ({
6+
page,
7+
}) => {
8+
await page.goto('');
9+
const component = page.getByAltText('Textarea');
10+
await component.scrollIntoViewIfNeeded();
11+
12+
const position = await getLocatorPosition(component);
13+
const targetPosition = {
14+
x: position.x + 500,
15+
y: position.y - 240,
16+
};
17+
await dragAndDrop(page, position, targetPosition);
18+
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
19+
const textarea = page.getByRole('textbox').first();
20+
const textareaContent = await textarea.inputValue();
21+
expect(textareaContent).toEqual('Your text here...');
22+
23+
const textContent = 'Hello';
24+
await textarea.fill(textContent);
25+
await page.mouse.click(800, 130);
26+
const textareaShape = (await getByShapeType(page, 'textarea')) as Group;
27+
28+
expect(textareaShape).toBeDefined();
29+
const textShape = textareaShape.children.find(
30+
child => child.attrs.text === textContent
31+
);
32+
expect(textShape).toBeDefined();
33+
});
34+
35+
test('cancels textarea edit on Escape and verifies original shape text', async ({
36+
page,
37+
}) => {
38+
await page.goto('');
39+
const component = page.getByAltText('Textarea');
40+
await component.scrollIntoViewIfNeeded();
41+
42+
const position = await getLocatorPosition(component);
43+
const targetPosition = {
44+
x: position.x + 500,
45+
y: position.y - 240,
46+
};
47+
await dragAndDrop(page, position, targetPosition);
48+
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
49+
const textarea = page.getByRole('textbox').first();
50+
51+
const textContent = 'Hello';
52+
await textarea.fill(textContent);
53+
await page.keyboard.press('Escape');
54+
const originalTextContent = 'Your text here...';
55+
const textareaShape = (await getByShapeType(page, 'textarea')) as Group;
56+
57+
expect(textareaShape).toBeDefined();
58+
const textShape = textareaShape.children.find(
59+
child => child.attrs.text === originalTextContent
60+
);
61+
expect(textShape).toBeDefined();
62+
});
63+
64+
test('can add and edit input, and delete last letter', async ({ page }) => {
65+
await page.goto('');
66+
const component = page.getByAltText('Textarea');
67+
await component.scrollIntoViewIfNeeded();
68+
69+
const position = await getLocatorPosition(component);
70+
const targetPosition = {
71+
x: position.x + 500,
72+
y: position.y - 240,
73+
};
74+
await dragAndDrop(page, position, targetPosition);
75+
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
76+
const textarea = page.getByRole('textbox').first();
77+
78+
const textContent = 'World';
79+
await textarea.fill(textContent);
80+
await page.keyboard.press('Backspace');
81+
const updatedTextareaContent = await textarea.inputValue();
82+
expect(updatedTextareaContent).toEqual('Worl');
83+
84+
await page.mouse.click(800, 130);
85+
86+
const textareaShape = (await getByShapeType(page, 'textarea')) as Group;
87+
expect(textareaShape).toBeDefined();
88+
const textShape = textareaShape.children.find(
89+
child => child.attrs.text === 'Worl'
90+
);
91+
expect(textShape).toBeDefined();
92+
});
93+
94+
test('adds multi-line text to textarea on canvas and verifies shape text', async ({
95+
page,
96+
}) => {
97+
await page.goto('');
98+
const component = page.getByAltText('Textarea');
99+
await component.scrollIntoViewIfNeeded();
100+
101+
const position = await getLocatorPosition(component);
102+
const targetPosition = {
103+
x: position.x + 500,
104+
y: position.y - 240,
105+
};
106+
await dragAndDrop(page, position, targetPosition);
107+
await page.mouse.dblclick(targetPosition.x, targetPosition.y + 40);
108+
const textarea = page.getByRole('textbox').first();
109+
110+
const textContent = 'Line 1\nLine 2';
111+
await textarea.fill(textContent);
112+
113+
await page.mouse.click(800, 130);
114+
115+
const textareaShape = (await getByShapeType(page, 'textarea')) as Group;
116+
expect(textareaShape).toBeDefined();
117+
const textShape = textareaShape.children.find(
118+
child => child.attrs.text === textContent
119+
);
120+
expect(textShape).toBeDefined();
121+
});

e2e/selection/shape-selection.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ test('drop shape in canvas, click on canvas, drop diselected', async ({
4646
const inputShape = (await getByShapeType(page, 'input')) as Group;
4747
expect(inputShape).toBeDefined();
4848

49-
await page.click('canvas');
49+
//Click Away
50+
await page.mouse.click(800, 130);
5051

5152
const transformer = await getTransformer(page);
5253
expect(transformer).toBeDefined();
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { test, expect } from '@playwright/test';
2+
import {
3+
addComponentsToCanvas,
4+
dragAndDrop,
5+
getWithinCanvasItemList,
6+
} from '../helpers';
7+
import { E2E_CanvasItemKeyAttrs } from '../helpers/types/e2e-types';
8+
import {
9+
clickCopyUiButton,
10+
clickPasteUiButton,
11+
} from '../helpers/ui-buttons.helpers';
12+
13+
test.describe('Copy/Paste functionality tests', () => {
14+
test.beforeEach(async ({ page }) => {
15+
await page.goto('');
16+
});
17+
18+
test('Should copy and paste a single shape using the ToolBar UI buttons', async ({
19+
page,
20+
}) => {
21+
//Arrange one Input component
22+
const addInputIntoCanvas = ['Input'];
23+
await addComponentsToCanvas(page, addInputIntoCanvas);
24+
25+
//Copy and assert there are only one component within the canvas
26+
await clickCopyUiButton(page);
27+
const insideCanvasItemList = (await getWithinCanvasItemList(
28+
page
29+
)) as E2E_CanvasItemKeyAttrs[];
30+
expect(insideCanvasItemList.length).toEqual(1);
31+
32+
//Paste and assert there are 2 Input Components and that they have different IDs
33+
await clickPasteUiButton(page);
34+
const updatedInsideCanvasItemList = (await getWithinCanvasItemList(
35+
page
36+
)) as E2E_CanvasItemKeyAttrs[];
37+
const [originalComponent, copiedComponent] = updatedInsideCanvasItemList;
38+
39+
expect(updatedInsideCanvasItemList.length).toEqual(2);
40+
expect(originalComponent.shapeType).toEqual(copiedComponent.shapeType);
41+
expect(originalComponent['data-id']).not.toEqual(
42+
copiedComponent['data-id']
43+
);
44+
});
45+
46+
test('Should copy and paste a single shape using keyboard commands', async ({
47+
page,
48+
}) => {
49+
// NOTE: This test has the same steps as the previous one, except for the keyboard commands.
50+
//Arrange one Input component
51+
const addInputIntoCanvas = ['Input'];
52+
await addComponentsToCanvas(page, addInputIntoCanvas);
53+
54+
//Copy and assert there are only one component within the canvas
55+
await page.keyboard.press('ControlOrMeta+c');
56+
const insideCanvasItemList = (await getWithinCanvasItemList(
57+
page
58+
)) as E2E_CanvasItemKeyAttrs[];
59+
expect(insideCanvasItemList.length).toEqual(1);
60+
61+
//Paste and assert there are 2 Input Components and that they have different IDs
62+
await page.keyboard.press('ControlOrMeta+v');
63+
const updatedInsideCanvasItemList = (await getWithinCanvasItemList(
64+
page
65+
)) as E2E_CanvasItemKeyAttrs[];
66+
const [originalComponent, copiedComponent] = updatedInsideCanvasItemList;
67+
68+
expect(updatedInsideCanvasItemList.length).toEqual(2);
69+
expect(originalComponent.shapeType).toEqual(copiedComponent.shapeType);
70+
expect(originalComponent['data-id']).not.toEqual(
71+
copiedComponent['data-id']
72+
);
73+
});
74+
75+
/*
76+
test('Should copy and paste a multiple shapes using the ToolBar UI buttons', async ({
77+
page,
78+
}) => {
79+
//Add several components into the canvas
80+
const addInputIntoCanvas = ['Input', 'Combobox', 'Icon'];
81+
await addComponentsToCanvas(page, addInputIntoCanvas);
82+
83+
//Select items by drag and drop
84+
await dragAndDrop(page, { x: 260, y: 130 }, { x: 1000, y: 550 });
85+
86+
//Copy and assert there are 3 components within the canvas
87+
await clickCopyUiButton(page);
88+
const insideCanvasItemList = (await getWithinCanvasItemList(
89+
page
90+
)) as E2E_CanvasItemKeyAttrs[];
91+
const [originalComp_1, originalComp_2, originalComp_3] =
92+
insideCanvasItemList;
93+
expect(insideCanvasItemList.length).toEqual(3);
94+
95+
//Paste
96+
await clickPasteUiButton(page);
97+
const updatedInsideCanvasItemList = (await getWithinCanvasItemList(
98+
page
99+
)) as E2E_CanvasItemKeyAttrs[];
100+
const [, , , copiedComp_1, copiedComp_2, copiedComp_3] =
101+
updatedInsideCanvasItemList;
102+
103+
//Assert there are 6 Components,
104+
expect(updatedInsideCanvasItemList.length).toEqual(6);
105+
106+
//Assert they match the same shapes respectively
107+
expect(originalComp_1.shapeType).toEqual(copiedComp_1.shapeType);
108+
expect(originalComp_2.shapeType).toEqual(copiedComp_2.shapeType);
109+
expect(originalComp_3.shapeType).toEqual(copiedComp_3.shapeType);
110+
111+
//Assert they have different IDs
112+
expect(originalComp_1['data-id']).not.toEqual(copiedComp_1['data-id']);
113+
expect(originalComp_2['data-id']).not.toEqual(copiedComp_2['data-id']);
114+
expect(originalComp_3['data-id']).not.toEqual(copiedComp_3['data-id']);
115+
});
116+
*/
117+
test('Should copy and paste a multiple shapes using keyboard commands', async ({
118+
page,
119+
}) => {
120+
// NOTE: This test has the same steps as the previous one, except for the keyboard commands.
121+
//Add several components into the canvas
122+
const addInputIntoCanvas = ['Input', 'Combobox', 'Icon'];
123+
await addComponentsToCanvas(page, addInputIntoCanvas);
124+
125+
//Select items by drag and drop
126+
await dragAndDrop(page, { x: 260, y: 130 }, { x: 1000, y: 550 });
127+
128+
//Copy and assert there are 3 components within the canvas
129+
await page.keyboard.press('ControlOrMeta+c');
130+
const insideCanvasItemList = (await getWithinCanvasItemList(
131+
page
132+
)) as E2E_CanvasItemKeyAttrs[];
133+
const [originalComp_1, originalComp_2, originalComp_3] =
134+
insideCanvasItemList;
135+
expect(insideCanvasItemList.length).toEqual(3);
136+
137+
//Paste
138+
await page.keyboard.press('ControlOrMeta+v');
139+
const updatedInsideCanvasItemList = (await getWithinCanvasItemList(
140+
page
141+
)) as E2E_CanvasItemKeyAttrs[];
142+
const [, , , copiedComp_1, copiedComp_2, copiedComp_3] =
143+
updatedInsideCanvasItemList;
144+
145+
//Assert there are 6 Components,
146+
expect(updatedInsideCanvasItemList.length).toEqual(6);
147+
148+
//Assert they match the same shapes respectively
149+
expect(originalComp_1.shapeType).toEqual(copiedComp_1.shapeType);
150+
expect(originalComp_2.shapeType).toEqual(copiedComp_2.shapeType);
151+
expect(originalComp_3.shapeType).toEqual(copiedComp_3.shapeType);
152+
153+
//Assert they have different IDs
154+
expect(originalComp_1['data-id']).not.toEqual(copiedComp_1['data-id']);
155+
expect(originalComp_2['data-id']).not.toEqual(copiedComp_2['data-id']);
156+
expect(originalComp_3['data-id']).not.toEqual(copiedComp_3['data-id']);
157+
});
158+
});

0 commit comments

Comments
 (0)