diff --git a/code/e2e-tests/addon-interactions.spec.ts b/code/e2e-tests/addon-interactions.spec.ts index 981c5bf678a6..d77ef67beeca 100644 --- a/code/e2e-tests/addon-interactions.spec.ts +++ b/code/e2e-tests/addon-interactions.spec.ts @@ -29,7 +29,7 @@ test.describe('addon-interactions', () => { await expect(welcome).toContainText('Welcome, Jane Doe!'); const interactionsTab = await page.locator('#tabbutton-storybook-interactions-panel'); - await expect(interactionsTab).toContainText(/(1)/); + await expect(interactionsTab).toContainText(/(\d)/); await expect(interactionsTab).toBeVisible(); const panel = sbPage.panelContent(); @@ -37,7 +37,7 @@ test.describe('addon-interactions', () => { await expect(panel).toContainText(/userEvent.click/); await expect(panel).toBeVisible(); - const done = await panel.locator('[data-testid=icon-done]'); + const done = await panel.locator('[data-testid=icon-done]').nth(0); await expect(done).toBeVisible(); }); diff --git a/code/frameworks/angular/template/cli/Page.stories.ts b/code/frameworks/angular/template/cli/Page.stories.ts index e7f3c0e9a3b6..a21cdf7d8304 100644 --- a/code/frameworks/angular/template/cli/Page.stories.ts +++ b/code/frameworks/angular/template/cli/Page.stories.ts @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from '@storybook/angular'; import { moduleMetadata } from '@storybook/angular'; -import { within, userEvent } from '@storybook/testing-library'; import { CommonModule } from '@angular/common'; +import { within, userEvent, expect } from '@storybook/test'; import Button from './button.component'; import Header from './header.component'; @@ -38,9 +38,12 @@ export const LoggedIn: Story = { }), play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/frameworks/nextjs/template/cli/js/Page.stories.js b/code/frameworks/nextjs/template/cli/js/Page.stories.js index 5bd1d6eba765..f339fa246d39 100644 --- a/code/frameworks/nextjs/template/cli/js/Page.stories.js +++ b/code/frameworks/nextjs/template/cli/js/Page.stories.js @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Page } from './Page'; export default { @@ -16,9 +16,12 @@ export const LoggedOut = {}; export const LoggedIn = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/frameworks/nextjs/template/cli/ts-3-8/Page.stories.ts b/code/frameworks/nextjs/template/cli/ts-3-8/Page.stories.ts index 0e48941ab149..c072a1cc43ed 100644 --- a/code/frameworks/nextjs/template/cli/ts-3-8/Page.stories.ts +++ b/code/frameworks/nextjs/template/cli/ts-3-8/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Page } from './Page'; @@ -21,9 +21,12 @@ export const LoggedOut: Story = {}; export const LoggedIn: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/frameworks/nextjs/template/cli/ts-4-9/Page.stories.ts b/code/frameworks/nextjs/template/cli/ts-4-9/Page.stories.ts index 69852a2bdc00..622858e72e7f 100644 --- a/code/frameworks/nextjs/template/cli/ts-4-9/Page.stories.ts +++ b/code/frameworks/nextjs/template/cli/ts-4-9/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Page } from './Page'; @@ -21,9 +21,12 @@ export const LoggedOut: Story = {}; export const LoggedIn: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/lib/cli/src/generators/baseGenerator.ts b/code/lib/cli/src/generators/baseGenerator.ts index 48b2f8affd5b..a7bdb1764668 100644 --- a/code/lib/cli/src/generators/baseGenerator.ts +++ b/code/lib/cli/src/generators/baseGenerator.ts @@ -251,7 +251,14 @@ export async function baseGenerator( if (hasInteractiveStories(rendererId)) { addons.push('@storybook/addon-interactions'); - addonPackages.push('@storybook/addon-interactions', '@storybook/testing-library@^0.2.0-next.0'); + addonPackages.push('@storybook/addon-interactions'); + + // TODO: migrate template stories in solid and qwik to use @storybook/test + if (['solid', 'qwik'].includes(rendererId)) { + addonPackages.push('@storybook/testing-library'); + } else { + addonPackages.push('@storybook/test'); + } } const files = await fse.readdir(process.cwd()); diff --git a/code/lib/test/src/expect.ts b/code/lib/test/src/expect.ts index d277380a3596..7e8b9d95cf03 100644 --- a/code/lib/test/src/expect.ts +++ b/code/lib/test/src/expect.ts @@ -15,13 +15,13 @@ import { setState, } from '@vitest/expect'; import * as matchers from '@testing-library/jest-dom/matchers'; -import type { TestingLibraryMatchers } from '@testing-library/jest-dom/types/matchers'; import type { PromisifyObject } from './utils'; +type Matchers = PromisifyObject> & + matchers.TestingLibraryMatchers, Promise>; + // We only expose the jest compatible API for now -export interface Assertion - extends PromisifyObject>, - TestingLibraryMatchers, Promise> { +export interface Assertion extends Matchers { toHaveBeenCalledOnce(): Promise; toSatisfy(matcher: (value: E) => boolean, message?: string): Promise; resolves: Assertion; diff --git a/code/package.json b/code/package.json index d742d3ab90b5..323c5ebbe927 100644 --- a/code/package.json +++ b/code/package.json @@ -80,6 +80,7 @@ ], "resolutions": { "@playwright/test": "1.36.0", + "@testing-library/jest-dom/aria-query": "5.1.3", "@typescript-eslint/eslint-plugin": "^5.45.0", "@typescript-eslint/experimental-utils": "^5.45.0", "@typescript-eslint/parser": "^5.45.0", diff --git a/code/renderers/html/template/cli/js/Page.stories.js b/code/renderers/html/template/cli/js/Page.stories.js index a80a4c4a9d24..fcab88181bee 100644 --- a/code/renderers/html/template/cli/js/Page.stories.js +++ b/code/renderers/html/template/cli/js/Page.stories.js @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { createPage } from './Page'; export default { @@ -16,9 +16,12 @@ export const LoggedOut = {}; export const LoggedIn = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/html/template/cli/ts-3-8/Page.stories.ts b/code/renderers/html/template/cli/ts-3-8/Page.stories.ts index 04b893f795fc..0c2e79e8e907 100644 --- a/code/renderers/html/template/cli/ts-3-8/Page.stories.ts +++ b/code/renderers/html/template/cli/ts-3-8/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/html'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { createPage } from './Page'; const meta: Meta = { @@ -19,9 +19,12 @@ export const LoggedOut: StoryObj = {}; export const LoggedIn: StoryObj = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/html/template/cli/ts-4-9/Page.stories.ts b/code/renderers/html/template/cli/ts-4-9/Page.stories.ts index 6de6300e49a0..c64a88fbb84f 100644 --- a/code/renderers/html/template/cli/ts-4-9/Page.stories.ts +++ b/code/renderers/html/template/cli/ts-4-9/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/html'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { createPage } from './Page'; const meta = { @@ -19,9 +19,12 @@ export const LoggedOut: StoryObj = {}; export const LoggedIn: StoryObj = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/preact/template/cli/Page.stories.jsx b/code/renderers/preact/template/cli/Page.stories.jsx index d49ca397aaee..46669ac1c89d 100644 --- a/code/renderers/preact/template/cli/Page.stories.jsx +++ b/code/renderers/preact/template/cli/Page.stories.jsx @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent } from '@storybook/test'; import { Page } from './Page'; diff --git a/code/renderers/react/template/cli/js/Page.stories.js b/code/renderers/react/template/cli/js/Page.stories.js index 7467c98cf48a..204189f6d21d 100644 --- a/code/renderers/react/template/cli/js/Page.stories.js +++ b/code/renderers/react/template/cli/js/Page.stories.js @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Page } from './Page'; @@ -17,9 +17,12 @@ export const LoggedOut = {}; export const LoggedIn = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/react/template/cli/ts-3-8/Page.stories.ts b/code/renderers/react/template/cli/ts-3-8/Page.stories.ts index 52c4cb406233..adbab5d615f2 100644 --- a/code/renderers/react/template/cli/ts-3-8/Page.stories.ts +++ b/code/renderers/react/template/cli/ts-3-8/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Page } from './Page'; @@ -21,9 +21,12 @@ export const LoggedOut: Story = {}; export const LoggedIn: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/react/template/cli/ts-4-9/Page.stories.ts b/code/renderers/react/template/cli/ts-4-9/Page.stories.ts index 69852a2bdc00..622858e72e7f 100644 --- a/code/renderers/react/template/cli/ts-4-9/Page.stories.ts +++ b/code/renderers/react/template/cli/ts-4-9/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Page } from './Page'; @@ -21,9 +21,12 @@ export const LoggedOut: Story = {}; export const LoggedIn: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/svelte/template/cli/js/Page.stories.js b/code/renderers/svelte/template/cli/js/Page.stories.js index 9c6008b4c705..a4492ae66631 100644 --- a/code/renderers/svelte/template/cli/js/Page.stories.js +++ b/code/renderers/svelte/template/cli/js/Page.stories.js @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import Page from './Page.svelte'; @@ -17,9 +17,12 @@ export const LoggedOut = {}; export const LoggedIn = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/svelte/template/cli/ts-3-8/Page.stories.ts b/code/renderers/svelte/template/cli/ts-3-8/Page.stories.ts index 3aba1302bf24..82e49cd3be09 100644 --- a/code/renderers/svelte/template/cli/ts-3-8/Page.stories.ts +++ b/code/renderers/svelte/template/cli/ts-3-8/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/svelte'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import Page from './Page.svelte'; @@ -21,9 +21,12 @@ export const LoggedOut: Story = {}; export const LoggedIn: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/svelte/template/cli/ts-4-9/Page.stories.ts b/code/renderers/svelte/template/cli/ts-4-9/Page.stories.ts index 78665a28bfae..d7e97628ea24 100644 --- a/code/renderers/svelte/template/cli/ts-4-9/Page.stories.ts +++ b/code/renderers/svelte/template/cli/ts-4-9/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/svelte'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import Page from './Page.svelte'; @@ -21,9 +21,12 @@ export const LoggedOut: Story = {}; export const LoggedIn: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/vue/template/cli/Page.stories.js b/code/renderers/vue/template/cli/Page.stories.js index 8bd022352948..5e9b6ffa7318 100644 --- a/code/renderers/vue/template/cli/Page.stories.js +++ b/code/renderers/vue/template/cli/Page.stories.js @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import MyPage from './Page.vue'; export default { @@ -19,9 +19,12 @@ export const LoggedOut = {}; export const LoggedIn = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/vue3/template/cli/js/Page.stories.js b/code/renderers/vue3/template/cli/js/Page.stories.js index f11ff44e5bdf..3c4ce9312539 100644 --- a/code/renderers/vue3/template/cli/js/Page.stories.js +++ b/code/renderers/vue3/template/cli/js/Page.stories.js @@ -1,4 +1,4 @@ -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import MyPage from './Page.vue'; export default { @@ -22,9 +22,12 @@ export const LoggedIn = { }), play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/vue3/template/cli/ts-3-8/Page.stories.ts b/code/renderers/vue3/template/cli/ts-3-8/Page.stories.ts index 1ac73cf4433d..c26e06d2d0de 100644 --- a/code/renderers/vue3/template/cli/ts-3-8/Page.stories.ts +++ b/code/renderers/vue3/template/cli/ts-3-8/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/vue3'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import MyPage from './Page.vue'; const meta: Meta = { @@ -24,10 +24,13 @@ type Story = StoryObj; export const LoggedIn: Story = { play: async ({ canvasElement }: any) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts b/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts index e9988015819d..2bf745b21f21 100644 --- a/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts +++ b/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/vue3'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import MyPage from './Page.vue'; const meta = { @@ -24,10 +24,13 @@ type Story = StoryObj; export const LoggedIn: Story = { play: async ({ canvasElement }: any) => { const canvas = within(canvasElement); - const loginButton = await canvas.getByRole('button', { - name: /Log in/i, - }); + const loginButton = canvas.getByRole('button', { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole('button', { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); }, }; diff --git a/code/yarn.lock b/code/yarn.lock index c450dcda37e2..224d55ee40c9 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -11597,7 +11597,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.0.0, aria-query@npm:^5.1.3, aria-query@npm:^5.3.0": +"aria-query@npm:^5.1.3, aria-query@npm:^5.3.0": version: 5.3.0 resolution: "aria-query@npm:5.3.0" dependencies: