From d284e828283963cff7c8adccadcef8206d541d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20J=C3=A4derberg?= Date: Tue, 13 Jan 2026 13:48:06 +0000 Subject: [PATCH] Merged in chore/fix-tests (pull request #3430) Chore/fix tests * chore: Upgrade nextjs@16.1.1 * chore: upgrade next@16.1.1 * upgrade underlying types * merge * Fix broken tests * bump @swc/plugin-formatjs to latest version * bump sentry * transpile "import-in-the-middle" & "require-in-the-middle" * revert next@16.1.1 upgrade * revert transpilation addition * . --- apps/partner-sas/package.json | 3 +- apps/scandic-web/package.json | 2 +- .../lib/components/Alert/Alert.stories.tsx | 3 +- .../lib/components/Button/Button.stories.tsx | 8 +- .../ButtonLink/ButtonLink.stories.tsx | 130 +++++------- .../IconButton/IconButton.stories.tsx | 32 +-- .../components/Icons/MaterialIcon/index.tsx | 7 +- .../components/InfoCard/InfoCard.stories.tsx | 1 - .../lib/components/Input/Input.test.tsx | 16 +- .../PasswordInput/PasswordInput.test.tsx | 30 +-- .../components/TextLink/TextLink.stories.tsx | 35 ++- .../lib/components/Toasts/Toast.stories.tsx | 19 +- .../VideoPlayer/VideoPlayer.stories.tsx | 5 + packages/design-system/vitest.config.ts | 1 + yarn.lock | 199 +++++++++++++++++- 15 files changed, 334 insertions(+), 157 deletions(-) diff --git a/apps/partner-sas/package.json b/apps/partner-sas/package.json index f4c6b1c25..baec9384c 100644 --- a/apps/partner-sas/package.json +++ b/apps/partner-sas/package.json @@ -27,7 +27,7 @@ "@scandic-hotels/design-system": "workspace:*", "@scandic-hotels/tracking": "workspace:*", "@scandic-hotels/trpc": "workspace:*", - "@sentry/nextjs": "^10.26.0", + "@sentry/nextjs": "^10.33.0", "@swc/plugin-formatjs": "^3.2.2", "@tanstack/react-query": "^5.75.5", "@tanstack/react-query-devtools": "^5.75.5", @@ -45,7 +45,6 @@ "@playwright/test": "^1.53.1", "@scandic-hotels/common": "workspace:*", "@scandic-hotels/typescript-config": "workspace:*", - "@swc/plugin-formatjs": "^3.2.2", "@types/node": "^20", "@types/react": "19.2.7", "@types/react-dom": "19.2.3", diff --git a/apps/scandic-web/package.json b/apps/scandic-web/package.json index 2e6e22702..e7a50aaff 100644 --- a/apps/scandic-web/package.json +++ b/apps/scandic-web/package.json @@ -38,7 +38,7 @@ "@scandic-hotels/design-system": "workspace:*", "@scandic-hotels/tracking": "workspace:*", "@scandic-hotels/trpc": "workspace:*", - "@sentry/nextjs": "^10.26.0", + "@sentry/nextjs": "^10.33.0", "@swc/plugin-formatjs": "^3.2.2", "@t3-oss/env-nextjs": "^0.13.4", "@tanstack/react-query": "^5.75.5", diff --git a/packages/design-system/lib/components/Alert/Alert.stories.tsx b/packages/design-system/lib/components/Alert/Alert.stories.tsx index 01d6a9240..167f04bd6 100644 --- a/packages/design-system/lib/components/Alert/Alert.stories.tsx +++ b/packages/design-system/lib/components/Alert/Alert.stories.tsx @@ -40,7 +40,8 @@ export const Default: Story = { ariaRole: "alert", }, play: async ({ canvas }) => { - canvas.findByRole("alert") + const alert = await canvas.findByRole("alert") + expect(alert).toBeVisible() }, } diff --git a/packages/design-system/lib/components/Button/Button.stories.tsx b/packages/design-system/lib/components/Button/Button.stories.tsx index 6a95a91b0..8770f392e 100644 --- a/packages/design-system/lib/components/Button/Button.stories.tsx +++ b/packages/design-system/lib/components/Button/Button.stories.tsx @@ -560,8 +560,8 @@ export const TextWithIcon: Story = { await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) - expect(canvas.getByText("Text with icon")).toBeDefined() - expect(canvas.getByTestId("MaterialIcon")).toBeDefined() + expect(await canvas.findByText("Text with icon")).toBeDefined() + expect(await canvas.findByTestId("MaterialIcon")).toBeDefined() }, } @@ -575,7 +575,7 @@ export const TextWithIconInverted: Story = { await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) - expect(canvas.getByText("Text with icon")).toBeDefined() - expect(canvas.getByTestId("MaterialIcon")).toBeDefined() + expect(await canvas.findByText("Text with icon")).toBeDefined() + expect(await canvas.findByTestId("MaterialIcon")).toBeDefined() }, } diff --git a/packages/design-system/lib/components/ButtonLink/ButtonLink.stories.tsx b/packages/design-system/lib/components/ButtonLink/ButtonLink.stories.tsx index 9338ce0fc..a558919b7 100644 --- a/packages/design-system/lib/components/ButtonLink/ButtonLink.stories.tsx +++ b/packages/design-system/lib/components/ButtonLink/ButtonLink.stories.tsx @@ -46,9 +46,8 @@ export const Default: Story = { href: "#", children: "Button link", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -59,9 +58,8 @@ export const PrimaryLarge: Story = { variant: "Primary", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -71,9 +69,8 @@ export const PrimaryMedium: Story = { ...PrimaryLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -83,9 +80,8 @@ export const PrimarySmall: Story = { ...PrimaryLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -97,9 +93,8 @@ export const PrimaryOnDarkBackground: Story = { variant: "Primary", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -113,9 +108,8 @@ export const PrimaryInvertedLarge: Story = { size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -126,9 +120,8 @@ export const PrimaryInvertedMedium: Story = { ...PrimaryInvertedLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -139,9 +132,8 @@ export const PrimaryInvertedSmall: Story = { ...PrimaryInvertedLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -152,9 +144,8 @@ export const SecondaryLarge: Story = { variant: "Secondary", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -164,9 +155,8 @@ export const SecondaryMedium: Story = { ...SecondaryLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -176,9 +166,8 @@ export const SecondarySmall: Story = { ...SecondaryLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -191,9 +180,8 @@ export const SecondaryInvertedLarge: Story = { color: "Inverted", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -204,9 +192,8 @@ export const SecondaryInvertedMedium: Story = { ...SecondaryInvertedLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -217,9 +204,8 @@ export const SecondaryInvertedSmall: Story = { ...SecondaryInvertedLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -230,9 +216,8 @@ export const TertiaryLarge: Story = { variant: "Tertiary", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -242,9 +227,8 @@ export const TertiaryMedium: Story = { ...TertiaryLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -254,9 +238,8 @@ export const TertiarySmall: Story = { ...TertiaryLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -267,9 +250,8 @@ export const TextLarge: Story = { variant: "Text", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -279,9 +261,8 @@ export const TextMedium: Story = { ...TextLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -291,9 +272,8 @@ export const TextSmall: Story = { ...TextLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -304,9 +284,8 @@ export const TextNoWrapping: Story = { children: "Text button with wrapping false", wrapping: false, }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -319,9 +298,8 @@ export const TextInvertedLarge: Story = { color: "Inverted", size: "lg", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -332,9 +310,8 @@ export const TextInvertedMedium: Story = { ...TextInvertedLarge.args, size: "md", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -345,9 +322,8 @@ export const TextInvertedSmall: Story = { ...TextInvertedLarge.args, size: "sm", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -359,9 +335,8 @@ export const TextWithIcon: Story = { children: "Text with icon", trailingIconName: "chevron_right", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link", { name: /Text with icon/i }) expect(link).toBeInTheDocument() }, } @@ -372,9 +347,8 @@ export const TextWithIconInverted: Story = { ...TextWithIcon.args, color: "Inverted", }, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } diff --git a/packages/design-system/lib/components/IconButton/IconButton.stories.tsx b/packages/design-system/lib/components/IconButton/IconButton.stories.tsx index 6ac22f81f..d3458bdf3 100644 --- a/packages/design-system/lib/components/IconButton/IconButton.stories.tsx +++ b/packages/design-system/lib/components/IconButton/IconButton.stories.tsx @@ -116,7 +116,7 @@ export const Default: Story = { iconName: "search", }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -268,7 +268,7 @@ export const Filled: Story = { variant: "Filled", }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -279,7 +279,7 @@ export const FilledDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } @@ -290,7 +290,7 @@ export const FilledOnDarkBackground: Story = { ...Filled.args, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -302,7 +302,7 @@ export const FilledWithEmphasis: Story = { emphasis: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -313,7 +313,7 @@ export const FilledWithEmphasisDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } @@ -325,7 +325,7 @@ export const Outlined: Story = { variant: "Outlined", }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -336,7 +336,7 @@ export const OutlinedDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } @@ -348,7 +348,7 @@ export const Elevated: Story = { variant: "Elevated", }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -359,7 +359,7 @@ export const ElevatedDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } @@ -372,7 +372,7 @@ export const Faded: Story = { variant: "Faded", }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -384,7 +384,7 @@ export const FadedDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } @@ -397,7 +397,7 @@ export const Muted: Story = { variant: "Muted", }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -409,7 +409,7 @@ export const MutedDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } @@ -420,7 +420,7 @@ export const MutedWithEmphasis: Story = { emphasis: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(1) }, } @@ -431,7 +431,7 @@ export const MutedWithEmphasisDisabled: Story = { isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { - await userEvent.click(canvas.getByRole("button")) + await userEvent.click(await canvas.findByRole("button")) expect(args.onPress).toHaveBeenCalledTimes(0) }, } diff --git a/packages/design-system/lib/components/Icons/MaterialIcon/index.tsx b/packages/design-system/lib/components/Icons/MaterialIcon/index.tsx index 847e47374..4810f6e94 100644 --- a/packages/design-system/lib/components/Icons/MaterialIcon/index.tsx +++ b/packages/design-system/lib/components/Icons/MaterialIcon/index.tsx @@ -52,7 +52,12 @@ export function MaterialIcon({ const iconClassName = iconVariants({ color }) return ( - + = { style={{ display: "grid", gap: "1rem" }} > {Object.keys(infoCardConfig.variants.theme).map((theme) => { - console.log(theme) const args = { ...context.args, backgroundImage: diff --git a/packages/design-system/lib/components/Input/Input.test.tsx b/packages/design-system/lib/components/Input/Input.test.tsx index 9d9767527..c8cf3edde 100644 --- a/packages/design-system/lib/components/Input/Input.test.tsx +++ b/packages/design-system/lib/components/Input/Input.test.tsx @@ -71,35 +71,37 @@ describe("Input", () => { expect(screen.queryByLabelText("Clear content")).toBeNull() }) - it("does not show clear button when input is empty", () => { + it("does not show clear button when input is empty", async () => { renderInput({ label: "Email", value: "", onChange: vi.fn(), showClearContentIcon: true, }) + + expect(await screen.findByRole("textbox")).toBeTruthy() expect(screen.queryByLabelText("Clear content")).toBeNull() }) - it("shows clear button when input has value and showClearContentIcon is true", () => { + it("shows clear button when input has value and showClearContentIcon is true", async () => { renderInput({ label: "Email", value: "test", onChange: vi.fn(), showClearContentIcon: true, }) - expect(screen.getByLabelText("Clear content")).toBeTruthy() + expect(await screen.findByLabelText("Clear content")).toBeTruthy() }) }) describe("icons", () => { - it("renders left icon when provided", () => { + it("renders left icon when provided", async () => { renderInput({ label: "Search", // eslint-disable-next-line formatjs/no-literal-string-in-jsx leftIcon: 🔍, }) - expect(screen.getByTestId("left-icon")).toBeTruthy() + expect(await screen.findByTestId("left-icon")).toBeTruthy() }) it("renders right icon when provided", () => { @@ -111,7 +113,7 @@ describe("Input", () => { expect(screen.getByTestId("right-icon")).toBeTruthy() }) - it("hides right icon when clear button is shown", () => { + it("hides right icon when clear button is shown", async () => { renderInput({ label: "Email", value: "test", @@ -120,8 +122,8 @@ describe("Input", () => { // eslint-disable-next-line formatjs/no-literal-string-in-jsx rightIcon: 👁, }) + expect(await screen.findByLabelText("Clear content")).toBeTruthy() expect(screen.queryByTestId("right-icon")).toBeNull() - expect(screen.getByLabelText("Clear content")).toBeTruthy() }) it("shows right icon when clear button condition not met", () => { diff --git a/packages/design-system/lib/components/PasswordInput/PasswordInput.test.tsx b/packages/design-system/lib/components/PasswordInput/PasswordInput.test.tsx index f6c21641b..9e49b3fc8 100644 --- a/packages/design-system/lib/components/PasswordInput/PasswordInput.test.tsx +++ b/packages/design-system/lib/components/PasswordInput/PasswordInput.test.tsx @@ -39,39 +39,43 @@ const renderPasswordInput = ( describe("PasswordInput", () => { describe("rendering", () => { - it("renders with default password label", () => { + it("renders with default password label", async () => { renderPasswordInput() - expect(screen.getByLabelText("Password")).toBeTruthy() + expect(await screen.findByLabelText("Password")).toBeTruthy() }) - it("renders with custom label", () => { + it("renders with custom label", async () => { renderPasswordInput({ label: "Enter your password" }) - expect(screen.getByLabelText("Enter your password")).toBeTruthy() + expect(await screen.findByLabelText("Enter your password")).toBeTruthy() }) - it("renders with new password label when isNewPassword is true", () => { + it("renders with new password label when isNewPassword is true", async () => { renderPasswordInput({ isNewPassword: true }) - expect(screen.getByLabelText("New password")).toBeTruthy() + expect(await screen.findByLabelText("New password")).toBeTruthy() }) }) describe("visibility toggle", () => { - it("shows visibility toggle button by default", () => { + it("shows visibility toggle button by default", async () => { renderPasswordInput() - expect(screen.getByLabelText("Show password")).toBeTruthy() + expect(await screen.findByLabelText("Show password")).toBeTruthy() }) - it("hides visibility toggle when visibilityToggleable is false", () => { + it("hides visibility toggle when visibilityToggleable is false", async () => { renderPasswordInput({ visibilityToggleable: false }) + expect(await screen.findByLabelText("Password")).toBeTruthy() expect(screen.queryByLabelText("Show password")).toBeNull() expect(screen.queryByLabelText("Hide password")).toBeNull() }) }) describe("disabled state", () => { - it("disables the input when disabled prop is true", () => { + it("disables the input when disabled prop is true", async () => { renderPasswordInput({ disabled: true }) - expect(screen.getByLabelText("Password")).toHaveProperty("disabled", true) + expect(await screen.findByLabelText("Password")).toHaveProperty( + "disabled", + true + ) }) }) @@ -80,7 +84,7 @@ describe("PasswordInput", () => { const user = userEvent.setup() renderPasswordInput() - const input = screen.getByLabelText("Password") + const input = await screen.findByLabelText("Password") await user.type(input, "secret123") expect(input).toHaveProperty("value", "secret123") @@ -90,7 +94,7 @@ describe("PasswordInput", () => { const user = userEvent.setup() renderPasswordInput({ name: "confirmPassword" }, { confirmPassword: "" }) - const input = screen.getByLabelText("Password") + const input = await screen.findByLabelText("Password") await user.type(input, "test") expect(input).toHaveProperty("value", "test") diff --git a/packages/design-system/lib/components/TextLink/TextLink.stories.tsx b/packages/design-system/lib/components/TextLink/TextLink.stories.tsx index d8664f329..300b3ae5d 100644 --- a/packages/design-system/lib/components/TextLink/TextLink.stories.tsx +++ b/packages/design-system/lib/components/TextLink/TextLink.stories.tsx @@ -39,9 +39,8 @@ export const Default: Story = { href: "https://www.scandichotels.com/en", }, render: (args) => Default link, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -52,9 +51,8 @@ export const Inverted: Story = { theme: "Inverted", }, render: (args) => Inverted link, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -65,9 +63,8 @@ export const Disabled: Story = { isDisabled: true, }, render: (args) => Disabled link, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -82,9 +79,8 @@ export const WithIcon: Story = { ), - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -95,9 +91,8 @@ export const Small: Story = { typography: "Link/sm", }, render: (args) => Small link, - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -113,9 +108,8 @@ export const SmallWithIcon: Story = { ), - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } @@ -135,9 +129,8 @@ export const Inline: Story = {

), - play: async ({ canvasElement }) => { - const link = canvasElement.querySelector("a") - if (!link) throw new Error("Link not found") + play: async ({ canvas }) => { + const link = await canvas.findByRole("link") expect(link).toBeInTheDocument() }, } diff --git a/packages/design-system/lib/components/Toasts/Toast.stories.tsx b/packages/design-system/lib/components/Toasts/Toast.stories.tsx index 99501d8a0..90b78bd81 100644 --- a/packages/design-system/lib/components/Toasts/Toast.stories.tsx +++ b/packages/design-system/lib/components/Toasts/Toast.stories.tsx @@ -1,7 +1,7 @@ import { Toast } from "./Toast" import type { Meta, StoryObj } from "@storybook/nextjs-vite" -import { expect } from "storybook/test" +import { expect, within } from "storybook/test" import { config } from "./variants.ts" @@ -52,7 +52,7 @@ export const DefaultWithCustomContent: Story = { play: async ({ canvas }) => { const toast = await canvas.findByRole("status") expect(toast).toBeVisible() - expect(canvas.getByText("This is a custom info toast")).toBeVisible() + expect(await canvas.findByText("This is a custom info toast")).toBeVisible() }, } @@ -61,10 +61,11 @@ export const Success: Story = { variant: "success", message: "This is a success toast", }, - play: async ({ canvas, args }) => { + play: async ({ canvasElement, args }) => { + const canvas = within(canvasElement) const toast = await canvas.findByRole("status") expect(toast).toBeVisible() - expect(canvas.getByText(args.message as string)).toBeVisible() + expect(await canvas.findByText(args.message as string)).toBeVisible() }, } @@ -73,10 +74,11 @@ export const Error: Story = { variant: "error", message: "This is an error toast", }, - play: async ({ canvas, args }) => { + play: async ({ canvasElement, args }) => { + const canvas = within(canvasElement) const toast = await canvas.findByRole("alert") expect(toast).toBeVisible() - expect(canvas.getByText(args.message as string)).toBeVisible() + expect(await canvas.findByText(args.message as string)).toBeVisible() }, } @@ -85,9 +87,10 @@ export const Warning: Story = { variant: "warning", message: "This is a warning toast", }, - play: async ({ canvas, args }) => { + play: async ({ args, canvasElement }) => { + const canvas = within(canvasElement) const toast = await canvas.findByRole("alert") expect(toast).toBeVisible() - expect(canvas.getByText(args.message as string)).toBeVisible() + expect(await canvas.findByText(args.message as string)).toBeVisible() }, } diff --git a/packages/design-system/lib/components/VideoPlayer/VideoPlayer.stories.tsx b/packages/design-system/lib/components/VideoPlayer/VideoPlayer.stories.tsx index 5493bbe1c..d5f38354a 100644 --- a/packages/design-system/lib/components/VideoPlayer/VideoPlayer.stories.tsx +++ b/packages/design-system/lib/components/VideoPlayer/VideoPlayer.stories.tsx @@ -7,6 +7,11 @@ import { config as videoPlayerConfig } from "./variants" const meta: Meta = { title: "Core Components/Video/VideoPlayer", component: VideoPlayer, + beforeEach: () => { + // Mock video methods to prevent actual playback + window.HTMLMediaElement.prototype.play = () => Promise.resolve() + window.HTMLMediaElement.prototype.pause = () => {} + }, parameters: { docs: { diff --git a/packages/design-system/vitest.config.ts b/packages/design-system/vitest.config.ts index a2aa2b610..e65d5e5bf 100644 --- a/packages/design-system/vitest.config.ts +++ b/packages/design-system/vitest.config.ts @@ -52,6 +52,7 @@ export default mergeConfig( headless: true, instances: browserInstances, }, + fileParallelism: false, setupFiles: ["./.storybook/vitest.setup.ts"], }, }, diff --git a/yarn.lock b/yarn.lock index c8d4900e8..03b223aa1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5159,7 +5159,7 @@ __metadata: "@scandic-hotels/tracking": "workspace:*" "@scandic-hotels/trpc": "workspace:*" "@scandic-hotels/typescript-config": "workspace:*" - "@sentry/nextjs": "npm:^10.26.0" + "@sentry/nextjs": "npm:^10.33.0" "@swc/plugin-formatjs": "npm:^3.2.2" "@tanstack/react-query": "npm:^5.75.5" "@tanstack/react-query-devtools": "npm:^5.75.5" @@ -5248,7 +5248,7 @@ __metadata: "@scandic-hotels/tracking": "workspace:*" "@scandic-hotels/trpc": "workspace:*" "@scandic-hotels/typescript-config": "workspace:*" - "@sentry/nextjs": "npm:^10.26.0" + "@sentry/nextjs": "npm:^10.33.0" "@swc/plugin-formatjs": "npm:^3.2.2" "@t3-oss/env-nextjs": "npm:^0.13.4" "@tanstack/react-query": "npm:^5.75.5" @@ -5406,6 +5406,15 @@ __metadata: languageName: node linkType: hard +"@sentry-internal/browser-utils@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry-internal/browser-utils@npm:10.33.0" + dependencies: + "@sentry/core": "npm:10.33.0" + checksum: 10c0/aee888fd7f5a0af50522ed5138604f470d370d35f9cc07369ec16a16a1fe4f2a749551838449c1c21532cd00d3cc35bb9f95225330af06b3f29bb271aeca46f0 + languageName: node + linkType: hard + "@sentry-internal/feedback@npm:10.27.0": version: 10.27.0 resolution: "@sentry-internal/feedback@npm:10.27.0" @@ -5415,6 +5424,15 @@ __metadata: languageName: node linkType: hard +"@sentry-internal/feedback@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry-internal/feedback@npm:10.33.0" + dependencies: + "@sentry/core": "npm:10.33.0" + checksum: 10c0/e203a01094bab810bb223a908c4b46ce9f02f81bb39125820e844a89f5301213cf1a205e8937629db91143c8f0201c946001b6e6641005ddc43ca0d01dfdb37a + languageName: node + linkType: hard + "@sentry-internal/replay-canvas@npm:10.27.0": version: 10.27.0 resolution: "@sentry-internal/replay-canvas@npm:10.27.0" @@ -5425,6 +5443,16 @@ __metadata: languageName: node linkType: hard +"@sentry-internal/replay-canvas@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry-internal/replay-canvas@npm:10.33.0" + dependencies: + "@sentry-internal/replay": "npm:10.33.0" + "@sentry/core": "npm:10.33.0" + checksum: 10c0/40abac10efb635faa797049d60f076aa741810fd7a350f23ed4f51e487d1cbde2e21bfa5834deace19d8825ef6e3f02b07e9525cec35f74691750b20f479924d + languageName: node + linkType: hard + "@sentry-internal/replay@npm:10.27.0": version: 10.27.0 resolution: "@sentry-internal/replay@npm:10.27.0" @@ -5435,6 +5463,16 @@ __metadata: languageName: node linkType: hard +"@sentry-internal/replay@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry-internal/replay@npm:10.33.0" + dependencies: + "@sentry-internal/browser-utils": "npm:10.33.0" + "@sentry/core": "npm:10.33.0" + checksum: 10c0/37261f2da729a623d3a1b7756c36a5ee4c2cb598791770273dc73eab6c3f69eb364a56ca2d41e2f951eedc58d7b099807e2a5805afa8e08feafb42cc5a6abbad + languageName: node + linkType: hard + "@sentry-internal/tracing@npm:7.120.4": version: 7.120.4 resolution: "@sentry-internal/tracing@npm:7.120.4" @@ -5466,6 +5504,19 @@ __metadata: languageName: node linkType: hard +"@sentry/browser@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/browser@npm:10.33.0" + dependencies: + "@sentry-internal/browser-utils": "npm:10.33.0" + "@sentry-internal/feedback": "npm:10.33.0" + "@sentry-internal/replay": "npm:10.33.0" + "@sentry-internal/replay-canvas": "npm:10.33.0" + "@sentry/core": "npm:10.33.0" + checksum: 10c0/c8ac3d387de8d16582cd2726dfac80c27f82d676140e62210e233e767d30b4e9de82d8c692630b0ca17a9ed1f646af0ac421e364d078aed0756c6a82fac0eb34 + languageName: node + linkType: hard + "@sentry/bun@npm:10.31.0": version: 10.31.0 resolution: "@sentry/bun@npm:10.31.0" @@ -5602,6 +5653,13 @@ __metadata: languageName: node linkType: hard +"@sentry/core@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/core@npm:10.33.0" + checksum: 10c0/60573a58f406b8b667347cabf9b5292f6b726765d914498eeb2678cb7a2f581dd78b4ce35da23e50660a588ec532f1c26464a9971453fea478efea2490fdb28f + languageName: node + linkType: hard + "@sentry/core@npm:7.120.4": version: 7.120.4 resolution: "@sentry/core@npm:7.120.4" @@ -5636,6 +5694,29 @@ __metadata: languageName: node linkType: hard +"@sentry/nextjs@npm:^10.33.0": + version: 10.33.0 + resolution: "@sentry/nextjs@npm:10.33.0" + dependencies: + "@opentelemetry/api": "npm:^1.9.0" + "@opentelemetry/semantic-conventions": "npm:^1.37.0" + "@rollup/plugin-commonjs": "npm:28.0.1" + "@sentry-internal/browser-utils": "npm:10.33.0" + "@sentry/bundler-plugin-core": "npm:^4.6.1" + "@sentry/core": "npm:10.33.0" + "@sentry/node": "npm:10.33.0" + "@sentry/opentelemetry": "npm:10.33.0" + "@sentry/react": "npm:10.33.0" + "@sentry/vercel-edge": "npm:10.33.0" + "@sentry/webpack-plugin": "npm:^4.6.1" + rollup: "npm:^4.35.0" + stacktrace-parser: "npm:^0.1.10" + peerDependencies: + next: ^13.2.0 || ^14.0 || ^15.0.0-rc.0 || ^16.0.0-0 + checksum: 10c0/61f63d99bae2487a0042b43ebc96dddf4ee43145bc638e717d7f21dfd85ee676491958eb150d0e90cf62ba6b717b3d625f4ca5c15167e1ed6e348d03992a683b + languageName: node + linkType: hard + "@sentry/node-core@npm:10.27.0": version: 10.27.0 resolution: "@sentry/node-core@npm:10.27.0" @@ -5676,6 +5757,26 @@ __metadata: languageName: node linkType: hard +"@sentry/node-core@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/node-core@npm:10.33.0" + dependencies: + "@apm-js-collab/tracing-hooks": "npm:^0.3.1" + "@sentry/core": "npm:10.33.0" + "@sentry/opentelemetry": "npm:10.33.0" + import-in-the-middle: "npm:^2.0.1" + peerDependencies: + "@opentelemetry/api": ^1.9.0 + "@opentelemetry/context-async-hooks": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/instrumentation": ">=0.57.1 <1" + "@opentelemetry/resources": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/semantic-conventions": ^1.37.0 + checksum: 10c0/f2ef7de1d6ef361d9395a3f985aaf9f03390cd788816cd58881dd7f56a91bd3373592b4a4ce5927229813a686e67bef465e1f0794ca0b19bb182fd3ba911d193 + languageName: node + linkType: hard + "@sentry/node@npm:10.27.0": version: 10.27.0 resolution: "@sentry/node@npm:10.27.0" @@ -5762,6 +5863,49 @@ __metadata: languageName: node linkType: hard +"@sentry/node@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/node@npm:10.33.0" + dependencies: + "@opentelemetry/api": "npm:^1.9.0" + "@opentelemetry/context-async-hooks": "npm:^2.2.0" + "@opentelemetry/core": "npm:^2.2.0" + "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation-amqplib": "npm:0.55.0" + "@opentelemetry/instrumentation-connect": "npm:0.52.0" + "@opentelemetry/instrumentation-dataloader": "npm:0.26.0" + "@opentelemetry/instrumentation-express": "npm:0.57.0" + "@opentelemetry/instrumentation-fs": "npm:0.28.0" + "@opentelemetry/instrumentation-generic-pool": "npm:0.52.0" + "@opentelemetry/instrumentation-graphql": "npm:0.56.0" + "@opentelemetry/instrumentation-hapi": "npm:0.55.0" + "@opentelemetry/instrumentation-http": "npm:0.208.0" + "@opentelemetry/instrumentation-ioredis": "npm:0.56.0" + "@opentelemetry/instrumentation-kafkajs": "npm:0.18.0" + "@opentelemetry/instrumentation-knex": "npm:0.53.0" + "@opentelemetry/instrumentation-koa": "npm:0.57.0" + "@opentelemetry/instrumentation-lru-memoizer": "npm:0.53.0" + "@opentelemetry/instrumentation-mongodb": "npm:0.61.0" + "@opentelemetry/instrumentation-mongoose": "npm:0.55.0" + "@opentelemetry/instrumentation-mysql": "npm:0.54.0" + "@opentelemetry/instrumentation-mysql2": "npm:0.55.0" + "@opentelemetry/instrumentation-pg": "npm:0.61.0" + "@opentelemetry/instrumentation-redis": "npm:0.57.0" + "@opentelemetry/instrumentation-tedious": "npm:0.27.0" + "@opentelemetry/instrumentation-undici": "npm:0.19.0" + "@opentelemetry/resources": "npm:^2.2.0" + "@opentelemetry/sdk-trace-base": "npm:^2.2.0" + "@opentelemetry/semantic-conventions": "npm:^1.37.0" + "@prisma/instrumentation": "npm:6.19.0" + "@sentry/core": "npm:10.33.0" + "@sentry/node-core": "npm:10.33.0" + "@sentry/opentelemetry": "npm:10.33.0" + import-in-the-middle: "npm:^2.0.1" + minimatch: "npm:^9.0.0" + checksum: 10c0/df3212d02dc63526184707a144d664b486acc0c1019342a4616e5b638ab8061459e57e2e1d89acee381bc9674cb28c738eb576d8d85c271a07f724a983415900 + languageName: node + linkType: hard + "@sentry/opentelemetry@npm:10.27.0": version: 10.27.0 resolution: "@sentry/opentelemetry@npm:10.27.0" @@ -5792,6 +5936,21 @@ __metadata: languageName: node linkType: hard +"@sentry/opentelemetry@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/opentelemetry@npm:10.33.0" + dependencies: + "@sentry/core": "npm:10.33.0" + peerDependencies: + "@opentelemetry/api": ^1.9.0 + "@opentelemetry/context-async-hooks": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/semantic-conventions": ^1.37.0 + checksum: 10c0/6861ec231642388a2d69b6d9702b16c5f3c75c279db878bf16319103d0b7d40bbda8507753c3448e4038bfb761e68570008ef1310eb51a4ae24b97a06239dffa + languageName: node + linkType: hard + "@sentry/react@npm:10.27.0": version: 10.27.0 resolution: "@sentry/react@npm:10.27.0" @@ -5805,6 +5964,18 @@ __metadata: languageName: node linkType: hard +"@sentry/react@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/react@npm:10.33.0" + dependencies: + "@sentry/browser": "npm:10.33.0" + "@sentry/core": "npm:10.33.0" + peerDependencies: + react: ^16.14.0 || 17.x || 18.x || 19.x + checksum: 10c0/82e70c86c506ac17cb4d73231078a548de5e010981d707c56b55dc27844bbef69d1eb5b35907db90cce2c3abebd09aee5fff3687151279cbf37793c1f21cc253 + languageName: node + linkType: hard + "@sentry/tracing@npm:7.120.4": version: 7.120.4 resolution: "@sentry/tracing@npm:7.120.4" @@ -5841,7 +6012,18 @@ __metadata: languageName: node linkType: hard -"@sentry/webpack-plugin@npm:^4.3.0": +"@sentry/vercel-edge@npm:10.33.0": + version: 10.33.0 + resolution: "@sentry/vercel-edge@npm:10.33.0" + dependencies: + "@opentelemetry/api": "npm:^1.9.0" + "@opentelemetry/resources": "npm:^2.2.0" + "@sentry/core": "npm:10.33.0" + checksum: 10c0/007dd1954d46373519628da760b40420213381098ffbd2d94b898dd9d68e60876f9025f3d40a0b063f32dbee18aab6e4628cba215ad90d329875f571426d7a75 + languageName: node + linkType: hard + +"@sentry/webpack-plugin@npm:^4.3.0, @sentry/webpack-plugin@npm:^4.6.1": version: 4.6.1 resolution: "@sentry/webpack-plugin@npm:4.6.1" dependencies: @@ -6904,7 +7086,16 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:16 || 17 || 18 || 19, @types/react@npm:19.2.7": +"@types/react@npm:16 || 17 || 18 || 19": + version: 19.2.8 + resolution: "@types/react@npm:19.2.8" + dependencies: + csstype: "npm:^3.2.2" + checksum: 10c0/832834998c4ee971fca72ecf1eb95dc924ad3931a2112c687a4dae498aabd115c5fa4db09186853e34a646226b0223808c8f867df03d17601168f9cf119448de + languageName: node + linkType: hard + +"@types/react@npm:19.2.7": version: 19.2.7 resolution: "@types/react@npm:19.2.7" dependencies: