diff --git a/code/builders/builder-vite/src/codegen-importfn-script.test.ts b/code/builders/builder-vite/src/codegen-importfn-script.test.ts index 4d3ce5bcb79a..da0e15c2154d 100644 --- a/code/builders/builder-vite/src/codegen-importfn-script.test.ts +++ b/code/builders/builder-vite/src/codegen-importfn-script.test.ts @@ -1,13 +1,14 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { toImportFn } from './codegen-importfn-script'; describe('toImportFn', () => { it('should correctly map story paths to import functions for absolute paths on Linux', async () => { - const root = '/absolute/path'; + vi.spyOn(process, 'cwd').mockReturnValue('/absolute/path'); + const stories = ['/absolute/path/to/story1.js', '/absolute/path/to/story2.js']; - const result = await toImportFn(root, stories); + const result = await toImportFn(stories); expect(result).toMatchInlineSnapshot(` "const importers = { @@ -22,10 +23,10 @@ describe('toImportFn', () => { }); it('should correctly map story paths to import functions for absolute paths on Windows', async () => { - const root = 'C:\\absolute\\path'; + vi.spyOn(process, 'cwd').mockReturnValue('C:\\absolute\\path'); const stories = ['C:\\absolute\\path\\to\\story1.js', 'C:\\absolute\\path\\to\\story2.js']; - const result = await toImportFn(root, stories); + const result = await toImportFn(stories); expect(result).toMatchInlineSnapshot(` "const importers = { @@ -43,7 +44,7 @@ describe('toImportFn', () => { const root = '/absolute/path'; const stories: string[] = []; - const result = await toImportFn(root, stories); + const result = await toImportFn(stories); expect(result).toMatchInlineSnapshot(` "const importers = {}; diff --git a/code/builders/builder-vite/src/codegen-importfn-script.ts b/code/builders/builder-vite/src/codegen-importfn-script.ts index 4b118ad9cc51..dc485c88f74d 100644 --- a/code/builders/builder-vite/src/codegen-importfn-script.ts +++ b/code/builders/builder-vite/src/codegen-importfn-script.ts @@ -29,9 +29,9 @@ function toImportPath(relativePath: string) { * * @param stories An array of absolute story paths. */ -export async function toImportFn(root: string, stories: string[]) { +export async function toImportFn(stories: string[]) { const objectEntries = stories.map((file) => { - const relativePath = relative(root, file); + const relativePath = relative(process.cwd(), file); return [toImportPath(relativePath), genDynamicImport(normalize(file))] as [string, string]; }); @@ -51,5 +51,5 @@ export async function generateImportFnScriptCode(options: Options): Promise(options); - options.projectRoot = options.projectRoot || resolve(options.configDir, '..'); + const projectRoot = resolve(options.configDir, '..'); // I destructure away the `build` property from the user's config object // I do this because I can contain config that breaks storybook, such as we had in a lit project. // If the user needs to configure the `build` they need to do so in the viteFinal function in main.js. const { config: { build: buildProperty = undefined, ...userConfig } = {} } = - (await loadConfigFromFile(configEnv, viteConfigPath, options.projectRoot)) ?? {}; + (await loadConfigFromFile(configEnv, viteConfigPath, projectRoot)) ?? {}; const sbConfig: InlineConfig = { configFile: false, cacheDir: resolvePathInStorybookCache('sb-vite', options.cacheKey), - root: options.projectRoot, + root: projectRoot, // Allow storybook deployed as subfolder. See https://github.com/storybookjs/builder-vite/issues/238 base: './', plugins: await pluginConfig(options), diff --git a/code/core/src/types/modules/core-common.ts b/code/core/src/types/modules/core-common.ts index 2b4624a0564b..08d9be50e64f 100644 --- a/code/core/src/types/modules/core-common.ts +++ b/code/core/src/types/modules/core-common.ts @@ -195,7 +195,6 @@ export interface BuilderOptions { ignorePreview?: boolean; cache?: FileSystemCache; configDir: string; - projectRoot?: string; docsMode?: boolean; features?: StorybookConfigRaw['features']; versionCheck?: VersionCheck; diff --git a/code/renderers/react/src/__test__/portable-stories.test.tsx b/code/renderers/react/src/__test__/portable-stories.test.tsx index 85f33c9a714a..fcb278628b7b 100644 --- a/code/renderers/react/src/__test__/portable-stories.test.tsx +++ b/code/renderers/react/src/__test__/portable-stories.test.tsx @@ -67,7 +67,7 @@ describe('renders', () => { }); it('should throw error when rendering a component with a render error', async () => { - await expect(() => ThrowsError.run()).rejects.toThrowError('Error in render'); + await expect(ThrowsError.run()).rejects.toThrowError('Error in render'); }); it('should render component mounted in play function', async () => { @@ -77,8 +77,8 @@ describe('renders', () => { expect(screen.getByTestId('loaded-data').textContent).toEqual('loaded data'); }); - it('should throw an error in play function', () => { - expect(() => MountInPlayFunctionThrow.run()).rejects.toThrowError('Error thrown in play'); + it('should throw an error in play function', async () => { + await expect(MountInPlayFunctionThrow.run()).rejects.toThrowError('Error thrown in play'); }); it('should call and compose loaders data', async () => { diff --git a/code/renderers/react/src/renderToCanvas.tsx b/code/renderers/react/src/renderToCanvas.tsx index 4ae1acbb7fe9..57c1086cee1b 100644 --- a/code/renderers/react/src/renderToCanvas.tsx +++ b/code/renderers/react/src/renderToCanvas.tsx @@ -45,6 +45,23 @@ class ErrorBoundary extends ReactComponent<{ const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; +const actQueue: (() => Promise)[] = []; +let isActing = false; + +const processActQueue = async () => { + if (isActing || actQueue.length === 0) { + return; + } + + isActing = true; + const actTask = actQueue.shift(); + if (actTask) { + await actTask(); + } + isActing = false; + processActQueue(); +}; + export async function renderToCanvas( { storyContext, @@ -81,8 +98,18 @@ export async function renderToCanvas( unmountElement(canvasElement); } - await act(async () => { - await renderElement(element, canvasElement, storyContext?.parameters?.react?.rootOptions); + await new Promise(async (resolve, reject) => { + actQueue.push(async () => { + try { + await act(async () => { + await renderElement(element, canvasElement, storyContext?.parameters?.react?.rootOptions); + }); + resolve(); + } catch (e) { + reject(e); + } + }); + processActQueue(); }); return async () => { diff --git a/docs/_snippets/addon-a11y-meta-tag.md b/docs/_snippets/addon-a11y-meta-tag.md index 3ef18124964e..58de99af555f 100644 --- a/docs/_snippets/addon-a11y-meta-tag.md +++ b/docs/_snippets/addon-a11y-meta-tag.md @@ -5,8 +5,8 @@ import { Button } from './button.component'; const meta: Meta