diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index e5212d214e18..217d74b01133 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,10 @@ +## 8.5.0-beta.2 + +- Addon Test: Clear coverage data when starting or watching - [#30072](https://github.com/storybookjs/storybook/pull/30072), thanks @ghengeveld! +- Addon Test: Improve error message on missing coverage package - [#30088](https://github.com/storybookjs/storybook/pull/30088), thanks @JReinhold! +- UI: Fix test provider event handling on startup - [#30083](https://github.com/storybookjs/storybook/pull/30083), thanks @ghengeveld! +- UI: Keep failing stories in the sidebar, disregarding filters - [#30086](https://github.com/storybookjs/storybook/pull/30086), thanks @JReinhold! + ## 8.5.0-beta.1 - Addon A11y: Add conditional rendering for a11y violation number in Testing Module - [#30073](https://github.com/storybookjs/storybook/pull/30073), thanks @valentinpalkovic! diff --git a/code/addons/test/src/components/TestProviderRender.tsx b/code/addons/test/src/components/TestProviderRender.tsx index bcad8e83b67e..e04772447c43 100644 --- a/code/addons/test/src/components/TestProviderRender.tsx +++ b/code/addons/test/src/components/TestProviderRender.tsx @@ -309,6 +309,7 @@ export const TestProviderRender: FC< href={'/coverage/index.html'} // @ts-expect-error ListItem doesn't include all anchor attributes in types, but it is an achor element target="_blank" + aria-label="Open coverage report" icon={ } - right={coverageSummary.percentage ? `${coverageSummary.percentage}%` : null} + right={ + coverageSummary.percentage ? ( + + {coverageSummary.percentage} % + + ) : null + } /> ) : ( { }, stateUpdater: (state, update) => { - if (!update.details?.testResults) { - return; + const updated = { + ...state, + ...update, + details: { ...state.details, ...update.details }, + }; + + if ((!state.running && update.running) || (!state.watching && update.watching)) { + // Clear coverage data when starting test run or enabling watch mode + delete updated.details.coverageSummary; } - (async () => { - await api.experimental_updateStatus( - TEST_PROVIDER_ID, - Object.fromEntries( - update.details.testResults.flatMap((testResult) => - testResult.results - .filter(({ storyId }) => storyId) - .map(({ storyId, status, testRunId, ...rest }) => [ - storyId, - { - title: 'Component tests', - status: statusMap[status], - description: - 'failureMessages' in rest && rest.failureMessages - ? rest.failureMessages.join('\n') - : '', - data: { testRunId }, - onClick: openTestsPanel, - sidebarContextMenu: false, - } satisfies API_StatusObject, - ]) + if (update.details?.testResults) { + (async () => { + await api.experimental_updateStatus( + TEST_PROVIDER_ID, + Object.fromEntries( + update.details.testResults.flatMap((testResult) => + testResult.results + .filter(({ storyId }) => storyId) + .map(({ storyId, status, testRunId, ...rest }) => [ + storyId, + { + title: 'Component tests', + status: statusMap[status], + description: + 'failureMessages' in rest && rest.failureMessages + ? rest.failureMessages.join('\n') + : '', + data: { testRunId }, + onClick: openTestsPanel, + sidebarContextMenu: false, + } satisfies API_StatusObject, + ]) + ) ) - ) - ); + ); - await api.experimental_updateStatus( - 'storybook/addon-a11y/test-provider', - Object.fromEntries( - update.details.testResults.flatMap((testResult) => - testResult.results - .filter(({ storyId }) => storyId) - .map(({ storyId, testRunId, reports }) => { - const a11yReport = reports.find((r: any) => r.type === 'a11y'); - return [ - storyId, - a11yReport - ? ({ - title: 'Accessibility tests', - description: '', - status: statusMap[a11yReport.status], - data: { testRunId }, - onClick: () => { - api.setSelectedPanel('storybook/a11y/panel'); - api.togglePanel(true); - }, - sidebarContextMenu: false, - } satisfies API_StatusObject) - : null, - ]; - }) + await api.experimental_updateStatus( + 'storybook/addon-a11y/test-provider', + Object.fromEntries( + update.details.testResults.flatMap((testResult) => + testResult.results + .filter(({ storyId }) => storyId) + .map(({ storyId, testRunId, reports }) => { + const a11yReport = reports.find((r: any) => r.type === 'a11y'); + return [ + storyId, + a11yReport + ? ({ + title: 'Accessibility tests', + description: '', + status: statusMap[a11yReport.status], + data: { testRunId }, + onClick: () => { + api.setSelectedPanel('storybook/a11y/panel'); + api.togglePanel(true); + }, + sidebarContextMenu: false, + } satisfies API_StatusObject) + : null, + ]; + }) + ) ) - ) - ); - })(); + ); + })(); + } + + return updated; }, } as Addon_TestProviderType); } diff --git a/code/addons/test/src/node/coverage-reporter.ts b/code/addons/test/src/node/coverage-reporter.ts index 452643cd9d60..cc1dd548000f 100644 --- a/code/addons/test/src/node/coverage-reporter.ts +++ b/code/addons/test/src/node/coverage-reporter.ts @@ -8,7 +8,7 @@ import type { TestManager } from './test-manager'; export type StorybookCoverageReporterOptions = { testManager: TestManager; - coverageOptions: ResolvedCoverageOptions<'v8'>; + coverageOptions: ResolvedCoverageOptions<'v8'> | undefined; }; export default class StorybookCoverageReporter extends ReportBase implements Partial { @@ -32,7 +32,7 @@ export default class StorybookCoverageReporter extends ReportBase implements Par // Fallback to Vitest's default watermarks https://vitest.dev/config/#coverage-watermarks const [lowWatermark = 50, highWatermark = 80] = - this.#coverageOptions.watermarks?.statements ?? []; + this.#coverageOptions?.watermarks?.statements ?? []; const coverageDetails: Details['coverageSummary'] = { percentage, diff --git a/code/addons/test/src/node/test-manager.ts b/code/addons/test/src/node/test-manager.ts index 4770f2b5a174..1595c2da3fa9 100644 --- a/code/addons/test/src/node/test-manager.ts +++ b/code/addons/test/src/node/test-manager.ts @@ -53,14 +53,7 @@ export class TestManager { coverage: this.coverage, }); } catch (e) { - const isV8 = e.message?.includes('@vitest/coverage-v8'); - const isIstanbul = e.message?.includes('@vitest/coverage-istanbul'); - - if (e.message?.includes('Error: Failed to load url') && (isIstanbul || isV8)) { - const coveragePackage = isIstanbul ? 'coverage-istanbul' : 'coverage-v8'; - e.message = `Please install the @vitest/${coveragePackage} package to run with coverage`; - } - this.reportFatalError('Failed to change coverage mode', e); + this.reportFatalError('Failed to change coverage configuration', e); } } } diff --git a/code/addons/test/src/node/vitest-manager.ts b/code/addons/test/src/node/vitest-manager.ts index d55d3bc6d5b1..26dbe16ab526 100644 --- a/code/addons/test/src/node/vitest-manager.ts +++ b/code/addons/test/src/node/vitest-manager.ts @@ -52,7 +52,7 @@ export class VitestManager { join(packageDir, 'dist/node/coverage-reporter.js'), { testManager: this.testManager, - coverageOptions: this.vitest?.config?.coverage as ResolvedCoverageOptions<'v8'>, + coverageOptions: this.vitest?.config?.coverage as ResolvedCoverageOptions<'v8'> | undefined, }, ]; const coverageOptions = ( @@ -89,15 +89,21 @@ export class VitestManager { try { await this.vitest.init(); } catch (e) { + let message = 'Failed to initialize Vitest'; const isV8 = e.message?.includes('@vitest/coverage-v8'); const isIstanbul = e.message?.includes('@vitest/coverage-istanbul'); - if (e.message?.includes('Error: Failed to load url') && (isIstanbul || isV8)) { + if ( + (e.message?.includes('Failed to load url') && (isIstanbul || isV8)) || + // Vitest will sometimes not throw the correct missing-package-detection error, so we have to check for this as well + (e instanceof TypeError && + e?.message === "Cannot read properties of undefined (reading 'name')") + ) { const coveragePackage = isIstanbul ? 'coverage-istanbul' : 'coverage-v8'; - e.message = `Please install the @vitest/${coveragePackage} package to run with coverage`; + message += `\n\nPlease install the @vitest/${coveragePackage} package to collect coverage\n`; } - - this.testManager.reportFatalError('Failed to init Vitest', e); + this.testManager.reportFatalError(message, e); + return; } await this.setupWatchers(); diff --git a/code/core/src/manager-api/lib/stories.test.ts b/code/core/src/manager-api/lib/stories.test.ts index 76aaadd7f99d..3f0cbe63b5be 100644 --- a/code/core/src/manager-api/lib/stories.test.ts +++ b/code/core/src/manager-api/lib/stories.test.ts @@ -2,8 +2,10 @@ import { describe, expect, it } from 'vitest'; import type { API_PreparedStoryIndex, StoryIndexV2, StoryIndexV3 } from '@storybook/core/types'; +import type { State } from '../root'; import { mockEntries } from '../tests/mockStoriesEntries'; import { + transformStoryIndexToStoriesHash, transformStoryIndexV2toV3, transformStoryIndexV3toV4, transformStoryIndexV4toV5, @@ -216,3 +218,60 @@ describe('transformStoryIndexV4toV5', () => { `); }); }); + +describe('transformStoryIndexToStoriesHash', () => { + it('does not apply filters to failing stories', () => { + // Arrange - set up an index with two stories, one of which has a failing status + const indexV5: API_PreparedStoryIndex = { + v: 5, + entries: { + '1': { + id: '1', + type: 'story', + title: 'Story 1', + name: 'Story 1', + importPath: './path/to/story-1.ts', + parameters: {}, + tags: [], + }, + '2': { + id: '2', + type: 'story', + title: 'Story 2', + name: 'Story 2', + importPath: './path/to/story-2.ts', + parameters: {}, + tags: [], + }, + }, + }; + + const filters: State['filters'] = { + someFilter: () => false, + }; + + const status: State['status'] = { + '1': { someStatus: { status: 'error', title: 'broken', description: 'very bad' } }, + '2': { someStatus: { status: 'success', title: 'perfect', description: 'nice' } }, + }; + + const options = { + provider: { + getConfig: () => ({ sidebar: {} }), + } as any, + docsOptions: { docsMode: false }, + filters, + status, + }; + + // Act - transform the index to hashes + const result = transformStoryIndexToStoriesHash(indexV5, options); + + // Assert - the failing story is still present in the result, even though the filters remove all stories + expect(Object.keys(result)).toHaveLength(2); + expect(result['story-1']).toBeTruthy(); + expect(result['1']).toBeTruthy(); + expect(result['story-2']).toBeUndefined(); + expect(result['2']).toBeUndefined(); + }); +}); diff --git a/code/core/src/manager-api/lib/stories.ts b/code/core/src/manager-api/lib/stories.ts index 28fbc190853b..b38d30000531 100644 --- a/code/core/src/manager-api/lib/stories.ts +++ b/code/core/src/manager-api/lib/stories.ts @@ -192,11 +192,17 @@ export const transformStoryIndexToStoriesHash = ( const entryValues = Object.values(index.entries).filter((entry: any) => { let result = true; + // All stories with a failing status should always show up, regardless of the applied filters + const storyStatus = status[entry.id]; + if (Object.values(storyStatus ?? {}).some(({ status: s }) => s === 'error')) { + return result; + } + Object.values(filters).forEach((filter: any) => { if (result === false) { return; } - result = filter({ ...entry, status: status[entry.id] }); + result = filter({ ...entry, status: storyStatus }); }); return result; diff --git a/code/core/src/manager/components/sidebar/SidebarBottom.tsx b/code/core/src/manager/components/sidebar/SidebarBottom.tsx index 37a872810a6a..38efdae4f682 100644 --- a/code/core/src/manager/components/sidebar/SidebarBottom.tsx +++ b/code/core/src/manager/components/sidebar/SidebarBottom.tsx @@ -1,7 +1,7 @@ -import React, { Fragment, useEffect, useRef, useState } from 'react'; +import React, { Fragment, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { styled } from '@storybook/core/theming'; -import { type API_FilterFunction, type API_StatusValue } from '@storybook/core/types'; +import { type API_FilterFunction } from '@storybook/core/types'; import { TESTING_MODULE_CRASH_REPORT, @@ -119,7 +119,8 @@ export const SidebarBottomBase = ({ api.experimental_setFilter('sidebar-bottom-filter', filter); }, [api, hasWarnings, hasErrors, warningsActive, errorsActive]); - useEffect(() => { + // Register listeners before the first render + useLayoutEffect(() => { const onCrashReport = ({ providerId, ...details }: TestingModuleCrashReportPayload) => { api.updateTestProviderState(providerId, { error: { name: 'Crashed!', message: details.error.message }, diff --git a/code/package.json b/code/package.json index 6d52c3061cf1..dab85e1bcdc0 100644 --- a/code/package.json +++ b/code/package.json @@ -90,7 +90,7 @@ "type-fest": "~2.19" }, "dependencies": { - "@chromatic-com/storybook": "^3.2.0", + "@chromatic-com/storybook": "^3.2.2", "@happy-dom/global-registrator": "^14.12.0", "@nx/eslint": "20.2.2", "@nx/vite": "20.2.2", @@ -294,5 +294,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.5.0-beta.2" } diff --git a/code/yarn.lock b/code/yarn.lock index 87e41b6b5a15..2e83b8e16192 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -2532,21 +2532,18 @@ __metadata: languageName: node linkType: hard -"@chromatic-com/storybook@npm:^3.2.0": - version: 3.2.0 - resolution: "@chromatic-com/storybook@npm:3.2.0" +"@chromatic-com/storybook@npm:^3.2.2": + version: 3.2.2 + resolution: "@chromatic-com/storybook@npm:3.2.2" dependencies: - "@storybook/channels": "npm:^8.3.0" - "@storybook/telemetry": "npm:^8.3.0" - "@storybook/types": "npm:^8.3.0" chromatic: "npm:^11.15.0" filesize: "npm:^10.0.12" jsonfile: "npm:^6.1.0" react-confetti: "npm:^6.1.0" strip-ansi: "npm:^7.1.0" peerDependencies: - storybook: "*" - checksum: 10c0/59485e69a55df6b1998e19bf0e129fa1f9a86d3ae541f4dcb6f6dd945e7b9a6258ce75e244aaa73821039cef8c57424402a3c0bf63a66b4511a2ac0b5611103b + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + checksum: 10c0/7b8da1ddb399c804337ff28a28594b548392b7bead52f66615b98e201cdeb4d31184b9e355791ba5d0d8cfdd2bea7d38355ecd0058f26f4790f9a887107bde0f languageName: node linkType: hard @@ -6037,15 +6034,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/channels@npm:^8.3.0": - version: 8.3.6 - resolution: "@storybook/channels@npm:8.3.6" - peerDependencies: - storybook: ^8.3.6 - checksum: 10c0/3c34ed2b03c60c6ed1160d9a0efdb836be892e333556848ff492c16ab6d92521207512670d42f69d681f521e50f130a00f692610a3ca63228a8d2b49be57f4fa - languageName: node - linkType: hard - "@storybook/channels@workspace:deprecated/channels": version: 0.0.0-use.local resolution: "@storybook/channels@workspace:deprecated/channels" @@ -7035,7 +7023,7 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/root@workspace:." dependencies: - "@chromatic-com/storybook": "npm:^3.2.0" + "@chromatic-com/storybook": "npm:^3.2.2" "@happy-dom/global-registrator": "npm:^14.12.0" "@nx/eslint": "npm:20.2.2" "@nx/vite": "npm:20.2.2" @@ -7325,15 +7313,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/telemetry@npm:^8.3.0": - version: 8.3.6 - resolution: "@storybook/telemetry@npm:8.3.6" - peerDependencies: - storybook: ^8.3.6 - checksum: 10c0/b4fd8d0e238335249aa82dea49bde56813e0c771e67dd7110fb9e038d1e2bd64aa03e76ee865ef6a7f0fd5220d02bd7bcf3273bb4c19403e3d527d9dd7a258d4 - languageName: node - linkType: hard - "@storybook/telemetry@workspace:deprecated/telemetry": version: 0.0.0-use.local resolution: "@storybook/telemetry@workspace:deprecated/telemetry" @@ -7383,15 +7362,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/types@npm:^8.3.0": - version: 8.3.6 - resolution: "@storybook/types@npm:8.3.6" - peerDependencies: - storybook: ^8.3.6 - checksum: 10c0/482f55e34877f9eb94a8ff4627a254f3b5442f91f13363e6837e3a9c220a369be1c6ce4652b870b7fa4e522c3365825651f9e04a21bda76b104a6c1f7435e274 - languageName: node - linkType: hard - "@storybook/types@workspace:*, @storybook/types@workspace:deprecated/types": version: 0.0.0-use.local resolution: "@storybook/types@workspace:deprecated/types" diff --git a/docs/versions/next.json b/docs/versions/next.json index ac38904a3bb2..7399d21ebb8d 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.5.0-beta.1","info":{"plain":"- Addon A11y: Add conditional rendering for a11y violation number in Testing Module - [#30073](https://github.com/storybookjs/storybook/pull/30073), thanks @valentinpalkovic!\n- Addon A11y: Remove warnings API - [#30049](https://github.com/storybookjs/storybook/pull/30049), thanks @kasperpeulen!\n- Addon A11y: Show errors of axe properly - [#30050](https://github.com/storybookjs/storybook/pull/30050), thanks @kasperpeulen!\n- Addon Test: Fix printing null% for coverage - [#30061](https://github.com/storybookjs/storybook/pull/30061), thanks @ghengeveld!\n- Telemetry: Add metadata distinguishing \\\"apps\\\" from \\\"design systems\\\" - [#30070](https://github.com/storybookjs/storybook/pull/30070), thanks @tmeasday!"}} +{"version":"8.5.0-beta.2","info":{"plain":"- Addon Test: Clear coverage data when starting or watching - [#30072](https://github.com/storybookjs/storybook/pull/30072), thanks @ghengeveld!\n- Addon Test: Improve error message on missing coverage package - [#30088](https://github.com/storybookjs/storybook/pull/30088), thanks @JReinhold!\n- UI: Fix test provider event handling on startup - [#30083](https://github.com/storybookjs/storybook/pull/30083), thanks @ghengeveld!\n- UI: Keep failing stories in the sidebar, disregarding filters - [#30086](https://github.com/storybookjs/storybook/pull/30086), thanks @JReinhold!"}} diff --git a/test-storybooks/portable-stories-kitchen-sink/react/.storybook/aliased.ts b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/aliased.ts new file mode 100644 index 000000000000..030574bfd2a6 --- /dev/null +++ b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/aliased.ts @@ -0,0 +1,4 @@ +// This file is used to test that viteFinal is correctly loaded in Vitest +// main.ts defines this file as a resolve alias, which is used in the ViteFinalTest story + +export const aliasedFunction = () => true; diff --git a/test-storybooks/portable-stories-kitchen-sink/react/.storybook/main.ts b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/main.ts index 57b96d2e8d1e..fff0f008dd37 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/.storybook/main.ts +++ b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/main.ts @@ -1,4 +1,5 @@ import type { StorybookConfig } from "@storybook/react-vite"; +import { join } from 'path'; const config: StorybookConfig = { stories: ["../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"], @@ -32,5 +33,18 @@ const config: StorybookConfig = { border: 1px solid red; } `, + staticDirs: [{ from: './test-static-dirs', to:'test-static-dirs' }], + viteFinal: (config) => { + return { + ...config, + resolve: { + ...config.resolve, + alias: { + ...config.resolve?.alias, + 'test-alias': join(__dirname, 'aliased.ts'), + }, + } + }; + }, }; export default config; diff --git a/test-storybooks/portable-stories-kitchen-sink/react/.storybook/test-static-dirs/static.js b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/test-static-dirs/static.js new file mode 100644 index 000000000000..56ff9f9c7ad4 --- /dev/null +++ b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/test-static-dirs/static.js @@ -0,0 +1,3 @@ +// This file is used to test that staticDirs are correctly loaded in Vitest + +export const staticFunction = () => true; diff --git a/test-storybooks/portable-stories-kitchen-sink/react/e2e-tests/component-testing.spec.ts b/test-storybooks/portable-stories-kitchen-sink/react/e2e-tests/component-testing.spec.ts index ed3eebbbae59..9e88b7d0a579 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/e2e-tests/component-testing.spec.ts +++ b/test-storybooks/portable-stories-kitchen-sink/react/e2e-tests/component-testing.spec.ts @@ -6,16 +6,13 @@ import { expect, test } from "@playwright/test"; import { SbPage } from "../../../../code/e2e-tests/util"; -const storybookUrl = "http://localhost:6006"; -const testStoryPath = path.resolve( - __dirname, - "..", - "stories/AddonTest.stories.tsx" -); +const STORYBOOK_URL = "http://localhost:6006"; +const TEST_STORY_PATH = path.resolve(__dirname, "..", "stories", "AddonTest.stories.tsx"); +const BUTTON_COMPONENT_PATH = path.resolve(__dirname, "..", "stories", "Button.tsx"); const setForceFailureFlag = async (value: boolean) => { // Read the story file content asynchronously - const storyContent = (await fs.readFile(testStoryPath)).toString(); + const storyContent = (await fs.readFile(TEST_STORY_PATH)).toString(); // Create a regex to match 'forceFailure: true' or 'forceFailure: false' const forceFailureRegex = /forceFailure:\s*(true|false)/; @@ -27,7 +24,7 @@ const setForceFailureFlag = async (value: boolean) => { ); // Write the updated content back to the file asynchronously - await fs.writeFile(testStoryPath, updatedContent); + await fs.writeFile(TEST_STORY_PATH, updatedContent); // the file change causes a HMR event, which causes a browser reload,and that can take a few seconds await new Promise((resolve) => setTimeout(resolve, 2000)); @@ -38,7 +35,7 @@ test.describe("component testing", () => { test.beforeEach(async ({ page }) => { const sbPage = new SbPage(page, expect); - await page.goto(storybookUrl); + await page.goto(STORYBOOK_URL); await page.evaluate(() => window.sessionStorage.clear()); await sbPage.waitUntilLoaded(); }); @@ -48,9 +45,10 @@ test.describe("component testing", () => { browserName, }) => { test.skip(browserName !== "chromium", `Skipping tests for ${browserName}`); + test.setTimeout(40_000) const sbPage = new SbPage(page, expect); - await sbPage.navigateToStory("addons/test", "Mismatch Failure"); + await sbPage.navigateToStory("addons/group/test", "Mismatch Failure"); const expandButton = await page.getByLabel('Expand testing module') await expandButton.click(); @@ -89,7 +87,7 @@ test.describe("component testing", () => { // Assert discrepancy: CLI pass + Browser fail const failingStoryElement = page.locator( - '[data-item-id="addons-test--mismatch-failure"] [role="status"]' + '[data-item-id="addons-group-test--mismatch-failure"] [role="status"]' ); await expect(failingStoryElement).toHaveAttribute( "aria-label", @@ -100,9 +98,9 @@ test.describe("component testing", () => { ); // Assert discrepancy: CLI fail + Browser pass - await sbPage.navigateToStory("addons/test", "Mismatch Success"); + await sbPage.navigateToStory("addons/group/test", "Mismatch Success"); const successfulStoryElement = page.locator( - '[data-item-id="addons-test--mismatch-success"] [role="status"]' + '[data-item-id="addons-group-test--mismatch-success"] [role="status"]' ); await expect(successfulStoryElement).toHaveAttribute( "aria-label", @@ -121,7 +119,7 @@ test.describe("component testing", () => { await setForceFailureFlag(true); const sbPage = new SbPage(page, expect); - await sbPage.navigateToStory("addons/test", "Expected Failure"); + await sbPage.navigateToStory("addons/group/test", "Expected Failure"); const expandButton = page.getByLabel('Expand testing module') await expandButton.click(); @@ -159,7 +157,7 @@ test.describe("component testing", () => { // Assert for expected success const successfulStoryElement = page.locator( - '[data-item-id="addons-test--expected-success"] [role="status"]' + '[data-item-id="addons-group-test--expected-success"] [role="status"]' ); await expect(successfulStoryElement).toHaveAttribute( "aria-label", @@ -168,7 +166,7 @@ test.describe("component testing", () => { // Assert for expected failure const failingStoryElement = page.locator( - '[data-item-id="addons-test--expected-failure"] [role="status"]' + '[data-item-id="addons-group-test--expected-failure"] [role="status"]' ); await expect(failingStoryElement).toHaveAttribute( "aria-label", @@ -181,7 +179,7 @@ test.describe("component testing", () => { const sidebarItems = page.locator( '.sidebar-item[data-ref-id="storybook_internal"][data-nodetype="component"]' ); - await expect(sidebarItems).toHaveCount(1); + await expect(sidebarItems).toHaveCount(2); }); test("should execute watch mode tests via testing module UI", async ({ @@ -192,7 +190,7 @@ test.describe("component testing", () => { await setForceFailureFlag(false); const sbPage = new SbPage(page, expect); - await sbPage.navigateToStory("addons/test", "Expected Failure"); + await sbPage.navigateToStory("addons/group/test", "Expected Failure"); const expandButton = await page.getByLabel('Expand testing module') await expandButton.click(); @@ -207,8 +205,11 @@ test.describe("component testing", () => { // We shouldn't have to do an arbitrary wait, but because there is no UI for loading state yet, we have to await page.waitForTimeout(8000); - await setForceFailureFlag(true); + await page.waitForTimeout(500); + + // Cleanup, to ensure watch mode is disabled in the other tests + await page.getByLabel("Disable watch mode for Component tests").click(); // Wait for test results to appear const errorFilter = page.getByLabel("Toggle errors"); @@ -216,7 +217,7 @@ test.describe("component testing", () => { // Assert for expected success const successfulStoryElement = page.locator( - '[data-item-id="addons-test--expected-success"] [role="status"]' + '[data-item-id="addons-group-test--expected-success"] [role="status"]' ); await expect(successfulStoryElement).toHaveAttribute( "aria-label", @@ -225,7 +226,7 @@ test.describe("component testing", () => { // Assert for expected failure const failingStoryElement = page.locator( - '[data-item-id="addons-test--expected-failure"] [role="status"]' + '[data-item-id="addons-group-test--expected-failure"] [role="status"]' ); await expect(failingStoryElement).toHaveAttribute( "aria-label", @@ -240,4 +241,223 @@ test.describe("component testing", () => { ); await expect(sidebarItems).toHaveCount(1); }); + + test("should collect coverage to testing module and HTML report", async ({ + page, + browserName, + }) => { + test.skip(browserName !== "chromium", `Skipping tests for ${browserName}`); + // Arrange - Prepare Storybook + await setForceFailureFlag(false); + + const sbPage = new SbPage(page, expect); + await sbPage.navigateToStory("addons/group/test", "Expected Failure"); + + const expandButton = await page.getByLabel('Expand testing module') + await expandButton.click(); + + const storyElement = sbPage + .getCanvasBodyElement() + .getByRole("button", { name: "test" }); + await expect(storyElement).toBeVisible({ timeout: 30000 }); + + // Assert - No coverage report initially + await expect(page.getByLabel("Open coverage report")).toHaveCount(0); + + // Act - Enable coverage and run tests + await page.getByLabel("Open settings for Component tests").click(); + await page.getByLabel("Coverage").click(); + await expect(page.getByText("Settings updated")).toBeVisible({ timeout: 3000 }); + await page.getByLabel("Close settings for Component tests").click(); + // Wait for Vitest to have (re)started + await page.waitForTimeout(2000); + + await page.getByLabel("Start Component tests").click(); + + // Assert - Coverage report is collected and shown + await expect(page.getByLabel("Open coverage report")).toBeVisible({ timeout: 30000 }); + const sbPercentageText = await page.getByLabel(/percent coverage$/).textContent(); + expect(sbPercentageText).toMatch(/^\d+\s%$/); + const sbPercentage = Number.parseInt(sbPercentageText!.replace(' %', '') ?? ''); + expect(sbPercentage).toBeGreaterThanOrEqual(0); + expect(sbPercentage).toBeLessThanOrEqual(100); + + // Act - Open HTML coverage report + const coverageReportLink = await page.getByLabel("Open coverage report"); + // Remove target="_blank" attribute to open in the same tab + await coverageReportLink.evaluate((elem) => elem.removeAttribute("target")); + await page.getByLabel("Open coverage report").click(); + + // Assert - HTML coverage report is accessible and reports the same coverage percentage as Storybook + const htmlPercentageText = await page.locator('span:has(+ :text("Statements"))').first().textContent() ?? ''; + const htmlPercentage = Number.parseFloat(htmlPercentageText.replace('% ', '')); + expect(Math.round(htmlPercentage)).toBe(sbPercentage); + + // Cleanup - Disable coverage again + await page.goBack(); + await expandButton.click(); + await page.getByLabel("Open settings for Component tests").click(); + await page.getByLabel("Coverage").click(); + await expect(page.getByText("Settings updated")).toBeVisible({ timeout: 3000 }); + }); + + test("should run focused test for a single story", async ({ + page, + browserName, + }) => { + test.skip(browserName !== "chromium", `Skipping tests for ${browserName}`); + // Arrange - Prepare Storybook + await setForceFailureFlag(false); + + const sbPage = new SbPage(page, expect); + await sbPage.navigateToStory("addons/group/test", "Expected Failure"); + + const expandButton = await page.getByLabel('Expand testing module') + await expandButton.click(); + + const storyElement = sbPage + .getCanvasBodyElement() + .getByRole("button", { name: "test" }); + await expect(storyElement).toBeVisible({ timeout: 30000 }); + + // Act - Open sidebar context menu and start focused test + await page.locator('[data-item-id="addons-group-test--expected-failure"]').hover(); + await page.locator('[data-item-id="addons-group-test--expected-failure"] div[data-testid="context-menu"] button').click(); + const sidebarContextMenu = page.getByTestId('tooltip'); + await sidebarContextMenu.getByLabel('Start Component tests').click(); + + // Assert - Only one test is running and reported + await expect(sidebarContextMenu.locator('#testing-module-description')).toContainText('Ran 1 test', { timeout: 30000 }); + await expect(sidebarContextMenu.getByLabel('status: passed')).toHaveCount(1); + await page.click('body'); + await expect(page.locator('#storybook-explorer-menu').getByRole('status', { name: 'Test status: success' })).toHaveCount(1); + }); + + test("should run focused test for a component", async ({ + page, + browserName, + }) => { + test.skip(browserName !== "chromium", `Skipping tests for ${browserName}`); + // Arrange - Prepare Storybook + await setForceFailureFlag(false); + + const sbPage = new SbPage(page, expect); + await sbPage.navigateToStory("addons/group/test", "Expected Failure"); + + const expandButton = await page.getByLabel('Expand testing module') + await expandButton.click(); + + const storyElement = sbPage + .getCanvasBodyElement() + .getByRole("button", { name: "test" }); + await expect(storyElement).toBeVisible({ timeout: 30000 }); + + // Act - Open sidebar context menu and start focused test + await page.locator('[data-item-id="addons-group-test"]').hover(); + await page.locator('[data-item-id="addons-group-test"] div[data-testid="context-menu"] button').click(); + const sidebarContextMenu = page.getByTestId('tooltip'); + await sidebarContextMenu.getByLabel('Start Component tests').click(); + + // Assert - Tests are running and reported + await expect(sidebarContextMenu.locator('#testing-module-description')).toContainText('Ran 8 tests', { timeout: 30000 }); + // Assert - Failing test shows as a failed status + await expect(sidebarContextMenu.getByText('1 story with errors')).toBeVisible(); + await expect(sidebarContextMenu.getByLabel('status: failed')).toHaveCount(1); + + await page.click('body'); + await expect(page.locator('#storybook-explorer-menu').getByRole('status', { name: 'Test status: success' })).toHaveCount(7); + await expect(page.locator('#storybook-explorer-menu').getByRole('status', { name: 'Test status: error' })).toHaveCount(1); + }); + + test("should run focused test for a group", async ({ + page, + browserName, + }) => { + test.skip(browserName !== "chromium", `Skipping tests for ${browserName}`); + // Arrange - Prepare Storybook + await setForceFailureFlag(false); + + const sbPage = new SbPage(page, expect); + await sbPage.navigateToStory("addons/group/test", "Expected Failure"); + + const expandButton = await page.getByLabel('Expand testing module') + await expandButton.click(); + + const storyElement = sbPage + .getCanvasBodyElement() + .getByRole("button", { name: "test" }); + await expect(storyElement).toBeVisible({ timeout: 30000 }); + + // Act - Open sidebar context menu and start focused test + await page.locator('[data-item-id="addons-group"]').hover(); + await page.locator('[data-item-id="addons-group"] div[data-testid="context-menu"] button').click(); + const sidebarContextMenu = page.getByTestId('tooltip'); + await sidebarContextMenu.getByLabel('Start Component tests').click(); + + // Assert - Tests are running and reported + await expect(sidebarContextMenu.locator('#testing-module-description')).toContainText('Ran 10 test', { timeout: 30000 }); + // Assert - 1 failing test shows as a failed status + await expect(sidebarContextMenu.getByText('2 stories with errors')).toBeVisible(); + await expect(sidebarContextMenu.getByLabel('status: failed')).toHaveCount(1); + + await page.click('body'); + await expect(page.locator('#storybook-explorer-menu').getByRole('status', { name: 'Test status: success' })).toHaveCount(7); + await expect(page.locator('#storybook-explorer-menu').getByRole('status', { name: 'Test status: error' })).toHaveCount(1); + }); + + test("should run focused tests without coverage, even when enabled", async ({ + page, + browserName, + }) => { + test.skip(browserName !== "chromium", `Skipping tests for ${browserName}`); + // Arrange - Prepare Storybook + await setForceFailureFlag(false); + + const sbPage = new SbPage(page, expect); + await sbPage.navigateToStory("example/button", "CSF 3 Primary"); + + const expandButton = await page.getByLabel('Expand testing module') + await expandButton.click(); + + const storyElement = sbPage + .getCanvasBodyElement() + .getByRole("button", { name: "foo" }); + await expect(storyElement).toBeVisible({ timeout: 30000 }); + + // Act - Enable coverage + await page.getByLabel("Open settings for Component tests").click(); + await page.getByLabel("Coverage").click(); + await expect(page.getByText("Settings updated")).toBeVisible({ timeout: 3000 }); + await page.getByLabel("Close settings for Component tests").click(); + // Wait for Vitest to have (re)started + await page.waitForTimeout(2000); + + // Act - Open sidebar context menu and start focused test + await page.locator('[data-item-id="example-button--csf-3-primary"]').hover(); + await page.locator('[data-item-id="example-button--csf-3-primary"] div[data-testid="context-menu"] button').click(); + const sidebarContextMenu = page.getByTestId('tooltip'); + await sidebarContextMenu.getByLabel('Start Component tests').click(); + + // Arrange - Wait for test to finish and unfocus sidebar context menu + await expect(sidebarContextMenu.locator('#testing-module-description')).toContainText('Ran 1 test', { timeout: 30000 }); + await page.click('body'); + + // Assert - Coverage is not shown because Focused Tests shouldn't collect coverage + await expect(page.getByLabel("Open coverage report")).not.toBeVisible(); + + // Act - Run ALL tests + await page.getByLabel("Start Component tests").click(); + + // Arrange - Wait for tests to finish + await expect(page.locator('#testing-module-description')).toContainText(/Ran \d{2,} tests/, { timeout: 30000 }); + + // Assert - Coverage percentage is now collected and shown because running all tests automatically re-enables coverage + await expect(page.getByLabel("Open coverage report")).toBeVisible({ timeout: 30000 }); + const sbPercentageText = await page.getByLabel(/percent coverage$/).textContent(); + expect(sbPercentageText).toMatch(/^\d+\s%$/); + const sbPercentage = Number.parseInt(sbPercentageText!.replace(' %', '') ?? ''); + expect(sbPercentage).toBeGreaterThanOrEqual(0); + expect(sbPercentage).toBeLessThanOrEqual(100); + }); + }); diff --git a/test-storybooks/portable-stories-kitchen-sink/react/package.json b/test-storybooks/portable-stories-kitchen-sink/react/package.json index 8f392f7f1add..383364e5909a 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/package.json +++ b/test-storybooks/portable-stories-kitchen-sink/react/package.json @@ -12,8 +12,8 @@ "playwright-ct": "playwright test -c playwright-ct.config.ts", "playwright-e2e": "playwright test -c playwright-e2e.config.ts", "preview": "vite preview", - "storybook": "storybook dev -p 6006", - "vitest": "echo 'not running'" + "storybook": "NODE_OPTIONS=\"--preserve-symlinks --preserve-symlinks-main\" storybook dev -p 6006", + "vitest": "SKIP_FAIL_ON_PURPOSE=true vitest run" }, "resolutions": { "@playwright/test": "1.48.1", @@ -110,6 +110,8 @@ "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react": "^4.2.1", "@vitest/browser": "^2.1.3", + "@vitest/coverage-v8": "^2.1.3", + "@vitest/ui": "^2.1.3", "cypress": "^13.6.4", "eslint": "^8.56.0", "eslint-plugin-react-hooks": "^4.6.0", diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/AddonTest.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/react/stories/AddonTest.stories.tsx index 365ed4da0e6b..650b091b33cb 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/stories/AddonTest.stories.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/AddonTest.stories.tsx @@ -1,24 +1,28 @@ -import { Meta } from '@storybook/react' +import { expect } from '@storybook/test'; +import { Meta, type StoryObj } from '@storybook/react' import { instrument } from '@storybook/instrumenter' -import type { StoryAnnotations } from 'storybook/internal/types'; declare global { - // eslint-disable-next-line no-var, @typescript-eslint/naming-convention + // eslint-disable-next-line no-var var __vitest_browser__: boolean; } const Component = () => -export default { - title: 'Addons/Test', +const meta = { + title: 'Addons/Group/Test', component: Component, } as Meta; +export default meta; + +type Story = StoryObj; + const { pass } = instrument({ pass: async () => {}, }, { intercept: true }) -export const ExpectedFailure = { +export const ExpectedFailure: Story = { args: { forceFailure: false, }, @@ -28,34 +32,61 @@ export const ExpectedFailure = { throw new Error('Expected failure'); } } -} satisfies StoryAnnotations; +}; -export const ExpectedSuccess = { +export const ExpectedSuccess: Story = { play: async () => { await pass(); } -} satisfies StoryAnnotations; +}; -export const LongRunning = { +export const LongRunning: Story = { loaders: [async () => new Promise((resolve) => setTimeout(resolve, 800))], -} satisfies StoryAnnotations; +}; // Tests will pass in browser, but fail in CLI -export const MismatchFailure = { +export const MismatchFailure: Story = { play: async () => { await pass(); if(!globalThis.__vitest_browser__) { throw new Error('Expected failure'); } } -} satisfies StoryAnnotations; +}; // Tests will fail in browser, but pass in CLI -export const MismatchSuccess = { +export const MismatchSuccess: Story = { play: async () => { await pass(); if(globalThis.__vitest_browser__) { throw new Error('Unexpected success'); } + }, + tags: ['fail-on-purpose'], +}; + +export const PreviewHeadTest: Story = { + play: async () => { + const styles = window.getComputedStyle(document.body); + // set in preview-head.html + expect(styles.backgroundColor).toBe('rgb(250, 250, 210)'); + // set in main.js#previewHead + expect(styles.borderColor).toBe('rgb(255, 0, 0)'); } -} satisfies StoryAnnotations; \ No newline at end of file +}; + +export const StaticDirTest: Story = { + play: async () => { + const path = '/test-static-dirs/static.js'; + const { staticFunction } = await import(/* @vite-ignore */path); + expect(staticFunction()).toBe(true); + } +} + +export const ViteFinalTest: Story = { + play: async () => { + // @ts-expect-error TS doesn't know about the alias + const { aliasedFunction } = await import('test-alias'); + expect(aliasedFunction()).toBe(true); + } +} diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx index db4590c82fab..ee201e587159 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ + import { createTest } from '@storybook/react/experimental-playwright'; import { test as base, expect } from '@playwright/experimental-ct-react'; import stories, { SingleComposedStory, WithSpanishGlobal } from './Button.stories.playwright'; diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.tsx index 9d2cf8230964..2c976b43cc43 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.tsx @@ -67,6 +67,8 @@ export const CSF3Primary: CSF3Story = { size: 'large', primary: true, }, + // Accessibility is failing for the Button + tags: ['fail-on-purpose'], }; export const CSF3Button: CSF3Story = { diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/OtherComponent.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/react/stories/OtherComponent.stories.tsx new file mode 100644 index 000000000000..dd410fe9c748 --- /dev/null +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/OtherComponent.stories.tsx @@ -0,0 +1,22 @@ +import { Meta, type StoryObj } from '@storybook/react' + +const Component = () => + +const meta = { + title: 'Addons/Group/Other', + component: Component, +} as Meta; + +export default meta; + +type Story = StoryObj; + +export const Passes: Story = { +}; + +export const Fails: Story = { + play: async () => { + throw new Error('Expected failure'); + }, + tags: ['fail-on-purpose'], +}; diff --git a/test-storybooks/portable-stories-kitchen-sink/react/vitest.workspace.ts b/test-storybooks/portable-stories-kitchen-sink/react/vitest.workspace.ts index 041918fb126d..effd954bd780 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/vitest.workspace.ts +++ b/test-storybooks/portable-stories-kitchen-sink/react/vitest.workspace.ts @@ -5,7 +5,11 @@ export default defineWorkspace([ { extends: "vite.config.ts", plugins: [ - storybookTest(), + storybookTest(process.env.SKIP_FAIL_ON_PURPOSE ? { + tags: { + exclude: ["fail-on-purpose"], + } + } : undefined), ], test: { name: "storybook", diff --git a/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock index e3484dc01721..b8242119352f 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock +++ b/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock @@ -12,7 +12,7 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": +"@ampproject/remapping@npm:^2.2.0, @ampproject/remapping@npm:^2.3.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" dependencies: @@ -135,6 +135,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-string-parser@npm:7.25.9" + checksum: 10/c28656c52bd48e8c1d9f3e8e68ecafd09d949c57755b0d353739eb4eae7ba4f7e67e92e4036f1cd43378cc1397a2c943ed7bcaf5949b04ab48607def0258b775 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-validator-identifier@npm:7.25.7" @@ -142,6 +149,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-validator-identifier@npm:7.25.9" + checksum: 10/3f9b649be0c2fd457fa1957b694b4e69532a668866b8a0d81eabfa34ba16dbf3107b39e0e7144c55c3c652bf773ec816af8df4a61273a2bb4eb3145ca9cf478e + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-validator-option@npm:7.25.7" @@ -182,6 +196,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.25.4": + version: 7.26.2 + resolution: "@babel/parser@npm:7.26.2" + dependencies: + "@babel/types": "npm:^7.26.0" + bin: + parser: ./bin/babel-parser.js + checksum: 10/8baee43752a3678ad9f9e360ec845065eeee806f1fdc8e0f348a8a0e13eef0959dabed4a197c978896c493ea205c804d0a1187cc52e4a1ba017c7935bab4983d + languageName: node + linkType: hard + "@babel/plugin-syntax-async-generators@npm:^7.8.4": version: 7.8.4 resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" @@ -437,6 +462,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.25.4, @babel/types@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/types@npm:7.26.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.25.9" + "@babel/helper-validator-identifier": "npm:^7.25.9" + checksum: 10/40780741ecec886ed9edae234b5eb4976968cc70d72b4e5a40d55f83ff2cc457de20f9b0f4fe9d858350e43dab0ea496e7ef62e2b2f08df699481a76df02cd6e + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -444,12 +479,12 @@ __metadata: languageName: node linkType: hard -"@bundled-es-modules/cookie@npm:^2.0.0": - version: 2.0.0 - resolution: "@bundled-es-modules/cookie@npm:2.0.0" +"@bundled-es-modules/cookie@npm:^2.0.1": + version: 2.0.1 + resolution: "@bundled-es-modules/cookie@npm:2.0.1" dependencies: - cookie: "npm:^0.5.0" - checksum: 10/c8ef02aa5d3f6c786cfa407e1c93b4af29c600eb09990973f47a7a49e4771c1bec37c8f8e567638bb9cbc41f4e38d065ff1d8eaf9bf91f0c3613a6d60bc82c8c + cookie: "npm:^0.7.2" + checksum: 10/0038a5e82c41bfcd722afedabeb6961a5f15747b3681d7f4b61e35eb1e33130039e10ee9250dc9c9e4d3915ce1aeee717c0fb92225111574f0a030411abc0987 languageName: node linkType: hard @@ -911,58 +946,48 @@ __metadata: languageName: node linkType: hard -"@inquirer/confirm@npm:^3.0.0": - version: 3.2.0 - resolution: "@inquirer/confirm@npm:3.2.0" +"@inquirer/confirm@npm:^5.0.0": + version: 5.0.2 + resolution: "@inquirer/confirm@npm:5.0.2" dependencies: - "@inquirer/core": "npm:^9.1.0" - "@inquirer/type": "npm:^1.5.3" - checksum: 10/6b032a26c64075dc14769558720b17f09bc6784a223bbf2c85ec42e491be6ce4c4b83518433c47e05d7e8836ba680ab1b2f6b9c553410d4326582308a1fd2259 + "@inquirer/core": "npm:^10.1.0" + "@inquirer/type": "npm:^3.0.1" + peerDependencies: + "@types/node": ">=18" + checksum: 10/4e775b80b689adeb0b2852ed79b368ef23a82fe3d5f580a562f4af7cdf002a19e0ec1b3b95acc6d49427a72c0fcb5b6548e0cdcafe2f0d3f3d6a923e04aabd0c languageName: node linkType: hard -"@inquirer/core@npm:^9.1.0": - version: 9.2.1 - resolution: "@inquirer/core@npm:9.2.1" +"@inquirer/core@npm:^10.1.0": + version: 10.1.0 + resolution: "@inquirer/core@npm:10.1.0" dependencies: - "@inquirer/figures": "npm:^1.0.6" - "@inquirer/type": "npm:^2.0.0" - "@types/mute-stream": "npm:^0.0.4" - "@types/node": "npm:^22.5.5" - "@types/wrap-ansi": "npm:^3.0.0" + "@inquirer/figures": "npm:^1.0.8" + "@inquirer/type": "npm:^3.0.1" ansi-escapes: "npm:^4.3.2" cli-width: "npm:^4.1.0" - mute-stream: "npm:^1.0.0" + mute-stream: "npm:^2.0.0" signal-exit: "npm:^4.1.0" strip-ansi: "npm:^6.0.1" wrap-ansi: "npm:^6.2.0" yoctocolors-cjs: "npm:^2.1.2" - checksum: 10/bf35e46e70add8ffa9e9d4ae6b528ac660484afca082bca31af95ce8a145a2f8c8d0d07cc7a8627771452e68ade9849c9c9c450a004133ed10ac2d6730900452 + checksum: 10/5d097d0484c1b758f788b792d29395199bdc84af3e8cd4d9273e31de2c5202839b6edf299056956044ba7fb097c4cee7b5c0288e094a380c045082b044f9946e languageName: node linkType: hard -"@inquirer/figures@npm:^1.0.6": - version: 1.0.7 - resolution: "@inquirer/figures@npm:1.0.7" - checksum: 10/ce896860de9d822a7c2a212667bcfd0f04cf2ce86d9a2411cc9c077bb59cd61732cb5f72ac66e88d52912466eec433f005bf8a25efa658f41e1a32f3977080bd - languageName: node - linkType: hard - -"@inquirer/type@npm:^1.5.3": - version: 1.5.5 - resolution: "@inquirer/type@npm:1.5.5" - dependencies: - mute-stream: "npm:^1.0.0" - checksum: 10/bd3f3d7510785af4ad599e042e99e4be6380f52f79f3db140fe6fed0a605acf27b1a0a20fb5cc688eaf7b8aa0c36dacb1d89c7bba4586f38cbf58ba9f159e7b5 +"@inquirer/figures@npm:^1.0.8": + version: 1.0.8 + resolution: "@inquirer/figures@npm:1.0.8" + checksum: 10/0e5e4fbb15e799e818c598fcc3558ef076daf78662149711b046723fd6316381e95f7d5573d6ef0062095ad22c6ac98833033f0948df5c722932107a567fd9c3 languageName: node linkType: hard -"@inquirer/type@npm:^2.0.0": - version: 2.0.0 - resolution: "@inquirer/type@npm:2.0.0" - dependencies: - mute-stream: "npm:^1.0.0" - checksum: 10/e85f359866c28cce06272d2d51cc17788a5c9de9fda7f181c27775dd26821de0dacbc947b521cfe2009cd2965ec54696799035ef3a25a9a5794e47d8e8bdf794 +"@inquirer/type@npm:^3.0.1": + version: 3.0.1 + resolution: "@inquirer/type@npm:3.0.1" + peerDependencies: + "@types/node": ">=18" + checksum: 10/af412f1e7541d43554b02199ae71a2039a1bff5dc51ceefd87de9ece55b199682733b28810fb4b6cb3ed4a159af4cc4a26d4bb29c58dd127e7d9dbda0797d8e7 languageName: node linkType: hard @@ -1287,7 +1312,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": version: 0.3.25 resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: @@ -1309,9 +1334,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.35.8": - version: 0.35.9 - resolution: "@mswjs/interceptors@npm:0.35.9" +"@mswjs/interceptors@npm:^0.37.0": + version: 0.37.3 + resolution: "@mswjs/interceptors@npm:0.37.3" dependencies: "@open-draft/deferred-promise": "npm:^2.2.0" "@open-draft/logger": "npm:^0.3.0" @@ -1319,7 +1344,7 @@ __metadata: is-node-process: "npm:^1.2.0" outvariant: "npm:^1.4.3" strict-event-emitter: "npm:^0.5.1" - checksum: 10/9eaf8d7876c9a38c2c9a1259873f8ad27ab41c68a49f7e14a55cd9f596458d9232adb85a5084b044d4eead3be1e7ef5bf54ed6d774d16b02d96caf1e7faa2ab3 + checksum: 10/3d3e2e073feead8702c18dc97e5201785865292b32bd882c4d80461adc3380483b33517c55d7c6c1e53723f5e2ecf50cca0412e6ecd2eb771f4eaabfa2138932 languageName: node linkType: hard @@ -1780,11 +1805,11 @@ __metadata: linkType: soft "@storybook/components@file:../../../code/deprecated/components::locator=portable-stories-react%40workspace%3A.": - version: 8.5.0-alpha.18 - resolution: "@storybook/components@file:../../../code/deprecated/components#../../../code/deprecated/components::hash=aad2fe&locator=portable-stories-react%40workspace%3A." + version: 8.5.0-alpha.20 + resolution: "@storybook/components@file:../../../code/deprecated/components#../../../code/deprecated/components::hash=40954d&locator=portable-stories-react%40workspace%3A." peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/44d4a8a54fd32d94b03dc9f29e2d68ca3c37156b56055b94493f5f626786a02349c195859c48b4f8fa25e209ce12f385305d601135f7e63bdc4541fa0645cae5 + checksum: 10/ff9107e9c84c5d522a0067f77e217a9963c4bdde27032fdd38efae906f67df7b65488969a9cee89715d49fa89213fe04a72af825ac118e72e835f4be648409ff languageName: node linkType: hard @@ -1840,15 +1865,14 @@ __metadata: linkType: hard "@storybook/experimental-addon-test@file:../../../code/addons/test::locator=portable-stories-react%40workspace%3A.": - version: 8.5.0-alpha.18 - resolution: "@storybook/experimental-addon-test@file:../../../code/addons/test#../../../code/addons/test::hash=21369f&locator=portable-stories-react%40workspace%3A." + version: 8.5.0-alpha.20 + resolution: "@storybook/experimental-addon-test@file:../../../code/addons/test#../../../code/addons/test::hash=1aa098&locator=portable-stories-react%40workspace%3A." dependencies: "@storybook/csf": "npm:0.1.12" "@storybook/global": "npm:^5.0.0" "@storybook/icons": "npm:^1.2.12" "@storybook/instrumenter": "workspace:*" "@storybook/test": "workspace:*" - "@storybook/theming": "workspace:*" polished: "npm:^4.2.2" prompts: "npm:^2.4.0" ts-dedent: "npm:^2.2.0" @@ -1864,7 +1888,7 @@ __metadata: optional: true vitest: optional: true - checksum: 10/2081814e214dc1dd31144870a6a4ea7637c9c241ab02044488be57e19402c206c0037d449197f77bb4262147703f6d0b27f09c9f6cc2ee358c97fd7d1cdfa908 + checksum: 10/42188bb3814cae7c04df03c75994f8df971cc2ce71bda9e536211b96468bbdf2b8babc78526fdec1b2ddbd4d703118474f23c31f2bddffb6fa8947dc35ef0f19 languageName: node linkType: hard @@ -1897,20 +1921,20 @@ __metadata: linkType: soft "@storybook/manager-api@file:../../../code/deprecated/manager-api::locator=portable-stories-react%40workspace%3A.": - version: 8.5.0-alpha.18 - resolution: "@storybook/manager-api@file:../../../code/deprecated/manager-api#../../../code/deprecated/manager-api::hash=c1892e&locator=portable-stories-react%40workspace%3A." + version: 8.5.0-alpha.20 + resolution: "@storybook/manager-api@file:../../../code/deprecated/manager-api#../../../code/deprecated/manager-api::hash=92b213&locator=portable-stories-react%40workspace%3A." peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/405745f48728bfa4d8340fe2403bca0d60f803ed346c12d20a63ab9472ba1d8d1021aa12ee0fd36a6b41aec42d8c2a657acffeb9c8663aa32edcda490882e7f5 + checksum: 10/c63e624ab2d90f2992ecb2a650d9e54ace0f7f699d425bc68f616f870651a2b5f3c6c7d66be84aaab9200a9f01686376a7532f905f0dbd4dddb5542afe855584 languageName: node linkType: hard "@storybook/preview-api@file:../../../code/deprecated/preview-api::locator=portable-stories-react%40workspace%3A.": - version: 8.5.0-alpha.18 - resolution: "@storybook/preview-api@file:../../../code/deprecated/preview-api#../../../code/deprecated/preview-api::hash=0085a8&locator=portable-stories-react%40workspace%3A." + version: 8.5.0-alpha.20 + resolution: "@storybook/preview-api@file:../../../code/deprecated/preview-api#../../../code/deprecated/preview-api::hash=b70449&locator=portable-stories-react%40workspace%3A." peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/29c5f7134b4300bac03c42f57c3138e24315516b23515893cfb4a144786327fb6e0a90d5470d951eb22e055466769fc9ad4577658afc7da43b60870c0d06e767 + checksum: 10/3251de34aca72eb6c82b7aa8fde6e877e0974294d97eb60f63819b890b399cd7703a4dfde151180cf81918b36b3523bdbafe0731d232bda7d77c9f3b8fc5b75b languageName: node linkType: hard @@ -1991,11 +2015,11 @@ __metadata: linkType: soft "@storybook/theming@file:../../../code/deprecated/theming::locator=portable-stories-react%40workspace%3A.": - version: 8.5.0-alpha.18 - resolution: "@storybook/theming@file:../../../code/deprecated/theming#../../../code/deprecated/theming::hash=dd5360&locator=portable-stories-react%40workspace%3A." + version: 8.5.0-alpha.20 + resolution: "@storybook/theming@file:../../../code/deprecated/theming#../../../code/deprecated/theming::hash=db0fbd&locator=portable-stories-react%40workspace%3A." peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/8f8ecbd709ff4a8e0bafa19642497aad0d6ee40f2e613793a4248cb3825765783dd40eb57d180cb6cc4ad1f8acbd4e4a1a1b3448245b89e28581e25289c88c86 + checksum: 10/de77ed744ce172b1007cf94b4b5ff1cf9cf8492d4ddb9ac1ca61d76b18ed73f76e911c1518c1b66ba37c8d2d4e0f63f2eb3bddc64cd0beb7d64f952a45f9b8b7 languageName: node linkType: hard @@ -2356,16 +2380,7 @@ __metadata: languageName: node linkType: hard -"@types/mute-stream@npm:^0.0.4": - version: 0.0.4 - resolution: "@types/mute-stream@npm:0.0.4" - dependencies: - "@types/node": "npm:*" - checksum: 10/af8d83ad7b68ea05d9357985daf81b6c9b73af4feacb2f5c2693c7fd3e13e5135ef1bd083ce8d5bdc8e97acd28563b61bb32dec4e4508a8067fcd31b8a098632 - languageName: node - linkType: hard - -"@types/node@npm:*, @types/node@npm:^22.5.5": +"@types/node@npm:*": version: 22.7.7 resolution: "@types/node@npm:22.7.7" dependencies: @@ -2456,13 +2471,6 @@ __metadata: languageName: node linkType: hard -"@types/wrap-ansi@npm:^3.0.0": - version: 3.0.0 - resolution: "@types/wrap-ansi@npm:3.0.0" - checksum: 10/8aa644946ca4e859668c36b8e2bcf2ac4bdee59dac760414730ea57be8a93ae9166ebd40a088f2ab714843aaea2a2a67f0e6e6ec11cfc9c8701b2466ca1c4089 - languageName: node - linkType: hard - "@types/yargs-parser@npm:*": version: 21.0.3 resolution: "@types/yargs-parser@npm:21.0.3" @@ -2697,21 +2705,21 @@ __metadata: linkType: hard "@vitest/browser@npm:^2.1.3": - version: 2.1.3 - resolution: "@vitest/browser@npm:2.1.3" + version: 2.1.8 + resolution: "@vitest/browser@npm:2.1.8" dependencies: "@testing-library/dom": "npm:^10.4.0" "@testing-library/user-event": "npm:^14.5.2" - "@vitest/mocker": "npm:2.1.3" - "@vitest/utils": "npm:2.1.3" - magic-string: "npm:^0.30.11" - msw: "npm:^2.3.5" - sirv: "npm:^2.0.4" + "@vitest/mocker": "npm:2.1.8" + "@vitest/utils": "npm:2.1.8" + magic-string: "npm:^0.30.12" + msw: "npm:^2.6.4" + sirv: "npm:^3.0.0" tinyrainbow: "npm:^1.2.0" ws: "npm:^8.18.0" peerDependencies: playwright: "*" - vitest: 2.1.3 + vitest: 2.1.8 webdriverio: "*" peerDependenciesMeta: playwright: @@ -2720,7 +2728,33 @@ __metadata: optional: true webdriverio: optional: true - checksum: 10/e639496fa529140fb9e7dce97890c5b75fffbfb41881bee5ef25b194832d3cadcb77490d9b54777bfa968b993f6878649fe4961d6ef312ca1222b9a2fc8d4f12 + checksum: 10/6063e02222440347bbc23b2c54e259078aa83a29869337b9ffd642be5a4321ac3ddf3c0bbe4eac5237eb0bb8b9fa17d21d2c31299376de407716e3c7dd3b704c + languageName: node + linkType: hard + +"@vitest/coverage-v8@npm:^2.1.3": + version: 2.1.8 + resolution: "@vitest/coverage-v8@npm:2.1.8" + dependencies: + "@ampproject/remapping": "npm:^2.3.0" + "@bcoe/v8-coverage": "npm:^0.2.3" + debug: "npm:^4.3.7" + istanbul-lib-coverage: "npm:^3.2.2" + istanbul-lib-report: "npm:^3.0.1" + istanbul-lib-source-maps: "npm:^5.0.6" + istanbul-reports: "npm:^3.1.7" + magic-string: "npm:^0.30.12" + magicast: "npm:^0.3.5" + std-env: "npm:^3.8.0" + test-exclude: "npm:^7.0.1" + tinyrainbow: "npm:^1.2.0" + peerDependencies: + "@vitest/browser": 2.1.8 + vitest: 2.1.8 + peerDependenciesMeta: + "@vitest/browser": + optional: true + checksum: 10/2e1e7fe2a20c1eec738f6d84d890bed4aa5138094943dd1229962c2c42428a1a517c8a4ad4fb52637d7494f044440e061e9bc5982a83df95223db185d5a28f4d languageName: node linkType: hard @@ -2736,35 +2770,34 @@ __metadata: languageName: node linkType: hard -"@vitest/expect@npm:2.1.3": - version: 2.1.3 - resolution: "@vitest/expect@npm:2.1.3" +"@vitest/expect@npm:2.1.8": + version: 2.1.8 + resolution: "@vitest/expect@npm:2.1.8" dependencies: - "@vitest/spy": "npm:2.1.3" - "@vitest/utils": "npm:2.1.3" - chai: "npm:^5.1.1" + "@vitest/spy": "npm:2.1.8" + "@vitest/utils": "npm:2.1.8" + chai: "npm:^5.1.2" tinyrainbow: "npm:^1.2.0" - checksum: 10/94e61e01f14cfcd9ced0e7ac1bbdeee55ff4bf68f09d8f244fd7d73f97b106f35d10cba3fe7a0132464c312206f2eee9e83b16a8d761101b61da053890062858 + checksum: 10/3594149dd67dfac884a90f8b6a35687cdddd2f5f764562819bf7b66ae2eacfd4aa5e8914155deb4082fbe5a3792dced2fd7e59a948ffafe67acba4d2229dfe5f languageName: node linkType: hard -"@vitest/mocker@npm:2.1.3": - version: 2.1.3 - resolution: "@vitest/mocker@npm:2.1.3" +"@vitest/mocker@npm:2.1.8": + version: 2.1.8 + resolution: "@vitest/mocker@npm:2.1.8" dependencies: - "@vitest/spy": "npm:2.1.3" + "@vitest/spy": "npm:2.1.8" estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.11" + magic-string: "npm:^0.30.12" peerDependencies: - "@vitest/spy": 2.1.3 - msw: ^2.3.5 + msw: ^2.4.9 vite: ^5.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - checksum: 10/84be8830d6e965109730257d7a84b3d7594db0998ae55decdbfc304857c1c7d29b49f1f5b23f2addcbce1bd7e8bb33832407737a9bb3f95cb3bf7bb312db4d9d + checksum: 10/f04060f42102caa4cca72059e63c1ecae8b8e091aaa61a2d4a914b129fc711ada4ad117eb0184e49e363757784ed1117fdbf9f4a81a45fe575fd92769740a970 languageName: node linkType: hard @@ -2777,33 +2810,33 @@ __metadata: languageName: node linkType: hard -"@vitest/pretty-format@npm:2.1.3, @vitest/pretty-format@npm:^2.1.3": - version: 2.1.3 - resolution: "@vitest/pretty-format@npm:2.1.3" +"@vitest/pretty-format@npm:2.1.8, @vitest/pretty-format@npm:^2.1.8": + version: 2.1.8 + resolution: "@vitest/pretty-format@npm:2.1.8" dependencies: tinyrainbow: "npm:^1.2.0" - checksum: 10/d9382ee93f0f32e2ef8fe03bda818e5277f052a50ddb05b6a6cf0864b2ccb228484f12f130c05faf62dc2140292ffafc213f2941b0fa24058b3ee2943daa286c + checksum: 10/f0f60c007424194887ad398d202867d58d850154de327993925041e2972357544eea95a22e0bb3a62a470b006ff8de5f691d2078708dcd7f625e24f8a06b26e7 languageName: node linkType: hard -"@vitest/runner@npm:2.1.3": - version: 2.1.3 - resolution: "@vitest/runner@npm:2.1.3" +"@vitest/runner@npm:2.1.8": + version: 2.1.8 + resolution: "@vitest/runner@npm:2.1.8" dependencies: - "@vitest/utils": "npm:2.1.3" + "@vitest/utils": "npm:2.1.8" pathe: "npm:^1.1.2" - checksum: 10/cdf9b82d388c1cc148753f4a8632dfcadf9c4a1c0e065fdcd485d5af824af62507fd7eab9efb21244009775c05773ccb59547043af522a5ab6d216433321066e + checksum: 10/27f265a3ab1e20297b948b06232bfa4dc9fda44d1f9bb6206baa9e6fa643b71143ebfd2d1771570296b7ee74a12d684e529a830f545ad61235cefb454e94a8e9 languageName: node linkType: hard -"@vitest/snapshot@npm:2.1.3": - version: 2.1.3 - resolution: "@vitest/snapshot@npm:2.1.3" +"@vitest/snapshot@npm:2.1.8": + version: 2.1.8 + resolution: "@vitest/snapshot@npm:2.1.8" dependencies: - "@vitest/pretty-format": "npm:2.1.3" - magic-string: "npm:^0.30.11" + "@vitest/pretty-format": "npm:2.1.8" + magic-string: "npm:^0.30.12" pathe: "npm:^1.1.2" - checksum: 10/2c0c4ad8abb758f2f76d1d6094f8928360437e09d0a59e0c6a85a544c892cc41a5324ebbc5657a66c8a3793e51cbf58e357c7f71e899f4e5c5eb76e8c9745abf + checksum: 10/71edf4f574d317579c605ed0a7ecab7ee96fddcebc777bd130774a770ddc692c538f9f5b3dfde89af83ecb36f7338fe880943c83cede58f55e3556768a1a0749 languageName: node linkType: hard @@ -2816,12 +2849,29 @@ __metadata: languageName: node linkType: hard -"@vitest/spy@npm:2.1.3": - version: 2.1.3 - resolution: "@vitest/spy@npm:2.1.3" +"@vitest/spy@npm:2.1.8": + version: 2.1.8 + resolution: "@vitest/spy@npm:2.1.8" dependencies: - tinyspy: "npm:^3.0.0" - checksum: 10/94d6f1bc34da5d0c973d9382c133b938e555fcf2d238edf0aaad3de1a98dd57ebf7c104ba229c6beec48122d2e6f55386d8d2cf96a5804dc95ac683a54754cc7 + tinyspy: "npm:^3.0.2" + checksum: 10/9a1cb9cf6b23c122681469b5890d91ca26fc8d74953b3d46d293a5d2a4944490106891f6a178cd732ab7a8abbda339f43681c81d1594565ecc3bf3e7f9b7735f + languageName: node + linkType: hard + +"@vitest/ui@npm:^2.1.3": + version: 2.1.8 + resolution: "@vitest/ui@npm:2.1.8" + dependencies: + "@vitest/utils": "npm:2.1.8" + fflate: "npm:^0.8.2" + flatted: "npm:^3.3.1" + pathe: "npm:^1.1.2" + sirv: "npm:^3.0.0" + tinyglobby: "npm:^0.2.10" + tinyrainbow: "npm:^1.2.0" + peerDependencies: + vitest: 2.1.8 + checksum: 10/7ff0532b3b0e3f93c037cad3528b8fde8a93188f3222b92faae42e0fdd996e9284b362c4e5e9d725ce0a019870d3b0b7ad80c1874f74b43ffc5a1d703803fdd8 languageName: node linkType: hard @@ -2837,14 +2887,14 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:2.1.3, @vitest/utils@npm:^2.1.1": - version: 2.1.3 - resolution: "@vitest/utils@npm:2.1.3" +"@vitest/utils@npm:2.1.8, @vitest/utils@npm:^2.1.1": + version: 2.1.8 + resolution: "@vitest/utils@npm:2.1.8" dependencies: - "@vitest/pretty-format": "npm:2.1.3" - loupe: "npm:^3.1.1" + "@vitest/pretty-format": "npm:2.1.8" + loupe: "npm:^3.1.2" tinyrainbow: "npm:^1.2.0" - checksum: 10/f064e6634cb84c925a17d8937df7441d150c3e24fa5bbd6304151d11dab6cdeb0cb3d5a95a9aacb8b416c87fb0d9aa8c6b9cc5e174191784231e8345948d6d18 + checksum: 10/be1f4254347199fb5c1d9de8e4537dad4af3f434c033e7cd023165bd4b7e9de16fa0f86664256ab331120585df95ed6be8eea58b209b510651b49f6482051733 languageName: node linkType: hard @@ -3455,16 +3505,16 @@ __metadata: languageName: node linkType: hard -"chai@npm:^5.1.1": - version: 5.1.1 - resolution: "chai@npm:5.1.1" +"chai@npm:^5.1.1, chai@npm:^5.1.2": + version: 5.1.2 + resolution: "chai@npm:5.1.2" dependencies: assertion-error: "npm:^2.0.1" check-error: "npm:^2.1.1" deep-eql: "npm:^5.0.1" loupe: "npm:^3.1.0" pathval: "npm:^2.0.0" - checksum: 10/ee67279a5613bd36dc1dc13660042429ae2f1dc5a9030a6abcf381345866dfb5bce7bc10b9d74c8de86b6f656489f654bbbef3f3361e06925591e6a00c72afff + checksum: 10/e8c2bbc83cb5a2f87130d93056d4cfbbe04106e12aa798b504816dbe3fa538a9f68541b472e56cbf0f54558b501d7e31867d74b8218abcd5a8cc8ba536fba46c languageName: node linkType: hard @@ -3695,10 +3745,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:^0.5.0": - version: 0.5.0 - resolution: "cookie@npm:0.5.0" - checksum: 10/aae7911ddc5f444a9025fbd979ad1b5d60191011339bce48e555cb83343d0f98b865ff5c4d71fecdfb8555a5cafdc65632f6fce172f32aaf6936830a883a0380 +"cookie@npm:^0.7.2": + version: 0.7.2 + resolution: "cookie@npm:0.7.2" + checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f languageName: node linkType: hard @@ -3853,7 +3903,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.7": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -4174,6 +4224,13 @@ __metadata: languageName: node linkType: hard +"es-module-lexer@npm:^1.5.4": + version: 1.5.4 + resolution: "es-module-lexer@npm:1.5.4" + checksum: 10/f29c7c97a58eb17640dcbd71bd6ef754ad4f58f95c3073894573d29dae2cad43ecd2060d97ed5b866dfb7804d5590fb7de1d2c5339a5fceae8bd60b580387fc5 + languageName: node + linkType: hard + "esbuild-register@npm:^3.5.0": version: 3.6.0 resolution: "esbuild-register@npm:3.6.0" @@ -4634,6 +4691,13 @@ __metadata: languageName: node linkType: hard +"expect-type@npm:^1.1.0": + version: 1.1.0 + resolution: "expect-type@npm:1.1.0" + checksum: 10/05fca80ddc7d493a89361f783c6b000750fa04a8226bc24701f3b90adb0efc2fb467f2a0baaed4015a02d8b9034ef5bb87521df9dba980f50b1105bd596ef833 + languageName: node + linkType: hard + "expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" @@ -4753,6 +4817,25 @@ __metadata: languageName: node linkType: hard +"fdir@npm:^6.4.2": + version: 6.4.2 + resolution: "fdir@npm:6.4.2" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10/5ff80d1d2034e75cc68be175401c9f64c4938a6b2c1e9a0c27f2d211ffbe491fd86d29e4576825d9da8aff9bd465f0283427c2dddc11653457906c46d3bbc448 + languageName: node + linkType: hard + +"fflate@npm:^0.8.2": + version: 0.8.2 + resolution: "fflate@npm:0.8.2" + checksum: 10/2bd26ba6d235d428de793c6a0cd1aaa96a06269ebd4e21b46c8fd1bd136abc631acf27e188d47c3936db090bf3e1ede11d15ce9eae9bffdc4bfe1b9dc66ca9cb + languageName: node + linkType: hard + "figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -4818,6 +4901,13 @@ __metadata: languageName: node linkType: hard +"flatted@npm:^3.3.1": + version: 3.3.2 + resolution: "flatted@npm:3.3.2" + checksum: 10/ac3c159742e01d0e860a861164bcfd35bb567ccbebb8a0dd041e61cf3c64a435b917dd1e7ed1c380c2ebca85735fb16644485ec33665bc6aafc3b316aa1eed44 + languageName: node + linkType: hard + "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -5030,7 +5120,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10": +"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.1": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -5726,7 +5816,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0, istanbul-lib-coverage@npm:^3.2.2": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" checksum: 10/40bbdd1e937dfd8c830fa286d0f665e81b7a78bdabcd4565f6d5667c99828bda3db7fb7ac6b96a3e2e8a2461ddbc5452d9f8bc7d00cb00075fa6a3e99f5b6a81 @@ -5759,7 +5849,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-report@npm:^3.0.0": +"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": version: 3.0.1 resolution: "istanbul-lib-report@npm:3.0.1" dependencies: @@ -5781,7 +5871,18 @@ __metadata: languageName: node linkType: hard -"istanbul-reports@npm:^3.1.3": +"istanbul-lib-source-maps@npm:^5.0.6": + version: 5.0.6 + resolution: "istanbul-lib-source-maps@npm:5.0.6" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.23" + debug: "npm:^4.1.1" + istanbul-lib-coverage: "npm:^3.0.0" + checksum: 10/569dd0a392ee3464b1fe1accbaef5cc26de3479eacb5b91d8c67ebb7b425d39fd02247d85649c3a0e9c29b600809fa60b5af5a281a75a89c01f385b1e24823a2 + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.3, istanbul-reports@npm:^3.1.7": version: 3.1.7 resolution: "istanbul-reports@npm:3.1.7" dependencies: @@ -6593,7 +6694,7 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^3.1.0, loupe@npm:^3.1.1": +"loupe@npm:^3.1.0, loupe@npm:^3.1.1, loupe@npm:^3.1.2": version: 3.1.2 resolution: "loupe@npm:3.1.2" checksum: 10/8f5734e53fb64cd914aa7d986e01b6d4c2e3c6c56dcbd5428d71c2703f0ab46b5ab9f9eeaaf2b485e8a1c43f865bdd16ec08ae1a661c8f55acdbd9f4d59c607a @@ -6634,7 +6735,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.0, magic-string@npm:^0.30.11": +"magic-string@npm:^0.30.0": version: 0.30.12 resolution: "magic-string@npm:0.30.12" dependencies: @@ -6643,6 +6744,26 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.12": + version: 0.30.14 + resolution: "magic-string@npm:0.30.14" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + checksum: 10/8ca0f8937c2824e48ebc70e7e065a193c467713639cc6e5972aaba0fa5417b375a6f62c383410a19a66e618c386bb7253fbd3ccbfb0144bb310f0ba772121f12 + languageName: node + linkType: hard + +"magicast@npm:^0.3.5": + version: 0.3.5 + resolution: "magicast@npm:0.3.5" + dependencies: + "@babel/parser": "npm:^7.25.4" + "@babel/types": "npm:^7.25.4" + source-map-js: "npm:^1.2.0" + checksum: 10/3a2dba6b0bdde957797361d09c7931ebdc1b30231705360eeb40ed458d28e1c3112841c3ed4e1b87ceb28f741e333c7673cd961193aa9fdb4f4946b202e6205a + languageName: node + linkType: hard + "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -6892,15 +7013,16 @@ __metadata: languageName: node linkType: hard -"msw@npm:^2.3.5": - version: 2.4.11 - resolution: "msw@npm:2.4.11" +"msw@npm:^2.6.4": + version: 2.6.6 + resolution: "msw@npm:2.6.6" dependencies: - "@bundled-es-modules/cookie": "npm:^2.0.0" + "@bundled-es-modules/cookie": "npm:^2.0.1" "@bundled-es-modules/statuses": "npm:^1.0.1" "@bundled-es-modules/tough-cookie": "npm:^0.1.6" - "@inquirer/confirm": "npm:^3.0.0" - "@mswjs/interceptors": "npm:^0.35.8" + "@inquirer/confirm": "npm:^5.0.0" + "@mswjs/interceptors": "npm:^0.37.0" + "@open-draft/deferred-promise": "npm:^2.2.0" "@open-draft/until": "npm:^2.1.0" "@types/cookie": "npm:^0.6.0" "@types/statuses": "npm:^2.0.4" @@ -6920,14 +7042,14 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 10/d073ede4bfc7f1f41f7a0cb05b3d20d9befc1658e53faacd3f217a7cb78e3e748a3ee8e937e2a4d93fd09f16b35cba00d71df767736dd567ac15fd8e01aa7d6e + checksum: 10/7762ba5f1570789328af27167e03c2b8eb4981faa476ae47d74c125c90ddc1792bc28b9ce1100bbc4e105b55e3e7d65e7cae8d27fa7677b6516e42a63c38b7a3 languageName: node linkType: hard -"mute-stream@npm:^1.0.0": - version: 1.0.0 - resolution: "mute-stream@npm:1.0.0" - checksum: 10/36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7 +"mute-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "mute-stream@npm:2.0.0" + checksum: 10/d2e4fd2f5aa342b89b98134a8d899d8ef9b0a6d69274c4af9df46faa2d97aeb1f2ce83d867880d6de63643c52386579b99139801e24e7526c3b9b0a6d1e18d6c languageName: node linkType: hard @@ -7298,6 +7420,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 10/ce617b8da36797d09c0baacb96ca8a44460452c89362d7cb8f70ca46b4158ba8bc3606912de7c818eb4a939f7f9015cef3c766ec8a0c6bfc725fdc078e39c717 + languageName: node + linkType: hard + "pify@npm:^2.2.0": version: 2.3.0 resolution: "pify@npm:2.3.0" @@ -7380,6 +7509,8 @@ __metadata: "@typescript-eslint/parser": "npm:^6.21.0" "@vitejs/plugin-react": "npm:^4.2.1" "@vitest/browser": "npm:^2.1.3" + "@vitest/coverage-v8": "npm:^2.1.3" + "@vitest/ui": "npm:^2.1.3" cypress: "npm:^13.6.4" eslint: "npm:^8.56.0" eslint-plugin-react-hooks: "npm:^4.6.0" @@ -7991,14 +8122,14 @@ __metadata: languageName: node linkType: hard -"sirv@npm:^2.0.4": - version: 2.0.4 - resolution: "sirv@npm:2.0.4" +"sirv@npm:^3.0.0": + version: 3.0.0 + resolution: "sirv@npm:3.0.0" dependencies: "@polka/url": "npm:^1.0.0-next.24" mrmime: "npm:^2.0.0" totalist: "npm:^3.0.0" - checksum: 10/24f42cf06895017e589c9d16fc3f1c6c07fe8b0dbafce8a8b46322cfba67b7f2498610183954cb0e9d089c8cb60002a7ee7e8bca6a91a0d7042bfbc3473c95c3 + checksum: 10/94dbd5df7cf4965f7c5941767117cbf9709e1d25de1d619a114c3f77fc63c124b5a5255717af2a0de637bb83d0b0defd0822d01420764b56432b53281b1d675d languageName: node linkType: hard @@ -8066,7 +8197,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.2.1": +"source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3 @@ -8157,10 +8288,10 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^3.7.0": - version: 3.7.0 - resolution: "std-env@npm:3.7.0" - checksum: 10/6ee0cca1add3fd84656b0002cfbc5bfa20340389d9ba4720569840f1caa34bce74322aef4c93f046391583e50649d0cf81a5f8fe1d411e50b659571690a45f12 +"std-env@npm:^3.8.0": + version: 3.8.0 + resolution: "std-env@npm:3.8.0" + checksum: 10/034176196cfcaaab16dbdd96fc9e925a9544799fb6dc5a3e36fe43270f3a287c7f779d785b89edaf22cef2b5f1dcada2aae67430b8602e785ee74bdb3f671768 languageName: node linkType: hard @@ -8359,6 +8490,17 @@ __metadata: languageName: node linkType: hard +"test-exclude@npm:^7.0.1": + version: 7.0.1 + resolution: "test-exclude@npm:7.0.1" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^10.4.1" + minimatch: "npm:^9.0.4" + checksum: 10/e6f6f4e1df2e7810e082e8d7dfc53be51a931e6e87925f5e1c2ef92cc1165246ba3bf2dae6b5d86251c16925683dba906bd41e40169ebc77120a2d1b5a0dbbe0 + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -8394,17 +8536,27 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^0.3.0": +"tinyexec@npm:^0.3.1": version: 0.3.1 resolution: "tinyexec@npm:0.3.1" checksum: 10/0537c70590d52d354f40c0255ff0f654a3d18ddb3812b440ddf9d436edf516c8057838ad5a38744c0c59670ec03e3cf23fbe04ae3d49f031d948274e99002569 languageName: node linkType: hard -"tinypool@npm:^1.0.0": - version: 1.0.1 - resolution: "tinypool@npm:1.0.1" - checksum: 10/eaceb93784b8e27e60c0e3e2c7d11c29e1e79b2a025b2c232215db73b90fe22bd4753ad53fc8e801c2b5a63b94a823af549555d8361272bc98271de7dd4a9925 +"tinyglobby@npm:^0.2.10": + version: 0.2.10 + resolution: "tinyglobby@npm:0.2.10" + dependencies: + fdir: "npm:^6.4.2" + picomatch: "npm:^4.0.2" + checksum: 10/10c976866d849702edc47fc3fef27d63f074c40f75ef17171ecc1452967900699fa1e62373681dd58e673ddff2e3f6094bcd0a2101e3e4b30f4c2b9da41397f2 + languageName: node + linkType: hard + +"tinypool@npm:^1.0.1": + version: 1.0.2 + resolution: "tinypool@npm:1.0.2" + checksum: 10/6109322f14b3763f65c8fa49fddab72cd3edd96b82dd50e05e63de74867329ff5353bff4377281ec963213d9314f37f4a353e9ee34bbac85fd4c1e4a568d6076 languageName: node linkType: hard @@ -8415,7 +8567,7 @@ __metadata: languageName: node linkType: hard -"tinyspy@npm:^3.0.0": +"tinyspy@npm:^3.0.0, tinyspy@npm:^3.0.2": version: 3.0.2 resolution: "tinyspy@npm:3.0.2" checksum: 10/5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 @@ -8759,17 +8911,18 @@ __metadata: languageName: node linkType: hard -"vite-node@npm:2.1.3": - version: 2.1.3 - resolution: "vite-node@npm:2.1.3" +"vite-node@npm:2.1.8": + version: 2.1.8 + resolution: "vite-node@npm:2.1.8" dependencies: cac: "npm:^6.7.14" - debug: "npm:^4.3.6" + debug: "npm:^4.3.7" + es-module-lexer: "npm:^1.5.4" pathe: "npm:^1.1.2" vite: "npm:^5.0.0" bin: vite-node: vite-node.mjs - checksum: 10/8ba6b145cbb02a492c7bb1f0490d02383000462f234ed61d24f650547163825c16f14e6908ee1eb661403bd0a7a3fb3cdbedf116cc015b1e5cdf7bb992872a01 + checksum: 10/0ff0ed7a6fb234d3ddc4946e4c1150229980cac9f34fb4bd7f443aab0aae2da5b73ac20ff68af1df476545807dc23189247194e8cea0dcdfa394311c73f04429 languageName: node linkType: hard @@ -8833,33 +8986,34 @@ __metadata: linkType: hard "vitest@npm:^2.1.3": - version: 2.1.3 - resolution: "vitest@npm:2.1.3" - dependencies: - "@vitest/expect": "npm:2.1.3" - "@vitest/mocker": "npm:2.1.3" - "@vitest/pretty-format": "npm:^2.1.3" - "@vitest/runner": "npm:2.1.3" - "@vitest/snapshot": "npm:2.1.3" - "@vitest/spy": "npm:2.1.3" - "@vitest/utils": "npm:2.1.3" - chai: "npm:^5.1.1" - debug: "npm:^4.3.6" - magic-string: "npm:^0.30.11" + version: 2.1.8 + resolution: "vitest@npm:2.1.8" + dependencies: + "@vitest/expect": "npm:2.1.8" + "@vitest/mocker": "npm:2.1.8" + "@vitest/pretty-format": "npm:^2.1.8" + "@vitest/runner": "npm:2.1.8" + "@vitest/snapshot": "npm:2.1.8" + "@vitest/spy": "npm:2.1.8" + "@vitest/utils": "npm:2.1.8" + chai: "npm:^5.1.2" + debug: "npm:^4.3.7" + expect-type: "npm:^1.1.0" + magic-string: "npm:^0.30.12" pathe: "npm:^1.1.2" - std-env: "npm:^3.7.0" + std-env: "npm:^3.8.0" tinybench: "npm:^2.9.0" - tinyexec: "npm:^0.3.0" - tinypool: "npm:^1.0.0" + tinyexec: "npm:^0.3.1" + tinypool: "npm:^1.0.1" tinyrainbow: "npm:^1.2.0" vite: "npm:^5.0.0" - vite-node: "npm:2.1.3" + vite-node: "npm:2.1.8" why-is-node-running: "npm:^2.3.0" peerDependencies: "@edge-runtime/vm": "*" "@types/node": ^18.0.0 || >=20.0.0 - "@vitest/browser": 2.1.3 - "@vitest/ui": 2.1.3 + "@vitest/browser": 2.1.8 + "@vitest/ui": 2.1.8 happy-dom: "*" jsdom: "*" peerDependenciesMeta: @@ -8877,7 +9031,7 @@ __metadata: optional: true bin: vitest: vitest.mjs - checksum: 10/f6079a88583045b551e6526c08774aeac4a9cf85b132793a03f9470c013326abd7fce3985e3c2217dc0dac2fadeee3506e3dc51e215f10862b2fe9da9289af0f + checksum: 10/c2552c068f6faac82eb4e6debb9ed505c0e8016fd6e0a0f0e0dbb5b5417922fbcde80c54af0d3b5a5503a5d6ad6862b6e95b9b59b8b7e98bb553217b9c6fc227 languageName: node linkType: hard