diff --git a/frontend/playwright/data/workspace/get-team-tokens.json b/frontend/playwright/data/workspace/get-team-tokens.json new file mode 100644 index 0000000000..855b1506ac --- /dev/null +++ b/frontend/playwright/data/workspace/get-team-tokens.json @@ -0,0 +1,24 @@ +{ + "~: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-38e630f40f6d", + "~:created-at": "~m1713533116375", + "~:is-default": true +} diff --git a/frontend/playwright/ui/pages/WorkspacePage.js b/frontend/playwright/ui/pages/WorkspacePage.js index 71c20b639f..1b66cc34c6 100644 --- a/frontend/playwright/ui/pages/WorkspacePage.js +++ b/frontend/playwright/ui/pages/WorkspacePage.js @@ -76,6 +76,9 @@ export class WorkspacePage extends BaseWebSocketPage { this.togglePalettesVisibility = page.getByTestId( "toggle-palettes-visibility", ); + this.tokensUpdateCreateModal = page.getByTestId( + "token-update-create-modal", + ); } async goToWorkspace({ diff --git a/frontend/playwright/ui/specs/tokens.spec.js b/frontend/playwright/ui/specs/tokens.spec.js new file mode 100644 index 0000000000..7ea79ce74a --- /dev/null +++ b/frontend/playwright/ui/specs/tokens.spec.js @@ -0,0 +1,87 @@ +import { test, expect } from "@playwright/test"; +import { WorkspacePage } from "../pages/WorkspacePage"; + +test.beforeEach(async ({ page }) => { + await WorkspacePage.init(page); +}); + +test.describe("Tokens: Tab", () => { + test("Clicking tokens tab button opens tokens sidebar tab", async ({ + page, + }) => { + const workspacePage = new WorkspacePage(page); + await workspacePage.setupEmptyFile(); + await workspacePage.mockRPC( + "get-team?id=*", + "workspace/get-team-tokens.json", + ); + + await workspacePage.goToWorkspace(); + + const tokensTabButton = page.getByRole("tab", { name: "Tokens" }); + await tokensTabButton.click(); + + const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); + + await expect(tokensTabPanel).toHaveText(/TOKENS/); + await expect(tokensTabPanel).toHaveText(/Themes/); + }); + + test("Created color token shows up in the sidebar", async ({ page }) => { + const workspacePage = new WorkspacePage(page); + await workspacePage.setupEmptyFile(); + await workspacePage.mockRPC( + "get-team?id=*", + "workspace/get-team-tokens.json", + ); + + await workspacePage.goToWorkspace(); + + const tokensTabButton = page.getByRole("tab", { name: "Tokens" }); + await tokensTabButton.click(); + + const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); + await tokensTabPanel.getByTitle("Add token: Color").click(); + + // Create color token with mouse + + await expect(workspacePage.tokensUpdateCreateModal).toBeVisible(); + + const nameField = workspacePage.tokensUpdateCreateModal.getByLabel("Name"); + const valueField = + workspacePage.tokensUpdateCreateModal.getByLabel("Value"); + + await nameField.click(); + await nameField.fill("color.primary"); + + await valueField.click(); + await valueField.fill("red"); + + const submitButtonSelector = `button[type="submit"]:enabled`; + await page.waitForSelector(submitButtonSelector); + await page.locator(submitButtonSelector).click(); + + await expect(tokensTabPanel.getByText("color.primary")).toBeEnabled(); + + // Create token referencing the previous one with keyboard + + await tokensTabPanel.getByTitle("Add token: Color").click(); + await expect(workspacePage.tokensUpdateCreateModal).toBeVisible(); + + await nameField.click(); + await nameField.fill("color.secondary"); + await nameField.press("Tab"); + + await valueField.click(); + await valueField.fill("{color.primary}"); + + await page.waitForSelector(submitButtonSelector); + await nameField.press("Enter"); + + const referenceToken = tokensTabPanel.getByText("color.secondary"); + await expect(referenceToken).toBeEnabled(); + + // Tokens tab panel should have two tokens with the color red / #ff0000 + await expect(tokensTabPanel.getByTitle("#ff0000")).toHaveCount(2); + }); +}); diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index de24713031..a23ea972c2 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -360,8 +360,8 @@ Token names should only contain letters and digits separated by . characters.")} (dom/prevent-default e) (modal/hide!)))] - [:form {:class (stl/css :form-wrapper) - :on-submit on-submit} + [:form {:class (stl/css :form-wrapper) + :on-submit on-submit} [:div {:class (stl/css :token-rows)} [:> heading* {:level 2 :typography "headline-medium" :class (stl/css :form-modal-title)} (if (= action "edit") diff --git a/frontend/src/app/main/ui/workspace/tokens/modals.cljs b/frontend/src/app/main/ui/workspace/tokens/modals.cljs index a34ccfe618..56a77ccd72 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals.cljs @@ -48,7 +48,8 @@ (fn [] (modal/hide!)))] [:div {:class (stl/css :token-modal-wrapper) - :style wrapper-style} + :style wrapper-style + :data-testid "token-update-create-modal"} [:> icon-button* {:on-click close-modal :class (stl/css :close-btn) :icon i/close diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index b496a2d974..20f4b7c0af 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -148,7 +148,8 @@ :open? open?} [:& cmm/asset-section-block {:role :title-button} [:button {:class (stl/css :action-button) - :on-click on-popover-open-click} + :on-click on-popover-open-click + :title (str "Add token: " title)} i/add]] (when open? [:& cmm/asset-section-block {:role :content}