From d8249cc3db6283c12ba983d4b44a8c322aaffb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 11 Mar 2026 14:17:57 +0100 Subject: [PATCH] :sparkles: Add regression test for token highlight bug (13302) (#8573) * :sparkles: Add aria role to token pill * :sparkles: Clean up unused vars, imports and unneeded intercepts in tokens tests * :sparkles: Add regression test for bug 13302 (highlight token) --- .../playwright/data/get-teams-tokens.json | 26 -- .../data/tokens/get-file-13302.json | 206 +++++++++++ .../data/tokens/update-file-13302.json | 338 ++++++++++++++++++ .../playwright/ui/specs/tokens/apply.spec.js | 68 ++-- .../playwright/ui/specs/tokens/crud.spec.js | 110 +++--- .../ui/specs/tokens/general.spec.js | 33 +- .../playwright/ui/specs/tokens/helpers.js | 27 +- .../ui/specs/tokens/remapping.spec.js | 57 ++- .../playwright/ui/specs/tokens/sets.spec.js | 19 +- .../playwright/ui/specs/tokens/themes.spec.js | 2 - .../playwright/ui/specs/tokens/tree.spec.js | 7 +- .../tokens/management/token_pill.cljs | 7 +- 12 files changed, 700 insertions(+), 200 deletions(-) delete mode 100644 frontend/playwright/data/get-teams-tokens.json create mode 100644 frontend/playwright/data/tokens/get-file-13302.json create mode 100644 frontend/playwright/data/tokens/update-file-13302.json diff --git a/frontend/playwright/data/get-teams-tokens.json b/frontend/playwright/data/get-teams-tokens.json deleted file mode 100644 index 7ec12f1877..0000000000 --- a/frontend/playwright/data/get-teams-tokens.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "~:features": { - "~#set": [ - "design-tokens/v1", - "layout/grid", - "styles/v2", - "fdata/pointer-map", - "fdata/objects-map", - "components/v2", - "fdata/shape-data-type" - ] - }, - "~:permissions": { - "~:type": "~:membership", - "~:is-owner": true, - "~:is-admin": true, - "~:can-edit": true - }, - "~:name": "Default", - "~:modified-at": "~m1713533116375", - "~:id": "~uc7ce0794-0992-8105-8004-38e630f7920a", - "~:created-at": "~m1713533116375", - "~:is-default": true - } -] diff --git a/frontend/playwright/data/tokens/get-file-13302.json b/frontend/playwright/data/tokens/get-file-13302.json new file mode 100644 index 0000000000..1580c3d489 --- /dev/null +++ b/frontend/playwright/data/tokens/get-file-13302.json @@ -0,0 +1,206 @@ +{ + "~:features": { + "~#set": [ + "fdata/path-data", + "plugins/runtime", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "styles/v2", + "fdata/objects-map", + "render-wasm/v1", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:team-id": "~u99e49e93-362f-80ef-8007-3450ea52c9a4", + "~:permissions": { + "~:type": "~:membership", + "~:is-owner": true, + "~:is-admin": true, + "~:can-edit": true, + "~:can-read": true, + "~:is-logged": true + }, + "~:has-media-trimmed": false, + "~:comment-thread-seqn": 0, + "~:name": "BUG 13302 - Token highlight", + "~:revn": 13, + "~:modified-at": "~m1770721633482", + "~:vern": 0, + "~:id": "~u6886b62b-1979-8195-8007-8d0b92d3116a", + "~:is-shared": false, + "~:migrations": { + "~#ordered-set": [ + "legacy-2", + "legacy-3", + "legacy-5", + "legacy-6", + "legacy-7", + "legacy-8", + "legacy-9", + "legacy-10", + "legacy-11", + "legacy-12", + "legacy-13", + "legacy-14", + "legacy-16", + "legacy-17", + "legacy-18", + "legacy-19", + "legacy-25", + "legacy-26", + "legacy-27", + "legacy-28", + "legacy-29", + "legacy-31", + "legacy-32", + "legacy-33", + "legacy-34", + "legacy-36", + "legacy-37", + "legacy-38", + "legacy-39", + "legacy-40", + "legacy-41", + "legacy-42", + "legacy-43", + "legacy-44", + "legacy-45", + "legacy-46", + "legacy-47", + "legacy-48", + "legacy-49", + "legacy-50", + "legacy-51", + "legacy-52", + "legacy-53", + "legacy-54", + "legacy-55", + "legacy-56", + "legacy-57", + "legacy-59", + "legacy-62", + "legacy-65", + "legacy-66", + "legacy-67", + "0001-remove-tokens-from-groups", + "0002-normalize-bool-content-v2", + "0002-clean-shape-interactions", + "0003-fix-root-shape", + "0003-convert-path-content-v2", + "0005-deprecate-image-type", + "0006-fix-old-texts-fills", + "0008-fix-library-colors-v4", + "0009-clean-library-colors", + "0009-add-partial-text-touched-flags", + "0010-fix-swap-slots-pointing-non-existent-shapes", + "0011-fix-invalid-text-touched-flags", + "0012-fix-position-data", + "0013-fix-component-path", + "0013-clear-invalid-strokes-and-fills", + "0014-fix-tokens-lib-duplicate-ids", + "0014-clear-components-nil-objects", + "0015-fix-text-attrs-blank-strings", + "0015-clean-shadow-color", + "0016-copy-fills-from-position-data-to-text-node" + ] + }, + "~:version": 67, + "~:project-id": "~ucd8f7672-e5d1-810f-8007-87e124eda82a", + "~:created-at": "~m1770719668044", + "~:backend": "legacy-db", + "~:data": { + "~:pages": [ + "~u6886b62b-1979-8195-8007-8d0b92d3116b" + ], + "~:pages-index": { + "~u6886b62b-1979-8195-8007-8d0b92d3116b": { + "~:objects": { + "~#penpot/objects-map/v2": { + "~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~ud601cd4c-f774-802c-8007-8d0c13228bba\"]]]", + "~ud601cd4c-f774-802c-8007-8d0c13228bba": "[\"~#shape\",[\"^ \",\"~:y\",79.00000276416532,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",100.00000353902578,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0,\"~:y\",79.0000027641653]],[\"^<\",[\"^ \",\"~:x\",100.00000353902578,\"~:y\",79.0000027641653]],[\"^<\",[\"^ \",\"~:x\",100.00000353902578,\"~:y\",178.9999994188543]],[\"^<\",[\"^ \",\"~:x\",0,\"~:y\",178.9999994188543]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~ud601cd4c-f774-802c-8007-8d0c13228bba\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \"],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",79.00000276416532,\"^8\",100.00000353902578,\"~:height\",99.99999665468899,\"~:x1\",0,\"~:y1\",79.00000276416532,\"~:x2\",100.00000353902578,\"~:y2\",178.99999941885432]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^K\",99.99999665468899,\"~:flip-y\",null]]" + } + }, + "~:id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:name": "Page 1" + } + }, + "~:id": "~u6886b62b-1979-8195-8007-8d0b92d3116a", + "~:options": { + "~:components-v2": true, + "~:base-font-size": "16px" + }, + "~:tokens-lib": { + "~#penpot/tokens-lib": { + "~:sets": { + "~#ordered-map": [ + [ + "S-Global", + { + "~#penpot/token-set": { + "~:id": "~u7b395852-8f6b-8027-8007-8d0bb31bd9d9", + "~:name": "Global", + "~:description": "", + "~:modified-at": "~m1770719731235", + "~:tokens": { + "~#ordered-map": [ + [ + "any-dimensions-token", + { + "~#penpot/token": { + "~:id": "~u7b395852-8f6b-8027-8007-8d0bb31b8a10", + "~:name": "any-dimensions-token", + "~:type": "~:dimensions", + "~:value": "256", + "~:description": "", + "~:modified-at": "~m1770719731235" + } + } + ] + ] + } + } + } + ] + ] + }, + "~:themes": { + "~#ordered-map": [ + [ + "", + { + "~#ordered-map": [ + [ + "__PENPOT__HIDDEN__TOKEN__THEME__", + { + "~#penpot/token-theme": { + "~:id": "~u00000000-0000-0000-0000-000000000000", + "~:name": "__PENPOT__HIDDEN__TOKEN__THEME__", + "~:group": "", + "~:description": "", + "~:is-source": false, + "~:external-id": "", + "~:modified-at": "~m1770719704149", + "~:sets": { + "~#set": [ + "Global" + ] + } + } + } + ] + ] + } + ] + ] + }, + "~:active-themes": { + "~#set": [ + "/__PENPOT__HIDDEN__TOKEN__THEME__" + ] + } + } + } + } +} \ No newline at end of file diff --git a/frontend/playwright/data/tokens/update-file-13302.json b/frontend/playwright/data/tokens/update-file-13302.json new file mode 100644 index 0000000000..9bd9e68074 --- /dev/null +++ b/frontend/playwright/data/tokens/update-file-13302.json @@ -0,0 +1,338 @@ +{ + "~:revn": 11, + "~:lagged": [ + { + "~:id": "~u6886b62b-1979-8195-8007-8d12e2ccd0f1", + "~:revn": 11, + "~:file-id": "~u6886b62b-1979-8195-8007-8d0b92d3116a", + "~:session-id": "~u488d46ff-4717-808d-8007-8d0c3dac344e", + "~:changes": [ + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:width", + "~:val": 100.00000353902578, + "~:ignore-geometry": false, + "~:ignore-touched": false + }, + { + "~:type": "~:set", + "~:attr": "~:points", + "~:val": [ + { + "~#point": { + "~:x": 0, + "~:y": 79.00000333786011 + } + }, + { + "~#point": { + "~:x": 100.00000353902578, + "~:y": 79.00000333786011 + } + }, + { + "~#point": { + "~:x": 100.00000353902578, + "~:y": 335.00001430511475 + } + }, + { + "~#point": { + "~:x": 0, + "~:y": 335.00001430511475 + } + } + ], + "~:ignore-geometry": false, + "~:ignore-touched": false + }, + { + "~:type": "~:set", + "~:attr": "~:selrect", + "~:val": { + "~#rect": { + "~:x": 0, + "~:y": 79.00000333786011, + "~:width": 100.00000353902578, + "~:height": 256.00001096725464, + "~:x1": 0, + "~:y1": 79.00000333786011, + "~:x2": 100.00000353902578, + "~:y2": 335.00001430511475 + } + }, + "~:ignore-geometry": false, + "~:ignore-touched": false + } + ] + }, + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:applied-tokens", + "~:val": { + "~:height": "any-dimensions-token" + }, + "~:ignore-geometry": false, + "~:ignore-touched": false + } + ] + }, + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:y", + "~:val": 79.00000276416532, + "~:ignore-geometry": false, + "~:ignore-touched": false + }, + { + "~:type": "~:set", + "~:attr": "~:points", + "~:val": [ + { + "~#point": { + "~:x": 0, + "~:y": 79.0000027641653 + } + }, + { + "~#point": { + "~:x": 100.00000353902578, + "~:y": 79.0000027641653 + } + }, + { + "~#point": { + "~:x": 100.00000353902578, + "~:y": 178.9999994188543 + } + }, + { + "~#point": { + "~:x": 0, + "~:y": 178.9999994188543 + } + } + ], + "~:ignore-geometry": false, + "~:ignore-touched": false + }, + { + "~:type": "~:set", + "~:attr": "~:selrect", + "~:val": { + "~#rect": { + "~:x": 0, + "~:y": 79.00000276416532, + "~:width": 100.00000353902578, + "~:height": 99.99999665468899, + "~:x1": 0, + "~:y1": 79.00000276416532, + "~:x2": 100.00000353902578, + "~:y2": 178.99999941885432 + } + }, + "~:ignore-geometry": false, + "~:ignore-touched": false + }, + { + "~:type": "~:set", + "~:attr": "~:height", + "~:val": 99.99999665468899, + "~:ignore-geometry": false, + "~:ignore-touched": false + } + ] + }, + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:applied-tokens", + "~:val": {}, + "~:ignore-geometry": false, + "~:ignore-touched": false + } + ] + } + ] + }, + { + "~:id": "~u6886b62b-1979-8195-8007-8d12e996895c", + "~:revn": 12, + "~:file-id": "~u6886b62b-1979-8195-8007-8d0b92d3116a", + "~:session-id": "~u488d46ff-4717-808d-8007-8d0c3dac344e", + "~:changes": [ + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:applied-tokens", + "~:val": { + "~:width": "any-dimensions-token", + "~:height": "any-dimensions-token" + }, + "~:ignore-geometry": false, + "~:ignore-touched": false + } + ] + }, + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:width", + "~:val": 256.0000033378599, + "~:ignore-geometry": false, + "~:ignore-touched": true + }, + { + "~:type": "~:set", + "~:attr": "~:points", + "~:val": [ + { + "~#point": { + "~:x": 0, + "~:y": 79.0000027641653 + } + }, + { + "~#point": { + "~:x": 256.0000033378599, + "~:y": 79.0000027641653 + } + }, + { + "~#point": { + "~:x": 256.0000033378599, + "~:y": 178.9999994188543 + } + }, + { + "~#point": { + "~:x": 0, + "~:y": 178.9999994188543 + } + } + ], + "~:ignore-geometry": false, + "~:ignore-touched": true + }, + { + "~:type": "~:set", + "~:attr": "~:selrect", + "~:val": { + "~#rect": { + "~:x": 0, + "~:y": 79.00000276416532, + "~:width": 256.0000033378599, + "~:height": 99.99999665468899, + "~:x1": 0, + "~:y1": 79.00000276416532, + "~:x2": 256.0000033378599, + "~:y2": 178.99999941885432 + } + }, + "~:ignore-geometry": false, + "~:ignore-touched": true + } + ] + }, + { + "~:type": "~:mod-obj", + "~:id": "~ud601cd4c-f774-802c-8007-8d0c13228bba", + "~:page-id": "~u6886b62b-1979-8195-8007-8d0b92d3116b", + "~:operations": [ + { + "~:type": "~:set", + "~:attr": "~:y", + "~:val": 79.00000826835657, + "~:ignore-geometry": false, + "~:ignore-touched": true + }, + { + "~:type": "~:set", + "~:attr": "~:points", + "~:val": [ + { + "~#point": { + "~:x": 0, + "~:y": 79.00000826835657 + } + }, + { + "~#point": { + "~:x": 256.0000033378599, + "~:y": 79.00000826835657 + } + }, + { + "~#point": { + "~:x": 256.0000033378599, + "~:y": 335.0000178241718 + } + }, + { + "~#point": { + "~:x": 0, + "~:y": 335.0000178241718 + } + } + ], + "~:ignore-geometry": false, + "~:ignore-touched": true + }, + { + "~:type": "~:set", + "~:attr": "~:selrect", + "~:val": { + "~#rect": { + "~:x": 0, + "~:y": 79.00000826835657, + "~:width": 256.0000033378599, + "~:height": 256.0000095558152, + "~:x1": 0, + "~:y1": 79.00000826835657, + "~:x2": 256.0000033378599, + "~:y2": 335.0000178241718 + } + }, + "~:ignore-geometry": false, + "~:ignore-touched": true + }, + { + "~:type": "~:set", + "~:attr": "~:height", + "~:val": 256.0000095558152, + "~:ignore-geometry": false, + "~:ignore-touched": true + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/frontend/playwright/ui/specs/tokens/apply.spec.js b/frontend/playwright/ui/specs/tokens/apply.spec.js index 1d3bee2278..7bd34e1801 100644 --- a/frontend/playwright/ui/specs/tokens/apply.spec.js +++ b/frontend/playwright/ui/specs/tokens/apply.spec.js @@ -1,5 +1,4 @@ import { test, expect } from "@playwright/test"; -import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage"; import { WasmWorkspacePage } from "../../pages/WasmWorkspacePage"; import { setupTokensFileRender, @@ -8,8 +7,10 @@ import { } from "./helpers"; test.beforeEach(async ({ page }) => { - await WasmWorkspacePage.init(page); - await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json"); + await WasmWorkspacePage.init(page); + await WasmWorkspacePage.mockConfigFlags(page, [ + "enable-feature-design-tokens-v1", + ]); }); test.describe("Tokens: Apply token", () => { @@ -30,7 +31,7 @@ test.describe("Tokens: Apply token", () => { unfoldTokenTree(tokensSidebar, "color", "colors.black"); await tokensSidebar - .getByRole("button", { name: "black" }) + .getByRole("checkbox", { name: "black" }) .click({ button: "right" }); await tokenContextMenuForToken.getByText("Fill").click(); @@ -42,8 +43,7 @@ test.describe("Tokens: Apply token", () => { test("User applies border-radius token to a shape from sidebar", async ({ page, }) => { - const { workspacePage, tokensSidebar, tokenContextMenuForToken } = - await setupTokensFileRender(page); + const { workspacePage, tokensSidebar } = await setupTokensFileRender(page); await page.getByRole("tab", { name: "Layers" }).click(); @@ -60,12 +60,12 @@ test.describe("Tokens: Apply token", () => { ).toBeVisible(); await tokensSidebar.getByRole("button", { name: "borderRadius" }).click(); await expect( - tokensSidebar.getByRole("button", { name: "borderRadius.sm" }), + tokensSidebar.getByRole("checkbox", { name: "borderRadius.sm" }), ).toBeVisible(); // Apply border radius token from token panels await tokensSidebar - .getByRole("button", { name: "borderRadius.sm" }) + .getByRole("checkbox", { name: "borderRadius.sm" }) .click(); // Check if border radius sections is visible on right sidebar @@ -103,7 +103,7 @@ test.describe("Tokens: Apply token", () => { test("User applies opacity token to a shape from sidebar", async ({ page, }) => { - const { workspacePage, tokensSidebar, tokenContextMenuForToken } = + const { workspacePage, tokensSidebar } = await setupTokensFileRender(page); await page.getByRole("tab", { name: "Layers" }).click(); @@ -123,11 +123,11 @@ test.describe("Tokens: Apply token", () => { .getByRole("button", { name: "opacity", exact: true }) .click(); await expect( - tokensSidebar.getByRole("button", { name: "opacity.high" }), + tokensSidebar.getByRole("checkbox", { name: "opacity.high" }), ).toBeVisible(); // Apply opacity token from token panels - await tokensSidebar.getByRole("button", { name: "opacity.high" }).click(); + await tokensSidebar.getByRole("checkbox", { name: "opacity.high" }).click(); // Check if opacity sections is visible on right sidebar const layerMenuSection = page.getByRole("region", { @@ -167,8 +167,7 @@ test.describe("Tokens: Apply token", () => { }); test("User applies typography token to a text shape", async ({ page }) => { - const { workspacePage, tokensSidebar, tokenContextMenuForToken } = - await setupTypographyTokensFileRender(page); + const { workspacePage, tokensSidebar } = await setupTypographyTokensFileRender(page); await page.getByRole("tab", { name: "Layers" }).click(); @@ -185,7 +184,7 @@ test.describe("Tokens: Apply token", () => { .filter({ hasText: "Typography" }) .click(); - await tokensSidebar.getByRole("button", { name: "Full" }).click(); + await tokensSidebar.getByRole("checkbox", { name: "Full" }).click(); const fontSizeInput = workspacePage.rightSidebar.getByRole("textbox", { name: "Font Size", @@ -201,7 +200,6 @@ test.describe("Tokens: Apply token", () => { tokensUpdateCreateModal, tokensSidebar, workspacePage, - tokenContextMenuForToken, } = await setupTokensFileRender(page, { flags: ["enable-token-shadow"] }); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); @@ -465,7 +463,7 @@ test.describe("Tokens: Apply token", () => { unfoldTokenTree(tokensSidebar, "shadow", "primary"); // Verify token appears in sidebar - const shadowToken = tokensSidebar.getByRole("button", { + const shadowToken = tokensSidebar.getByRole("checkbox", { name: "primary", }); await expect(shadowToken).toBeEnabled(); @@ -487,8 +485,7 @@ test.describe("Tokens: Apply token", () => { test("User applies dimension token to a shape on width and height", async ({ page, }) => { - const { workspacePage, tokensSidebar, tokenContextMenuForToken } = - await setupTokensFileRender(page); + const { workspacePage, tokensSidebar } = await setupTokensFileRender(page); // Unfolds dimensions on token panel await page.getByRole("tab", { name: "Layers" }).click(); @@ -501,7 +498,7 @@ test.describe("Tokens: Apply token", () => { unfoldTokenTree(tokensSidebar, "dimensions", "dimension.dimension.sm"); // Apply token to width and height token from token panel - await tokensSidebar.getByRole("button", { name: "dimension.sm" }).click(); + await tokensSidebar.getByRole("checkbox", { name: "dimension.sm" }).click(); // Check if measures sections is visible on right sidebar const measuresSection = page.getByRole("region", { @@ -553,7 +550,7 @@ test.describe("Tokens: Apply token", () => { // Apply token to width and height token from token panel await tokensSidebar - .getByRole("button", { name: "dimension.sm" }) + .getByRole("checkbox", { name: "dimension.sm" }) .click({ button: "right" }); await tokenContextMenuForToken.getByText("AxisX").click(); @@ -607,7 +604,7 @@ test.describe("Tokens: Apply token", () => { // Apply token to width and height token from token panel await tokensSidebar - .getByRole("button", { name: "dimension.sm" }) + .getByRole("checkbox", { name: "dimension.sm" }) .click({ button: "right" }); await tokenContextMenuForToken.getByText("Y").click(); @@ -661,7 +658,7 @@ test.describe("Tokens: Apply token", () => { // Apply token to width and height token from token panel await tokensSidebar - .getByRole("button", { name: "dimension.xs" }) + .getByRole("checkbox", { name: "dimension.xs" }) .click({ button: "right" }); await tokenContextMenuForToken.getByText("Border radius").hover(); await tokenContextMenuForToken.getByText("RadiusAll").click(); @@ -722,9 +719,9 @@ test.describe("Tokens: Apply token", () => { await page.getByRole("button", { name: "Stroke Width 2" }).click(); const tokensSidebar = workspace.tokensSidebar; await expect( - tokensSidebar.getByRole("button", { name: "width-big" }), + tokensSidebar.getByRole("checkbox", { name: "width-big" }), ).toBeVisible(); - await tokensSidebar.getByRole("button", { name: "width-big" }).click(); + await tokensSidebar.getByRole("checkbox", { name: "width-big" }).click(); // Check if token pill is visible on right sidebar const strokeSectionSidebar = rightSidebar.getByRole("region", { @@ -733,17 +730,17 @@ test.describe("Tokens: Apply token", () => { await expect(strokeSectionSidebar).toBeVisible(); const firstStrokeRow = strokeSectionSidebar.getByLabel("stroke-row-0"); await expect(firstStrokeRow).toBeVisible(); - const StrokeWidthPill = firstStrokeRow.getByRole("button", { + const strokeWidthPill = firstStrokeRow.getByRole("button", { name: "width-big", }); - await expect(StrokeWidthPill).toBeVisible(); + await expect(strokeWidthPill).toBeVisible(); // Detach token from right sidebar and apply another from dropdown const detachButton = firstStrokeRow.getByRole("button", { name: "Detach token", }); await detachButton.click(); - await expect(StrokeWidthPill).not.toBeVisible(); + await expect(strokeWidthPill).not.toBeVisible(); const tokenDropdown = firstStrokeRow.getByRole("button", { name: "Open token list", @@ -753,10 +750,10 @@ test.describe("Tokens: Apply token", () => { const widthOptionSmall = firstStrokeRow.getByRole('option', { name: 'width-small' }); await expect(widthOptionSmall).toBeVisible(); await widthOptionSmall.click(); - const StrokeWidthPillSmall = firstStrokeRow.getByRole("button", { + const strokeWidthPillSmall = firstStrokeRow.getByRole("button", { name: "width-small", }); - await expect(StrokeWidthPillSmall).toBeVisible(); + await expect(strokeWidthPillSmall).toBeVisible(); }); test("User applies margin token to a shape", async ({ page }) => { @@ -790,10 +787,10 @@ test.describe("Tokens: Apply token", () => { await page.getByRole("button", { name: "dim", exact: true }).click(); const tokensSidebar = workspace.tokensSidebar; await expect( - tokensSidebar.getByRole("button", { name: "dim.md" }), + tokensSidebar.getByRole("checkbox", { name: "dim.md" }), ).toBeVisible(); await tokensSidebar - .getByRole("button", { name: "dim.md" }) + .getByRole("checkbox", { name: "dim.md" }) .click({ button: "right" }); await page .getByTestId("tokens-context-menu-for-token") @@ -846,8 +843,7 @@ test.describe("Tokens: Detach token", () => { test("User applies border-radius token to a shape from sidebar", async ({ page, }) => { - const { workspacePage, tokensSidebar, tokenContextMenuForToken } = - await setupTokensFileRender(page); + const { workspacePage, tokensSidebar } = await setupTokensFileRender(page); await page.getByRole("tab", { name: "Layers" }).click(); @@ -864,12 +860,12 @@ test.describe("Tokens: Detach token", () => { ).toBeVisible(); await tokensSidebar.getByRole("button", { name: "borderRadius" }).click(); await expect( - tokensSidebar.getByRole("button", { name: "borderRadius.sm" }), + tokensSidebar.getByRole("checkbox", { name: "borderRadius.sm" }), ).toBeVisible(); // Apply border radius token from token panels await tokensSidebar - .getByRole("button", { name: "borderRadius.sm" }) + .getByRole("checkbox", { name: "borderRadius.sm" }) .click(); // Check if border radius sections is visible on right sidebar @@ -887,7 +883,7 @@ test.describe("Tokens: Detach token", () => { // Rename token await tokensSidebar - .getByRole("button", { name: "borderRadius.sm" }) + .getByRole("checkbox", { name: "borderRadius.sm" }) .click({ button: "right" }); await expect(page.getByText("Edit token")).toBeVisible(); await page.getByText("Edit token").click(); diff --git a/frontend/playwright/ui/specs/tokens/crud.spec.js b/frontend/playwright/ui/specs/tokens/crud.spec.js index cadc58231b..9830ccb4e3 100644 --- a/frontend/playwright/ui/specs/tokens/crud.spec.js +++ b/frontend/playwright/ui/specs/tokens/crud.spec.js @@ -1,6 +1,5 @@ import { test, expect } from "@playwright/test"; import { WasmWorkspacePage } from "../../pages/WasmWorkspacePage"; -import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage"; import { setupEmptyTokensFileRender, setupTokensFileRender, @@ -11,7 +10,9 @@ import { test.beforeEach(async ({ page }) => { await WasmWorkspacePage.init(page); - await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json"); + await WasmWorkspacePage.mockConfigFlags(page, [ + "enable-feature-design-tokens-v1", + ]); }); test.describe("Tokens - creation", () => { @@ -247,14 +248,14 @@ test.describe("Tokens - creation", () => { await submitButton.press("Enter"); await expect( - tokensSidebar.getByRole("button", { + tokensSidebar.getByRole("checkbox", { name: "secondary", }), ).toBeEnabled(); // Tokens tab panel should have two tokens with the color red / #ff0000 await expect( - tokensSidebar.getByRole("button", { name: "#ff0000" }), + tokensSidebar.getByRole("checkbox", { name: "#ff0000" }), ).toHaveCount(2); // Global set has been auto created and is active @@ -395,7 +396,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -436,7 +437,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); // @@ -453,7 +454,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-3" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-3" }), ).toBeEnabled(); }); @@ -549,7 +550,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -569,7 +570,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); // @@ -589,7 +590,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-3" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-3" }), ).toBeEnabled(); }); @@ -600,8 +601,7 @@ test.describe("Tokens - creation", () => { const selfReferenceError = "Token has self reference"; const missingReferenceError = "Missing token references"; - const { tokensUpdateCreateModal, tokenThemesSetsSidebar } = - await setupEmptyTokensFileRender(page); + const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page); // Open modal const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); @@ -685,7 +685,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -705,7 +705,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); }); @@ -716,7 +716,7 @@ test.describe("Tokens - creation", () => { const selfReferenceError = "Token has self reference"; const missingReferenceError = "Missing token references"; - const { tokensUpdateCreateModal, tokenThemesSetsSidebar } = + const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page); // Open modal @@ -803,7 +803,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -823,14 +823,14 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); }); test("User creates shadow token", async ({ page }) => { const emptyNameError = "Name should be at least 1 character"; - const { tokensUpdateCreateModal, tokenThemesSetsSidebar } = + const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page, { flags: ["enable-token-shadow"] }); // Open modal @@ -967,7 +967,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -1004,14 +1004,14 @@ test.describe("Tokens - creation", () => { await expect(submitButton).toBeEnabled(); await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); }); - test("User cant submit empty typography token or reference", async ({ + test("User can't submit empty typography token or reference", async ({ page, }) => { - const { tokensUpdateCreateModal, tokenThemesSetsSidebar, tokensSidebar } = + const { tokensUpdateCreateModal } = await setupTypographyTokensFileRender(page); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); @@ -1024,7 +1024,7 @@ test.describe("Tokens - creation", () => { const nameField = tokensUpdateCreateModal.getByLabel("Name"); await nameField.fill("typography.empty"); - const valueField = tokensUpdateCreateModal.getByRole("textbox", {name: "Font Size"}); + const valueField = tokensUpdateCreateModal.getByRole("textbox", { name: "Font Size" }); // Insert a value and then delete it await valueField.fill("1"); @@ -1046,7 +1046,7 @@ test.describe("Tokens - creation", () => { test("User creates shadow token with negative spread", async ({ page }) => { const emptyNameError = "Name should be at least 1 character"; - const { tokensUpdateCreateModal, tokenThemesSetsSidebar } = + const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page, { flags: ["enable-token-shadow"] }); // Open modal @@ -1188,7 +1188,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -1225,14 +1225,13 @@ test.describe("Tokens - creation", () => { await expect(submitButton).toBeEnabled(); await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); }); test("User creates typography token", async ({ page }) => { const emptyNameError = "Name should be at least 1 character"; - const { tokensUpdateCreateModal, tokenThemesSetsSidebar } = - await setupEmptyTokensFileRender(page); + const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page); // Open modal const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); @@ -1432,7 +1431,7 @@ test.describe("Tokens - creation", () => { await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -1473,12 +1472,12 @@ test.describe("Tokens - creation", () => { await expect(submitButton).toBeEnabled(); await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); }); test("User adds typography token with reference", async ({ page }) => { - const { tokensUpdateCreateModal, tokenThemesSetsSidebar, tokensSidebar } = + const { tokensUpdateCreateModal, tokensSidebar } = await setupTypographyTokensFileRender(page); const newTokenTitle = "NewReference"; @@ -1520,7 +1519,7 @@ test.describe("Tokens - creation", () => { await expect(tokensUpdateCreateModal).not.toBeVisible(); - const newToken = tokensSidebar.getByRole("button", { + const newToken = tokensSidebar.getByRole("checkbox", { name: newTokenTitle, }); @@ -1528,7 +1527,7 @@ test.describe("Tokens - creation", () => { }); test("User creates grouped color token", async ({ page }) => { - const { workspacePage, tokensUpdateCreateModal, tokensSidebar } = + const { tokensUpdateCreateModal, tokensSidebar } = await setupEmptyTokensFileRender(page); await tokensSidebar @@ -1559,7 +1558,7 @@ test.describe("Tokens - creation", () => { await expect(tokensSidebar.getByLabel("primary")).toBeEnabled(); }); - test("User cant create regular token with value missing", async ({ + test("User can't create regular token with value missing", async ({ page, }) => { const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page); @@ -1586,29 +1585,6 @@ test.describe("Tokens - creation", () => { // Submit button should remain disabled when value is empty await expect(submitButton).toBeDisabled(); }); - - test("User duplicate color token", async ({ page }) => { - const { tokensSidebar, tokenContextMenuForToken } = - await setupTokensFileRender(page); - - await expect(tokensSidebar).toBeVisible(); - - unfoldTokenTree(tokensSidebar, "color", "colors.blue.100"); - - const colorToken = tokensSidebar.getByRole("button", { - name: "100", - }); - - await colorToken.click({ button: "right" }); - await expect(tokenContextMenuForToken).toBeVisible(); - - await tokenContextMenuForToken.getByText("Duplicate token").click(); - await expect(tokenContextMenuForToken).not.toBeVisible(); - - await expect( - tokensSidebar.getByRole("button", { name: "colors.blue.100-copy" }), - ).toBeVisible(); - }); }); test("User creates grouped color token", async ({ page }) => { @@ -1667,7 +1643,7 @@ test("User cant create regular token with value missing", async ({ page }) => { await expect(submitButton).toBeDisabled(); }); -test("User duplicate color token", async ({ page }) => { +test("User duplicates color token", async ({ page }) => { const { tokensSidebar, tokenContextMenuForToken } = await setupTokensFileRender(page); @@ -1675,7 +1651,7 @@ test("User duplicate color token", async ({ page }) => { unfoldTokenTree(tokensSidebar, "color", "colors.blue.100"); - const colorToken = tokensSidebar.getByRole("button", { + const colorToken = tokensSidebar.getByRole("checkbox", { name: "100", }); @@ -1686,7 +1662,7 @@ test("User duplicate color token", async ({ page }) => { await expect(tokenContextMenuForToken).not.toBeVisible(); await expect( - tokensSidebar.getByRole("button", { name: "colors.blue.100-copy" }), + tokensSidebar.getByRole("checkbox", { name: "colors.blue.100-copy" }), ).toBeVisible(); }); @@ -1694,7 +1670,7 @@ test.describe("Tokens tab - edition", () => { test("User edits typography token and all fields are valid", async ({ page, }) => { - const { tokensUpdateCreateModal, tokenThemesSetsSidebar, tokensSidebar } = + const { tokensUpdateCreateModal, tokensSidebar } = await setupTypographyTokensFileRender(page); await tokensSidebar @@ -1703,7 +1679,7 @@ test.describe("Tokens tab - edition", () => { .click(); // Open edit modal for "Full" typography token - const token = tokensSidebar.getByRole("button", { name: "Full" }); + const token = tokensSidebar.getByRole("checkbox", { name: "Full" }); await token.click({ button: "right" }); await page.getByText("Edit token").click(); @@ -1797,7 +1773,7 @@ test.describe("Tokens tab - edition", () => { await unfoldTokenTree(tokensSidebar, "color", "colors.blue.100"); - const colorToken = tokensSidebar.getByRole("button", { + const colorToken = tokensSidebar.getByRole("checkbox", { name: "100", }); @@ -1818,7 +1794,7 @@ test.describe("Tokens tab - edition", () => { await unfoldTokenTree(tokensSidebar, "color", "colors.blue.100.changed"); - const colorTokenChanged = tokensSidebar.getByRole("button", { + const colorTokenChanged = tokensSidebar.getByRole("checkbox", { name: "changed", }); await expect(colorTokenChanged).toBeVisible(); @@ -1881,7 +1857,7 @@ test.describe("Tokens tab - edition", () => { }); test.describe("Tokens tab - delete", () => { - test("User delete color token", async ({ page }) => { + test("User deletes color token", async ({ page }) => { const { tokensSidebar, tokenContextMenuForToken } = await setupTokensFileRender(page); @@ -1889,7 +1865,7 @@ test.describe("Tokens tab - delete", () => { unfoldTokenTree(tokensSidebar, "color", "colors.blue.100"); - const colorToken = tokensSidebar.getByRole("button", { + const colorToken = tokensSidebar.getByRole("checkbox", { name: "100", }); await expect(colorToken).toBeVisible(); @@ -1915,7 +1891,7 @@ test.describe("Tokens tab - delete", () => { name: "colors", exact: true, }); - const colorNodeToken = tokensSidebar.getByRole("button", { + const colorNodeToken = tokensSidebar.getByRole("checkbox", { name: "100", }); diff --git a/frontend/playwright/ui/specs/tokens/general.spec.js b/frontend/playwright/ui/specs/tokens/general.spec.js index 1aefcba2d7..f276199de5 100644 --- a/frontend/playwright/ui/specs/tokens/general.spec.js +++ b/frontend/playwright/ui/specs/tokens/general.spec.js @@ -1,11 +1,12 @@ import { test, expect } from "@playwright/test"; import { WasmWorkspacePage } from "../../pages/WasmWorkspacePage"; -import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage"; import { setupEmptyTokensFileRender } from "./helpers"; test.beforeEach(async ({ page }) => { await WasmWorkspacePage.init(page); - await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json"); + await WasmWorkspacePage.mockConfigFlags(page, [ + "enable-feature-design-tokens-v1", + ]); }); test.describe("Tokens tab - common tests", () => { @@ -20,3 +21,31 @@ test.describe("Tokens tab - common tests", () => { await expect(tokensTabPanel).toHaveText(/Themes/); }); }); + +test("BUG 13302 - Dimension token not being highlighted after applying it", async ({ page }) => { + const workspacePage = new WasmWorkspacePage(page); + await workspacePage.setupEmptyFile(); + + await workspacePage.mockGetFile("tokens/get-file-13302.json"); + await workspacePage.mockRPC("update-file?id=*", "tokens/update-file-13302.json"); + + await workspacePage.goToWorkspace({ + fileId: "6886b62b-1979-8195-8007-8d0b92d3116a", + pageId: "6886b62b-1979-8195-8007-8d0b92d3116b", + }); + + await workspacePage.clickLeafLayer("Rectangle"); + + await workspacePage.sidebar.getByRole("tab", { name: "Tokens" }).click(); + + await workspacePage.tokensSidebar + .getByRole("button", { name: "Dimensions 1" }) + .click(); + + const token = workspacePage.tokensSidebar.getByRole("checkbox", { name: "any-dimensions-token" }); + await token.click(); + + // FIXME: this is a bug somewhere else in tokens, this should be fully applied + // for a dimensions token + await expect(token).toBeChecked({ indeterminate: true }); +}); diff --git a/frontend/playwright/ui/specs/tokens/helpers.js b/frontend/playwright/ui/specs/tokens/helpers.js index 63c54af0f9..92437818d9 100644 --- a/frontend/playwright/ui/specs/tokens/helpers.js +++ b/frontend/playwright/ui/specs/tokens/helpers.js @@ -11,10 +11,6 @@ const setupEmptyTokensFile = async (page, options = {}) => { } await workspacePage.setupEmptyFile(); - await workspacePage.mockRPC( - "get-team?id=*", - "workspace/get-team-tokens.json", - ); await workspacePage.mockRPC( "update-file?id=*", @@ -50,10 +46,6 @@ const setupEmptyTokensFileRender = async (page, options = {}) => { } await workspacePage.setupEmptyFile(); - await workspacePage.mockRPC( - "get-team?id=*", - "workspace/get-team-tokens.json", - ); await workspacePage.mockRPC( "update-file?id=*", @@ -93,10 +85,7 @@ const setupTokensFile = async (page, options = {}) => { } await workspacePage.setupEmptyFile(); - await workspacePage.mockRPC( - "get-team?id=*", - "workspace/get-team-tokens.json", - ); + await workspacePage.mockRPC(/get\-file\?/, file); await workspacePage.mockRPC(/get\-file\-fragment\?/, fileFragment); await workspacePage.mockRPC( @@ -138,10 +127,7 @@ const setupTokensFileRender = async (page, options = {}) => { } await workspacePage.setupEmptyFile(); - await workspacePage.mockRPC( - "get-team?id=*", - "workspace/get-team-tokens.json", - ); + await workspacePage.mockRPC(/get\-file\?/, file); await workspacePage.mockRPC(/get\-file\-fragment\?/, fileFragment); await workspacePage.mockRPC( @@ -206,8 +192,7 @@ const testTokenCreationFlow = async ( const selfReferenceError = "Token has self reference"; const missingReferenceError = "Missing token references"; - const { tokensUpdateCreateModal, tokenThemesSetsSidebar } = - await setupEmptyTokensFileRender(page); + const { tokensUpdateCreateModal } = await setupEmptyTokensFileRender(page); // Open modal const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); @@ -288,7 +273,7 @@ const testTokenCreationFlow = async ( await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token" }), ).toBeEnabled(); // @@ -308,7 +293,7 @@ const testTokenCreationFlow = async ( await submitButton.click(); await expect( - tokensTabPanel.getByRole("button", { name: "my-token-2" }), + tokensTabPanel.getByRole("checkbox", { name: "my-token-2" }), ).toBeEnabled(); }; @@ -344,7 +329,7 @@ const unfoldTokenTree = async (tokensTabPanel, type, tokenName) => { } await expect( - typeParentWrapper.getByRole("button", { + typeParentWrapper.getByRole("checkbox", { name: tokenLeafName, }), ).toBeEnabled(); diff --git a/frontend/playwright/ui/specs/tokens/remapping.spec.js b/frontend/playwright/ui/specs/tokens/remapping.spec.js index 9cf91a1a9c..c954bcd317 100644 --- a/frontend/playwright/ui/specs/tokens/remapping.spec.js +++ b/frontend/playwright/ui/specs/tokens/remapping.spec.js @@ -11,7 +11,6 @@ test.beforeEach(async ({ page }) => { await WasmWorkspacePage.mockConfigFlags(page, [ "enable-feature-design-tokens-v1", ]); - await WasmWorkspacePage.mockRPC(page, "get-teams", "get-teams-tokens.json"); }); const createToken = async (page, type, name, textFieldName, value) => { @@ -46,7 +45,7 @@ const renameToken = async (page, oldName, newName) => { const { tokensUpdateCreateModal, tokensSidebar, tokenContextMenuForToken } = await setupTokensFileRender(page, { flags: ["enable-token-shadow"] }); - const baseToken = tokensSidebar.getByRole("button", { + const baseToken = tokensSidebar.getByRole("checkbox", { name: oldName, }); await baseToken.click({ button: "right" }); @@ -131,10 +130,10 @@ test.describe("Remapping Tokens", () => { // Verify token was renamed await expect( - tokensSidebar.getByRole("button", { name: "foundation-shadow" }), + tokensSidebar.getByRole("checkbox", { name: "foundation-shadow" }), ).toBeVisible(); await expect( - tokensSidebar.getByRole("button", { name: "derived-shadow" }), + tokensSidebar.getByRole("checkbox", { name: "derived-shadow" }), ).toBeVisible(); }); @@ -167,13 +166,13 @@ test.describe("Remapping Tokens", () => { .click(); await page.getByRole("tab", { name: "Tokens" }).click(); - const cardShadowToken = tokensSidebar.getByRole("button", { + const cardShadowToken = tokensSidebar.getByRole("checkbox", { name: "card-shadow", }); await cardShadowToken.click(); // Rename and update value of base token - const primaryToken = tokensSidebar.getByRole("button", { + const primaryToken = tokensSidebar.getByRole("checkbox", { name: "primary-shadow", }); await primaryToken.click({ button: "right" }); @@ -205,12 +204,12 @@ test.describe("Remapping Tokens", () => { // Verify base token was renamed await expect( - tokensSidebar.getByRole("button", { name: "main-shadow" }), + tokensSidebar.getByRole("checkbox", { name: "main-shadow" }), ).toBeVisible(); // Verify referenced token still exists await expect( - tokensSidebar.getByRole("button", { name: "card-shadow" }), + tokensSidebar.getByRole("checkbox", { name: "card-shadow" }), ).toBeVisible(); // Verify the shape still has the token applied with the NEW name @@ -247,13 +246,7 @@ test.describe("Remapping Tokens", () => { test("User renames typography token with alias references", async ({ page, }) => { - const { - tokensUpdateCreateModal, - tokensSidebar, - tokenContextMenuForToken, - } = await setupTypographyTokensFileRender(page); - - const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); + const { tokensSidebar } = await setupTypographyTokensFileRender(page); // Create base typography token await createToken(page, "Typography", "base-text", "Font size", "16"); @@ -280,10 +273,10 @@ test.describe("Remapping Tokens", () => { // Verify token was renamed await expect( - tokensSidebar.getByRole("button", { name: "default-text" }), + tokensSidebar.getByRole("checkbox", { name: "default-text" }), ).toBeVisible(); await expect( - tokensSidebar.getByRole("button", { name: "body-text" }), + tokensSidebar.getByRole("checkbox", { name: "body-text" }), ).toBeVisible(); }); @@ -336,13 +329,13 @@ test.describe("Remapping Tokens", () => { .click(); await page.getByRole("tab", { name: "Tokens" }).click(); - const paragraphToken = tokensSidebar.getByRole("button", { + const paragraphToken = tokensSidebar.getByRole("checkbox", { name: "paragraph-style", }); await paragraphToken.click(); // Rename and update value of base token - const bodyToken = tokensSidebar.getByRole("button", { + const bodyToken = tokensSidebar.getByRole("checkbox", { name: "body-style", }); await bodyToken.click({ button: "right" }); @@ -374,12 +367,12 @@ test.describe("Remapping Tokens", () => { // Verify base token was renamed await expect( - tokensSidebar.getByRole("button", { name: "text-base" }), + tokensSidebar.getByRole("checkbox", { name: "text-base" }), ).toBeVisible(); // Verify referenced token still exists await expect( - tokensSidebar.getByRole("button", { name: "paragraph-style" }), + tokensSidebar.getByRole("checkbox", { name: "paragraph-style" }), ).toBeVisible(); // Verify the text shape still has the token applied with NEW name and value @@ -431,10 +424,10 @@ test.describe("Remapping Tokens", () => { // Verify token was renamed await expect( - tokensSidebar.getByRole("button", { name: "primary-radius" }), + tokensSidebar.getByRole("checkbox", { name: "primary-radius" }), ).toBeVisible(); await expect( - tokensSidebar.getByRole("button", { name: "card-radius" }), + tokensSidebar.getByRole("checkbox", { name: "card-radius" }), ).toBeVisible(); }); @@ -460,7 +453,7 @@ test.describe("Remapping Tokens", () => { ); // Rename and update value of base token - const radiusToken = tokensSidebar.getByRole("button", { + const radiusToken = tokensSidebar.getByRole("checkbox", { name: "radius-sm", }); await radiusToken.click({ button: "right" }); @@ -490,17 +483,17 @@ test.describe("Remapping Tokens", () => { // Verify base token was renamed await expect( - tokensSidebar.getByRole("button", { name: "radius-base" }), + tokensSidebar.getByRole("checkbox", { name: "radius-base" }), ).toBeVisible(); // Verify referenced token still exists await expect( - tokensSidebar.getByRole("button", { name: "button-radius" }), + tokensSidebar.getByRole("checkbox", { name: "button-radius" }), ).toBeVisible(); // Verify the referenced token now points to the renamed token // by opening it and checking the reference - const buttonRadiusToken = tokensSidebar.getByRole("button", { + const buttonRadiusToken = tokensSidebar.getByRole("checkbox", { name: "button-radius", }); await buttonRadiusToken.click({ button: "right" }); @@ -543,13 +536,11 @@ test.describe("Remapping Tokens", () => { // Verify token was renamed await expect( - tokensSidebar.getByRole("button", { + tokensSidebar.getByRole("checkbox", { name: "foundation-shadow", }), ).toBeVisible(); - await expect( - tokensSidebar.locator('[aria-label="Missing reference"]'), - ).toBeVisible(); + await expect(tokensSidebar.getByLabel("Missing reference")).toBeVisible(); }); test("Cancel process - no changes applied", async ({ page }) => { @@ -582,10 +573,10 @@ test.describe("Remapping Tokens", () => { // Verify original token name still exists await expect( - tokensSidebar.getByRole("button", { name: "base-shadow" }), + tokensSidebar.getByRole("checkbox", { name: "base-shadow" }), ).toBeVisible(); await expect( - tokensSidebar.getByRole("button", { name: "derived-shadow" }), + tokensSidebar.getByRole("checkbox", { name: "derived-shadow" }), ).toBeVisible(); }); }); diff --git a/frontend/playwright/ui/specs/tokens/sets.spec.js b/frontend/playwright/ui/specs/tokens/sets.spec.js index c0fc52a17a..f8e11c56f4 100644 --- a/frontend/playwright/ui/specs/tokens/sets.spec.js +++ b/frontend/playwright/ui/specs/tokens/sets.spec.js @@ -1,11 +1,12 @@ import { test, expect } from "@playwright/test"; -import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage"; import { WasmWorkspacePage } from "../../pages/WasmWorkspacePage"; import { setupEmptyTokensFileRender, setupTokensFileRender } from "./helpers"; test.beforeEach(async ({ page }) => { - await WasmWorkspacePage.init(page); - await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json"); + await WasmWorkspacePage.init(page); + await WasmWorkspacePage.mockConfigFlags(page, [ + "enable-feature-design-tokens-v1", + ]); }); test.describe("Tokens: Sets Tab", () => { @@ -17,11 +18,11 @@ test.describe("Tokens: Sets Tab", () => { }; const createSet = async (sidebar, setName, finalKey = "Enter") => { - const tokensTabButton = sidebar + sidebar .getByRole("button", { name: "Add set" }) .click(); - await changeSetInput(sidebar, setName, (finalKey = "Enter")); + await changeSetInput(sidebar, setName, finalKey); }; const assertEmptySetsList = async (el) => { @@ -44,7 +45,7 @@ test.describe("Tokens: Sets Tab", () => { const { tokenThemesSetsSidebar, tokenContextMenuForSet } = await setupEmptyTokensFileRender(page); - const tokensTabButton = tokenThemesSetsSidebar + tokenThemesSetsSidebar .getByRole("button", { name: "Add set" }) .click(); @@ -138,10 +139,10 @@ test.describe("Tokens: Sets Tab", () => { test("User can create & edit sets and set groups with an identical name", async ({ page, }) => { - const { tokenThemesSetsSidebar, tokenContextMenuForSet } = + const { tokenThemesSetsSidebar } = await setupEmptyTokensFileRender(page); - const tokensTabButton = tokenThemesSetsSidebar + tokenThemesSetsSidebar .getByRole("button", { name: "Add set" }) .click(); @@ -218,7 +219,7 @@ test.describe("Tokens: Sets Tab", () => { }); test("Display active set and verify if is enabled", async ({ page }) => { - const { tokenThemesSetsSidebar, tokensSidebar, tokenSetItems } = + const { tokenThemesSetsSidebar, tokensSidebar } = await setupTokensFileRender(page); // Create set diff --git a/frontend/playwright/ui/specs/tokens/themes.spec.js b/frontend/playwright/ui/specs/tokens/themes.spec.js index 0685aaf959..2e0221b0c8 100644 --- a/frontend/playwright/ui/specs/tokens/themes.spec.js +++ b/frontend/playwright/ui/specs/tokens/themes.spec.js @@ -1,6 +1,5 @@ import { test, expect } from "@playwright/test"; import { WasmWorkspacePage } from "../../pages/WasmWorkspacePage"; -import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage"; import { setupEmptyTokensFileRender, setupTokensFileRender } from "./helpers"; // THEMES HELPERS @@ -27,7 +26,6 @@ test.beforeEach(async ({ page }) => { await WasmWorkspacePage.mockConfigFlags(page, [ "enable-feature-design-tokens-v1", ]); - await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json"); }); test.describe("Tokens Themes", () => { diff --git a/frontend/playwright/ui/specs/tokens/tree.spec.js b/frontend/playwright/ui/specs/tokens/tree.spec.js index ae43197acc..e7d4952ad9 100644 --- a/frontend/playwright/ui/specs/tokens/tree.spec.js +++ b/frontend/playwright/ui/specs/tokens/tree.spec.js @@ -1,11 +1,12 @@ import { test, expect } from "@playwright/test"; import { WasmWorkspacePage } from "../../pages/WasmWorkspacePage"; -import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage"; import { setupTokensFileRender, unfoldTokenTree } from "./helpers"; test.beforeEach(async ({ page }) => { await WasmWorkspacePage.init(page); - await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json"); + await WasmWorkspacePage.mockConfigFlags(page, [ + "enable-feature-design-tokens-v1", + ]); }); test.describe("Tokens - node tree", () => { @@ -22,7 +23,7 @@ test.describe("Tokens - node tree", () => { await unfoldTokenTree(tokensSidebar, "color", "colors.blue.100"); - const colorToken = tokensSidebar.getByRole("button", { + const colorToken = tokensSidebar.getByRole("checkbox", { name: "100", }); await expect(colorToken).toBeVisible(); diff --git a/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs b/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs index c76651c151..79c460aa3e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs @@ -191,7 +191,7 @@ full-applied? (if has-selected? (applied-all-attributes? token selected-shapes attributes) - true) + false) applied? (if has-selected? @@ -290,6 +290,11 @@ :token-pill-invalid-applied-viewer (and is-viewer? (and full-applied? errors?))) :type "button" + :role "checkbox" + :aria-checked (cond + full-applied? "true" + half-applied? "mixed" + :else "false") :on-focus on-hover :on-click on-click