mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
605 lines
21 KiB
JavaScript
605 lines
21 KiB
JavaScript
import { test, expect } from "@playwright/test";
|
|
import { WorkspacePage } from "../../pages/WorkspacePage";
|
|
import { BaseWebSocketPage } from "../../pages/BaseWebSocketPage";
|
|
import {
|
|
setupEmptyTokensFile,
|
|
setupTokensFile,
|
|
setupTypographyTokensFile,
|
|
unfoldTokenTree,
|
|
} from "./helpers";
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await WorkspacePage.init(page);
|
|
await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-tokens.json");
|
|
});
|
|
|
|
test.describe("Tokens: Apply token", () => {
|
|
test("User applies color token to a shape", async ({ page }) => {
|
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
|
await setupTokensFile(page);
|
|
|
|
await page.getByRole("tab", { name: "Layers" }).click();
|
|
|
|
await workspacePage.layers
|
|
.getByTestId("layer-row")
|
|
.filter({ hasText: "Button" })
|
|
.click();
|
|
|
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
|
await tokensTabButton.click();
|
|
|
|
unfoldTokenTree(tokensSidebar, "color", "colors.black");
|
|
|
|
await tokensSidebar
|
|
.getByRole("button", { name: "black" })
|
|
.click({ button: "right" });
|
|
await tokenContextMenuForToken.getByText("Fill").click();
|
|
|
|
await expect(
|
|
workspacePage.page.getByLabel("Name: colors.black"),
|
|
).toBeVisible();
|
|
});
|
|
|
|
test("User applies border-radius token to a shape from sidebar", async ({
|
|
page,
|
|
}) => {
|
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
|
await setupTokensFile(page);
|
|
|
|
await page.getByRole("tab", { name: "Layers" }).click();
|
|
|
|
await workspacePage.layers.getByTestId("layer-row").nth(1).click();
|
|
|
|
// Open tokens sections on left sidebar
|
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
|
await tokensTabButton.click();
|
|
|
|
// Unfold border radius tokens
|
|
await page.getByRole("button", { name: "Border Radius 3" }).click();
|
|
await expect(
|
|
tokensSidebar.getByRole("button", { name: "borderRadius" }),
|
|
).toBeVisible();
|
|
await tokensSidebar.getByRole("button", { name: "borderRadius" }).click();
|
|
await expect(
|
|
tokensSidebar.getByRole("button", { name: "borderRadius.sm" }),
|
|
).toBeVisible();
|
|
|
|
// Apply border radius token from token panels
|
|
await tokensSidebar
|
|
.getByRole("button", { name: "borderRadius.sm" })
|
|
.click();
|
|
|
|
// Check if border radius sections is visible on right sidebar
|
|
const borderRadiusSection = page.getByRole("region", {
|
|
name: "border-radius-section",
|
|
});
|
|
await expect(borderRadiusSection).toBeVisible();
|
|
|
|
// Check if token pill is visible on design tab on right sidebar
|
|
const brTokenPillSM = borderRadiusSection.getByRole("button", {
|
|
name: "borderRadius.sm",
|
|
});
|
|
await expect(brTokenPillSM).toBeVisible();
|
|
await brTokenPillSM.click();
|
|
|
|
// Change token from dropdown
|
|
const brTokenOptionXl = borderRadiusSection.getByLabel("borderRadius.xl");
|
|
await expect(brTokenOptionXl).toBeVisible();
|
|
await brTokenOptionXl.click();
|
|
|
|
await expect(brTokenPillSM).not.toBeVisible();
|
|
const brTokenPillXL = borderRadiusSection.getByRole("button", {
|
|
name: "borderRadius.xl",
|
|
});
|
|
await expect(brTokenPillXL).toBeVisible();
|
|
|
|
// Detach token from design tab on right sidebar
|
|
const detachButton = borderRadiusSection.getByRole("button", {
|
|
name: "Detach token",
|
|
});
|
|
await detachButton.click();
|
|
await expect(brTokenPillXL).not.toBeVisible();
|
|
});
|
|
|
|
test("User applies typography token to a text shape", async ({ page }) => {
|
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
|
await setupTypographyTokensFile(page);
|
|
|
|
await page.getByRole("tab", { name: "Layers" }).click();
|
|
|
|
await workspacePage.layers
|
|
.getByTestId("layer-row")
|
|
.filter({ hasText: "Some Text" })
|
|
.click();
|
|
|
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
|
await tokensTabButton.click();
|
|
|
|
await tokensSidebar
|
|
.getByRole("button")
|
|
.filter({ hasText: "Typography" })
|
|
.click();
|
|
|
|
await tokensSidebar.getByRole("button", { name: "Full" }).click();
|
|
|
|
const fontSizeInput = workspacePage.rightSidebar.getByRole("textbox", {
|
|
name: "Font Size",
|
|
});
|
|
await expect(fontSizeInput).toBeVisible();
|
|
await expect(fontSizeInput).toHaveValue("100");
|
|
});
|
|
|
|
test("User edits typography token and all fields are valid", async ({
|
|
page,
|
|
}) => {
|
|
const { tokensUpdateCreateModal, tokenThemesSetsSidebar, tokensSidebar } =
|
|
await setupTypographyTokensFile(page);
|
|
|
|
await tokensSidebar
|
|
.getByRole("button")
|
|
.filter({ hasText: "Typography" })
|
|
.click();
|
|
|
|
// Open edit modal for "Full" typography token
|
|
const token = tokensSidebar.getByRole("button", { name: "Full" });
|
|
await token.click({ button: "right" });
|
|
await page.getByText("Edit token").click();
|
|
|
|
// Modal opens
|
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
|
|
|
const saveButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: /save/i,
|
|
});
|
|
|
|
// Fill font-family to verify to verify that input value doesn't get split into list of characters
|
|
const fontFamilyField = tokensUpdateCreateModal
|
|
.getByLabel("Font family")
|
|
.first();
|
|
await fontFamilyField.fill("OneWord");
|
|
|
|
// Invalidate incorrect values for font size
|
|
const fontSizeField = tokensUpdateCreateModal.getByLabel(/Font Size/i);
|
|
await fontSizeField.fill("invalid");
|
|
await expect(
|
|
tokensUpdateCreateModal.getByText(/Invalid token value:/),
|
|
).toBeVisible();
|
|
await expect(saveButton).toBeDisabled();
|
|
|
|
// Show error with line-height depending on invalid font-size
|
|
await fontSizeField.fill("");
|
|
await expect(saveButton).toBeDisabled();
|
|
|
|
// Fill in values for all fields and verify they persist when switching tabs
|
|
await fontSizeField.fill("16");
|
|
await expect(saveButton).toBeEnabled();
|
|
|
|
const fontWeightField = tokensUpdateCreateModal.getByLabel(/Font Weight/i);
|
|
const letterSpacingField =
|
|
tokensUpdateCreateModal.getByLabel(/Letter Spacing/i);
|
|
const lineHeightField = tokensUpdateCreateModal.getByLabel(/Line Height/i);
|
|
const textCaseField = tokensUpdateCreateModal.getByLabel(/Text Case/i);
|
|
const textDecorationField =
|
|
tokensUpdateCreateModal.getByLabel(/Text Decoration/i);
|
|
|
|
// Capture all values before switching tabs
|
|
const originalValues = {
|
|
fontSize: await fontSizeField.inputValue(),
|
|
fontFamily: await fontFamilyField.inputValue(),
|
|
fontWeight: await fontWeightField.inputValue(),
|
|
letterSpacing: await letterSpacingField.inputValue(),
|
|
lineHeight: await lineHeightField.inputValue(),
|
|
textCase: await textCaseField.inputValue(),
|
|
textDecoration: await textDecorationField.inputValue(),
|
|
};
|
|
|
|
// Switch to reference tab and back to composite tab
|
|
const referenceTabButton =
|
|
tokensUpdateCreateModal.getByTestId("reference-opt");
|
|
await referenceTabButton.click();
|
|
|
|
// Empty reference tab should be disabled
|
|
await expect(saveButton).toBeDisabled();
|
|
|
|
const compositeTabButton =
|
|
tokensUpdateCreateModal.getByTestId("composite-opt");
|
|
await compositeTabButton.click();
|
|
|
|
// Filled composite tab should be enabled
|
|
await expect(saveButton).toBeEnabled();
|
|
|
|
// Verify all values are preserved after switching tabs
|
|
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(lineHeightField).toHaveValue(originalValues.lineHeight);
|
|
await expect(textCaseField).toHaveValue(originalValues.textCase);
|
|
await expect(textDecorationField).toHaveValue(
|
|
originalValues.textDecoration,
|
|
);
|
|
|
|
await saveButton.click();
|
|
|
|
// Modal should close, token should be visible (with new name) in sidebar
|
|
await expect(tokensUpdateCreateModal).not.toBeVisible();
|
|
});
|
|
|
|
test("User cant submit empty typography token or reference", async ({
|
|
page,
|
|
}) => {
|
|
const { tokensUpdateCreateModal, tokenThemesSetsSidebar, tokensSidebar } =
|
|
await setupTypographyTokensFile(page);
|
|
|
|
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
|
|
await tokensTabPanel
|
|
.getByRole("button", { name: "Add Token: Typography" })
|
|
.click();
|
|
|
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
|
|
|
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
|
await nameField.fill("typography.empty");
|
|
|
|
const valueField = tokensUpdateCreateModal.getByLabel("Font Size");
|
|
|
|
// Insert a value and then delete it
|
|
await valueField.fill("1");
|
|
await valueField.fill("");
|
|
|
|
// Submit button should be disabled when field is empty
|
|
const submitButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: "Save",
|
|
});
|
|
await expect(submitButton).toBeDisabled();
|
|
|
|
// Switch to reference tab, should not be submittable either
|
|
const referenceTabButton =
|
|
tokensUpdateCreateModal.getByTestId("reference-opt");
|
|
await referenceTabButton.click();
|
|
await expect(submitButton).toBeDisabled();
|
|
});
|
|
|
|
test("User adds typography token with reference", async ({ page }) => {
|
|
const { tokensUpdateCreateModal, tokenThemesSetsSidebar, tokensSidebar } =
|
|
await setupTypographyTokensFile(page);
|
|
|
|
const newTokenTitle = "NewReference";
|
|
|
|
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
|
|
await tokensTabPanel
|
|
.getByRole("button", { name: "Add Token: Typography" })
|
|
.click();
|
|
|
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
|
|
|
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
|
await nameField.fill(newTokenTitle);
|
|
|
|
const referenceTabButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: "Use a reference",
|
|
});
|
|
referenceTabButton.click();
|
|
|
|
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
|
|
name: "Reference",
|
|
});
|
|
await referenceField.fill("{Full}");
|
|
|
|
const submitButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: "Save",
|
|
});
|
|
|
|
const resolvedValue =
|
|
await tokensUpdateCreateModal.getByText("Resolved value:");
|
|
await expect(resolvedValue).toBeVisible();
|
|
await expect(resolvedValue).toContainText("Font Family: 42dot Sans");
|
|
await expect(resolvedValue).toContainText("Font Size: 100");
|
|
await expect(resolvedValue).toContainText("Font Weight: 300");
|
|
await expect(resolvedValue).toContainText("Letter Spacing: 2");
|
|
await expect(resolvedValue).toContainText("Text Case: uppercase");
|
|
await expect(resolvedValue).toContainText("Text Decoration: underline");
|
|
|
|
await expect(submitButton).toBeEnabled();
|
|
await submitButton.click();
|
|
|
|
await expect(tokensUpdateCreateModal).not.toBeVisible();
|
|
|
|
const newToken = tokensSidebar.getByRole("button", {
|
|
name: newTokenTitle,
|
|
});
|
|
|
|
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"] });
|
|
|
|
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
|
|
|
|
await test.step("Stage 1: Basic open", async () => {
|
|
// User adds shadow via the sidebar
|
|
await tokensTabPanel
|
|
.getByRole("button", { name: "Add Token: Shadow" })
|
|
.click();
|
|
|
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
|
|
|
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
|
await nameField.fill("primary");
|
|
|
|
// User adds first shadow with a color from the color ramp
|
|
const firstShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-0",
|
|
);
|
|
await expect(firstShadowFields).toBeVisible();
|
|
|
|
// Fill in the shadow values
|
|
const offsetXInput = firstShadowFields.getByLabel("X");
|
|
const offsetYInput = firstShadowFields.getByLabel("Y");
|
|
const blurInput = firstShadowFields.getByRole("textbox", {
|
|
name: "Blur",
|
|
});
|
|
const spreadInput = firstShadowFields.getByRole("textbox", {
|
|
name: "Spread",
|
|
});
|
|
|
|
await offsetXInput.fill("2");
|
|
await offsetYInput.fill("2");
|
|
await blurInput.fill("4");
|
|
await spreadInput.fill("0");
|
|
|
|
// Add color using the color picker
|
|
const colorBullet = firstShadowFields.getByTestId(
|
|
"token-form-color-bullet",
|
|
);
|
|
await colorBullet.click();
|
|
|
|
// Click on the color ramp to select a color
|
|
const valueSaturationSelector = tokensUpdateCreateModal.getByTestId(
|
|
"value-saturation-selector",
|
|
);
|
|
await expect(valueSaturationSelector).toBeVisible();
|
|
await valueSaturationSelector.click({ position: { x: 50, y: 50 } });
|
|
|
|
// Verify that a color value was set
|
|
const colorInput = firstShadowFields.getByRole("textbox", {
|
|
name: "Color",
|
|
});
|
|
await expect(colorInput).toHaveValue(/^rgb(.*)$/);
|
|
|
|
// Wait for validation to complete
|
|
await expect(
|
|
tokensUpdateCreateModal.getByText(/Resolved value:/).first(),
|
|
).toBeVisible();
|
|
|
|
// Save button should be enabled
|
|
const submitButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: "Save",
|
|
});
|
|
await expect(submitButton).toBeEnabled();
|
|
});
|
|
|
|
await test.step("Stage 2: Shadow adding/removing works", async () => {
|
|
const firstShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-0",
|
|
);
|
|
const colorInput = firstShadowFields.getByRole("textbox", {
|
|
name: "Color",
|
|
});
|
|
const firstColorValue = await colorInput.inputValue();
|
|
|
|
// User adds a second shadow
|
|
const addButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: "Add Shadow",
|
|
});
|
|
await addButton.click();
|
|
|
|
const secondShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-1",
|
|
);
|
|
await expect(secondShadowFields).toBeVisible();
|
|
|
|
// User adds a third shadow
|
|
await addButton.click();
|
|
|
|
const thirdShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-2",
|
|
);
|
|
await expect(thirdShadowFields).toBeVisible();
|
|
|
|
// User adds values for the third shadow
|
|
const thirdOffsetXInput = thirdShadowFields.getByLabel("X");
|
|
const thirdOffsetYInput = thirdShadowFields.getByLabel("Y");
|
|
const thirdBlurInput = thirdShadowFields.getByRole("textbox", {
|
|
name: "Blur",
|
|
});
|
|
const thirdSpreadInput = thirdShadowFields.getByRole("textbox", {
|
|
name: "Spread",
|
|
});
|
|
const thirdColorInput = thirdShadowFields.getByRole("textbox", {
|
|
name: "Color",
|
|
});
|
|
|
|
await thirdOffsetXInput.fill("10");
|
|
await thirdOffsetYInput.fill("10");
|
|
await thirdBlurInput.fill("20");
|
|
await thirdSpreadInput.fill("5");
|
|
await thirdColorInput.fill("#FF0000");
|
|
|
|
// User removes the 2nd shadow
|
|
const removeButton2 = secondShadowFields.getByRole("button", {
|
|
name: "Remove Shadow",
|
|
});
|
|
await removeButton2.click();
|
|
|
|
// Verify that we have only two shadow fields
|
|
await expect(thirdShadowFields).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
|
|
.getByRole("textbox", { name: "Blur" })
|
|
.inputValue();
|
|
const firstSpreadValue = await firstShadowFields
|
|
.getByRole("textbox", { name: "Spread" })
|
|
.inputValue();
|
|
const firstColorValueAfter = await firstShadowFields
|
|
.getByRole("textbox", { name: "Color" })
|
|
.inputValue();
|
|
|
|
await expect(firstOffsetXValue).toBe("2");
|
|
await expect(firstOffsetYValue).toBe("2");
|
|
await expect(firstBlurValue).toBe("4");
|
|
await expect(firstSpreadValue).toBe("0");
|
|
await expect(firstColorValueAfter).toBe(firstColorValue);
|
|
|
|
// Verify that the second kept its values (after shadow 3)
|
|
// After removing index 1, the third shadow becomes the second shadow at index 1
|
|
const newSecondShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-1",
|
|
);
|
|
await expect(newSecondShadowFields).toBeVisible();
|
|
|
|
const secondOffsetXValue = await newSecondShadowFields
|
|
.getByLabel("X")
|
|
.inputValue();
|
|
const secondOffsetYValue = await newSecondShadowFields
|
|
.getByLabel("Y")
|
|
.inputValue();
|
|
const secondBlurValue = await newSecondShadowFields
|
|
.getByRole("textbox", { name: "Blur" })
|
|
.inputValue();
|
|
const secondSpreadValue = await newSecondShadowFields
|
|
.getByRole("textbox", { name: "Spread" })
|
|
.inputValue();
|
|
const secondColorValue = await newSecondShadowFields
|
|
.getByRole("textbox", { name: "Color" })
|
|
.inputValue();
|
|
|
|
await expect(secondOffsetXValue).toBe("10");
|
|
await expect(secondOffsetYValue).toBe("10");
|
|
await expect(secondBlurValue).toBe("20");
|
|
await expect(secondSpreadValue).toBe("5");
|
|
await expect(secondColorValue).toBe("#FF0000");
|
|
});
|
|
|
|
await test.step("Stage 3: Restore when switching tabs works", async () => {
|
|
const firstShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-0",
|
|
);
|
|
const newSecondShadowFields = tokensUpdateCreateModal.getByTestId(
|
|
"shadow-input-fields-1",
|
|
);
|
|
const colorInput = firstShadowFields.getByRole("textbox", {
|
|
name: "Color",
|
|
});
|
|
const firstColorValue = await colorInput.inputValue();
|
|
|
|
// Switch to reference tab
|
|
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");
|
|
await compositeTabButton.click();
|
|
|
|
// Verify that shadows are restored
|
|
await expect(firstShadowFields).toBeVisible();
|
|
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
|
|
.getByRole("textbox", { name: "Blur" })
|
|
.inputValue();
|
|
const restoredFirstSpread = await firstShadowFields
|
|
.getByRole("textbox", { name: "Spread" })
|
|
.inputValue();
|
|
const restoredFirstColor = await firstShadowFields
|
|
.getByRole("textbox", { name: "Color" })
|
|
.inputValue();
|
|
|
|
await expect(restoredFirstOffsetX).toBe("2");
|
|
await expect(restoredFirstOffsetY).toBe("2");
|
|
await expect(restoredFirstBlur).toBe("4");
|
|
await expect(restoredFirstSpread).toBe("0");
|
|
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
|
|
.getByRole("textbox", { name: "Blur" })
|
|
.inputValue();
|
|
const restoredSecondSpread = await newSecondShadowFields
|
|
.getByRole("textbox", { name: "Spread" })
|
|
.inputValue();
|
|
const restoredSecondColor = await newSecondShadowFields
|
|
.getByRole("textbox", { name: "Color" })
|
|
.inputValue();
|
|
|
|
await expect(restoredSecondOffsetX).toBe("10");
|
|
await expect(restoredSecondOffsetY).toBe("10");
|
|
await expect(restoredSecondBlur).toBe("20");
|
|
await expect(restoredSecondSpread).toBe("5");
|
|
await expect(restoredSecondColor).toBe("#FF0000");
|
|
});
|
|
|
|
await test.step("Stage 4: Layer application works", async () => {
|
|
// Save the token
|
|
const submitButton = tokensUpdateCreateModal.getByRole("button", {
|
|
name: "Save",
|
|
});
|
|
await submitButton.click();
|
|
await expect(tokensUpdateCreateModal).not.toBeVisible();
|
|
|
|
unfoldTokenTree(tokensSidebar, "shadow", "primary");
|
|
|
|
// Verify token appears in sidebar
|
|
const shadowToken = tokensSidebar.getByRole("button", {
|
|
name: "primary",
|
|
});
|
|
await expect(shadowToken).toBeEnabled();
|
|
|
|
// Apply the shadow
|
|
await workspacePage.clickLayers();
|
|
await workspacePage.clickLeafLayer("Button");
|
|
|
|
const shadowSection = workspacePage.rightSidebar.getByText("Drop shadow");
|
|
await expect(shadowSection).toHaveCount(0);
|
|
|
|
await page.getByRole("tab", { name: "Tokens" }).click();
|
|
await shadowToken.click();
|
|
|
|
await expect(shadowSection).toHaveCount(2);
|
|
});
|
|
});
|
|
});
|