Skip to content

Commit eab904f

Browse files
authored
Merge pull request #29606 from storybookjs/version-non-patch-from-8.5.0-alpha.4
Release: Prerelease 8.5.0-alpha.5
2 parents 7d3bbd7 + 70ac1bc commit eab904f

File tree

16 files changed

+295
-50
lines changed

16 files changed

+295
-50
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 8.4.4
2+
3+
- Addon Test: Only optimize react deps if applicable in vitest-plugin - [#29617](https://github.com/storybookjs/storybook/pull/29617), thanks @yannbf!
4+
5+
## 8.4.3
6+
7+
- Addon Test: Optimize internal dependencies - [#29595](https://github.com/storybookjs/storybook/pull/29595), thanks @yannbf!
8+
- Next.js: Add support for Next 15 - [#29587](https://github.com/storybookjs/storybook/pull/29587), thanks @yannbf!
9+
110
## 8.4.2
211

312
- Addon Test: Fix post-install logic for Next.js Vite framework support - [#29524](https://github.com/storybookjs/storybook/pull/29524), thanks @valentinpalkovic!

CHANGELOG.prerelease.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 8.5.0-alpha.5
2+
3+
- Addon Test: Only optimize react deps if applicable in vitest-plugin - [#29617](https://github.com/storybookjs/storybook/pull/29617), thanks @yannbf!
4+
- Addon Test: Optimize internal dependencies - [#29595](https://github.com/storybookjs/storybook/pull/29595), thanks @yannbf!
5+
- CLI: Fix init help for `storybook` command - [#29480](https://github.com/storybookjs/storybook/pull/29480), thanks @toothlessdev!
6+
- Composition: Fix composed story search - [#29453](https://github.com/storybookjs/storybook/pull/29453), thanks @jsingh0026!
7+
18
## 8.5.0-alpha.4
29

310
- Next.js: Add support for Next 15 - [#29587](https://github.com/storybookjs/storybook/pull/29587), thanks @yannbf!

code/addons/test/src/vitest-plugin/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ export const storybookTest = (options?: UserOptions): Plugin => {
131131
config.test.server.deps.inline.push('@storybook/experimental-addon-test');
132132
}
133133

134+
config.optimizeDeps ??= {};
135+
config.optimizeDeps = {
136+
...config.optimizeDeps,
137+
include: [...(config.optimizeDeps.include ?? []), '@storybook/experimental-addon-test/**'],
138+
};
139+
140+
if (frameworkName?.includes('react') || frameworkName?.includes('nextjs')) {
141+
config.optimizeDeps.include.push('react-dom/test-utils');
142+
}
143+
134144
if (frameworkName?.includes('vue3')) {
135145
config.define ??= {};
136146
config.define.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ = 'false';

code/core/src/manager/components/mobile/navigation/MobileNavigation.tsx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from 'react';
44
import { IconButton } from '@storybook/core/components';
55
import { styled } from '@storybook/core/theming';
66
import { BottomBarToggleIcon, MenuIcon } from '@storybook/icons';
7+
import type { API_IndexHash, API_Refs } from '@storybook/types';
78

89
import { useStorybookApi, useStorybookState } from '@storybook/core/manager-api';
910

@@ -17,27 +18,46 @@ interface MobileNavigationProps {
1718
showPanel: boolean;
1819
}
1920

21+
// Function to combine all indexes
22+
function combineIndexes(rootIndex: API_IndexHash | undefined, refs: API_Refs) {
23+
// Create a copy of the root index to avoid mutation
24+
const combinedIndex = { ...(rootIndex || {}) }; // Use an empty object as fallback
25+
26+
// Traverse refs and merge each nested index with the root index
27+
Object.values(refs).forEach((ref) => {
28+
if (ref.index) {
29+
Object.assign(combinedIndex, ref.index);
30+
}
31+
});
32+
33+
return combinedIndex;
34+
}
35+
2036
/**
2137
* Walks the tree from the current story to combine story+component+folder names into a single
2238
* string
2339
*/
2440
const useFullStoryName = () => {
25-
const { index } = useStorybookState();
41+
const { index, refs } = useStorybookState();
2642
const api = useStorybookApi();
2743
const currentStory = api.getCurrentStoryData();
2844

2945
if (!currentStory) {
3046
return '';
3147
}
32-
48+
const combinedIndex = combineIndexes(index, refs || {});
3349
let fullStoryName = currentStory.renderLabel?.(currentStory, api) || currentStory.name;
34-
// @ts-expect-error (non strict)
35-
let node = index[currentStory.id];
3650

37-
// @ts-expect-error (non strict)
38-
while ('parent' in node && node.parent && index[node.parent] && fullStoryName.length < 24) {
39-
// @ts-expect-error (non strict)
40-
node = index[node.parent];
51+
let node = combinedIndex[currentStory.id];
52+
53+
while (
54+
node &&
55+
'parent' in node &&
56+
node.parent &&
57+
combinedIndex[node.parent] &&
58+
fullStoryName.length < 24
59+
) {
60+
node = combinedIndex[node.parent];
4161
const parentName = node.renderLabel?.(node, api) || node.name;
4262
fullStoryName = `${parentName}/${fullStoryName}`;
4363
}

code/core/src/manager/components/sidebar/TestingModule.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ const DynamicInfo = ({ state }: { state: TestProviders[keyof TestProviders] }) =
175175
const Title = state.title;
176176
return (
177177
<Info>
178-
<TitleWrapper crashed={state.crashed}>
178+
<TitleWrapper crashed={state.crashed} id="testing-module-title">
179179
<Title {...state} />
180180
</TitleWrapper>
181-
<DescriptionWrapper>
181+
<DescriptionWrapper id="testing-module-description">
182182
<Description {...state} />
183183
</DescriptionWrapper>
184184
</Info>
@@ -244,7 +244,7 @@ export const TestingModule = ({
244244
>
245245
<Content ref={contentRef}>
246246
{testProviders.map((state) => (
247-
<TestProvider key={state.id}>
247+
<TestProvider key={state.id} data-module-id={state.id}>
248248
<DynamicInfo state={state} />
249249
<Actions>
250250
{state.watchable && (

code/e2e-tests/composition.spec.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ test.describe('composition', () => {
1111
'Slow, framework independent test, so only run it on in react-vite/default-ts'
1212
);
1313

14-
test.beforeEach(async ({ page }) => {
14+
test('should filter and render composed stories', async ({ page }) => {
1515
await page.goto(storybookUrl);
1616
await new SbPage(page, expect).waitUntilLoaded();
17-
});
1817

19-
test('should correctly filter composed stories', async ({ page }) => {
2018
// Expect that composed Storybooks are visible
2119
await expect(page.getByTitle('Storybook 8.0.0')).toBeVisible();
2220
await expect(page.getByTitle('Storybook 7.6.18')).toBeVisible();
@@ -35,10 +33,64 @@ test.describe('composition', () => {
3533
// Expect composed stories `to be available in the search
3634
await page.getByPlaceholder('Find components').fill('Button');
3735
await expect(
38-
page.getByRole('option', { name: 'Button Storybook 8.0.0 / @blocks / examples' })
36+
page.getByRole('option', { name: 'Button Storybook 7.6.18 / @blocks / examples' })
3937
).toBeVisible();
38+
39+
const buttonStory = page.getByRole('option', {
40+
name: 'Button Storybook 8.0.0 / @blocks / examples',
41+
});
42+
await expect(buttonStory).toBeVisible();
43+
await buttonStory.click();
44+
45+
// Note: this could potentially be flaky due to it accessing a hosted Storybook
46+
await expect(
47+
page
48+
.locator('iframe[title="storybook-ref-storybook\\@8\\.0\\.0"]')
49+
.contentFrame()
50+
.getByRole('heading', { name: 'Example button component' })
51+
).toBeVisible({ timeout: 15000 });
52+
});
53+
54+
test('should filter and render composed stories on mobile', async ({ page }) => {
55+
page.setViewportSize({ width: 320, height: 800 });
56+
await page.goto(storybookUrl);
57+
await new SbPage(page, expect).waitUntilLoaded();
58+
59+
await page.click('button[title="Open navigation menu"]');
60+
61+
// Expect that composed Storybooks are visible
62+
await expect(page.getByTitle('Storybook 8.0.0')).toBeVisible();
63+
await expect(page.getByTitle('Storybook 7.6.18')).toBeVisible();
64+
65+
// Expect composed stories to be available in the sidebar
66+
await page.locator('[id="storybook\\@8\\.0\\.0_components-badge"]').click();
67+
await expect(
68+
page.locator('[id="storybook\\@8\\.0\\.0_components-badge--default"]')
69+
).toBeVisible();
70+
71+
await page.locator('[id="storybook\\@7\\.6\\.18_components-badge"]').click();
72+
await expect(
73+
page.locator('[id="storybook\\@7\\.6\\.18_components-badge--default"]')
74+
).toBeVisible();
75+
76+
// Expect composed stories `to be available in the search
77+
await page.getByPlaceholder('Find components').fill('Button');
4078
await expect(
4179
page.getByRole('option', { name: 'Button Storybook 7.6.18 / @blocks / examples' })
4280
).toBeVisible();
81+
82+
const buttonStory = page.getByRole('option', {
83+
name: 'Button Storybook 8.0.0 / @blocks / examples',
84+
});
85+
await expect(buttonStory).toBeVisible();
86+
await buttonStory.click();
87+
88+
// Note: this could potentially be flaky due to it accessing a hosted Storybook
89+
await expect(
90+
page
91+
.locator('iframe[title="storybook-ref-storybook\\@8\\.0\\.0"]')
92+
.contentFrame()
93+
.getByRole('heading', { name: 'Example button component' })
94+
).toBeVisible({ timeout: 15000 });
4395
});
4496
});

code/lib/cli-storybook/src/bin/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ const command = (name: string) =>
4040
.option('--debug', 'Get more logs in debug mode', false)
4141
.option('--enable-crash-reports', 'Enable sending crash reports to telemetry data');
4242

43+
command('init')
44+
.description('Initialize Storybook into your project')
45+
.option('-f --force', 'Force add Storybook')
46+
.option('-s --skip-install', 'Skip installing deps')
47+
.option('--package-manager <npm|pnpm|yarn1|yarn2>', 'Force package manager for installing deps')
48+
.option('--use-pnp', 'Enable PnP mode for Yarn 2+')
49+
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
50+
.option('-t --type <type>', 'Add Storybook for a specific project type')
51+
.option('-y --yes', 'Answer yes to all prompts')
52+
.option('-b --builder <webpack5 | vite>', 'Builder library')
53+
.option('-l --linkable', 'Prepare installation for link (contributor helper)')
54+
.option(
55+
'--dev',
56+
'Launch the development server after completing initialization. Enabled by default (default: true)',
57+
process.env.CI !== 'true' && process.env.IN_STORYBOOK_SANDBOX !== 'true'
58+
)
59+
.option(
60+
'--no-dev',
61+
'Complete the initialization of Storybook without launching the Storybook development server'
62+
);
63+
4364
command('add <addon>')
4465
.description('Add an addon to your Storybook')
4566
.option(

code/lib/cli-storybook/test/default/cli.test.cjs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect } from 'vitest';
1+
import { describe, expect, it } from 'vitest';
22

33
const run = require('../helpers.cjs');
44

@@ -12,3 +12,92 @@ describe('Default behavior', () => {
1212
expect(stdout.toString()).toContain('Did you mean upgrade?');
1313
});
1414
});
15+
16+
describe('Help command', () => {
17+
it('should prints out "init" command', () => {
18+
const { status, stdout, stderr } = run(['help']);
19+
20+
expect(status).toBe(0);
21+
expect(stderr.toString()).toBe('');
22+
expect(stdout.toString()).toContain('init');
23+
expect(stdout.toString()).toContain('Initialize Storybook into your project');
24+
});
25+
26+
it('should prints out "add" command', () => {
27+
const { status, stdout, stderr } = run(['help']);
28+
29+
expect(status).toBe(0);
30+
expect(stderr.toString()).toBe('');
31+
expect(stdout.toString()).toContain('add');
32+
expect(stdout.toString()).toContain('Add an addon to your Storybook');
33+
});
34+
35+
it('should prints out "remove" command', () => {
36+
const { status, stdout, stderr } = run(['help']);
37+
38+
expect(status).toBe(0);
39+
expect(stderr.toString()).toBe('');
40+
expect(stdout.toString()).toContain('remove');
41+
expect(stdout.toString()).toContain('Remove an addon from your Storybook');
42+
});
43+
44+
it('should prints out "upgrade" command', () => {
45+
const { status, stdout, stderr } = run(['help']);
46+
47+
expect(status).toBe(0);
48+
expect(stderr.toString()).toBe('');
49+
expect(stdout.toString()).toContain('upgrade');
50+
expect(stdout.toString()).toContain('Upgrade your Storybook packages to');
51+
});
52+
53+
it('should prints out "migrate" command', () => {
54+
const { status, stdout, stderr } = run(['help']);
55+
56+
expect(status).toBe(0);
57+
expect(stderr.toString()).toBe('');
58+
expect(stdout.toString()).toContain('migrate');
59+
expect(stdout.toString()).toContain('Run a Storybook codemod migration on your source files');
60+
});
61+
62+
it('should prints out "sandbox" command', () => {
63+
const { status, stdout, stderr } = run(['help']);
64+
65+
expect(status).toBe(0);
66+
expect(stderr.toString()).toBe('');
67+
expect(stdout.toString()).toContain('sandbox');
68+
expect(stdout.toString()).toContain('Create a sandbox from a set of possible templates');
69+
});
70+
71+
it('should prints out "link" command', () => {
72+
const { status, stdout, stderr } = run(['help']);
73+
74+
expect(status).toBe(0);
75+
expect(stderr.toString()).toBe('');
76+
expect(stdout.toString()).toContain('link');
77+
expect(stdout.toString()).toContain(
78+
'Pull down a repro from a URL (or a local directory), link it, and run storybook'
79+
);
80+
});
81+
82+
it('should prints out "automigrate" command', () => {
83+
const { status, stdout, stderr } = run(['help']);
84+
85+
expect(status).toBe(0);
86+
expect(stderr.toString()).toBe('');
87+
expect(stdout.toString()).toContain('automigrate');
88+
expect(stdout.toString()).toContain(
89+
'Check storybook for incompatibilities or migrations and apply fixes'
90+
);
91+
});
92+
93+
it('should prints out "doctor" command', () => {
94+
const { status, stdout, stderr } = run(['help']);
95+
96+
expect(status).toBe(0);
97+
expect(stderr.toString()).toBe('');
98+
expect(stdout.toString()).toContain('doctor');
99+
expect(stdout.toString()).toContain(
100+
'Check Storybook for known problems and provide suggestions or fixes'
101+
);
102+
});
103+
});

code/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,6 @@
293293
"Dependency Upgrades"
294294
]
295295
]
296-
}
296+
},
297+
"deferredNextVersion": "8.5.0-alpha.5"
297298
}

code/playwright.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { defineConfig, devices } from '@playwright/test';
33
/** Read environment variables from file. https://github.com/motdotla/dotenv */
44
// require('dotenv').config();
55

6+
// Comment this out and fill in the values to run E2E tests locally using the Playwright extension easily
7+
// process.env.STORYBOOK_URL = 'http://localhost:6006';
8+
// process.env.STORYBOOK_TEMPLATE_NAME = 'react-vite/default-ts';
9+
610
/** See https://playwright.dev/docs/test-configuration. */
711
export default defineConfig({
812
testDir: './e2e-tests',

0 commit comments

Comments
 (0)