diff --git a/frontend/playwright/ui/specs/export-frames.spec.js b/frontend/playwright/ui/specs/export-frames.spec.js index 5a7f5bf932..54b5b18f8d 100644 --- a/frontend/playwright/ui/specs/export-frames.spec.js +++ b/frontend/playwright/ui/specs/export-frames.spec.js @@ -42,9 +42,7 @@ test.describe("Export frames to PDF", () => { await page.getByText("file").last().click(); // The "Export frames to PDF" option should NOT be visible when there are no frames - await expect( - page.locator("#file-menu-export-frames"), - ).not.toBeVisible(); + await expect(page.locator("#file-menu-export-frames")).not.toBeVisible(); }); test("Export frames menu option is visible when there are frames (even if not selected)", async ({ @@ -58,12 +56,12 @@ test.describe("Export frames to PDF", () => { await page.getByText("file").last().click(); // The "Export frames to PDF" option should be visible when there are frames on the page - await expect( - page.locator("#file-menu-export-frames"), - ).toBeVisible(); + await expect(page.locator("#file-menu-export-frames")).toBeVisible(); }); - test("Export frames modal shows all frames when none are selected", async ({ page }) => { + test("Export frames modal shows all frames when none are selected", async ({ + page, + }) => { const workspacePage = new WorkspacePage(page); await setupWorkspaceWithFrames(workspacePage); @@ -87,7 +85,9 @@ test.describe("Export frames to PDF", () => { await expect(page.getByText("2 of 2 elements selected")).toBeVisible(); }); - test("Export frames modal shows only the selected frames", async ({ page }) => { + test("Export frames modal shows only the selected frames", async ({ + page, + }) => { const workspacePage = new WorkspacePage(page); await setupWorkspaceWithFrames(workspacePage); @@ -107,7 +107,9 @@ test.describe("Export frames to PDF", () => { // Only Frame 1 should appear in the list // await page.getByRole("button", { name: "Board 1" }), await expect(page.getByRole("button", { name: "Board 1" })).toBeVisible(); - await expect(page.getByRole("button", { name: "Board 2" })).not.toBeVisible(); + await expect( + page.getByRole("button", { name: "Board 2" }), + ).not.toBeVisible(); // The selection counter should show "1 of 1" await expect(page.getByText("1 of 1 elements selected")).toBeVisible(); @@ -119,7 +121,7 @@ test.describe("Export frames to PDF", () => { // Select Frame 1 await workspacePage.clickLeafLayer("Board 1"); - + // Add Frame 2 to selection await page.keyboard.down("Shift"); await workspacePage.clickLeafLayer("Board 2"); @@ -144,7 +146,9 @@ test.describe("Export frames to PDF", () => { await expect(exportButton).toBeEnabled(); }); - test("Export button is disabled when all frames are deselected", async ({ page }) => { + test("Export button is disabled when all frames are deselected", async ({ + page, + }) => { const workspacePage = new WorkspacePage(page); await setupWorkspaceWithFrames(workspacePage); @@ -163,7 +167,9 @@ test.describe("Export frames to PDF", () => { await expect(page.getByText("0 of 1 elements selected")).toBeVisible(); // // The export button should be disabled - await expect(page.getByRole("button", { name: "Export" , exact: true})).toBeDisabled(); + await expect( + page.getByRole("button", { name: "Export", exact: true }), + ).toBeDisabled(); }); test("User can cancel the export modal", async ({ page }) => { @@ -188,4 +194,3 @@ test.describe("Export frames to PDF", () => { await expect(page.getByText("0 of 1 elements selected")).not.toBeVisible(); }); }); - diff --git a/frontend/playwright/ui/specs/tokens.spec.js b/frontend/playwright/ui/specs/tokens.spec.js index e6c3239267..7300800292 100644 --- a/frontend/playwright/ui/specs/tokens.spec.js +++ b/frontend/playwright/ui/specs/tokens.spec.js @@ -102,22 +102,24 @@ const setupTypographyTokensFile = async (page, options = {}) => { }); }; -const checkInputFieldWithError = async (tokenThemeUpdateCreateModal, inputLocator) => { - await expect(inputLocator).toHaveAttribute("aria-invalid", "true"); +const checkInputFieldWithError = async ( + tokenThemeUpdateCreateModal, + inputLocator, +) => { + await expect(inputLocator).toHaveAttribute("aria-invalid", "true"); - const errorMessageId = await inputLocator.getAttribute("aria-describedby"); - await expect( - tokenThemeUpdateCreateModal.locator(`#${errorMessageId}`), - ).toBeVisible(); + const errorMessageId = await inputLocator.getAttribute("aria-describedby"); + await expect( + tokenThemeUpdateCreateModal.locator(`#${errorMessageId}`), + ).toBeVisible(); }; -const checkInputFieldWithoutError = async (tokenThemeUpdateCreateModal, inputLocator) => { - expect( - await inputLocator.getAttribute("aria-invalid") - ).toBeNull(); - expect( - await inputLocator.getAttribute("aria-describedby") - ).toBeNull(); +const checkInputFieldWithoutError = async ( + tokenThemeUpdateCreateModal, + inputLocator, +) => { + expect(await inputLocator.getAttribute("aria-invalid")).toBeNull(); + expect(await inputLocator.getAttribute("aria-describedby")).toBeNull(); }; test.describe("Tokens: Tokens Tab", () => { @@ -199,7 +201,9 @@ test.describe("Tokens: Tokens Tab", () => { ).toBeEnabled(); // Tokens tab panel should have two tokens with the color red / #ff0000 - await expect(tokensTabPanel.getByRole("button", {name: "#ff0000"})).toHaveCount(2); + await expect( + tokensTabPanel.getByRole("button", { name: "#ff0000" }), + ).toHaveCount(2); // Global set has been auto created and is active await expect( @@ -828,16 +832,14 @@ test.describe("Tokens: Themes modal", () => { .first() .click(); - await expect( - tokenThemeUpdateCreateModal - ).toBeVisible(); + await expect(tokenThemeUpdateCreateModal).toBeVisible(); const groupInput = tokenThemeUpdateCreateModal.getByLabel("Group"); const nameInput = tokenThemeUpdateCreateModal.getByLabel("Theme"); const saveButton = tokenThemeUpdateCreateModal.getByRole("button", { name: "Save theme", }); - + await groupInput.fill("New Group name"); await nameInput.fill("New Theme name"); @@ -853,7 +855,7 @@ test.describe("Tokens: Themes modal", () => { tokenThemeUpdateCreateModal.getByText("New Group name"), ).toBeVisible(); }); - + test("Add new theme", async ({ page }) => { const { tokenThemeUpdateCreateModal, workspacePage } = await setupTokensFile(page); @@ -871,7 +873,7 @@ test.describe("Tokens: Themes modal", () => { const saveButton = tokenThemeUpdateCreateModal.getByRole("button", { name: "Save theme", }); - + await groupInput.fill("Core"); // Invalid because "Core / Light" theme already exists await nameInput.fill("Light"); @@ -917,13 +919,13 @@ test.describe("Tokens: Themes modal", () => { const saveButton = tokenThemeUpdateCreateModal.getByRole("button", { name: "Save theme", }); - + await groupInput.fill("Core"); // Invalid because "Core / Dark" theme already exists await nameInput.fill("Dark"); await checkInputFieldWithError(tokenThemeUpdateCreateModal, nameInput); await expect(saveButton).toBeDisabled(); - + await groupInput.fill("Core"); // Valid because "Core / Light" theme already exists await nameInput.fill("Light"); // but it's the same theme we are editing @@ -936,12 +938,8 @@ test.describe("Tokens: Themes modal", () => { await checkInputFieldWithoutError(tokenThemeUpdateCreateModal, nameInput); await expect(saveButton).not.toBeDisabled(); - expect( - await nameInput.getAttribute("aria-invalid") - ).toBeNull(); - expect( - await nameInput.getAttribute("aria-describedby") - ).toBeNull(); + expect(await nameInput.getAttribute("aria-invalid")).toBeNull(); + expect(await nameInput.getAttribute("aria-describedby")).toBeNull(); const checkboxes = await tokenThemeUpdateCreateModal .locator('[role="checkbox"]') @@ -956,9 +954,9 @@ test.describe("Tokens: Themes modal", () => { } const firstButton = await tokenThemeUpdateCreateModal - .getByTestId('tokens-set-item') + .getByTestId("tokens-set-item") .first(); - + await firstButton.click(); await expect(saveButton).not.toBeDisabled(); @@ -1109,12 +1107,10 @@ test.describe("Tokens: Apply token", () => { // Fill in values for all fields and verify they persist when switching tabs await fontSizeField.fill("16"); - const fontWeightField = - tokensUpdateCreateModal.getByLabel(/Font Weight/i); + const fontWeightField = tokensUpdateCreateModal.getByLabel(/Font Weight/i); const letterSpacingField = tokensUpdateCreateModal.getByLabel(/Letter Spacing/i); - const lineHeightField = - tokensUpdateCreateModal.getByLabel(/Line Height/i); + const lineHeightField = tokensUpdateCreateModal.getByLabel(/Line Height/i); const textCaseField = tokensUpdateCreateModal.getByLabel(/Text Case/i); const textDecorationField = tokensUpdateCreateModal.getByLabel(/Text Decoration/i); @@ -1149,9 +1145,7 @@ test.describe("Tokens: Apply token", () => { await expect(fontSizeField).toHaveValue(originalValues.fontSize); await expect(fontFamilyField).toHaveValue(originalValues.fontFamily); await expect(fontWeightField).toHaveValue(originalValues.fontWeight); - await expect(letterSpacingField).toHaveValue( - originalValues.letterSpacing, - ); + await expect(letterSpacingField).toHaveValue(originalValues.letterSpacing); await expect(lineHeightField).toHaveValue(originalValues.lineHeight); await expect(textCaseField).toHaveValue(originalValues.textCase); await expect(textDecorationField).toHaveValue( @@ -1248,9 +1242,15 @@ test.describe("Tokens: Apply token", () => { await expect(newToken).toBeVisible(); }); - test("User adds shadow token with multiple shadows and applies it to shape", async ({ page, }) => { - const { tokensUpdateCreateModal, tokensSidebar, workspacePage, tokenContextMenuForToken } = - await setupTokensFile(page, { flags: ["enable-token-shadow"] }); + test("User adds shadow token with multiple shadows and applies it to shape", async ({ + page, + }) => { + const { + tokensUpdateCreateModal, + tokensSidebar, + workspacePage, + tokenContextMenuForToken, + } = await setupTokensFile(page, { flags: ["enable-token-shadow"] }); const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" }); @@ -1301,7 +1301,9 @@ test.describe("Tokens: Apply token", () => { await expect(firstColorValue).toMatch(/^rgb(.*)$/); // Wait for validation to complete - await expect(tokensUpdateCreateModal.getByText(/Resolved value:/).first()).toBeVisible(); + await expect( + tokensUpdateCreateModal.getByText(/Resolved value:/).first(), + ).toBeVisible(); // Save button should be enabled const submitButton = tokensUpdateCreateModal.getByRole("button", { @@ -1349,18 +1351,32 @@ test.describe("Tokens: Apply token", () => { await thirdColorInput.fill("#FF0000"); // User removes the 2nd shadow - const removeButton2 = secondShadowFields.getByTestId("shadow-remove-button-1"); + const removeButton2 = secondShadowFields.getByTestId( + "shadow-remove-button-1", + ); await removeButton2.click(); // Verify second shadow is removed - await expect(secondShadowFields.getByTestId("shadow-add-button-3")).not.toBeVisible(); + await expect( + secondShadowFields.getByTestId("shadow-add-button-3"), + ).not.toBeVisible(); // Verify that the first shadow kept its values - const firstOffsetXValue = await firstShadowFields.getByLabel("X").inputValue(); - const firstOffsetYValue = await firstShadowFields.getByLabel("Y").inputValue(); - const firstBlurValue = await firstShadowFields.getByLabel("Blur").inputValue(); - const firstSpreadValue = await firstShadowFields.getByLabel("Spread").inputValue(); - const firstColorValueAfter = await firstShadowFields.getByLabel("Color").inputValue(); + const firstOffsetXValue = await firstShadowFields + .getByLabel("X") + .inputValue(); + const firstOffsetYValue = await firstShadowFields + .getByLabel("Y") + .inputValue(); + const firstBlurValue = await firstShadowFields + .getByLabel("Blur") + .inputValue(); + const firstSpreadValue = await firstShadowFields + .getByLabel("Spread") + .inputValue(); + const firstColorValueAfter = await firstShadowFields + .getByLabel("Color") + .inputValue(); await expect(firstOffsetXValue).toBe("2"); await expect(firstOffsetYValue).toBe("2"); @@ -1375,11 +1391,21 @@ test.describe("Tokens: Apply token", () => { ); await expect(newSecondShadowFields).toBeVisible(); - const secondOffsetXValue = await newSecondShadowFields.getByLabel("X").inputValue(); - const secondOffsetYValue = await newSecondShadowFields.getByLabel("Y").inputValue(); - const secondBlurValue = await newSecondShadowFields.getByLabel("Blur").inputValue(); - const secondSpreadValue = await newSecondShadowFields.getByLabel("Spread").inputValue(); - const secondColorValue = await newSecondShadowFields.getByLabel("Color").inputValue(); + const secondOffsetXValue = await newSecondShadowFields + .getByLabel("X") + .inputValue(); + const secondOffsetYValue = await newSecondShadowFields + .getByLabel("Y") + .inputValue(); + const secondBlurValue = await newSecondShadowFields + .getByLabel("Blur") + .inputValue(); + const secondSpreadValue = await newSecondShadowFields + .getByLabel("Spread") + .inputValue(); + const secondColorValue = await newSecondShadowFields + .getByLabel("Color") + .inputValue(); await expect(secondOffsetXValue).toBe("10"); await expect(secondOffsetYValue).toBe("10"); @@ -1399,14 +1425,16 @@ test.describe("Tokens: Apply token", () => { const firstColorValue = await colorInput.inputValue(); // Switch to reference tab - const referenceTabButton = tokensUpdateCreateModal.getByTestId("reference-opt"); + const referenceTabButton = + tokensUpdateCreateModal.getByTestId("reference-opt"); await referenceTabButton.click(); // Verify we're in reference mode - the composite fields should not be visible await expect(firstShadowFields).not.toBeVisible(); // Switch back to composite tab - const compositeTabButton = tokensUpdateCreateModal.getByTestId("composite-opt"); + const compositeTabButton = + tokensUpdateCreateModal.getByTestId("composite-opt"); await compositeTabButton.click(); // Verify that shadows are restored @@ -1414,11 +1442,21 @@ test.describe("Tokens: Apply token", () => { await expect(newSecondShadowFields).toBeVisible(); // Verify first shadow values are still there - const restoredFirstOffsetX = await firstShadowFields.getByLabel("X").inputValue(); - const restoredFirstOffsetY = await firstShadowFields.getByLabel("Y").inputValue(); - const restoredFirstBlur = await firstShadowFields.getByLabel("Blur").inputValue(); - const restoredFirstSpread = await firstShadowFields.getByLabel("Spread").inputValue(); - const restoredFirstColor = await firstShadowFields.getByLabel("Color").inputValue(); + const restoredFirstOffsetX = await firstShadowFields + .getByLabel("X") + .inputValue(); + const restoredFirstOffsetY = await firstShadowFields + .getByLabel("Y") + .inputValue(); + const restoredFirstBlur = await firstShadowFields + .getByLabel("Blur") + .inputValue(); + const restoredFirstSpread = await firstShadowFields + .getByLabel("Spread") + .inputValue(); + const restoredFirstColor = await firstShadowFields + .getByLabel("Color") + .inputValue(); await expect(restoredFirstOffsetX).toBe("2"); await expect(restoredFirstOffsetY).toBe("2"); @@ -1427,11 +1465,21 @@ test.describe("Tokens: Apply token", () => { await expect(restoredFirstColor).toBe(firstColorValue); // Verify second shadow values are still there - const restoredSecondOffsetX = await newSecondShadowFields.getByLabel("X").inputValue(); - const restoredSecondOffsetY = await newSecondShadowFields.getByLabel("Y").inputValue(); - const restoredSecondBlur = await newSecondShadowFields.getByLabel("Blur").inputValue(); - const restoredSecondSpread = await newSecondShadowFields.getByLabel("Spread").inputValue(); - const restoredSecondColor = await newSecondShadowFields.getByLabel("Color").inputValue(); + const restoredSecondOffsetX = await newSecondShadowFields + .getByLabel("X") + .inputValue(); + const restoredSecondOffsetY = await newSecondShadowFields + .getByLabel("Y") + .inputValue(); + const restoredSecondBlur = await newSecondShadowFields + .getByLabel("Blur") + .inputValue(); + const restoredSecondSpread = await newSecondShadowFields + .getByLabel("Spread") + .inputValue(); + const restoredSecondColor = await newSecondShadowFields + .getByLabel("Color") + .inputValue(); await expect(restoredSecondOffsetX).toBe("10"); await expect(restoredSecondOffsetY).toBe("10"); diff --git a/frontend/playwright/ui/visual-specs/workspace.spec.js b/frontend/playwright/ui/visual-specs/workspace.spec.js index 628a7f2ebd..c1cc4ecbcc 100644 --- a/frontend/playwright/ui/visual-specs/workspace.spec.js +++ b/frontend/playwright/ui/visual-specs/workspace.spec.js @@ -161,4 +161,4 @@ test.describe("Palette", () => { workspace.palette.getByRole("button", { name: "#7798ff" }), ).toBeVisible(); }); -}); \ No newline at end of file +}); diff --git a/frontend/src/app/main/ui/ds/controls/numeric-input.stories.jsx b/frontend/src/app/main/ui/ds/controls/numeric-input.stories.jsx index 43d2971c42..f2af45a0bf 100644 --- a/frontend/src/app/main/ui/ds/controls/numeric-input.stories.jsx +++ b/frontend/src/app/main/ui/ds/controls/numeric-input.stories.jsx @@ -44,7 +44,7 @@ export default { property: "search", }, parameters: { - controls: { exclude: ["tokens"] } + controls: { exclude: ["tokens"] }, }, render: ({ ...args }) => , @@ -118,7 +118,7 @@ export const WithTokens = { ], }, }, - parameters: { + parameters: { controls: { exclude: ["tokens"] }, docs: { story: { diff --git a/frontend/src/app/main/ui/ds/controls/select.stories.jsx b/frontend/src/app/main/ui/ds/controls/select.stories.jsx index 5bbf204654..3cf750d5d7 100644 --- a/frontend/src/app/main/ui/ds/controls/select.stories.jsx +++ b/frontend/src/app/main/ui/ds/controls/select.stories.jsx @@ -9,10 +9,7 @@ import Components from "@target/components"; const { Select } = Components; -const variants = [ - "default", - "ghost", -]; +const variants = ["default", "ghost"]; const options = [ { id: "option-code", label: "Code" }, diff --git a/frontend/src/app/main/ui/ds/controls/switch.stories.jsx b/frontend/src/app/main/ui/ds/controls/switch.stories.jsx index 4e6b8aed99..1dfcf97ccb 100644 --- a/frontend/src/app/main/ui/ds/controls/switch.stories.jsx +++ b/frontend/src/app/main/ui/ds/controls/switch.stories.jsx @@ -20,17 +20,17 @@ export default { disabled: { control: { type: "boolean" }, description: "Whether the switch is disabled", - } + }, }, args: { - disabled: false + disabled: false, }, parameters: { - controls: { exclude: ["id", "class", "aria-label", "default-checked", "on-change"] }, + controls: { + exclude: ["id", "class", "aria-label", "default-checked", "on-change"], + }, }, - render: ({ ...args }) => ( - - ), + render: ({ ...args }) => , }; export const Default = { @@ -38,23 +38,20 @@ export const Default = { label: "Toggle something", disabled: false, }, - render: ({ ...args }) => ( - - ), + render: ({ ...args }) => , }; export const WithoutLabel = { args: { disabled: false, }, - render: ({ ...args }) => ( - - ), + render: ({ ...args }) => , }; export const WithLongLabel = { args: { - label: "This is a very long label that demonstrates how the switch component handles text wrapping and layout when the label content is extensive", + label: + "This is a very long label that demonstrates how the switch component handles text wrapping and layout when the label content is extensive", disabled: false, }, render: ({ ...args }) => ( diff --git a/frontend/src/app/main/ui/ds/foundations/assets/raw_svg.stories.jsx b/frontend/src/app/main/ui/ds/foundations/assets/raw_svg.stories.jsx index 0a2e27552f..6cbf1216a3 100644 --- a/frontend/src/app/main/ui/ds/foundations/assets/raw_svg.stories.jsx +++ b/frontend/src/app/main/ui/ds/foundations/assets/raw_svg.stories.jsx @@ -36,9 +36,11 @@ export const All = { ), parameters: { controls: { exclude: ["id"] }, - backgrounds: { options: { - debug: { name: "debug", value: "#ccc" } - } }, + backgrounds: { + options: { + debug: { name: "debug", value: "#ccc" }, + }, + }, }, }; diff --git a/frontend/src/app/main/ui/ds/foundations/typography/heading.stories.jsx b/frontend/src/app/main/ui/ds/foundations/typography/heading.stories.jsx index 87c76791af..494c342586 100644 --- a/frontend/src/app/main/ui/ds/foundations/typography/heading.stories.jsx +++ b/frontend/src/app/main/ui/ds/foundations/typography/heading.stories.jsx @@ -22,7 +22,7 @@ export default { }, parameters: { - controls: { exclude: ["children", "theme", "style"] } + controls: { exclude: ["children", "theme", "style"] }, }, args: { @@ -40,9 +40,9 @@ export default { globals: { backgrounds: { - value: "light" - } - } + value: "light", + }, + }, }; export const AnyHeading = {