Merge branch 'next' into win-build-support

This commit is contained in:
Valentin Palkovic 2025-01-16 10:11:12 +01:00 committed by GitHub
commit 38fa2e8a82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
138 changed files with 4954 additions and 3704 deletions

View File

@ -174,12 +174,13 @@ jobs:
git commit -m "Update CHANGELOG.md for v${{ steps.version.outputs.current-version }} [skip ci]" || true
git push origin next
# TODO: remove this step - @JReinhold
# Sync the next.json version file to the main branch so it gets deployed to the docs site
# but only if this is a prerelease, because in minor/major releases we're already force pushing next-release onto main, so it's already there
- name: Sync version JSONs from `next-release` to `main`
if: github.ref_name == 'next-release'
if: github.ref_name == 'next-release' && steps.is-prerelease.outputs.prerelease == 'true'
working-directory: .
run: |
VERSION_FILE="./docs/versions/${{ steps.is-prerelease.outputs.prerelease == 'true' && 'next' || 'latest' }}.json"
VERSION_FILE="./docs/versions/next.json"
git fetch origin main
git checkout main
git pull

View File

@ -1,3 +1,144 @@
## 8.5.0
Storybook 8.5 is packed with powerful features to enhance your development workflow. This release makes it easier than ever to build accessible, well-tested UIs. Heres whats new:
- 🦾 Realtime accessibility tests to help build UIs for everybody
- 🛡️ Project code coverage to measure the completeness of your tests
- 🎯 Focused tests for faster test feedback
- ⚛️ React Native Web Vite framework (experimental) for testing mobile UI⚛
- 🎁 Storybook test early access program to level up your testing game
- 💯 Hundreds more improvements
<details>
<summary>List of all updates</summary>
- Addon A11y: Add conditional rendering for a11y violation number in Testing Module - [#30073](https://github.com/storybookjs/storybook/pull/30073), thanks @valentinpalkovic!
- Addon A11y: Add typesVersions support for TypeScript definitions in a11y package - [#30005](https://github.com/storybookjs/storybook/pull/30005), thanks @valentinpalkovic!
- Addon A11y: Adjust default behaviour when using with experimental-addon-test - [#30162](https://github.com/storybookjs/storybook/pull/30162), thanks @valentinpalkovic!
- Addon A11y: Change default element selector - [#30253](https://github.com/storybookjs/storybook/pull/30253), thanks @valentinpalkovic!
- Addon A11y: Create a11y test provider and revamp a11y addon - [#29643](https://github.com/storybookjs/storybook/pull/29643), thanks @valentinpalkovic!
- Addon A11y: Don't set a11y tag as comment in automigrations - [#30257](https://github.com/storybookjs/storybook/pull/30257), thanks @valentinpalkovic!
- Addon A11y: Fix skipped status handling in Testing Module - [#30077](https://github.com/storybookjs/storybook/pull/30077), thanks @valentinpalkovic!
- Addon A11y: Refactor environment variable handling for Vitest integration - [#30022](https://github.com/storybookjs/storybook/pull/30022), thanks @valentinpalkovic!
- Addon A11y: Remove warnings API - [#30049](https://github.com/storybookjs/storybook/pull/30049), thanks @kasperpeulen!
- Addon A11y: Run the a11y automigration on postInstall - [#30004](https://github.com/storybookjs/storybook/pull/30004), thanks @kasperpeulen!
- Addon A11y: Show errors of axe properly - [#30050](https://github.com/storybookjs/storybook/pull/30050), thanks @kasperpeulen!
- Addon A11y: Update accessibility status handling in TestProviderRender - [#30027](https://github.com/storybookjs/storybook/pull/30027), thanks @valentinpalkovic!
- Addon Docs: Dynamically import rehype - [#29544](https://github.com/storybookjs/storybook/pull/29544), thanks @valentinpalkovic!
- Addon Docs: Make new code panel opt in - [#30248](https://github.com/storybookjs/storybook/pull/30248), thanks @shilman!
- Addon Onboarding: Prebundle react-confetti - [#29996](https://github.com/storybookjs/storybook/pull/29996), thanks @yannbf!
- Addon Test: Add `@vitest/coverage-v8` during postinstall if no coverage reporter is installed - [#29993](https://github.com/storybookjs/storybook/pull/29993), thanks @ghengeveld!
- Addon Test: Add prerequisite check for MSW - [#30193](https://github.com/storybookjs/storybook/pull/30193), thanks @yannbf!
- Addon Test: Add support for previewHead - [#29808](https://github.com/storybookjs/storybook/pull/29808), thanks @ndelangen!
- Addon Test: Add Vitest 3 support - [#30181](https://github.com/storybookjs/storybook/pull/30181), thanks @valentinpalkovic!
- Addon Test: Always run Vitest in watch mode internally - [#29749](https://github.com/storybookjs/storybook/pull/29749), thanks @JReinhold!
- Addon Test: Always use installed version of vitest - [#30134](https://github.com/storybookjs/storybook/pull/30134), thanks @kasperpeulen!
- Addon Test: Clarify message when `vitest` detects missing deps - [#29763](https://github.com/storybookjs/storybook/pull/29763), thanks @ndelangen!
- Addon Test: Clear coverage data when starting or watching - [#30072](https://github.com/storybookjs/storybook/pull/30072), thanks @ghengeveld!
- Addon Test: Context menu UI - [#29727](https://github.com/storybookjs/storybook/pull/29727), thanks @ghengeveld!
- Addon Test: Context menu updates - [#30107](https://github.com/storybookjs/storybook/pull/30107), thanks @ghengeveld!
- Addon Test: Correctly stop Storybook when Vitest closes - [#30012](https://github.com/storybookjs/storybook/pull/30012), thanks @JReinhold!
- Addon Test: Filter out falsy test results in TestProviderRender - [#30001](https://github.com/storybookjs/storybook/pull/30001), thanks @valentinpalkovic!
- Addon Test: Fix documentation links - [#30128](https://github.com/storybookjs/storybook/pull/30128), thanks @yannbf!
- Addon Test: Fix duplicate `test.include` patterns - [#30029](https://github.com/storybookjs/storybook/pull/30029), thanks @JReinhold!
- Addon Test: Fix environment variable for Vitest Storybook integration - [#30054](https://github.com/storybookjs/storybook/pull/30054), thanks @valentinpalkovic!
- Addon Test: Fix error reporting for `vitest` crashes - [#29751](https://github.com/storybookjs/storybook/pull/29751), thanks @ndelangen!
- Addon Test: Fix generated path to `vitest.setup.js` - [#30233](https://github.com/storybookjs/storybook/pull/30233), thanks @JReinhold!
- Addon Test: Fix indexing behavior - [#29836](https://github.com/storybookjs/storybook/pull/29836), thanks @yannbf!
- Addon Test: Fix printing null% for coverage - [#30061](https://github.com/storybookjs/storybook/pull/30061), thanks @ghengeveld!
- Addon Test: Fix run request while booting or restarting Vitest - [#29829](https://github.com/storybookjs/storybook/pull/29829), thanks @ghengeveld!
- Addon Test: Handle undefined storyId - [#29998](https://github.com/storybookjs/storybook/pull/29998), thanks @ghengeveld!
- Addon Test: Improve error message on missing coverage package - [#30088](https://github.com/storybookjs/storybook/pull/30088), thanks @JReinhold!
- Addon Test: Improve support for mono-repos - [#30216](https://github.com/storybookjs/storybook/pull/30216), thanks @valentinpalkovic!
- Addon Test: Make component tests status row link to the story\'s tests panel - [#29992](https://github.com/storybookjs/storybook/pull/29992), thanks @ghengeveld!
- Addon Test: Merge viteFinal config into vitest config - [#29806](https://github.com/storybookjs/storybook/pull/29806), thanks @ndelangen!
- Addon Test: Only optimize react deps if applicable in vitest-plugin - [#29617](https://github.com/storybookjs/storybook/pull/29617), thanks @yannbf!
- Addon Test: Only reset story count on file change when watch mode is enabled - [#30121](https://github.com/storybookjs/storybook/pull/30121), thanks @ghengeveld!
- Addon Test: Optimize internal dependencies - [#29595](https://github.com/storybookjs/storybook/pull/29595), thanks @yannbf!
- Addon Test: Prompt switch to `experimental-nextjs-vite` - [#29814](https://github.com/storybookjs/storybook/pull/29814), thanks @ndelangen!
- Addon Test: Refactor test addon to include stories automatically - [#29367](https://github.com/storybookjs/storybook/pull/29367), thanks @yannbf!
- Addon Test: Remove a11y placeholder - [#29769](https://github.com/storybookjs/storybook/pull/29769), thanks @JReinhold!
- Addon Test: Replace `glob` with `tinyglobby` - [#29817](https://github.com/storybookjs/storybook/pull/29817), thanks @ghengeveld!
- Addon Test: Serve `staticDirs` with Vitest - [#29811](https://github.com/storybookjs/storybook/pull/29811), thanks @ghengeveld!
- Addon Test: Show sub test provider toggle state in main testing module - [#30019](https://github.com/storybookjs/storybook/pull/30019), thanks @ghengeveld!
- Addon Test: Support Storybook environment variables in Vitest - [#29792](https://github.com/storybookjs/storybook/pull/29792), thanks @ghengeveld!
- Addon Test: Use correct vitest config file path - [#30135](https://github.com/storybookjs/storybook/pull/30135), thanks @kasperpeulen!
- Addon Test: Use local storybook binary instead - [#30021](https://github.com/storybookjs/storybook/pull/30021), thanks @kasperpeulen!
- Addon Test: Use ProgressSpinner for stop button in Testing Module - [#29997](https://github.com/storybookjs/storybook/pull/29997), thanks @ghengeveld!
- Addon Test: Wait for 2 seconds before showing result mismatch warning - [#30002](https://github.com/storybookjs/storybook/pull/30002), thanks @ghengeveld!
- Addon Test: Wrap sub-paths exported with `require.resolve` - [#30026](https://github.com/storybookjs/storybook/pull/30026), thanks @ndelangen!
- Addon Themes: Deprecate useThemeParameters - [#30111](https://github.com/storybookjs/storybook/pull/30111), thanks @yannbf!
- Angular: Support statsJson in angular schemas - [#29233](https://github.com/storybookjs/storybook/pull/29233), thanks @yannbf!
- Automigration: Improve addon-a11y-addon-test - [#30127](https://github.com/storybookjs/storybook/pull/30127), thanks @valentinpalkovic!
- Automigration: Improve setup file transformation and version range handling for a11y migration - [#30060](https://github.com/storybookjs/storybook/pull/30060), thanks @valentinpalkovic!
- Automigrations: Skip vite config file migration for react native web - [#30190](https://github.com/storybookjs/storybook/pull/30190), thanks @dannyhw!
- Build: Downgrade to esbuild 0.24.0 - [#30116](https://github.com/storybookjs/storybook/pull/30116), thanks @yannbf!
- Build: Revert Downgrade to esbuild 0.24.0 - [#30120](https://github.com/storybookjs/storybook/pull/30120), thanks @yannbf!
- CLI: Fix init help for `storybook` command - [#29480](https://github.com/storybookjs/storybook/pull/29480), thanks @toothlessdev!
- CLI: Fix new-frameworks automigration - [#29804](https://github.com/storybookjs/storybook/pull/29804), thanks @yannbf!
- CLI: Re-Add Nuxt support - [#28607](https://github.com/storybookjs/storybook/pull/28607), thanks @valentinpalkovic!
- CLI: Update a11y-test comment with experimental caveat - [#30258](https://github.com/storybookjs/storybook/pull/30258), thanks @shilman!
- Composition: Fix composed story search - [#29453](https://github.com/storybookjs/storybook/pull/29453), thanks @jsingh0026!
- Composition: Hide contextMenu on composed storybooks - [#29803](https://github.com/storybookjs/storybook/pull/29803), thanks @ndelangen!
- Core / Addon Test: Add config UI to Testing Module - [#29708](https://github.com/storybookjs/storybook/pull/29708), thanks @ghengeveld!
- Core / Addon Test: Support intercepting and modifying internal test provider state updates - [#29680](https://github.com/storybookjs/storybook/pull/29680), thanks @ghengeveld!
- Core + Addon Test: Refactor test API and fix total test count - [#29656](https://github.com/storybookjs/storybook/pull/29656), thanks @ghengeveld!
- Core: Add bun support with npm fallback - [#29267](https://github.com/storybookjs/storybook/pull/29267), thanks @stephenjason89!
- Core: Avoid getting stuck in locked state - [#29768](https://github.com/storybookjs/storybook/pull/29768), thanks @ghengeveld!
- Core: Disable SidebarContextMenu in static builds - [#29743](https://github.com/storybookjs/storybook/pull/29743), thanks @ndelangen!
- Core: Emit deprecated `TESTING_MODULE_RUN_ALL_REQUEST` for backward compatibility - [#29711](https://github.com/storybookjs/storybook/pull/29711), thanks @ghengeveld!
- Core: Evaluate main config when checking \'whats new\' notifications - [#29622](https://github.com/storybookjs/storybook/pull/29622), thanks @yannbf!
- Core: Fix `ERR_PACKAGE_PATH_NOT_EXPORTED` in `@storybook/node-logger` - [#30093](https://github.com/storybookjs/storybook/pull/30093), thanks @JReinhold!
- Core: Fix `scrollIntoView` behavior and reimplement testing module time rendering - [#30044](https://github.com/storybookjs/storybook/pull/30044), thanks @ghengeveld!
- Core: Fix bundling of React - [#30003](https://github.com/storybookjs/storybook/pull/30003), thanks @yannbf!
- Core: Float context menu button on top of story titles in sidebar - [#30080](https://github.com/storybookjs/storybook/pull/30080), thanks @ghengeveld!
- Core: Prevent clipping box shadow on file search modal - [#29523](https://github.com/storybookjs/storybook/pull/29523), thanks @ghengeveld!
- Core: Prevent infinite rerendering caused by comparison by reference - [#30081](https://github.com/storybookjs/storybook/pull/30081), thanks @ghengeveld!
- Docs: Add code snippet to addons panel - [#29253](https://github.com/storybookjs/storybook/pull/29253), thanks @larsrickert!
- Interactions: Correctly load preset when absolute paths are used - [#30264](https://github.com/storybookjs/storybook/pull/30264), thanks @JReinhold!
- Maintenance: Move `@types/node` to `devDeps` consistently - [#30163](https://github.com/storybookjs/storybook/pull/30163), thanks @ndelangen!
- Manager API: Fix infinite render-loop caused by `useSharedState` - [#30259](https://github.com/storybookjs/storybook/pull/30259), thanks @JReinhold!
- Manager: Add tags property to GroupEntry objects - [#29672](https://github.com/storybookjs/storybook/pull/29672), thanks @Sidnioulz!
- Manager: Fix size regression - [#29660](https://github.com/storybookjs/storybook/pull/29660), thanks @JReinhold!
- Manager: Optimize getPanels function with memoization - [#30192](https://github.com/storybookjs/storybook/pull/30192), thanks @valentinpalkovic!
- Next.js: Fix webpack fsCache not working - [#29654](https://github.com/storybookjs/storybook/pull/29654), thanks @sentience!
- Next.js: Support v15.1.1 - [#30068](https://github.com/storybookjs/storybook/pull/30068), thanks @valentinpalkovic!
- Next.js: Upgrade sass-loader from ^13.2.0 to ^14.2.1 - [#29264](https://github.com/storybookjs/storybook/pull/29264), thanks @HoncharenkoZhenya!
- Nextjs-Vite: Add TS docgen support - [#29824](https://github.com/storybookjs/storybook/pull/29824), thanks @yannbf!
- Nextjs-Vite: Fix docgen types in main config - [#30042](https://github.com/storybookjs/storybook/pull/30042), thanks @yannbf!
- Onboarding: Replace `react-confetti` with `@neoconfetti/react` - [#30098](https://github.com/storybookjs/storybook/pull/30098), thanks @ndelangen!
- React Native Web: Add framework, CLI integration, sandboxes - [#29520](https://github.com/storybookjs/storybook/pull/29520), thanks @shilman!
- React: Fix RSC compatibility with addon-themes and hooks - [#26243](https://github.com/storybookjs/storybook/pull/26243), thanks @shilman!
- React: Force act running always in sequence - [#30191](https://github.com/storybookjs/storybook/pull/30191), thanks @valentinpalkovic!
- React: Use Act wrapper in Storybook for component rendering - [#30037](https://github.com/storybookjs/storybook/pull/30037), thanks @valentinpalkovic!
- ReactVite: Add `@storybook/test` as optional peer dependency - [#29754](https://github.com/storybookjs/storybook/pull/29754), thanks @yannbf!
- RNW-Vite: Add built-in Flow support - [#29756](https://github.com/storybookjs/storybook/pull/29756), thanks @dannyhw!
- RNW-Vite: Add tsconfig path aliases support - [#29953](https://github.com/storybookjs/storybook/pull/29953), thanks @shilman!
- RNW-Vite: Fix flow plugin including too many things - [#29952](https://github.com/storybookjs/storybook/pull/29952), thanks @dannyhw!
- RNW-Vite: Fix reanimated support with babel plugin for node_modules - [#30188](https://github.com/storybookjs/storybook/pull/30188), thanks @dannyhw!
- RNW-Vite: Integrate with experimental-addon-test - [#29645](https://github.com/storybookjs/storybook/pull/29645), thanks @shilman!
- Storysource Addon: Fix source-loader prettier imports - [#29669](https://github.com/storybookjs/storybook/pull/29669), thanks @slax57!
- Telemetry: Add metadata distinguishing "apps" from "design systems" - [#30070](https://github.com/storybookjs/storybook/pull/30070), thanks @tmeasday!
- Test: Add coverage feature - [#29713](https://github.com/storybookjs/storybook/pull/29713), thanks @ndelangen!
- TestAddon: Refactor UI & add config options - [#29662](https://github.com/storybookjs/storybook/pull/29662), thanks @ndelangen!
- Toolbars: Suppress deprecation warning when using dynamic icons - [#29545](https://github.com/storybookjs/storybook/pull/29545), thanks @ValeraS!
- UI: Add support for groups to `TooltipLinkList` and use it in main menu - [#29507](https://github.com/storybookjs/storybook/pull/29507), thanks @ghengeveld!
- UI: Add Yarn to About Section - [#29225](https://github.com/storybookjs/storybook/pull/29225), thanks @grantwforsythe!
- UI: Fix controls and parameters on tag-filtered stories - [#30038](https://github.com/storybookjs/storybook/pull/30038), thanks @shilman!
- UI: Fix overlapping shadow of testing module on scrollbar - [#30132](https://github.com/storybookjs/storybook/pull/30132), thanks @valentinpalkovic!
- 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!
- UI: Sidebar context menu addon API - [#29557](https://github.com/storybookjs/storybook/pull/29557), thanks @ndelangen!
- Vite: Add extra entries to `optimizeDeps` - [#30117](https://github.com/storybookjs/storybook/pull/30117), thanks @ndelangen!
- Vite: Don\'t prefix story import with `@fs` - [#28941](https://github.com/storybookjs/storybook/pull/28941), thanks @tobiasdiez!
- Vite: Fix preview runtime import - [#29802](https://github.com/storybookjs/storybook/pull/29802), thanks @yannbf!
- Vite: Fix wrong import paths when configDir is not in project root - [#30206](https://github.com/storybookjs/storybook/pull/30206), thanks @JReinhold!
- Vite: Import preview runtime as ordinary module - [#29172](https://github.com/storybookjs/storybook/pull/29172), thanks @tobiasdiez!
- Vitest: Add plugins from `viteFinal` - [#30105](https://github.com/storybookjs/storybook/pull/30105), thanks @JReinhold!
- Vue: Extend sourceDecorator to support v-bind and nested keys in slots - [#28787](https://github.com/storybookjs/storybook/pull/28787), thanks @JoCa96!
- Vue: Fix `vue-component-meta` docgen HMR not working - [#29518](https://github.com/storybookjs/storybook/pull/29518), thanks @IonianPlayboy!
</details>
## 8.4.7
- Telemetry: Improve anonymous id calculation - [#29736](https://github.com/storybookjs/storybook/pull/29736), thanks @tmeasday!

View File

@ -1,3 +1,11 @@
## 8.6.0-alpha.0
## 8.5.0-beta.11
- CLI: Update a11y-test comment with experimental caveat - [#30258](https://github.com/storybookjs/storybook/pull/30258), thanks @shilman!
- Manager API: Fix infinite render-loop caused by `useSharedState` - [#30259](https://github.com/storybookjs/storybook/pull/30259), thanks @JReinhold!
## 8.5.0-beta.10
- Addon A11y: Adjust default behaviour when using with experimental-addon-test - [#30162](https://github.com/storybookjs/storybook/pull/30162), thanks @valentinpalkovic!

View File

@ -24,7 +24,7 @@ export default mergeConfig(
plugins: [
import('@storybook/experimental-addon-test/vitest-plugin').then(({ storybookTest }) =>
storybookTest({
configDir: process.cwd(),
configDir: __dirname,
tags: {
include: ['vitest'],
},

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Test component compliance with web accessibility standards",
"keywords": [
"a11y",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Get UI feedback when an action is performed on an interactive element",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Switch backgrounds to view components in different settings",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-controls",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Interact with component inputs dynamically in the Storybook UI",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Document component usage and properties in Markdown",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-essentials",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Curated addons to bring out the best of Storybook",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-mdx-gfm",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "GitHub Flavored Markdown in Storybook",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-highlight",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Highlight DOM nodes within your stories",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-interactions",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Automate, test and debug user interactions",
"keywords": [
"storybook-addons",

View File

@ -1,10 +1 @@
const { checkActionsLoaded } = require('./dist/preset');
function previewAnnotations(entry = [], options) {
checkActionsLoaded(options.configDir);
return entry;
}
module.exports = {
previewAnnotations,
};
module.exports = require('./dist/preset');

View File

@ -2,7 +2,7 @@ import { isAbsolute, join } from 'node:path';
import { checkAddonOrder, serverRequire } from 'storybook/internal/common';
export const checkActionsLoaded = (configDir: string) => {
export function previewAnnotations(entry: string[] = [], options: { configDir: string }) {
checkAddonOrder({
before: {
name: '@storybook/addon-actions',
@ -12,12 +12,13 @@ export const checkActionsLoaded = (configDir: string) => {
name: '@storybook/addon-interactions',
inEssentials: false,
},
configFile: isAbsolute(configDir)
? join(configDir, 'main')
: join(process.cwd(), configDir, 'main'),
configFile: isAbsolute(options.configDir)
? join(options.configDir, 'main')
: join(process.cwd(), options.configDir, 'main'),
getConfig: (configFile) => serverRequire(configFile),
});
};
return entry;
}
// This annotation is read by addon-test, so it can throw an error if both addons are used
export const ADDON_INTERACTIONS_IN_USE = true;

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Link stories together to build demos and prototypes with your UI components",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-measure",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Inspect layouts by visualizing the box model",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-onboarding",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook Addon Onboarding - Introduces a new onboarding experience",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-outline",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Outline all elements with CSS to help with layout placement and alignment",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storysource",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "View a storys source code to see how it works and paste into your app",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/experimental-addon-test",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Integrate Vitest with Storybook",
"keywords": [
"storybook-addons",
@ -95,8 +95,8 @@
"@types/istanbul-lib-report": "^3.0.3",
"@types/node": "^22.0.0",
"@types/semver": "^7",
"@vitest/browser": "^2.1.3",
"@vitest/runner": "^2.1.3",
"@vitest/browser": "3.0.0-beta.4",
"@vitest/runner": "3.0.0-beta.4",
"ansi-to-html": "^0.7.2",
"boxen": "^8.0.1",
"es-toolkit": "^1.22.0",
@ -116,13 +116,13 @@
"tree-kill": "^1.2.2",
"ts-dedent": "^2.2.0",
"typescript": "^5.3.2",
"vitest": "^2.1.3"
"vitest": "3.0.0-beta.4"
},
"peerDependencies": {
"@vitest/browser": "^2.1.1",
"@vitest/runner": "^2.1.1",
"@vitest/browser": "^2.1.1 || ^3.0.0",
"@vitest/runner": "^2.1.1 || ^3.0.0",
"storybook": "workspace:^",
"vitest": "^2.1.1"
"vitest": "^2.1.1 || ^3.0.0"
},
"peerDependenciesMeta": {
"@vitest/browser": {

View File

@ -1,5 +1,6 @@
import type { TaskState } from 'vitest';
import type { Vitest } from 'vitest/node';
import * as vitestNode from 'vitest/node';
import { type Reporter } from 'vitest/reporters';
import type {
@ -12,6 +13,7 @@ import type { API_StatusUpdate } from '@storybook/types';
import type { Suite } from '@vitest/runner';
import { throttle } from 'es-toolkit';
import { satisfies } from 'semver';
import { TEST_PROVIDER_ID } from '../constants';
import type { TestManager } from './test-manager';
@ -50,8 +52,15 @@ const statusMap: Record<TaskState, TestStatus> = {
run: 'pending',
skip: 'skipped',
todo: 'skipped',
queued: 'pending',
};
const vitestVersion = vitestNode.version;
const isVitest3OrLater = vitestVersion
? satisfies(vitestVersion, '>=3.0.0-beta.3', { includePrerelease: true })
: false;
export class StorybookReporter implements Reporter {
testStatusData: API_StatusUpdate = {};
@ -213,7 +222,10 @@ export class StorybookReporter implements Reporter {
async onFinished() {
const unhandledErrors = this.ctx.state.getUnhandledErrors();
const isCancelled = this.ctx.isCancelling;
const isCancelled = isVitest3OrLater
? this.testManager.vitestManager.isCancelling
: // @ts-expect-error isCancelling is private in Vitest 3.
this.ctx.isCancelling;
const report = await this.getProgressReport(Date.now());
const testSuiteFailures = report.details.testResults.filter(

View File

@ -19,20 +19,21 @@ const vitest = vi.hoisted(() => ({
cancelCurrentRun: vi.fn(),
globTestSpecs: vi.fn(),
getModuleProjects: vi.fn(() => []),
configOverride: {
actualTestNamePattern: undefined,
get testNamePattern() {
return this.actualTestNamePattern!;
setGlobalTestNamePattern: setTestNamePattern,
vite: {
watcher: {
removeAllListeners: vi.fn(),
on: vi.fn(),
},
set testNamePattern(value: string) {
setTestNamePattern(value);
// @ts-expect-error Ignore for testing
this.actualTestNamePattern = value;
moduleGraph: {
getModulesByFile: () => [],
invalidateModule: vi.fn(),
},
},
}));
vi.mock('vitest/node', () => ({
vi.mock('vitest/node', async (importOriginal) => ({
...(await importOriginal()),
createVitest: vi.fn(() => Promise.resolve(vitest)),
}));
const createVitest = vi.mocked(actualCreateVitest);
@ -137,7 +138,6 @@ describe('TestManager', () => {
storyIds: [],
});
expect(vitest.runFiles).toHaveBeenCalledWith([], true);
expect(vitest.configOverride.testNamePattern).toBeUndefined();
await testManager.handleRunRequest({
providerId: TEST_PROVIDER_ID,

View File

@ -4,10 +4,12 @@ import type {
CoverageOptions,
ResolvedCoverageOptions,
TestProject,
TestRunResult,
TestSpecification,
Vitest,
WorkspaceProject,
} from 'vitest/node';
import * as vitestNode from 'vitest/node';
import { resolvePathInStorybookCache } from 'storybook/internal/common';
import type { TestingModuleRunRequestPayload } from 'storybook/internal/core-events';
@ -16,6 +18,7 @@ import type { DocsIndexEntry, StoryIndex, StoryIndexEntry } from '@storybook/typ
import { findUp } from 'find-up';
import path, { dirname, join, normalize } from 'pathe';
import { satisfies } from 'semver';
import slash from 'slash';
import { COVERAGE_DIRECTORY, type Config } from '../constants';
@ -35,6 +38,11 @@ type TagsFilter = {
const packageDir = dirname(require.resolve('@storybook/experimental-addon-test/package.json'));
const vitestVersion = vitestNode.version;
const isVitest3OrLater = vitestVersion
? satisfies(vitestVersion, '>=3.0.0-beta.3', { includePrerelease: true })
: false;
// We have to tell Vitest that it runs as part of Storybook
process.env.VITEST_STORYBOOK = 'true';
@ -47,6 +55,10 @@ export class VitestManager {
storyCountForCurrentRun: number = 0;
runningPromise: Promise<any> | null = null;
isCancelling = false;
constructor(private testManager: TestManager) {}
async startVitest({ coverage = false } = {}) {
@ -123,7 +135,7 @@ export class VitestManager {
await this.vitestRestartPromise;
this.vitestRestartPromise = new Promise(async (resolve, reject) => {
try {
await this.vitest?.runningPromise;
await this.runningPromise;
await this.closeVitest();
await this.startVitest({ coverage });
resolve();
@ -136,6 +148,21 @@ export class VitestManager {
return this.vitestRestartPromise;
}
private setGlobalTestNamePattern(pattern: string | RegExp) {
if (isVitest3OrLater) {
this.vitest!.setGlobalTestNamePattern(pattern);
} else {
// @ts-expect-error vitest.configOverride is a Vitest < 3 API.
this.vitest!.configOverride.testNamePattern = pattern;
}
}
private resetGlobalTestNamePattern() {
if (this.vitest) {
this.setGlobalTestNamePattern('');
}
}
private updateLastChanged(filepath: string) {
const projects = this.vitest!.getModuleProjects(filepath);
projects.forEach(({ server, browser }) => {
@ -183,6 +210,23 @@ export class VitestManager {
return true;
}
private get vite() {
// TODO: vitest.server is a Vitest < 3.0.0 API. Remove as soon as we don't support < 3.0.0 anymore.
return isVitest3OrLater ? this.vitest?.vite : this.vitest?.server;
}
async runFiles(specifications: TestSpecification[], allTestsRun?: boolean) {
this.isCancelling = false;
const runTest: (
specifications: TestSpecification[],
allTestsRun?: boolean | undefined
// @ts-expect-error vitest.runFiles is a Vitest < 3.0.0 API. Remove as soon as we don't support < 3.0.0 anymore.
) => Promise<TestRunResult> = this.vitest!.runFiles ?? this.vitest!.runTestSpecifications;
this.runningPromise = runTest.call(this.vitest, specifications, allTestsRun);
await this.runningPromise;
this.runningPromise = null;
}
async runTests(requestPayload: TestingModuleRunRequestPayload<Config>) {
if (!this.vitest) {
await this.startVitest();
@ -190,7 +234,7 @@ export class VitestManager {
await this.vitestRestartPromise;
}
this.resetTestNamePattern();
this.resetGlobalTestNamePattern();
const stories = await this.fetchStories(requestPayload.indexUrl, requestPayload.storyIds);
const vitestTestSpecs = await this.getStorybookTestSpecs();
@ -229,18 +273,19 @@ export class VitestManager {
if (isSingleStoryRun) {
const storyName = stories[0].name;
this.vitest!.configOverride.testNamePattern = new RegExp(
`^${storyName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`
);
const regex = new RegExp(`^${storyName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`);
this.setGlobalTestNamePattern(regex);
}
await this.vitest!.runFiles(filteredTestFiles, true);
this.resetTestNamePattern();
await this.runFiles(filteredTestFiles, true);
this.resetGlobalTestNamePattern();
}
async cancelCurrentRun() {
this.isCancelling = true;
await this.vitest?.cancelCurrentRun('keyboard-input');
await this.vitest?.runningPromise;
await this.runningPromise;
this.isCancelling = false;
}
async closeVitest() {
@ -255,22 +300,26 @@ export class VitestManager {
}
private async getTestDependencies(spec: TestSpecification, deps = new Set<string>()) {
const addImports = async (project: WorkspaceProject, filepath: string) => {
const addImports = async (project: TestProject, filepath: string) => {
if (deps.has(filepath)) {
return;
}
deps.add(filepath);
const mod = project.server.moduleGraph.getModuleById(filepath);
const transformed =
mod?.ssrTransformResult || (await project.vitenode.transformRequest(filepath));
// TODO: Remove project.server once we don't support Vitest < 3.0.0 anymore
const server = isVitest3OrLater ? project.vite : project.server;
const mod = server.moduleGraph.getModuleById(filepath);
// @ts-expect-error project.vitenode is a Vitest < 3 API.
const viteNode = isVitest3OrLater ? project.vite : project.vitenode;
const transformed = mod?.ssrTransformResult || (await viteNode.transformRequest(filepath));
if (!transformed) {
return;
}
const dependencies = [...(transformed.deps || []), ...(transformed.dynamicDeps || [])];
await Promise.all(
dependencies.map(async (dep) => {
const idPath = await project.server.pluginContainer.resolveId(dep, filepath, {
const idPath = await server.pluginContainer.resolveId(dep, filepath, {
ssr: true,
});
const fsPath = idPath && !idPath.external && idPath.id.split('?')[0];
@ -286,7 +335,11 @@ export class VitestManager {
);
};
await addImports(spec.project.workspaceProject, spec.moduleId);
await addImports(
// @ts-expect-error spec.project.workspaceProject is a Vitest < 3 API.
isVitest3OrLater ? spec.project : spec.project.workspaceProject,
spec.moduleId
);
deps.delete(spec.moduleId);
return deps;
@ -296,9 +349,14 @@ export class VitestManager {
if (!this.vitest) {
return;
}
this.resetTestNamePattern();
this.resetGlobalTestNamePattern();
const globTestSpecs: (filters?: string[] | undefined) => Promise<TestSpecification[]> =
// TODO: vitest.globTestSpecs is a Vitest < 3.0.0 API.
isVitest3OrLater ? this.vitest.globTestSpecifications : this.vitest.globTestSpecs;
const globTestFiles = await globTestSpecs.call(this.vitest);
const globTestFiles = await this.vitest.globTestSpecs();
const testGraphs = await Promise.all(
globTestFiles
.filter((workspace) => this.isStorybookProject(workspace.project))
@ -317,8 +375,8 @@ export class VitestManager {
if (triggerAffectedTests.length) {
await this.vitest.cancelCurrentRun('keyboard-input');
await this.vitest.runningPromise;
await this.vitest.runFiles(triggerAffectedTests, false);
await this.runningPromise;
await this.runFiles(triggerAffectedTests, false);
}
}
@ -338,9 +396,9 @@ export class VitestManager {
}
async registerVitestConfigListener() {
this.vitest?.server?.watcher.on('change', async (file) => {
this.vite?.watcher.on('change', async (file) => {
file = normalize(file);
const isConfig = file === this.vitest?.server.config.configFile;
const isConfig = file === this.vite?.config.configFile;
if (isConfig) {
log('Restarting Vitest due to config change');
await this.closeVitest();
@ -350,20 +408,15 @@ export class VitestManager {
}
async setupWatchers() {
this.resetTestNamePattern();
this.vitest?.server?.watcher.removeAllListeners('change');
this.vitest?.server?.watcher.removeAllListeners('add');
this.vitest?.server?.watcher.on('change', this.runAffectedTestsAfterChange.bind(this));
this.vitest?.server?.watcher.on('add', this.runAffectedTestsAfterChange.bind(this));
this.resetGlobalTestNamePattern();
const server = this.vite;
server?.watcher.removeAllListeners('change');
server?.watcher.removeAllListeners('add');
server?.watcher.on('change', this.runAffectedTestsAfterChange.bind(this));
server?.watcher.on('add', this.runAffectedTestsAfterChange.bind(this));
this.registerVitestConfigListener();
}
resetTestNamePattern() {
if (this.vitest) {
this.vitest.configOverride.testNamePattern = undefined;
}
}
isStorybookProject(project: TestProject | WorkspaceProject) {
// eslint-disable-next-line no-underscore-dangle
return !!project.config.env?.__STORYBOOK_URL__;

View File

@ -6,6 +6,7 @@ import { traverse } from 'storybook/internal/babel';
import {
JsPackageManagerFactory,
extractProperFrameworkName,
formatFileContent,
loadAllPresets,
loadMainConfig,
serverResolve,
@ -415,8 +416,18 @@ export default async function postInstall(options: PostinstallOptions) {
}
const vitestConfigFile = await findFile('vitest.config');
const vitestShimFile = await findFile('vitest.shims.d');
const rootConfig = vitestConfigFile || viteConfigFile;
const isVitest3OrLater = !!(coercedVitestVersion && satisfies(coercedVitestVersion, '>=3.0.0'));
if (isVitest3OrLater && fileExtension === 'ts' && !vitestShimFile) {
await writeFile(
'vitest.shims.d.ts',
'/// <reference types="@vitest/browser/providers/playwright" />'
);
}
if (rootConfig) {
// If there's an existing config, we create a workspace file so we can run Storybook tests alongside.
const extension = extname(rootConfig);
@ -430,7 +441,9 @@ export default async function postInstall(options: PostinstallOptions) {
await writeFile(
browserWorkspaceFile,
dedent`
await formatFileContent(
browserWorkspaceFile,
dedent`
import { defineWorkspace } from 'vitest/config';
import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin';
import path from 'node:path';
@ -463,6 +476,7 @@ export default async function postInstall(options: PostinstallOptions) {
},
]);
`.replace(/\s+extends: '',/, '')
)
);
} else {
// If there's no existing Vitest/Vite config, we create a new Vitest config file.

View File

@ -1,7 +1,7 @@
/* eslint-disable no-underscore-dangle */
import { type ChildProcess, spawn } from 'node:child_process';
import type { GlobalSetupContext } from 'vitest/node';
import type { TestProject } from 'vitest/node';
import { logger } from 'storybook/internal/node-logger';
@ -61,7 +61,7 @@ const startStorybookIfNotRunning = async () => {
}
};
export const setup = async ({ config }: GlobalSetupContext) => {
export const setup = async ({ config }: TestProject) => {
if (config.watch && isVitestStandaloneRun) {
await startStorybookIfNotRunning();
}

View File

@ -209,7 +209,6 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin[]> =>
}
: {}),
// @ts-expect-error: TODO
browser: {
...inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test?.browser,
commands: {

View File

@ -36,7 +36,7 @@ describe('modifyErrorMessage', () => {
it('should not modify the error message if task type is not "test"', () => {
const task: Task = {
type: 'custom',
type: 'suite',
result: {
state: 'fail',
errors: [{ message: 'Original error message' }],

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable no-underscore-dangle */
import { type RunnerTask, type TaskContext, type TaskMeta, type TestContext } from 'vitest';
import { type RunnerTask, type TaskMeta, type TestContext } from 'vitest';
import { type Report, composeStory } from 'storybook/internal/preview-api';
import type { ComponentAnnotations, ComposedStoryFn } from 'storybook/internal/types';
@ -25,7 +25,7 @@ export const testStory = (
meta: ComponentAnnotations,
skipTags: string[]
) => {
return async (context: TestContext & TaskContext & { story: ComposedStoryFn }) => {
return async (context: TestContext & { story: ComposedStoryFn }) => {
const composedStory = composeStory(
story,
meta,

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-themes",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Switch between multiple themes for you components in Storybook",
"keywords": [
"css",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-toolbars",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Create your own toolbar items that control story rendering",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-viewport",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Build responsive components by adjusting Storybooks viewport size and orientation",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "A plugin to run and build Storybooks with Vite",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -60,7 +60,8 @@ export async function wrapManagerEntries(entrypoints: string[], uniqueId?: strin
const directory = dirname(location);
await mkdir(directory, { recursive: true });
}
await writeFile(location, `import '${slash(entry)}';`);
await writeFile(location, `import '${slash(entry).replaceAll(/'/g, "\\'")}';`);
return location;
})

View File

@ -3,8 +3,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { ChannelTransport, Listener } from '.';
import { Channel, WebsocketTransport } from '.';
vi.useFakeTimers();
const MockedWebsocket = vi.hoisted(() => {
const ref = { current: undefined as unknown as InstanceType<typeof MyMockedWebsocket> };
class MyMockedWebsocket {

View File

@ -1,88 +1,88 @@
// auto generated file, do not edit
export default {
'@storybook/addon-a11y': '8.5.0-beta.10',
'@storybook/addon-actions': '8.5.0-beta.10',
'@storybook/addon-backgrounds': '8.5.0-beta.10',
'@storybook/addon-controls': '8.5.0-beta.10',
'@storybook/addon-docs': '8.5.0-beta.10',
'@storybook/addon-essentials': '8.5.0-beta.10',
'@storybook/addon-mdx-gfm': '8.5.0-beta.10',
'@storybook/addon-highlight': '8.5.0-beta.10',
'@storybook/addon-interactions': '8.5.0-beta.10',
'@storybook/addon-jest': '8.5.0-beta.10',
'@storybook/addon-links': '8.5.0-beta.10',
'@storybook/addon-measure': '8.5.0-beta.10',
'@storybook/addon-onboarding': '8.5.0-beta.10',
'@storybook/addon-outline': '8.5.0-beta.10',
'@storybook/addon-storysource': '8.5.0-beta.10',
'@storybook/experimental-addon-test': '8.5.0-beta.10',
'@storybook/addon-themes': '8.5.0-beta.10',
'@storybook/addon-toolbars': '8.5.0-beta.10',
'@storybook/addon-viewport': '8.5.0-beta.10',
'@storybook/builder-vite': '8.5.0-beta.10',
'@storybook/builder-webpack5': '8.5.0-beta.10',
'@storybook/core': '8.5.0-beta.10',
'@storybook/builder-manager': '8.5.0-beta.10',
'@storybook/channels': '8.5.0-beta.10',
'@storybook/client-logger': '8.5.0-beta.10',
'@storybook/components': '8.5.0-beta.10',
'@storybook/core-common': '8.5.0-beta.10',
'@storybook/core-events': '8.5.0-beta.10',
'@storybook/core-server': '8.5.0-beta.10',
'@storybook/csf-tools': '8.5.0-beta.10',
'@storybook/docs-tools': '8.5.0-beta.10',
'@storybook/manager': '8.5.0-beta.10',
'@storybook/manager-api': '8.5.0-beta.10',
'@storybook/node-logger': '8.5.0-beta.10',
'@storybook/preview': '8.5.0-beta.10',
'@storybook/preview-api': '8.5.0-beta.10',
'@storybook/router': '8.5.0-beta.10',
'@storybook/telemetry': '8.5.0-beta.10',
'@storybook/theming': '8.5.0-beta.10',
'@storybook/types': '8.5.0-beta.10',
'@storybook/angular': '8.5.0-beta.10',
'@storybook/ember': '8.5.0-beta.10',
'@storybook/experimental-nextjs-vite': '8.5.0-beta.10',
'@storybook/html-vite': '8.5.0-beta.10',
'@storybook/html-webpack5': '8.5.0-beta.10',
'@storybook/nextjs': '8.5.0-beta.10',
'@storybook/preact-vite': '8.5.0-beta.10',
'@storybook/preact-webpack5': '8.5.0-beta.10',
'@storybook/react-native-web-vite': '8.5.0-beta.10',
'@storybook/react-vite': '8.5.0-beta.10',
'@storybook/react-webpack5': '8.5.0-beta.10',
'@storybook/server-webpack5': '8.5.0-beta.10',
'@storybook/svelte-vite': '8.5.0-beta.10',
'@storybook/svelte-webpack5': '8.5.0-beta.10',
'@storybook/sveltekit': '8.5.0-beta.10',
'@storybook/vue3-vite': '8.5.0-beta.10',
'@storybook/vue3-webpack5': '8.5.0-beta.10',
'@storybook/web-components-vite': '8.5.0-beta.10',
'@storybook/web-components-webpack5': '8.5.0-beta.10',
'@storybook/blocks': '8.5.0-beta.10',
storybook: '8.5.0-beta.10',
sb: '8.5.0-beta.10',
'@storybook/cli': '8.5.0-beta.10',
'@storybook/codemod': '8.5.0-beta.10',
'@storybook/core-webpack': '8.5.0-beta.10',
'create-storybook': '8.5.0-beta.10',
'@storybook/csf-plugin': '8.5.0-beta.10',
'@storybook/instrumenter': '8.5.0-beta.10',
'@storybook/react-dom-shim': '8.5.0-beta.10',
'@storybook/source-loader': '8.5.0-beta.10',
'@storybook/test': '8.5.0-beta.10',
'@storybook/preset-create-react-app': '8.5.0-beta.10',
'@storybook/preset-html-webpack': '8.5.0-beta.10',
'@storybook/preset-preact-webpack': '8.5.0-beta.10',
'@storybook/preset-react-webpack': '8.5.0-beta.10',
'@storybook/preset-server-webpack': '8.5.0-beta.10',
'@storybook/preset-svelte-webpack': '8.5.0-beta.10',
'@storybook/preset-vue3-webpack': '8.5.0-beta.10',
'@storybook/html': '8.5.0-beta.10',
'@storybook/preact': '8.5.0-beta.10',
'@storybook/react': '8.5.0-beta.10',
'@storybook/server': '8.5.0-beta.10',
'@storybook/svelte': '8.5.0-beta.10',
'@storybook/vue3': '8.5.0-beta.10',
'@storybook/web-components': '8.5.0-beta.10',
'@storybook/addon-a11y': '8.6.0-alpha.0',
'@storybook/addon-actions': '8.6.0-alpha.0',
'@storybook/addon-backgrounds': '8.6.0-alpha.0',
'@storybook/addon-controls': '8.6.0-alpha.0',
'@storybook/addon-docs': '8.6.0-alpha.0',
'@storybook/addon-essentials': '8.6.0-alpha.0',
'@storybook/addon-mdx-gfm': '8.6.0-alpha.0',
'@storybook/addon-highlight': '8.6.0-alpha.0',
'@storybook/addon-interactions': '8.6.0-alpha.0',
'@storybook/addon-jest': '8.6.0-alpha.0',
'@storybook/addon-links': '8.6.0-alpha.0',
'@storybook/addon-measure': '8.6.0-alpha.0',
'@storybook/addon-onboarding': '8.6.0-alpha.0',
'@storybook/addon-outline': '8.6.0-alpha.0',
'@storybook/addon-storysource': '8.6.0-alpha.0',
'@storybook/experimental-addon-test': '8.6.0-alpha.0',
'@storybook/addon-themes': '8.6.0-alpha.0',
'@storybook/addon-toolbars': '8.6.0-alpha.0',
'@storybook/addon-viewport': '8.6.0-alpha.0',
'@storybook/builder-vite': '8.6.0-alpha.0',
'@storybook/builder-webpack5': '8.6.0-alpha.0',
'@storybook/core': '8.6.0-alpha.0',
'@storybook/builder-manager': '8.6.0-alpha.0',
'@storybook/channels': '8.6.0-alpha.0',
'@storybook/client-logger': '8.6.0-alpha.0',
'@storybook/components': '8.6.0-alpha.0',
'@storybook/core-common': '8.6.0-alpha.0',
'@storybook/core-events': '8.6.0-alpha.0',
'@storybook/core-server': '8.6.0-alpha.0',
'@storybook/csf-tools': '8.6.0-alpha.0',
'@storybook/docs-tools': '8.6.0-alpha.0',
'@storybook/manager': '8.6.0-alpha.0',
'@storybook/manager-api': '8.6.0-alpha.0',
'@storybook/node-logger': '8.6.0-alpha.0',
'@storybook/preview': '8.6.0-alpha.0',
'@storybook/preview-api': '8.6.0-alpha.0',
'@storybook/router': '8.6.0-alpha.0',
'@storybook/telemetry': '8.6.0-alpha.0',
'@storybook/theming': '8.6.0-alpha.0',
'@storybook/types': '8.6.0-alpha.0',
'@storybook/angular': '8.6.0-alpha.0',
'@storybook/ember': '8.6.0-alpha.0',
'@storybook/experimental-nextjs-vite': '8.6.0-alpha.0',
'@storybook/html-vite': '8.6.0-alpha.0',
'@storybook/html-webpack5': '8.6.0-alpha.0',
'@storybook/nextjs': '8.6.0-alpha.0',
'@storybook/preact-vite': '8.6.0-alpha.0',
'@storybook/preact-webpack5': '8.6.0-alpha.0',
'@storybook/react-native-web-vite': '8.6.0-alpha.0',
'@storybook/react-vite': '8.6.0-alpha.0',
'@storybook/react-webpack5': '8.6.0-alpha.0',
'@storybook/server-webpack5': '8.6.0-alpha.0',
'@storybook/svelte-vite': '8.6.0-alpha.0',
'@storybook/svelte-webpack5': '8.6.0-alpha.0',
'@storybook/sveltekit': '8.6.0-alpha.0',
'@storybook/vue3-vite': '8.6.0-alpha.0',
'@storybook/vue3-webpack5': '8.6.0-alpha.0',
'@storybook/web-components-vite': '8.6.0-alpha.0',
'@storybook/web-components-webpack5': '8.6.0-alpha.0',
'@storybook/blocks': '8.6.0-alpha.0',
storybook: '8.6.0-alpha.0',
sb: '8.6.0-alpha.0',
'@storybook/cli': '8.6.0-alpha.0',
'@storybook/codemod': '8.6.0-alpha.0',
'@storybook/core-webpack': '8.6.0-alpha.0',
'create-storybook': '8.6.0-alpha.0',
'@storybook/csf-plugin': '8.6.0-alpha.0',
'@storybook/instrumenter': '8.6.0-alpha.0',
'@storybook/react-dom-shim': '8.6.0-alpha.0',
'@storybook/source-loader': '8.6.0-alpha.0',
'@storybook/test': '8.6.0-alpha.0',
'@storybook/preset-create-react-app': '8.6.0-alpha.0',
'@storybook/preset-html-webpack': '8.6.0-alpha.0',
'@storybook/preset-preact-webpack': '8.6.0-alpha.0',
'@storybook/preset-react-webpack': '8.6.0-alpha.0',
'@storybook/preset-server-webpack': '8.6.0-alpha.0',
'@storybook/preset-svelte-webpack': '8.6.0-alpha.0',
'@storybook/preset-vue3-webpack': '8.6.0-alpha.0',
'@storybook/html': '8.6.0-alpha.0',
'@storybook/preact': '8.6.0-alpha.0',
'@storybook/react': '8.6.0-alpha.0',
'@storybook/server': '8.6.0-alpha.0',
'@storybook/svelte': '8.6.0-alpha.0',
'@storybook/vue3': '8.6.0-alpha.0',
'@storybook/web-components': '8.6.0-alpha.0',
};

View File

@ -5,42 +5,42 @@ import { dedent } from 'ts-dedent';
import { formatter } from './formatter';
describe('dedent', () => {
it('handles empty string', () => {
it('handles empty string', async () => {
const input = '';
const result = formatter(true, input);
expect(result).resolves.toBe(input);
await expect(result).resolves.toBe(input);
});
it('handles single line', () => {
it('handles single line', async () => {
const input = 'console.log("hello world")';
const result = formatter(true, input);
expect(result).resolves.toBe(input);
await expect(result).resolves.toBe(input);
});
it('does not transform correct code', () => {
it('does not transform correct code', async () => {
const input = dedent`
console.log("hello");
console.log("world");
`;
const result = formatter(true, input);
expect(result).resolves.toBe(input);
await expect(result).resolves.toBe(input);
});
it('does transform incorrect code', () => {
it('does transform incorrect code', async () => {
const input = `
console.log("hello");
console.log("world");
`;
const result = formatter(true, input);
expect(result).resolves.toBe(`console.log("hello");
await expect(result).resolves.toBe(`console.log("hello");
console.log("world");`);
});
it('more indentations - skip first line', () => {
it('more indentations - skip first line', async () => {
const input = `
it('handles empty string', () => {
const input = '';
@ -51,7 +51,7 @@ console.log("world");`);
`;
const result = formatter(true, input);
expect(result).resolves.toBe(`it('handles empty string', () => {
await expect(result).resolves.toBe(`it('handles empty string', () => {
const input = '';
const result = formatter(input);
@ -59,7 +59,7 @@ console.log("world");`);
});`);
});
it('more indentations - code on first line', () => {
it('more indentations - code on first line', async () => {
const input = `// some comment
it('handles empty string', () => {
const input = '';
@ -70,7 +70,7 @@ console.log("world");`);
`;
const result = formatter(true, input);
expect(result).resolves.toBe(`// some comment
await expect(result).resolves.toBe(`// some comment
it('handles empty string', () => {
const input = '';
const result = formatter(input);
@ -79,7 +79,7 @@ it('handles empty string', () => {
});`);
});
it('removes whitespace in empty line completely', () => {
it('removes whitespace in empty line completely', async () => {
const input = `
console.log("hello");
@ -87,24 +87,24 @@ it('handles empty string', () => {
`;
const result = formatter(true, input);
expect(result).resolves.toBe(`console.log("hello");
await expect(result).resolves.toBe(`console.log("hello");
console.log("world");`);
});
});
describe('prettier (babel)', () => {
it('handles empty string', () => {
it('handles empty string', async () => {
const input = '';
const result = formatter('angular', input);
expect(result).resolves.toBe(input);
await expect(result).resolves.toBe(input);
});
it('handles single line', () => {
it('handles single line', async () => {
const input = 'console.log("hello world")';
const result = formatter('angular', input);
expect(result).resolves.toBe(input);
await expect(result).resolves.toBe(input);
});
});

View File

@ -35,114 +35,110 @@ vi.mock('node:fs/promises', async (importOriginal) => {
};
});
describe(
'createNewStoryChannel',
() => {
const transport = { setHandler: vi.fn(), send: vi.fn() } satisfies ChannelTransport;
const mockChannel = new Channel({ transport });
const createNewStoryFileEventListener = vi.fn();
describe('createNewStoryChannel', () => {
const transport = { setHandler: vi.fn(), send: vi.fn() } satisfies ChannelTransport;
const mockChannel = new Channel({ transport });
const createNewStoryFileEventListener = vi.fn();
beforeEach(() => {
transport.setHandler.mockClear();
transport.send.mockClear();
createNewStoryFileEventListener.mockClear();
});
beforeEach(() => {
transport.setHandler.mockClear();
transport.send.mockClear();
createNewStoryFileEventListener.mockClear();
});
describe('initCreateNewStoryChannel', () => {
it('should emit an event with a story id', async () => {
mockChannel.addListener(CREATE_NEW_STORYFILE_RESPONSE, createNewStoryFileEventListener);
const cwd = process.cwd();
describe('initCreateNewStoryChannel', { retry: 3 }, () => {
it('should emit an event with a story id', async () => {
mockChannel.addListener(CREATE_NEW_STORYFILE_RESPONSE, createNewStoryFileEventListener);
const cwd = process.cwd();
initCreateNewStoryChannel(
mockChannel,
{
configDir: join(cwd, '.storybook'),
presets: {
apply: (val: string) => {
if (val === 'framework') {
return Promise.resolve('@storybook/nextjs');
}
if (val === 'stories') {
return Promise.resolve(['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)']);
}
},
initCreateNewStoryChannel(
mockChannel,
{
configDir: join(cwd, '.storybook'),
presets: {
apply: (val: string) => {
if (val === 'framework') {
return Promise.resolve('@storybook/nextjs');
}
if (val === 'stories') {
return Promise.resolve(['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)']);
}
},
} as any,
{ disableTelemetry: true }
);
mockChannel.emit(CREATE_NEW_STORYFILE_REQUEST, {
id: 'components-page--default',
payload: {
componentFilePath: 'src/components/Page.jsx',
componentExportName: 'Page',
componentIsDefaultExport: true,
},
});
} as any,
{ disableTelemetry: true }
);
await vi.waitFor(() => {
expect(createNewStoryFileEventListener).toHaveBeenCalled();
});
expect(createNewStoryFileEventListener).toHaveBeenCalledWith({
error: null,
id: 'components-page--default',
payload: {
storyId: 'components-page--default',
storyFilePath: join('src', 'components', 'Page.stories.jsx'),
exportedStoryName: 'Default',
},
success: true,
});
mockChannel.emit(CREATE_NEW_STORYFILE_REQUEST, {
id: 'components-page--default',
payload: {
componentFilePath: 'src/components/Page.jsx',
componentExportName: 'Page',
componentIsDefaultExport: true,
},
});
it('should emit an error event if an error occurs', async () => {
mockChannel.addListener(CREATE_NEW_STORYFILE_RESPONSE, createNewStoryFileEventListener);
const cwd = process.cwd();
await vi.waitFor(() => {
expect(createNewStoryFileEventListener).toHaveBeenCalled();
});
mockFs.writeFile.mockImplementation(() => {
throw new Error('Failed to write file');
});
initCreateNewStoryChannel(
mockChannel,
{
configDir: join(cwd, '.storybook'),
presets: {
apply: (val: string) => {
if (val === 'framework') {
return Promise.resolve('@storybook/nextjs');
}
if (val === 'stories') {
return Promise.resolve(['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)']);
}
},
},
} as any,
{ disableTelemetry: true }
);
mockChannel.emit(CREATE_NEW_STORYFILE_REQUEST, {
id: 'components-page--default',
payload: {
componentFilePath: 'src/components/Page.jsx',
componentExportName: 'Page',
componentIsDefaultExport: true,
componentExportCount: 1,
},
} satisfies RequestData<CreateNewStoryRequestPayload>);
await vi.waitFor(() => {
expect(createNewStoryFileEventListener).toHaveBeenCalled();
});
expect(createNewStoryFileEventListener).toHaveBeenCalledWith({
error: 'Failed to write file',
id: 'components-page--default',
success: false,
});
expect(createNewStoryFileEventListener).toHaveBeenCalledWith({
error: null,
id: 'components-page--default',
payload: {
storyId: 'components-page--default',
storyFilePath: join('src', 'components', 'Page.stories.jsx'),
exportedStoryName: 'Default',
},
success: true,
});
});
},
{ retry: 3 }
);
it('should emit an error event if an error occurs', async () => {
mockChannel.addListener(CREATE_NEW_STORYFILE_RESPONSE, createNewStoryFileEventListener);
const cwd = process.cwd();
mockFs.writeFile.mockImplementation(() => {
throw new Error('Failed to write file');
});
initCreateNewStoryChannel(
mockChannel,
{
configDir: join(cwd, '.storybook'),
presets: {
apply: (val: string) => {
if (val === 'framework') {
return Promise.resolve('@storybook/nextjs');
}
if (val === 'stories') {
return Promise.resolve(['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)']);
}
},
},
} as any,
{ disableTelemetry: true }
);
mockChannel.emit(CREATE_NEW_STORYFILE_REQUEST, {
id: 'components-page--default',
payload: {
componentFilePath: 'src/components/Page.jsx',
componentExportName: 'Page',
componentIsDefaultExport: true,
componentExportCount: 1,
},
} satisfies RequestData<CreateNewStoryRequestPayload>);
await vi.waitFor(() => {
expect(createNewStoryFileEventListener).toHaveBeenCalled();
});
expect(createNewStoryFileEventListener).toHaveBeenCalledWith({
error: 'Failed to write file',
id: 'components-page--default',
success: false,
});
});
});
});

View File

@ -83,9 +83,9 @@ describe('success', () => {
const parsed = CSF.parse();
const names = Object.keys(parsed._stories);
names.forEach((name) => {
expect(() => duplicateStoryWithNewName(parsed, name, name + 'Duplicated')).toThrow();
});
for (const name of names) {
await expect(() => duplicateStoryWithNewName(parsed, name, name + 'Duplicated')).toThrow();
}
});
test('Typescript Constructs', async () => {
const before = await format(await readFile(FILES.typescriptConstructs, 'utf-8'), {

View File

@ -103,9 +103,9 @@ describe('success', () => {
const names = Object.keys(parsed._stories);
const nodes = names.map((name) => CSF.getStoryExport(name));
nodes.forEach((node) => {
expect(() => updateArgsInCsfFile(node, newArgs)).rejects.toThrowError();
});
for (const node of nodes) {
await expect(() => updateArgsInCsfFile(node, newArgs)).rejects.toThrowError();
}
});
test('CSF Variances', async () => {
const newArgs = { bordered: true, initial: 'test1' };

View File

@ -400,13 +400,17 @@ export function useSharedState<S>(stateId: string, defaultState?: S) {
}
}, [quicksync]);
const setState = async (s: S | API_StateMerger<S>, options?: Options) => {
await api.setAddonState<S>(stateId, s, options);
const result = api.getAddonState(stateId);
const setState = useCallback(
async (s: S | API_StateMerger<S>, options?: Options) => {
await api.setAddonState<S>(stateId, s, options);
const result = api.getAddonState(stateId);
STORYBOOK_ADDON_STATE[stateId] = result;
return result;
},
[api, stateId]
);
STORYBOOK_ADDON_STATE[stateId] = result;
return result;
};
const allListeners = useMemo(() => {
const stateChangeHandlers = {
[`${SHARED_STATE_CHANGED}-client-${stateId}`]: setState,
@ -446,14 +450,20 @@ export function useSharedState<S>(stateId: string, defaultState?: S) {
}, [stateId]);
const emit = useChannel(allListeners);
return [
state,
const stateSetter = useCallback(
async (newStateOrMerger: S | API_StateMerger<S>, options?: Options) => {
await setState(newStateOrMerger, options);
const result = api.getAddonState(stateId);
emit(`${SHARED_STATE_CHANGED}-manager-${stateId}`, result);
},
] as [S, (newStateOrMerger: S | API_StateMerger<S>, options?: Options) => void];
[api, emit, setState, stateId]
);
return [state, stateSetter] as [
S,
(newStateOrMerger: S | API_StateMerger<S>, options?: Options) => void,
];
}
export function useAddonState<S>(addonId: string, defaultState?: S) {

View File

@ -11,7 +11,6 @@ import EventEmitter from 'events';
import { init as initURL } from '../modules/url';
vi.mock('@storybook/core/client-logger');
vi.useFakeTimers();
describe('initial state', () => {
const viewMode = 'story';

View File

@ -1 +1 @@
export const version = '8.5.0-beta.10';
export const version = '8.6.0-alpha.0';

View File

@ -104,122 +104,118 @@ beforeEach(() => {
* Skipping this test, because it causes a cyclical dependency error, where core depends on docs &
* blocks This was done to avoid a conflict in the CPC work, we should revisit this.
*/
describe.skip(
'PreviewWeb',
() => {
describe('initial render', () => {
it('renders story mode through the stack', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
describe('PreviewWeb', { skip: true }, () => {
describe('initial render', () => {
it('renders story mode through the stack', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
projectAnnotations.renderToCanvas.mockImplementationOnce(
({ storyFn }: RenderContext<any>) => storyFn()
);
document.location.search = '?id=component-one--a';
await new PreviewWeb(importFn, getProjectAnnotations).ready();
projectAnnotations.renderToCanvas.mockImplementationOnce(({ storyFn }: RenderContext<any>) =>
storyFn()
);
document.location.search = '?id=component-one--a';
await new PreviewWeb(importFn, getProjectAnnotations).ready();
await waitForRender();
await waitForRender();
await vi.waitFor(() => {
expect(projectAnnotations.decorators[0]).toHaveBeenCalled();
expect(projectAnnotations.render).toHaveBeenCalled();
});
});
it('renders docs mode through docs page', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
document.location.search = '?id=component-one--docs&viewMode=docs';
const preview = new PreviewWeb(importFn, getProjectAnnotations);
const docsRoot = document.createElement('div');
vi.mocked(preview.view.prepareForDocs).mockReturnValue(docsRoot as any);
componentOneExports.default.parameters.docs.container.mockImplementationOnce(() =>
React.createElement('div', {}, 'INSIDE')
);
await preview.ready();
await vi.waitFor(
() => {
if (docsRoot.outerHTML !== '<div><div>INSIDE</div></div>') {
throw new Error('DocsRoot not ready yet');
}
},
{
timeout: 2000,
}
);
expect(docsRoot.outerHTML).toMatchInlineSnapshot('"<div><div>INSIDE</div></div>"');
// Extended timeout to try and avoid
// Error: Event was not emitted in time: storyRendered,docsRendered,storyThrewException,storyErrored,storyMissing
}, 10_000);
it('sends docs rendering exceptions to showException', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
document.location.search = '?id=component-one--docs&viewMode=docs';
const preview = new PreviewWeb(importFn, getProjectAnnotations);
const docsRoot = document.createElement('div');
vi.mocked(preview.view.prepareForDocs).mockReturnValue(docsRoot as any);
componentOneExports.default.parameters.docs.container.mockImplementation(() => {
throw new Error('Docs rendering error');
});
vi.mocked(preview.view.showErrorDisplay).mockClear();
await preview.ready();
await vi.waitFor(
() => {
expect(preview.view.showErrorDisplay).toHaveBeenCalled();
},
{
timeout: 2000,
}
);
await vi.waitFor(() => {
expect(projectAnnotations.decorators[0]).toHaveBeenCalled();
expect(projectAnnotations.render).toHaveBeenCalled();
});
});
describe('onGetGlobalMeta changed (HMR)', () => {
const newGlobalDecorator = vi.fn((s) => s());
const newGetProjectAnnotations = () => {
return {
...projectAnnotations,
args: { a: 'second' },
globals: { a: 'second' },
decorators: [newGlobalDecorator],
};
it('renders docs mode through docs page', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
document.location.search = '?id=component-one--docs&viewMode=docs';
const preview = new PreviewWeb(importFn, getProjectAnnotations);
const docsRoot = document.createElement('div');
vi.mocked(preview.view.prepareForDocs).mockReturnValue(docsRoot as any);
componentOneExports.default.parameters.docs.container.mockImplementationOnce(() =>
React.createElement('div', {}, 'INSIDE')
);
await preview.ready();
await vi.waitFor(
() => {
if (docsRoot.outerHTML !== '<div><div>INSIDE</div></div>') {
throw new Error('DocsRoot not ready yet');
}
},
{
timeout: 2000,
}
);
expect(docsRoot.outerHTML).toMatchInlineSnapshot('"<div><div>INSIDE</div></div>"');
// Extended timeout to try and avoid
// Error: Event was not emitted in time: storyRendered,docsRendered,storyThrewException,storyErrored,storyMissing
}, 10_000);
it('sends docs rendering exceptions to showException', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
document.location.search = '?id=component-one--docs&viewMode=docs';
const preview = new PreviewWeb(importFn, getProjectAnnotations);
const docsRoot = document.createElement('div');
vi.mocked(preview.view.prepareForDocs).mockReturnValue(docsRoot as any);
componentOneExports.default.parameters.docs.container.mockImplementation(() => {
throw new Error('Docs rendering error');
});
vi.mocked(preview.view.showErrorDisplay).mockClear();
await preview.ready();
await vi.waitFor(
() => {
expect(preview.view.showErrorDisplay).toHaveBeenCalled();
},
{
timeout: 2000,
}
);
});
});
describe('onGetGlobalMeta changed (HMR)', () => {
const newGlobalDecorator = vi.fn((s) => s());
const newGetProjectAnnotations = () => {
return {
...projectAnnotations,
args: { a: 'second' },
globals: { a: 'second' },
decorators: [newGlobalDecorator],
};
};
it('renders story mode through the updated stack', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
it('renders story mode through the updated stack', async () => {
const { DocsRenderer } = await import('../../../../../addons/docs/src/index');
projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;
document.location.search = '?id=component-one--a';
const preview = new PreviewWeb(importFn, getProjectAnnotations);
await preview.ready();
await waitForRender();
document.location.search = '?id=component-one--a';
const preview = new PreviewWeb(importFn, getProjectAnnotations);
await preview.ready();
await waitForRender();
projectAnnotations.renderToCanvas.mockImplementationOnce(
({ storyFn }: RenderContext<any>) => storyFn()
);
projectAnnotations.decorators[0].mockClear();
mockChannel.emit.mockClear();
preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations });
projectAnnotations.renderToCanvas.mockImplementationOnce(({ storyFn }: RenderContext<any>) =>
storyFn()
);
projectAnnotations.decorators[0].mockClear();
mockChannel.emit.mockClear();
preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations });
await vi.waitFor(() => {
expect(projectAnnotations.decorators[0]).not.toHaveBeenCalled();
expect(newGlobalDecorator).toHaveBeenCalled();
expect(projectAnnotations.render).toHaveBeenCalled();
});
await vi.waitFor(() => {
expect(projectAnnotations.decorators[0]).not.toHaveBeenCalled();
expect(newGlobalDecorator).toHaveBeenCalled();
expect(projectAnnotations.render).toHaveBeenCalled();
});
});
},
{ retry: 0 }
);
});
});

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-manager",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook manager builder",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/channels",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/client-logger",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/components",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Core Storybook Components",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-common",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-events",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Event names used in storybook core",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-server",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/csf-tools",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Parse and manipulate CSF and Storybook config files",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/docs-tools",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Shared utility functions for frameworks to implement docs",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/manager-api",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Core Storybook Manager API & Context",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/manager",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Core Storybook UI",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/node-logger",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preview-api",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preview",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/router",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Core Storybook Router",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/telemetry",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Telemetry logging for crash reports and usage statistics",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/theming",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Core Storybook Components",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/types",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Core Storybook TS Types",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/angular",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
"keywords": [
"storybook",

View File

@ -96,7 +96,9 @@ export abstract class AbstractRenderer {
const analyzedMetadata = new PropertyExtractor(storyFnAngular.moduleMetadata, component);
const storyUid = targetDOMNode.getAttribute(STORY_UID_ATTRIBUTE);
const storyUid = this.generateStoryUIdFromRawStoryUid(
targetDOMNode.getAttribute(STORY_UID_ATTRIBUTE)
);
const componentSelector = storyUid !== null ? `${targetSelector}[${storyUid}]` : targetSelector;
if (storyUid !== null) {
const element = targetDOMNode.querySelector(targetSelector);
@ -143,6 +145,27 @@ export abstract class AbstractRenderer {
return storyIdIsInvalidHtmlTagName ? `sb-${id.replace(invalidHtmlTag, '')}-component` : id;
}
/**
* Angular is unable to handle components that have selectors with accented attributes.
*
* Therefore, stories break when meta's title contains accents.
* https://github.com/storybookjs/storybook/issues/29132
*
* This method filters accents from a given raw id. For example, this method converts
* 'Example/Button with an "é" accent' into 'Example/Button with an "e" accent'.
*
* @memberof AbstractRenderer
* @protected
*/
protected generateStoryUIdFromRawStoryUid(rawStoryUid: string | null) {
if (rawStoryUid === null) {
return rawStoryUid;
}
const accentCharacters = /[\u0300-\u036f]/g;
return rawStoryUid.normalize('NFD').replace(accentCharacters, '');
}
/** Adds DOM element that angular will use as bootstrap component. */
protected initAngularRootElement(targetDOMNode: HTMLElement, targetSelector: string) {
targetDOMNode.innerHTML = '';

View File

@ -12,193 +12,189 @@ const instantWaitFor = (fn: () => void) => {
});
};
describe(
'BootstrapQueue',
() => {
beforeEach(async () => {
vi.spyOn(console, 'log').mockImplementation(() => {});
describe('BootstrapQueue', { retry: 3 }, () => {
beforeEach(async () => {
vi.spyOn(console, 'log').mockImplementation(() => {});
});
afterEach(() => {
vi.clearAllMocks();
});
it('@flaky should wait until complete', async () => {
const pendingSubject = new Subject<void>();
const bootstrapApp = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject);
});
const bootstrapAppFinished = vi.fn();
queueBootstrapping(bootstrapApp).then(() => {
bootstrapAppFinished();
});
afterEach(() => {
vi.clearAllMocks();
await instantWaitFor(() => {
if (bootstrapApp.mock.calls.length !== 1) {
throw new Error('bootstrapApp should not have been called yet');
}
});
it('@flaky should wait until complete', async () => {
const pendingSubject = new Subject<void>();
const bootstrapApp = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject);
});
const bootstrapAppFinished = vi.fn();
expect(bootstrapApp).toHaveBeenCalled();
expect(bootstrapAppFinished).not.toHaveBeenCalled();
queueBootstrapping(bootstrapApp).then(() => {
bootstrapAppFinished();
});
pendingSubject.next();
pendingSubject.complete();
await instantWaitFor(() => {
if (bootstrapApp.mock.calls.length !== 1) {
throw new Error('bootstrapApp should not have been called yet');
}
});
expect(bootstrapApp).toHaveBeenCalled();
expect(bootstrapAppFinished).not.toHaveBeenCalled();
pendingSubject.next();
pendingSubject.complete();
await instantWaitFor(() => {
if (bootstrapAppFinished.mock.calls.length !== 1) {
throw new Error('bootstrapApp should have been called once');
}
});
expect(bootstrapAppFinished).toHaveBeenCalled();
await instantWaitFor(() => {
if (bootstrapAppFinished.mock.calls.length !== 1) {
throw new Error('bootstrapApp should have been called once');
}
});
it('should prevent following tasks, until the preview tasks are complete', async () => {
const pendingSubject = new Subject<void>();
const bootstrapApp = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject);
});
const bootstrapAppFinished = vi.fn();
expect(bootstrapAppFinished).toHaveBeenCalled();
});
const pendingSubject2 = new Subject<void>();
const bootstrapApp2 = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject2);
});
const bootstrapAppFinished2 = vi.fn();
it('should prevent following tasks, until the preview tasks are complete', async () => {
const pendingSubject = new Subject<void>();
const bootstrapApp = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject);
});
const bootstrapAppFinished = vi.fn();
const pendingSubject3 = new Subject<void>();
const bootstrapApp3 = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject3);
});
const bootstrapAppFinished3 = vi.fn();
const pendingSubject2 = new Subject<void>();
const bootstrapApp2 = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject2);
});
const bootstrapAppFinished2 = vi.fn();
queueBootstrapping(bootstrapApp).then(bootstrapAppFinished);
queueBootstrapping(bootstrapApp2).then(bootstrapAppFinished2);
queueBootstrapping(bootstrapApp3).then(bootstrapAppFinished3);
const pendingSubject3 = new Subject<void>();
const bootstrapApp3 = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject3);
});
const bootstrapAppFinished3 = vi.fn();
await instantWaitFor(() => {
if (bootstrapApp.mock.calls.length !== 1) {
throw new Error('bootstrapApp should have been called once');
}
});
queueBootstrapping(bootstrapApp).then(bootstrapAppFinished);
queueBootstrapping(bootstrapApp2).then(bootstrapAppFinished2);
queueBootstrapping(bootstrapApp3).then(bootstrapAppFinished3);
expect(bootstrapApp).toHaveBeenCalled();
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapApp2).not.toHaveBeenCalled();
expect(bootstrapAppFinished2).not.toHaveBeenCalled();
expect(bootstrapApp3).not.toHaveBeenCalled();
expect(bootstrapAppFinished3).not.toHaveBeenCalled();
pendingSubject.next();
pendingSubject.complete();
await instantWaitFor(() => {
if (bootstrapApp2.mock.calls.length !== 1) {
throw new Error('bootstrapApp2 should have been called once');
}
});
expect(bootstrapApp).toHaveReturnedTimes(1);
expect(bootstrapAppFinished).toHaveBeenCalled();
expect(bootstrapApp2).toHaveBeenCalled();
expect(bootstrapAppFinished2).not.toHaveBeenCalled();
expect(bootstrapApp3).not.toHaveBeenCalled();
expect(bootstrapAppFinished3).not.toHaveBeenCalled();
pendingSubject2.next();
pendingSubject2.complete();
await instantWaitFor(() => {
if (bootstrapApp3.mock.calls.length !== 1) {
throw new Error('bootstrapApp3 should have been called once');
}
});
expect(bootstrapApp).toHaveReturnedTimes(1);
expect(bootstrapAppFinished).toHaveBeenCalled();
expect(bootstrapApp2).toHaveReturnedTimes(1);
expect(bootstrapAppFinished2).toHaveBeenCalled();
expect(bootstrapApp3).toHaveBeenCalled();
expect(bootstrapAppFinished3).not.toHaveBeenCalled();
pendingSubject3.next();
pendingSubject3.complete();
await instantWaitFor(() => {
if (bootstrapAppFinished3.mock.calls.length !== 1) {
throw new Error('bootstrapAppFinished3 should have been called once');
}
});
expect(bootstrapApp).toHaveReturnedTimes(1);
expect(bootstrapAppFinished).toHaveBeenCalled();
expect(bootstrapApp2).toHaveReturnedTimes(1);
expect(bootstrapAppFinished2).toHaveBeenCalled();
expect(bootstrapApp3).toHaveReturnedTimes(1);
expect(bootstrapAppFinished3).toHaveBeenCalled();
await instantWaitFor(() => {
if (bootstrapApp.mock.calls.length !== 1) {
throw new Error('bootstrapApp should have been called once');
}
});
it('should throw and continue next bootstrap on error', async () => {
const pendingSubject = new Subject<void>();
const bootstrapApp = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject);
});
const bootstrapAppFinished = vi.fn();
const bootstrapAppError = vi.fn();
expect(bootstrapApp).toHaveBeenCalled();
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapApp2).not.toHaveBeenCalled();
expect(bootstrapAppFinished2).not.toHaveBeenCalled();
expect(bootstrapApp3).not.toHaveBeenCalled();
expect(bootstrapAppFinished3).not.toHaveBeenCalled();
const pendingSubject2 = new Subject<void>();
const bootstrapApp2 = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject2);
});
const bootstrapAppFinished2 = vi.fn();
const bootstrapAppError2 = vi.fn();
pendingSubject.next();
pendingSubject.complete();
queueBootstrapping(bootstrapApp).then(bootstrapAppFinished).catch(bootstrapAppError);
queueBootstrapping(bootstrapApp2).then(bootstrapAppFinished2).catch(bootstrapAppError2);
await instantWaitFor(() => {
if (bootstrapApp.mock.calls.length !== 1) {
throw new Error('bootstrapApp should have been called once');
}
});
expect(bootstrapApp).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapApp2).not.toHaveBeenCalled();
pendingSubject.error(new Error('test error'));
await instantWaitFor(() => {
if (bootstrapAppError.mock.calls.length !== 1) {
throw new Error('bootstrapAppError should have been called once');
}
});
expect(bootstrapApp).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapAppError).toHaveBeenCalledTimes(1);
expect(bootstrapApp2).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished2).not.toHaveBeenCalled();
expect(bootstrapAppError2).not.toHaveBeenCalled();
pendingSubject2.next();
pendingSubject2.complete();
await instantWaitFor(() => {
if (bootstrapAppFinished2.mock.calls.length !== 1) {
throw new Error('bootstrapAppFinished2 should have been called once');
}
});
expect(bootstrapApp).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapAppError).toHaveBeenCalledTimes(1);
expect(bootstrapApp2).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished2).toHaveBeenCalledTimes(1);
expect(bootstrapAppError2).not.toHaveBeenCalled();
await instantWaitFor(() => {
if (bootstrapApp2.mock.calls.length !== 1) {
throw new Error('bootstrapApp2 should have been called once');
}
});
},
{ retry: 3 }
);
expect(bootstrapApp).toHaveReturnedTimes(1);
expect(bootstrapAppFinished).toHaveBeenCalled();
expect(bootstrapApp2).toHaveBeenCalled();
expect(bootstrapAppFinished2).not.toHaveBeenCalled();
expect(bootstrapApp3).not.toHaveBeenCalled();
expect(bootstrapAppFinished3).not.toHaveBeenCalled();
pendingSubject2.next();
pendingSubject2.complete();
await instantWaitFor(() => {
if (bootstrapApp3.mock.calls.length !== 1) {
throw new Error('bootstrapApp3 should have been called once');
}
});
expect(bootstrapApp).toHaveReturnedTimes(1);
expect(bootstrapAppFinished).toHaveBeenCalled();
expect(bootstrapApp2).toHaveReturnedTimes(1);
expect(bootstrapAppFinished2).toHaveBeenCalled();
expect(bootstrapApp3).toHaveBeenCalled();
expect(bootstrapAppFinished3).not.toHaveBeenCalled();
pendingSubject3.next();
pendingSubject3.complete();
await instantWaitFor(() => {
if (bootstrapAppFinished3.mock.calls.length !== 1) {
throw new Error('bootstrapAppFinished3 should have been called once');
}
});
expect(bootstrapApp).toHaveReturnedTimes(1);
expect(bootstrapAppFinished).toHaveBeenCalled();
expect(bootstrapApp2).toHaveReturnedTimes(1);
expect(bootstrapAppFinished2).toHaveBeenCalled();
expect(bootstrapApp3).toHaveReturnedTimes(1);
expect(bootstrapAppFinished3).toHaveBeenCalled();
});
it('should throw and continue next bootstrap on error', async () => {
const pendingSubject = new Subject<void>();
const bootstrapApp = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject);
});
const bootstrapAppFinished = vi.fn();
const bootstrapAppError = vi.fn();
const pendingSubject2 = new Subject<void>();
const bootstrapApp2 = vi.fn().mockImplementation(async () => {
return lastValueFrom(pendingSubject2);
});
const bootstrapAppFinished2 = vi.fn();
const bootstrapAppError2 = vi.fn();
queueBootstrapping(bootstrapApp).then(bootstrapAppFinished).catch(bootstrapAppError);
queueBootstrapping(bootstrapApp2).then(bootstrapAppFinished2).catch(bootstrapAppError2);
await instantWaitFor(() => {
if (bootstrapApp.mock.calls.length !== 1) {
throw new Error('bootstrapApp should have been called once');
}
});
expect(bootstrapApp).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapApp2).not.toHaveBeenCalled();
pendingSubject.error(new Error('test error'));
await instantWaitFor(() => {
if (bootstrapAppError.mock.calls.length !== 1) {
throw new Error('bootstrapAppError should have been called once');
}
});
expect(bootstrapApp).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapAppError).toHaveBeenCalledTimes(1);
expect(bootstrapApp2).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished2).not.toHaveBeenCalled();
expect(bootstrapAppError2).not.toHaveBeenCalled();
pendingSubject2.next();
pendingSubject2.complete();
await instantWaitFor(() => {
if (bootstrapAppFinished2.mock.calls.length !== 1) {
throw new Error('bootstrapAppFinished2 should have been called once');
}
});
expect(bootstrapApp).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished).not.toHaveBeenCalled();
expect(bootstrapAppError).toHaveBeenCalledTimes(1);
expect(bootstrapApp2).toHaveBeenCalledTimes(1);
expect(bootstrapAppFinished2).toHaveBeenCalledTimes(1);
expect(bootstrapAppError2).not.toHaveBeenCalled();
});
});

View File

@ -18,20 +18,20 @@ describe('angular component properties', () => {
expect(true).toEqual(true);
});
// TODO: Fix this test
// it(`${testEntry.name}`, () => {
// it(`${testEntry.name}`, async () => {
// const inputPath = join(testDir, testFile);
// // snapshot the output of compodoc
// const compodocOutput = runCompodoc(inputPath);
// const compodocJson = JSON.parse(compodocOutput);
// expect(compodocJson).toMatchFileSnapshot(
// await expect(compodocJson).toMatchFileSnapshot(
// join(testDir, `compodoc-${SNAPSHOT_OS}.snapshot`)
// );
// // snapshot the output of addon-docs angular-properties
// const componentData = findComponentByName('InputComponent', compodocJson);
// const argTypes = extractArgTypesFromData(componentData);
// expect(argTypes).toMatchFileSnapshot(join(testDir, 'argtypes.snapshot'));
// await expect(argTypes).toMatchFileSnapshot(join(testDir, 'argtypes.snapshot'));
// });
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/ember",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/experimental-nextjs-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Next.js and Vite",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/nextjs",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Next.js",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Preact: Develop Preact Component in isolation.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-native-web-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Develop react-native components an isolated web environment with hot reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for React: Develop React Component in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/server-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/sveltekit",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for SvelteKit",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-vite",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-webpack5",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.",
"keywords": [
"lit",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/blocks",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook Doc Blocks",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "sb",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook CLI",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/cli",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook CLI",
"keywords": [
"storybook"

View File

@ -1,9 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { formatFileContent } from '@storybook/core/common';
import { formatConfig, loadConfig } from '@storybook/core/csf-tools';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import * as jscodeshift from 'jscodeshift';
import path from 'path';
@ -157,12 +153,12 @@ describe('addonA11yAddonTest', () => {
previewFile: null,
transformedPreviewCode: null,
transformedSetupCode: expect.any(String),
skipPreviewTransformation: false,
skipPreviewTransformation: true,
skipVitestSetupTransformation: false,
});
});
it('should return previewFile and transformedPreviewCode if preview file exists', async () => {
it.skip('should return previewFile and transformedPreviewCode if preview file exists', async () => {
vi.mocked(getAddonNames).mockReturnValue([
'@storybook/addon-a11y',
'@storybook/experimental-addon-test',
@ -229,7 +225,7 @@ describe('addonA11yAddonTest', () => {
previewFile: null,
transformedPreviewCode: null,
transformedSetupCode: null,
skipPreviewTransformation: false,
skipPreviewTransformation: true,
skipVitestSetupTransformation: false,
});
});
@ -265,7 +261,7 @@ describe('addonA11yAddonTest', () => {
previewFile: path.join(configDir, 'preview.js'),
transformedPreviewCode: null,
transformedSetupCode: null,
skipPreviewTransformation: false,
skipPreviewTransformation: true,
skipVitestSetupTransformation: false,
});
});
@ -345,14 +341,7 @@ describe('addonA11yAddonTest', () => {
},
configDir,
} as any);
expect(result).toEqual({
setupFile: path.join(configDir, 'vitest.setup.js'),
previewFile: path.join(configDir, 'preview.js'),
transformedPreviewCode: expect.any(String),
transformedSetupCode: null,
skipPreviewTransformation: false,
skipVitestSetupTransformation: true,
});
expect(result).toEqual(null);
});
});
@ -679,7 +668,8 @@ describe('addonA11yAddonTest', () => {
},
// The \`a11y-test\` tag controls whether accessibility tests are run as part of a standalone Vitest test run
// For more information please visit: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
// The tag and its behavior are experimental and subject to change.
// For more information please see: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
tags: [/*'a11y-test'*/]
};
@ -740,7 +730,8 @@ describe('addonA11yAddonTest', () => {
const preview: Preview = {
// The \`a11y-test\` tag controls whether accessibility tests are run as part of a standalone Vitest test run
// For more information please visit: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
// The tag and its behavior are experimental and subject to change.
// For more information please see: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
tags: ["existingTag"/*, "a11y-test"*/],
parameters: {
controls: {
@ -824,7 +815,8 @@ describe('addonA11yAddonTest', () => {
},
// The \`a11y-test\` tag controls whether accessibility tests are run as part of a standalone Vitest test run
// For more information please visit: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
// The tag and its behavior are experimental and subject to change.
// For more information please see: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
tags: [/*"a11y-test"*/]
};"
`);
@ -850,7 +842,8 @@ describe('addonA11yAddonTest', () => {
expect(transformed).toMatchInlineSnapshot(`
"export default {
// The \`a11y-test\` tag controls whether accessibility tests are run as part of a standalone Vitest test run
// For more information please visit: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
// The tag and its behavior are experimental and subject to change.
// For more information please see: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon
tags: ["existingTag"/*, "a11y-test"*/],
parameters: {
controls: {

View File

@ -90,14 +90,15 @@ export const addonA11yAddonTest: Fix<AddonA11yAddonTestOptions> = {
.find((filePath) => existsSync(filePath)) ?? null;
let skipVitestSetupTransformation = false;
let skipPreviewTransformation = false;
// TODO: Set it to false after we have decided how to deal with a11y:test tag.
const skipPreviewTransformation = true;
if (vitestSetupFile && previewFile) {
const vitestSetupSource = readFileSync(vitestSetupFile, 'utf8');
const previewSetupSource = readFileSync(previewFile, 'utf8');
// const previewSetupSource = readFileSync(previewFile, 'utf8');
skipVitestSetupTransformation = vitestSetupSource.includes('@storybook/addon-a11y');
skipPreviewTransformation = previewSetupSource.includes('a11y-test');
// skipPreviewTransformation = previewSetupSource.includes('a11y-test');
if (skipVitestSetupTransformation && skipPreviewTransformation) {
return null;
@ -318,7 +319,7 @@ export async function transformPreviewFile(source: string, filePath: string) {
const indentation = lines[tagsLineIndex]?.match(/^\s*/)?.[0];
// Add the comment with the same indentation level
const comment = `${indentation}// The \`a11y-test\` tag controls whether accessibility tests are run as part of a standalone Vitest test run\n${indentation}// For more information please visit: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon`;
const comment = `${indentation}// The \`a11y-test\` tag controls whether accessibility tests are run as part of a standalone Vitest test run\n${indentation}// The tag and its behavior are experimental and subject to change.\n${indentation}// For more information please see: https://storybook.js.org/docs/writing-tests/accessibility-testing#configure-accessibility-tests-with-the-test-addon`;
lines.splice(tagsLineIndex, 0, comment);
return formatFileContent(filePath, lines.join('\n'));

View File

@ -96,7 +96,7 @@ describe('eslint-plugin fix', () => {
});
describe('should install eslint plugin', () => {
it('when .eslintrc is using a supported extension', async () => {
it.skip('when .eslintrc is using a supported extension', async () => {
await expect(
checkEslint({
packageJson,
@ -106,7 +106,7 @@ describe('eslint-plugin fix', () => {
);
});
it('when .eslintrc is using unsupported extension', async () => {
it.skip('when .eslintrc is using unsupported extension', async () => {
await expect(
checkEslint({
packageJson,

View File

@ -68,7 +68,7 @@ describe('webpack5Migration check function', () => {
},
});
expect(result).resolves.toBeNull();
await expect(result).resolves.toBeNull();
});
it('should return null if the builder is not webpack5', async () => {

View File

@ -1,6 +1,6 @@
{
"name": "storybook",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook's CLI - install, dev, build, upgrade, and more",
"keywords": [
"cli",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/codemod",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "A collection of codemod scripts written with JSCodeshift",
"keywords": [
"storybook"

View File

@ -24,8 +24,8 @@ readdirSync(fixturesDir).forEach((transformName) => {
.filter((fileName) => inputRegExp.test(fileName))
.forEach((fileName) => {
const inputPath = join(transformFixturesDir, fileName);
it(`transforms correctly using "${fileName}" data`, () =>
expect(
it(`transforms correctly using "${fileName}" data`, async () =>
await expect(
applyTransform(require(join(__dirname, '..', transformName)), null, {
path: inputPath,
source: fs.readFileSync(inputPath, 'utf8'),

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-webpack",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "create-storybook",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Initialize Storybook into your project",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/lib/create-storybook",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/csf-plugin",
"version": "8.5.0-beta.10",
"version": "8.6.0-alpha.0",
"description": "Enrich CSF files via static analysis",
"keywords": [
"storybook"

Some files were not shown because too many files have changed in this diff Show More