diff --git a/site/.storybook/main.js b/site/.storybook/main.js index e5ede7b46b2f8..9f1fdaacc6f7f 100644 --- a/site/.storybook/main.js +++ b/site/.storybook/main.js @@ -11,8 +11,9 @@ module.exports = { }, "@storybook/addon-links", "@storybook/addon-mdx-gfm", - "@storybook/addon-actions", "@storybook/addon-themes", + "@storybook/addon-actions", + "@storybook/addon-interactions", ], staticDirs: ["../static"], framework: { diff --git a/site/package.json b/site/package.json index 995d350b518a0..a4d13b6cb87cb 100644 --- a/site/package.json +++ b/site/package.json @@ -96,12 +96,15 @@ "@playwright/test": "1.39.0", "@storybook/addon-actions": "7.5.2", "@storybook/addon-essentials": "7.5.2", + "@storybook/addon-interactions": "7.6.10", "@storybook/addon-links": "7.5.2", "@storybook/addon-mdx-gfm": "7.5.2", "@storybook/addon-themes": "7.6.4", + "@storybook/jest": "0.2.3", "@storybook/preview-api": "7.6.9", "@storybook/react": "7.5.2", "@storybook/react-vite": "7.5.2", + "@storybook/testing-library": "0.2.2", "@swc/core": "1.3.38", "@swc/jest": "0.2.24", "@testing-library/jest-dom": "6.1.2", diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml index d2857c9196010..4118afa1d4fcc 100644 --- a/site/pnpm-lock.yaml +++ b/site/pnpm-lock.yaml @@ -209,6 +209,9 @@ devDependencies: '@storybook/addon-essentials': specifier: 7.5.2 version: 7.5.2(@types/react-dom@18.2.4)(@types/react@18.2.6)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-interactions': + specifier: 7.6.10 + version: 7.6.10 '@storybook/addon-links': specifier: 7.5.2 version: 7.5.2(react-dom@18.2.0)(react@18.2.0) @@ -218,6 +221,9 @@ devDependencies: '@storybook/addon-themes': specifier: 7.6.4 version: 7.6.4 + '@storybook/jest': + specifier: 0.2.3 + version: 0.2.3(jest@29.6.2) '@storybook/preview-api': specifier: 7.6.9 version: 7.6.9 @@ -227,6 +233,9 @@ devDependencies: '@storybook/react-vite': specifier: 7.5.2 version: 7.5.2(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.2) + '@storybook/testing-library': + specifier: 0.2.2 + version: 0.2.2 '@swc/core': specifier: 1.3.38 version: 1.3.38 @@ -2522,6 +2531,13 @@ packages: - supports-color dev: true + /@jest/schemas@28.1.3: + resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@sinclair/typebox': 0.24.51 + dev: true + /@jest/schemas@29.6.3: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3679,6 +3695,10 @@ packages: picomatch: 2.3.1 dev: true + /@sinclair/typebox@0.24.51: + resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} + dev: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -3860,6 +3880,16 @@ packages: '@storybook/preview-api': 7.5.2 dev: true + /@storybook/addon-interactions@7.6.10: + resolution: {integrity: sha512-lEsAdP/PrOZK/KmRbZ/fU4RjEqDP+e/PBlVVVJT2QvHniWK/xxkjCD0axsHU/XuaeQRFhmg0/KR342PC/cIf9A==} + dependencies: + '@storybook/global': 5.0.0 + '@storybook/types': 7.6.10 + jest-mock: 27.5.1 + polished: 4.2.2 + ts-dedent: 2.2.0 + dev: true + /@storybook/addon-links@7.5.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-IhUYNOJQYJd8Cnb93l8egnGCGhHV0VHo6HmZT9YjBVuUtetGQbW8Eoh0pQwuklUrJ3jLPwMoKFhN1irQXJjZwQ==} peerDependencies: @@ -4219,6 +4249,17 @@ packages: tiny-invariant: 1.3.1 dev: true + /@storybook/channels@7.6.10: + resolution: {integrity: sha512-ITCLhFuDBKgxetuKnWwYqMUWlU7zsfH3gEKZltTb+9/2OAWR7ez0iqU7H6bXP1ridm0DCKkt2UMWj2mmr9iQqg==} + dependencies: + '@storybook/client-logger': 7.6.10 + '@storybook/core-events': 7.6.10 + '@storybook/global': 5.0.0 + qs: 6.11.2 + telejson: 7.2.0 + tiny-invariant: 1.3.1 + dev: true + /@storybook/channels@7.6.9: resolution: {integrity: sha512-goGGZPT294CS1QDF65Fs+PCauvM/nTMseU913ZVSZbFTk4uvqIXOaOraqhQze8A/C8a0yls4qu2Wp00tCnyaTA==} dependencies: @@ -4301,6 +4342,12 @@ packages: '@storybook/global': 5.0.0 dev: true + /@storybook/client-logger@7.6.10: + resolution: {integrity: sha512-U7bbpu21ntgePMz/mKM18qvCSWCUGCUlYru8mgVlXLCKqFqfTeP887+CsPEQf29aoE3cLgDrxqbRJ1wxX9kL9A==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + /@storybook/client-logger@7.6.9: resolution: {integrity: sha512-Xm6fa6AR3cjxabauMldBv/66OOp5IhDiUEpp4D/a7hXfvCWqwmjVJ6EPz9WzkMhcPbMJr8vWJBaS3glkFqsRng==} dependencies: @@ -4461,6 +4508,12 @@ packages: ts-dedent: 2.2.0 dev: true + /@storybook/core-events@7.6.10: + resolution: {integrity: sha512-yccDH67KoROrdZbRKwxgTswFMAco5nlCyxszCDASCLygGSV2Q2e+YuywrhchQl3U6joiWi3Ps1qWu56NeNafag==} + dependencies: + ts-dedent: 2.2.0 + dev: true + /@storybook/core-events@7.6.9: resolution: {integrity: sha512-YCds7AA6sbnnZ2qq5l+AIxhQqYlXB8eVTkjj6phgczsLjkqKapYFxAFc3ppRnE0FcsL2iji17ikHzZ8+eHYznA==} dependencies: @@ -4599,10 +4652,29 @@ packages: - supports-color dev: true + /@storybook/expect@28.1.3-5: + resolution: {integrity: sha512-lS1oJnY1qTAxnH87C765NdfvGhksA6hBcbUVI5CHiSbNsEtr456wtg/z+dT9XlPriq1D5t2SgfNL9dBAoIGyIA==} + dependencies: + '@types/jest': 28.1.3 + dev: true + /@storybook/global@5.0.0: resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} dev: true + /@storybook/jest@0.2.3(jest@29.6.2): + resolution: {integrity: sha512-ov5izrmbAFObzKeh9AOC5MlmFxAcf0o5i6YFGae9sDx6DGh6alXsRM+chIbucVkUwVHVlSzdfbLDEFGY/ShaYw==} + dependencies: + '@storybook/expect': 28.1.3-5 + '@testing-library/jest-dom': 6.1.2(@types/jest@28.1.3)(jest@29.6.2) + '@types/jest': 28.1.3 + jest-mock: 27.5.1 + transitivePeerDependencies: + - '@jest/globals' + - jest + - vitest + dev: true + /@storybook/manager-api@7.5.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-WX8GjBkITRQzhQ08WEAVjdDW8QqqIQhWOpFzXUYCxCNzt1eSALI31QQ+M1/MYymw+TOkotC/SMcn/puIAm4rdA==} peerDependencies: @@ -4877,6 +4949,14 @@ packages: - supports-color dev: true + /@storybook/testing-library@0.2.2: + resolution: {integrity: sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==} + dependencies: + '@testing-library/dom': 9.3.3 + '@testing-library/user-event': 14.5.1(@testing-library/dom@9.3.3) + ts-dedent: 2.2.0 + dev: true + /@storybook/theming@6.5.16(react-dom@18.2.0)(react@17.0.2): resolution: {integrity: sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==} peerDependencies: @@ -4937,6 +5017,15 @@ packages: file-system-cache: 2.3.0 dev: true + /@storybook/types@7.6.10: + resolution: {integrity: sha512-hcS2HloJblaMpCAj2axgGV+53kgSRYPT0a1PG1IHsZaYQILfHSMmBqM8XzXXYTsgf9250kz3dqFX1l0n3EqMlQ==} + dependencies: + '@storybook/channels': 7.6.10 + '@types/babel__core': 7.20.5 + '@types/express': 4.17.17 + file-system-cache: 2.3.0 + dev: true + /@storybook/types@7.6.9: resolution: {integrity: sha512-Qnx7exS6bO1MrqasHl12h8/HeBuxrwg2oMXROO7t0qmprV6+DGb6OxztsVIgbKR+m6uqFFM1q+f/Q5soI1qJ6g==} dependencies: @@ -5122,6 +5211,36 @@ packages: pretty-format: 27.5.1 dev: true + /@testing-library/jest-dom@6.1.2(@types/jest@28.1.3)(jest@29.6.2): + resolution: {integrity: sha512-NP9jl1Q2qDDtx+cqogowtQtmgD2OVs37iMSIsTv5eN5ETRkf26Kj6ugVwA93/gZzzFWQAsgkKkcftDe91BJCkQ==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + peerDependencies: + '@jest/globals': '>= 28' + '@types/jest': '>= 28' + jest: '>= 28' + vitest: '>= 0.32' + peerDependenciesMeta: + '@jest/globals': + optional: true + '@types/jest': + optional: true + jest: + optional: true + vitest: + optional: true + dependencies: + '@adobe/css-tools': 4.3.2 + '@babel/runtime': 7.22.11 + '@types/jest': 28.1.3 + aria-query: 5.3.0 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.5.16 + jest: 29.6.2(@types/node@18.19.0)(ts-node@10.9.1) + lodash: 4.17.21 + redent: 3.0.0 + dev: true + /@testing-library/jest-dom@6.1.2(@types/jest@29.5.2)(jest@29.6.2): resolution: {integrity: sha512-NP9jl1Q2qDDtx+cqogowtQtmgD2OVs37iMSIsTv5eN5ETRkf26Kj6ugVwA93/gZzzFWQAsgkKkcftDe91BJCkQ==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} @@ -5451,6 +5570,13 @@ packages: '@types/istanbul-lib-report': 3.0.2 dev: true + /@types/jest@28.1.3: + resolution: {integrity: sha512-Tsbjk8Y2hkBaY/gJsataeb4q9Mubw9EOz7+4RjPkzD5KjTvHHs7cpws22InaoXxAVAhF5HfFbzJjo6oKWqSZLw==} + dependencies: + jest-matcher-utils: 28.1.3 + pretty-format: 28.1.3 + dev: true + /@types/jest@29.5.2: resolution: {integrity: sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==} dependencies: @@ -7421,6 +7547,11 @@ packages: dequal: 2.0.3 dev: false + /diff-sequences@28.1.1: + resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + /diff-sequences@29.4.3: resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9569,6 +9700,16 @@ packages: - supports-color dev: true + /jest-diff@28.1.3: + resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 28.1.1 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + /jest-diff@29.6.2: resolution: {integrity: sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9652,6 +9793,11 @@ packages: - encoding dev: true + /jest-get-type@28.0.2: + resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + /jest-get-type@29.4.3: resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9697,6 +9843,16 @@ packages: jest-diff: 29.7.0 dev: true + /jest-matcher-utils@28.1.3: + resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + /jest-matcher-utils@29.6.2: resolution: {integrity: sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9722,6 +9878,14 @@ packages: stack-utils: 2.0.6 dev: true + /jest-mock@27.5.1: + resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/node': 18.19.0 + dev: true + /jest-mock@29.6.2: resolution: {integrity: sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -11885,6 +12049,16 @@ packages: react-is: 17.0.2 dev: true + /pretty-format@28.1.3: + resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/schemas': 28.1.3 + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + /pretty-format@29.6.2: resolution: {integrity: sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} diff --git a/site/src/components/InfoTooltip/InfoTooltip.stories.tsx b/site/src/components/InfoTooltip/InfoTooltip.stories.tsx index b3c9bac634ecd..499d57e7e47b8 100644 --- a/site/src/components/InfoTooltip/InfoTooltip.stories.tsx +++ b/site/src/components/InfoTooltip/InfoTooltip.stories.tsx @@ -1,7 +1,9 @@ -import { InfoTooltip } from "./InfoTooltip"; +import { expect } from "@storybook/jest"; import type { Meta, StoryObj } from "@storybook/react"; +import { userEvent, waitFor, within } from "@storybook/testing-library"; +import { InfoTooltip } from "./InfoTooltip"; -const meta: Meta = { +const meta = { title: "components/InfoTooltip", component: InfoTooltip, args: { @@ -9,23 +11,54 @@ const meta: Meta = { title: "Hello, friend!", message: "Today is a lovely day :^)", }, -}; +} satisfies Meta; export default meta; type Story = StoryObj; -export const Example: Story = {}; +export const Example: Story = { + play: async ({ canvasElement, step }) => { + const screen = within(canvasElement); + + await step("activate hover trigger", async () => { + await userEvent.hover(screen.getByRole("button")); + await waitFor(() => + expect(screen.getByText(meta.args.message)).toBeInTheDocument(), + ); + }); + }, +}; -export const Notice: Story = { +export const Notice = { args: { type: "notice", message: "Unfortunately, there's a radio connected to my brain", }, -}; + play: async ({ canvasElement, step }) => { + const screen = within(canvasElement); + + await step("activate hover trigger", async () => { + await userEvent.hover(screen.getByRole("button")); + await waitFor(() => + expect(screen.getByText(Notice.args.message)).toBeInTheDocument(), + ); + }); + }, +} satisfies Story; -export const Warning: Story = { +export const Warning = { args: { type: "warning", message: "Unfortunately, there's a radio connected to my brain", }, -}; + play: async ({ canvasElement, step }) => { + const screen = within(canvasElement); + + await step("activate hover trigger", async () => { + await userEvent.hover(screen.getByRole("button")); + await waitFor(() => + expect(screen.getByText(Warning.args.message)).toBeInTheDocument(), + ); + }); + }, +} satisfies Story;