diff --git a/frontend/playwright/ui/pages/WasmWorkspacePage.js b/frontend/playwright/ui/pages/WasmWorkspacePage.js index 405f3eb55e..a877f03dba 100644 --- a/frontend/playwright/ui/pages/WasmWorkspacePage.js +++ b/frontend/playwright/ui/pages/WasmWorkspacePage.js @@ -35,8 +35,8 @@ export class WasmWorkspacePage extends WorkspacePage { return WasmWorkspacePage.mockConfigFlags(this.page, flags); } - constructor(page) { - super(page); + constructor(page, options) { + super(page, options); this.canvas = page.getByTestId("canvas-wasm-shapes"); } diff --git a/frontend/playwright/ui/pages/WorkspacePage.js b/frontend/playwright/ui/pages/WorkspacePage.js index 46c975827a..c9f6fd97c7 100644 --- a/frontend/playwright/ui/pages/WorkspacePage.js +++ b/frontend/playwright/ui/pages/WorkspacePage.js @@ -35,45 +35,9 @@ export class WorkspacePage extends BaseWebSocketPage { } async waitForEditor() { - return this.page.waitForSelector('[data-itype="editor"]'); - } - - async waitForRoot() { - return this.page.waitForSelector('[data-itype="root"]'); - } - - async waitForParagraph(nth) { - if (!nth) { - return this.page.waitForSelector('[data-itype="paragraph"]'); - } - return this.page.waitForSelector( - `[data-itype="paragraph"]:nth-child(${nth})`, - ); - } - - async waitForParagraphStyle(nth, styleName) { - const paragraph = await this.waitForParagraph(nth); - return this.waitForStyle(paragraph, styleName); - } - - async waitForTextSpan(nth = 0) { - if (!nth) { - return this.page.waitForSelector('[data-itype="span"]'); - } - return this.page.waitForSelector( - `[data-itype="span"]:nth-child(${nth})`, - ); - } - - async waitForTextSpanContent(nth = 0) { - const textSpan = await this.waitForTextSpan(nth); - const textContent = await textSpan.textContent(); - return textContent; - } - - async waitForTextSpanStyle(nth, styleName) { - const textSpan = await this.waitForTextSpan(nth); - return this.waitForStyle(textSpan, styleName); + const typographyInput = + this.workspacePage.rightSidebar.getByLabel("Font Size"); + await expect(typographyInput).toBeVisible(); } async startEditing() { @@ -98,7 +62,7 @@ export class WorkspacePage extends BaseWebSocketPage { } async moveFromStart(offset = 0) { - await this.page.keyboard.press("ArrowLeft"); + await this.page.keyboard.press("Home"); await this.moveToRight(offset); } @@ -125,7 +89,7 @@ export class WorkspacePage extends BaseWebSocketPage { await expect(locator).toBeVisible(); await locator.focus(); await locator.fill(`${newValue}`); - await locator.blur(); + await this.page.keyboard.press("Enter"); } changeFontSize(newValue) { @@ -390,10 +354,12 @@ export class WorkspacePage extends BaseWebSocketPage { const timeToWait = options?.timeToWait ?? 100; await this.page.keyboard.press("T"); await this.page.waitForTimeout(timeToWait); + + const layersCountBefore = await this.layers.getByTestId("layer-row").count(); await this.clickAndMove(x1, y1, x2, y2); - await expect(this.page.getByTestId("text-editor")).toBeVisible(); if (initialText) { + await this.waitForSelectedShapeName("Text"); await this.page.keyboard.type(initialText); } } @@ -493,10 +459,23 @@ export class WorkspacePage extends BaseWebSocketPage { async expectSelectedLayer(name) { await expect( - this.layers - .getByTestId("layer-row") - .filter({ has: this.page.getByText(name) }), - ).toHaveClass(/selected/); + this.layers.getByRole("checkbox", { name, checked: true }), + ).toBeVisible(); + } + + async getSelectedShapeName() { + const selectedLayer = this.layers + .getByRole("checkbox", { checked: true }) + .first(); + await selectedLayer.waitFor({ state: "visible" }); + return (await selectedLayer.innerText()).trim(); + } + + async waitForSelectedShapeName(expectedName) { + const selectedLayer = this.layers + .getByRole("checkbox", { checked: true }) + .first(); + await expect(selectedLayer).toHaveText(expectedName); } async expectHiddenToolbarOptions() { diff --git a/frontend/playwright/ui/specs/text-editor-v2.spec.js b/frontend/playwright/ui/specs/text-editor-v2.spec.js index 299430fad1..e32e0536a3 100644 --- a/frontend/playwright/ui/specs/text-editor-v2.spec.js +++ b/frontend/playwright/ui/specs/text-editor-v2.spec.js @@ -1,14 +1,14 @@ import { test, expect } from "@playwright/test"; import { Clipboard } from "../../helpers/Clipboard"; -import { WorkspacePage } from "../pages/WorkspacePage"; +import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; const timeToWait = 100; test.beforeEach(async ({ page, context }) => { await Clipboard.enable(context, Clipboard.Permission.ALL); - await WorkspacePage.init(page); - await WorkspacePage.mockConfigFlags(page, ["enable-feature-text-editor-v2"]); + await WasmWorkspacePage.init(page); + await WasmWorkspacePage.mockConfigFlags(page, ["enable-feature-text-editor-v2"]); }); test.afterEach(async ({ context }) => { @@ -17,22 +17,21 @@ test.afterEach(async ({ context }) => { test("Create a new text shape", async ({ page }) => { const initialText = "Lorem ipsum"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); await workspace.goToWorkspace(); await workspace.createTextShape(190, 150, 300, 200, initialText); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe(initialText); - await workspace.textEditor.stopEditing(); + + await workspace.waitForSelectedShapeName(initialText); }); test("Create a new text shape from pasting text", async ({ page, context }) => { const textToPaste = "Lorem ipsum"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -43,13 +42,9 @@ test("Create a new text shape from pasting text", async ({ page, context }) => { await workspace.clickAt(190, 150); await workspace.paste("keyboard"); - - await page.waitForTimeout(timeToWait); - - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe(textToPaste); - await workspace.textEditor.stopEditing(); + + await expect(workspace.layers.getByText(textToPaste)).toBeVisible(); }); test("Create a new text shape from pasting text using context menu", async ({ @@ -57,7 +52,7 @@ test("Create a new text shape from pasting text using context menu", async ({ context, }) => { const textToPaste = "Lorem ipsum"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -67,17 +62,15 @@ test("Create a new text shape from pasting text using context menu", async ({ await workspace.clickAt(190, 150); await workspace.paste("context-menu"); - - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe(textToPaste); - await workspace.textEditor.stopEditing(); + + await expect(workspace.layers.getByText(textToPaste)).toBeVisible(); }); test("Update an already created text shape by appending text", async ({ page, }) => { - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -87,15 +80,14 @@ test("Update an already created text shape by appending text", async ({ await workspace.textEditor.startEditing(); await workspace.textEditor.moveFromEnd(0); await page.keyboard.type(" dolor sit amet"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Lorem ipsum dolor sit amet"); await workspace.textEditor.stopEditing(); + await workspace.waitForSelectedShapeName("Lorem ipsum dolor sit amet"); }); test("Update an already created text shape by prepending text", async ({ page, }) => { - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -105,15 +97,14 @@ test("Update an already created text shape by prepending text", async ({ await workspace.textEditor.startEditing(); await workspace.textEditor.moveFromStart(0); await page.keyboard.type("Dolor sit amet "); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Dolor sit amet Lorem ipsum"); await workspace.textEditor.stopEditing(); + await workspace.waitForSelectedShapeName("Dolor sit amet Lorem ipsum"); }); test.skip("Update an already created text shape by inserting text in between", async ({ page, }) => { - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -123,9 +114,8 @@ test.skip("Update an already created text shape by inserting text in between", a await workspace.textEditor.startEditing(); await workspace.textEditor.moveFromStart(5); await page.keyboard.type(" dolor sit amet"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Lorem dolor sit amet ipsum"); await workspace.textEditor.stopEditing(); + await workspace.waitForSelectedShapeName("Lorem dolor sit amet ipsum"); }); test("Update a new text shape appending text by pasting text", async ({ @@ -133,7 +123,7 @@ test("Update a new text shape appending text by pasting text", async ({ context, }) => { const textToPaste = " dolor sit amet"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -146,17 +136,16 @@ test("Update a new text shape appending text by pasting text", async ({ await workspace.textEditor.startEditing(); await workspace.textEditor.moveFromEnd(); await workspace.paste("keyboard"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Lorem ipsum dolor sit amet"); await workspace.textEditor.stopEditing(); -}); + await workspace.waitForSelectedShapeName("Lorem ipsum dolor sit amet"); + }); test.skip("Update a new text shape prepending text by pasting text", async ({ page, context, }) => { const textToPaste = "Dolor sit amet "; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -169,16 +158,17 @@ test.skip("Update a new text shape prepending text by pasting text", async ({ await workspace.textEditor.startEditing(); await workspace.textEditor.moveFromStart(); await workspace.paste("keyboard"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Dolor sit amet Lorem ipsum"); await workspace.textEditor.stopEditing(); + + await workspace.hideUI(); + await expect(workspace.canvas).toHaveScreenshot(); }); test("Update a new text shape replacing (starting) text with pasted text", async ({ page, }) => { const textToPaste = "Dolor sit amet"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -192,17 +182,15 @@ test("Update a new text shape replacing (starting) text with pasted text", async await workspace.paste("keyboard"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Dolor sit amet ipsum"); - await workspace.textEditor.stopEditing(); + await workspace.waitForSelectedShapeName("Dolor sit amet ipsum"); }); test("Update a new text shape replacing (ending) text with pasted text", async ({ page, }) => { const textToPaste = "dolor sit amet"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -216,17 +204,15 @@ test("Update a new text shape replacing (ending) text with pasted text", async ( await workspace.paste("keyboard"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Lorem dolor sit amet"); - await workspace.textEditor.stopEditing(); + await workspace.waitForSelectedShapeName("Lorem dolor sit amet"); }); test("Update a new text shape replacing (in between) text with pasted text", async ({ page, }) => { const textToPaste = "dolor sit amet"; - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -240,16 +226,14 @@ test("Update a new text shape replacing (in between) text with pasted text", asy await workspace.paste("keyboard"); - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Lordolor sit ametsum"); - await workspace.textEditor.stopEditing(); + await workspace.waitForSelectedShapeName("Lordolor sit ametsum"); }); test("Update text font size selecting a part of it (starting)", async ({ page, }) => { - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -260,18 +244,16 @@ test("Update text font size selecting a part of it (starting)", async ({ await workspace.textEditor.startEditing(); await workspace.textEditor.selectFromStart(5); await workspace.textEditor.changeFontSize(36); - - const textContent1 = await workspace.textEditor.waitForTextSpanContent(1); - expect(textContent1).toBe("Lorem"); - const textContent2 = await workspace.textEditor.waitForTextSpanContent(2); - expect(textContent2).toBe(" ipsum"); await workspace.textEditor.stopEditing(); + + await workspace.hideUI(); + await expect(workspace.canvas).toHaveScreenshot(); }); -test.skip("Update text line height selecting a part of it (starting)", async ({ +test("Update text line height selecting a part of it (starting)", async ({ page, }) => { - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -281,24 +263,17 @@ test.skip("Update text line height selecting a part of it (starting)", async ({ await workspace.clickLeafLayer("Lorem ipsum"); await workspace.textEditor.startEditing(); await workspace.textEditor.selectFromStart(5); - await workspace.textEditor.changeLineHeight(1.4); - - const lineHeight = await workspace.textEditor.waitForParagraphStyle( - 1, - "line-height", - ); - expect(lineHeight).toBe("1.4"); - - const textContent = await workspace.textEditor.waitForTextSpanContent(); - expect(textContent).toBe("Lorem ipsum"); - + await workspace.textEditor.changeLineHeight(4.4); await workspace.textEditor.stopEditing(); + + await workspace.hideUI(); + await expect(workspace.canvas).toHaveScreenshot(); }); test.skip("Update text letter spacing selecting a part of it (starting)", async ({ page, }) => { - const workspace = new WorkspacePage(page, { + const workspace = new WasmWorkspacePage(page, { textEditor: true, }); await workspace.setupEmptyFile(); @@ -309,16 +284,14 @@ test.skip("Update text letter spacing selecting a part of it (starting)", async await workspace.textEditor.startEditing(); await workspace.textEditor.selectFromStart(5); await workspace.textEditor.changeLetterSpacing(10); - - const textContent1 = await workspace.textEditor.waitForTextSpanContent(1); - expect(textContent1).toBe("Lorem"); - const textContent2 = await workspace.textEditor.waitForTextSpanContent(2); - expect(textContent2).toBe(" ipsum"); await workspace.textEditor.stopEditing(); + + await workspace.hideUI(); + await expect(workspace.canvas).toHaveScreenshot(); }); test("BUG 11552 - Apply styles to the current caret", async ({ page }) => { - const workspace = new WorkspacePage(page); + const workspace = new WasmWorkspacePage(page); await workspace.setupEmptyFile(); await workspace.mockGetFile("text-editor/get-file-11552.json"); await workspace.mockRPC( diff --git a/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-font-size-selecting-a-part-of-it-starting-1.png b/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-font-size-selecting-a-part-of-it-starting-1.png new file mode 100644 index 0000000000..0d31872f79 Binary files /dev/null and b/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-font-size-selecting-a-part-of-it-starting-1.png differ diff --git a/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-letter-spacing-selecting-a-part-of-it-starting-1.png b/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-letter-spacing-selecting-a-part-of-it-starting-1.png new file mode 100644 index 0000000000..4b091658c9 Binary files /dev/null and b/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-letter-spacing-selecting-a-part-of-it-starting-1.png differ diff --git a/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-line-height-selecting-a-part-of-it-starting-1.png b/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-line-height-selecting-a-part-of-it-starting-1.png new file mode 100644 index 0000000000..1dc0a0dffa Binary files /dev/null and b/frontend/playwright/ui/specs/text-editor-v2.spec.js-snapshots/Update-text-line-height-selecting-a-part-of-it-starting-1.png differ diff --git a/frontend/src/app/main/ui/workspace/sidebar/layer_item.cljs b/frontend/src/app/main/ui/workspace/sidebar/layer_item.cljs index 8c22f87fc5..550e072d07 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layer_item.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/layer_item.cljs @@ -84,6 +84,8 @@ :on-click on-select-shape :on-context-menu on-context-menu :data-testid "layer-row" + :role "checkbox" + :aria-checked selected? :class (stl/css-case :layer-row true :highlight highlighted?