diff --git a/frontend/playwright/ui/specs/colorpicker.spec.js b/frontend/playwright/ui/specs/colorpicker.spec.js index e555eed3f..e847e659b 100644 --- a/frontend/playwright/ui/specs/colorpicker.spec.js +++ b/frontend/playwright/ui/specs/colorpicker.spec.js @@ -40,6 +40,7 @@ test("Create a LINEAR gradient", async ({ page }) => { fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374", pageId: "6191cd35-bb1f-81f7-8004-7cc63d087375", }); + await workspacePage.clickLeafLayer("Rectangle"); const swatch = workspacePage.page.getByRole("button", { name: "#B1B2B5" }); @@ -74,17 +75,21 @@ test("Create a LINEAR gradient", async ({ page }) => { const inputColor2 = workspacePage.colorpicker .getByPlaceholder("Mixed") - .nth(1); + .nth(2); await inputColor2.fill("red"); - const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(1); - await inputOpacity2.fill("100"); + const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(2); + await inputOpacity2.fill("40"); - const inputOpacityGlobal = workspacePage.page - .locator("div") - .filter({ hasText: /^FillLinear gradient%$/ }) - .getByPlaceholder("--"); - await inputOpacityGlobal.fill("100"); + const inputOpacityGlobal = workspacePage.colorpicker.getByTestId( + "opacity-global-input", + ); + await inputOpacityGlobal.fill("50"); + await inputOpacityGlobal.press("Enter"); + await expect(inputOpacityGlobal).toHaveValue("50"); + await expect(inputOpacityGlobal).toBeVisible(); + + await expect(workspacePage.page.getByText("Linear gradient")).toBeVisible(); }); test("Create a RADIAL gradient", async ({ page }) => { @@ -147,8 +152,18 @@ test("Create a RADIAL gradient", async ({ page }) => { const inputColor2 = workspacePage.page.getByPlaceholder("Mixed").nth(2); await inputColor2.fill("red"); - const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(1); + const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(2); await inputOpacity2.fill("100"); + + const inputOpacityGlobal = workspacePage.colorpicker.getByTestId( + "opacity-global-input", + ); + await inputOpacityGlobal.fill("50"); + await inputOpacityGlobal.press("Enter"); + await expect(inputOpacityGlobal).toHaveValue("50"); + await expect(inputOpacityGlobal).toBeVisible(); + + await expect(workspacePage.page.getByText("Radial gradient")).toBeVisible(); }); test("Gradient stops limit", async ({ page }) => { diff --git a/frontend/playwright/ui/specs/tokens.spec.js b/frontend/playwright/ui/specs/tokens.spec.js index 4ef124d24..e108c3025 100644 --- a/frontend/playwright/ui/specs/tokens.spec.js +++ b/frontend/playwright/ui/specs/tokens.spec.js @@ -92,7 +92,9 @@ test.describe("Tokens: Tokens Tab", () => { await setupEmptyTokensFile(page); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); - await tokensTabPanel.getByTitle("Add token: Color").click(); + await tokensTabPanel + .getByRole("button", { name: "Add Token: Color" }) + .click(); // Create color token with mouse @@ -129,7 +131,9 @@ test.describe("Tokens: Tokens Tab", () => { // Create token referencing the previous one with keyboard - await tokensTabPanel.getByTitle("Add token: Color").click(); + await tokensTabPanel + .getByRole("button", { name: "Add Token: Color" }) + .click(); await expect(tokensUpdateCreateModal).toBeVisible(); await nameField.click(); @@ -171,7 +175,9 @@ test.describe("Tokens: Tokens Tab", () => { await setupEmptyTokensFile(page); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); - await tokensTabPanel.getByTitle("Add token: Dimensions").click(); + await tokensTabPanel + .getByRole("button", { name: "Add token: Dimensions" }) + .click(); await expect(tokensUpdateCreateModal).toBeVisible(); @@ -351,7 +357,9 @@ test.describe("Tokens: Tokens Tab", () => { await setupEmptyTokensFile(page); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); - await tokensTabPanel.getByTitle("Add token: Color").click(); + await tokensTabPanel + .getByRole("button", { name: "Add Token: Color" }) + .click(); // Create grouped color token with mouse @@ -382,7 +390,9 @@ test.describe("Tokens: Tokens Tab", () => { await setupEmptyTokensFile(page); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); - await tokensTabPanel.getByTitle("Add token: Color").click(); + await tokensTabPanel + .getByRole("button", { name: "Add Token: Color" }) + .click(); await expect(tokensUpdateCreateModal).toBeVisible(); const nameField = tokensUpdateCreateModal.getByLabel("Name"); diff --git a/frontend/playwright/ui/specs/workspace-comments.spec.js b/frontend/playwright/ui/specs/workspace-comments.spec.js index 89d5fc1f4..b3ee1515e 100644 --- a/frontend/playwright/ui/specs/workspace-comments.spec.js +++ b/frontend/playwright/ui/specs/workspace-comments.spec.js @@ -22,7 +22,7 @@ test("Group bubbles when zooming out if they overlap", async ({ page }) => { const zoom = page.getByTitle("Zoom"); await zoom.click(); - const zoomOut = page.getByTitle("Zoom out"); + const zoomOut = page.getByRole("button", { name: "Zoom out" }); await zoomOut.click(); await zoomOut.click(); await zoomOut.click(); diff --git a/frontend/playwright/ui/specs/workspace-viewer-role.spec.js b/frontend/playwright/ui/specs/workspace-viewer-role.spec.js index d78c3a37d..bd1ce6b2e 100644 --- a/frontend/playwright/ui/specs/workspace-viewer-role.spec.js +++ b/frontend/playwright/ui/specs/workspace-viewer-role.spec.js @@ -18,7 +18,7 @@ test("User haven't toolbar", async ({ page }) => { }); test("User haven't edition menu entries", async ({ page }) => { - await page.getByTitle("main menu").click(); + await page.getByRole("button", { name: "Main menu" }).click(); await page.getByText("file").last().click(); await expect(page.getByText("Add as Shared Library")).toBeHidden(); diff --git a/frontend/playwright/ui/specs/workspace.spec.js b/frontend/playwright/ui/specs/workspace.spec.js index 676b2b842..82a42de14 100644 --- a/frontend/playwright/ui/specs/workspace.spec.js +++ b/frontend/playwright/ui/specs/workspace.spec.js @@ -294,7 +294,7 @@ test("User have edition menu entries", async ({ page }) => { await workspacePage.setupEmptyFile(page); await workspacePage.goToWorkspace(); - await page.getByTitle("Main menu").click(); + await page.getByRole("button", { name: "Main menu" }).click(); await page.getByText("file").last().click(); await expect(page.getByText("Add as Shared Library")).toBeVisible(); @@ -390,7 +390,7 @@ test("[Taiga #9930] Zoom fit all doesn't fits all", async ({ const zoom = await page.getByTitle("Zoom"); await zoom.click(); - const zoomIn = await page.getByTitle("Zoom in"); + const zoomIn = await page.getByRole("button", { name: "Zoom in" }); await zoomIn.click(); await zoomIn.click(); await zoomIn.click(); diff --git a/frontend/src/app/main/ui/ds/buttons/icon_button.cljs b/frontend/src/app/main/ui/ds/buttons/icon_button.cljs index d5c6015a7..33ee36952 100644 --- a/frontend/src/app/main/ui/ds/buttons/icon_button.cljs +++ b/frontend/src/app/main/ui/ds/buttons/icon_button.cljs @@ -10,13 +10,13 @@ [app.main.style :as stl]) (:require [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]] + [app.main.ui.ds.tooltip.tooltip :refer [tooltip*]] [rumext.v2 :as mf])) (def ^:private schema:icon-button [:map [:class {:optional true} :string] [:icon-class {:optional true} :string] - [:tooltip-id {:optional true} :string] [:icon [:and :string [:fn #(contains? icon-list %)]]] [:aria-label :string] @@ -25,18 +25,17 @@ (mf/defc icon-button* {::mf/schema schema:icon-button} - [{:keys [class icon icon-class variant aria-label children tooltip-id] :rest props}] + [{:keys [class icon icon-class variant aria-label children] :rest props}] (let [variant (or variant "primary") + tooltip-id (mf/use-id) class (dm/str class " " (stl/css-case :icon-button true :icon-button-primary (= variant "primary") :icon-button-secondary (= variant "secondary") :icon-button-ghost (= variant "ghost") :icon-button-action (= variant "action") :icon-button-destructive (= variant "destructive"))) - props (if (some? tooltip-id) - (mf/spread-props props {:class class - :aria-describedby tooltip-id}) - (mf/spread-props props {:class class - :aria-label aria-label - :title aria-label}))] - [:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children])) \ No newline at end of file + props (mf/spread-props props {:class class + :aria-labelledby tooltip-id})] + [:> tooltip* {:tooltip-content aria-label + :id tooltip-id} + [:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs index 5cc5b1c7e..ec04d4326 100644 --- a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs +++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs @@ -42,7 +42,7 @@ "left" {:top (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2)) - :left (- trigger-left tooltip-width) + :left (- trigger-left tooltip-width arrow-height) :right (+ (- trigger-left tooltip-width) tooltip-width) :bottom (+ (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2)) tooltip-height) :width tooltip-width @@ -109,7 +109,7 @@ (def ^:private schema:tooltip [:map [:class {:optional true} :string] - [:id :string] + [:id {:optional true} :string] [:offset {:optional true} :int] [:delay {:optional true} :int] [:placement {:optional true} @@ -118,7 +118,8 @@ (mf/defc tooltip* {::mf/schema schema:tooltip} [{:keys [class id children tooltip-content placement offset delay] :rest props}] - (let [placement* (mf/use-state #(d/nilv placement "top")) + (let [id (or id (mf/use-id)) + placement* (mf/use-state #(d/nilv placement "top")) placement (deref placement*) delay (d/nilv delay 300) diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index 97abf5443..e5c5548bc 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -420,6 +420,7 @@ {:value (-> data :opacity opacity->string) :on-change handle-change-gradient-opacity :default 100 + :data-testid "opacity-global-input" :min 0 :max 100}]]) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 78a2b3481..67c9528b6 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -336,7 +336,6 @@ [:> icon-button* {:variant "ghost" :aria-label (tr "workspace.options.fit-content") - :title (tr "workspace.options.fit-content") :on-pointer-down handle-fit-content :icon "fit-content"}]]) (when (options :size) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 4c2942797..5073c6f96 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -26,7 +26,6 @@ [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.typography.text :refer [text*]] - [app.main.ui.ds.tooltip.tooltip :refer [tooltip*]] [app.main.ui.hooks :as h] [app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.workspace.sidebar.assets.common :as cmm] @@ -424,13 +423,10 @@ (when (contains? cf/flags :token-units) - [:> tooltip* {:tooltip-content "Tokens settings" - :id "button-setting"} - [:> icon-button* {:variant "secondary" - :icon "settings" - :tooltip-id "button-setting" - :aria-label "Settings" - :on-click open-settings-modal}]])])) + [:> icon-button* {:variant "secondary" + :icon "settings" + :aria-label "Settings" + :on-click open-settings-modal}])])) (mf/defc tokens-sidebar-tab* {::mf/wrap [mf/memo]}