Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release: Prerelease 8.5.0-alpha.21 #30040

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
bac7061
Nextjs: Add TS docgen support for Vite implementation
yannbf Dec 5, 2024
4591ef9
Wait for 2 seconds before showing result mismatch warning
ghengeveld Dec 10, 2024
b1cc74d
Use local storybook binary instead
kasperpeulen Dec 11, 2024
69bcbaa
Handle telemetry where we determine the test discrepancy, not in the UI
ghengeveld Dec 11, 2024
3375c96
Merge branch 'next' into 29703-bug-test-discrepancy-handling-is-not-a…
ghengeveld Dec 11, 2024
aa75a98
remove existing test.include config
JReinhold Dec 11, 2024
9a680a3
remove unnecessary test.include in test kitchen sink
JReinhold Dec 11, 2024
d5b2286
Merge branch 'next' into jeppe/fix-duplicate-include
JReinhold Dec 11, 2024
d3c37c9
Update E2E tests with wording changes
ghengeveld Dec 12, 2024
0ece491
Merge branch 'next' of github.com:storybookjs/storybook into jeppe/fi…
JReinhold Dec 12, 2024
9cce225
Fix a11y addon docs
valentinpalkovic Dec 12, 2024
36d2413
Merge pull request #30036 from storybookjs/valentin/update-a11y-docs
valentinpalkovic Dec 12, 2024
30b6933
Merge branch 'next' into 29703-bug-test-discrepancy-handling-is-not-a…
ghengeveld Dec 12, 2024
db024c7
Merge pull request #30021 from storybookjs/kasper/use-local
kasperpeulen Dec 12, 2024
6e9fb74
Merge pull request #30029 from storybookjs/jeppe/fix-duplicate-include
JReinhold Dec 12, 2024
47cbf5a
Merge pull request #30002 from storybookjs/29703-bug-test-discrepancy…
ghengeveld Dec 12, 2024
c2ab01c
Merge pull request #29824 from storybookjs/yann/add-ts-docgen-support…
yannbf Dec 12, 2024
12fb013
Write changelog for 8.5.0-alpha.21 [skip ci]
storybook-bot Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## 8.5.0-alpha.21

- Addon A11y: Add typesVersions support for TypeScript definitions in a11y package - [#30005](https://github.com/storybookjs/storybook/pull/30005), thanks @valentinpalkovic!
- Addon A11y: Refactor environment variable handling for Vitest integration - [#30022](https://github.com/storybookjs/storybook/pull/30022), thanks @valentinpalkovic!
- Addon A11y: Run the a11y automigration on postInstall - [#30004](https://github.com/storybookjs/storybook/pull/30004), thanks @kasperpeulen!
- Addon A11y: Update accessibility status handling in TestProviderRender - [#30027](https://github.com/storybookjs/storybook/pull/30027), thanks @valentinpalkovic!
- Addon Onboarding: Prebundle react-confetti - [#29996](https://github.com/storybookjs/storybook/pull/29996), thanks @yannbf!
- Addon Test: Correctly stop Storybook when Vitest closes - [#30012](https://github.com/storybookjs/storybook/pull/30012), thanks @JReinhold!
- Addon Test: Show sub test provider toggle state in main testing module - [#30019](https://github.com/storybookjs/storybook/pull/30019), thanks @ghengeveld!
- Addon Test: Use local storybook binary instead - [#30021](https://github.com/storybookjs/storybook/pull/30021), thanks @kasperpeulen!
- 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!
- Core: Fix bundling of React - [#30003](https://github.com/storybookjs/storybook/pull/30003), thanks @yannbf!
- Nextjs-Vite: Add TS docgen support - [#29824](https://github.com/storybookjs/storybook/pull/29824), thanks @yannbf!
- Vitest: Fix duplicate `test.include` patterns - [#30029](https://github.com/storybookjs/storybook/pull/30029), thanks @JReinhold!

## 8.5.0-alpha.20

- Addon Test: Add `@vitest/coverage-v8` during postinstall if no coverage reporter is installed - [#29993](https://github.com/storybookjs/storybook/pull/29993), thanks @ghengeveld!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ const meta = {
endRef: null,
// prop for the AddonPanel used as wrapper of Panel
active: true,
storyId: 'story-id',
},
} as Meta<typeof InteractionsPanel>;

Expand Down
12 changes: 1 addition & 11 deletions code/addons/test/src/components/InteractionsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ interface InteractionsPanelProps {
onScrollToEnd?: () => void;
hasResultMismatch?: boolean;
browserTestStatus?: CallStates;
storyId: StoryId;
testRunId: string;
}

const Container = styled.div(({ theme }) => ({
Expand Down Expand Up @@ -105,20 +103,12 @@ export const InteractionsPanel: React.FC<InteractionsPanelProps> = React.memo(
endRef,
hasResultMismatch,
browserTestStatus,
storyId,
testRunId,
}) {
const filter = useAnsiToHtmlFilter();

return (
<Container>
{hasResultMismatch && (
<TestDiscrepancyMessage
browserTestStatus={browserTestStatus}
storyId={storyId}
testRunId={testRunId}
/>
)}
{hasResultMismatch && <TestDiscrepancyMessage browserTestStatus={browserTestStatus} />}
{(interactions.length > 0 || hasException) && (
<Subnav
controls={controls}
Expand Down
53 changes: 39 additions & 14 deletions code/addons/test/src/components/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { global } from '@storybook/global';
import { type Call, CallStates, EVENTS, type LogItem } from '@storybook/instrumenter';
import type { API_StatusValue } from '@storybook/types';

import { ADDON_ID, TEST_PROVIDER_ID } from '../constants';
import { ADDON_ID, STORYBOOK_ADDON_TEST_CHANNEL, TEST_PROVIDER_ID } from '../constants';
import { InteractionsPanel } from './InteractionsPanel';

interface Interaction extends Call {
Expand Down Expand Up @@ -114,6 +114,7 @@ export const Panel = memo<{ storyId: string }>(function PanelMemoized({ storyId
// local state
const [scrollTarget, setScrollTarget] = useState<HTMLElement | undefined>(undefined);
const [collapsed, setCollapsed] = useState<Set<Call['id']>>(new Set());
const [hasResultMismatch, setResultMismatch] = useState(false);

const {
controlStates = INITIAL_CONTROL_STATES,
Expand Down Expand Up @@ -226,7 +227,7 @@ export const Panel = memo<{ storyId: string }>(function PanelMemoized({ storyId
interactionsCount: list.filter(({ method }) => method !== 'step').length,
};
});
}, [collapsed]);
}, [set, collapsed]);

const controls = useMemo(
() => ({
Expand All @@ -239,7 +240,7 @@ export const Panel = memo<{ storyId: string }>(function PanelMemoized({ storyId
emit(FORCE_REMOUNT, { storyId });
},
}),
[storyId]
[emit, storyId]
);

const storyFilePath = useParameter('fileName', '');
Expand All @@ -252,22 +253,48 @@ export const Panel = memo<{ storyId: string }>(function PanelMemoized({ storyId
interactions.some((v) => v.status === CallStates.ERROR);

const storyStatus = storyStatuses[storyId]?.[TEST_PROVIDER_ID];
const storyTestStatus = storyStatus?.status;

const browserTestStatus = React.useMemo<CallStates | null>(() => {
const browserTestStatus = useMemo<CallStates | null>(() => {
if (!isPlaying && (interactions.length > 0 || hasException)) {
return hasException ? CallStates.ERROR : CallStates.DONE;
}
return isPlaying ? CallStates.ACTIVE : null;
}, [isPlaying, interactions, hasException]);

const hasResultMismatch = React.useMemo(() => {
return (
browserTestStatus !== null &&
browserTestStatus !== CallStates.ACTIVE &&
storyStatus?.status !== undefined &&
statusMap[browserTestStatus] !== storyStatus.status
);
}, [browserTestStatus, storyStatus]);
const { testRunId } = storyStatus?.data || {};

useEffect(() => {
const isMismatch =
browserTestStatus &&
storyTestStatus &&
storyTestStatus !== 'pending' &&
storyTestStatus !== statusMap[browserTestStatus];

if (isMismatch) {
const timeout = setTimeout(
() =>
setResultMismatch((currentValue) => {
if (!currentValue) {
emit(STORYBOOK_ADDON_TEST_CHANNEL, {
type: 'test-discrepancy',
payload: {
browserStatus: browserTestStatus === CallStates.DONE ? 'PASS' : 'FAIL',
cliStatus: browserTestStatus === CallStates.DONE ? 'FAIL' : 'PASS',
storyId,
testRunId,
},
});
}
return true;
}),
2000
);
return () => clearTimeout(timeout);
} else {
setResultMismatch(false);
}
}, [emit, browserTestStatus, storyTestStatus, storyId, testRunId]);

if (isErrored) {
return <Fragment key="component-tests" />;
Expand All @@ -290,8 +317,6 @@ export const Panel = memo<{ storyId: string }>(function PanelMemoized({ storyId
pausedAt={pausedAt}
endRef={endRef}
onScrollToEnd={scrollTarget && scrollToTarget}
storyId={storyId}
testRunId={storyStatus?.data?.testRunId}
/>
</Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ export default {
parameters: {
layout: 'fullscreen',
},
args: {
storyId: 'story-id',
},
decorators: [
(storyFn) => (
<ManagerContext.Provider value={managerContext}>{storyFn()}</ManagerContext.Provider>
Expand Down
30 changes: 7 additions & 23 deletions code/addons/test/src/components/TestDiscrepancyMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,39 +33,23 @@ const Wrapper = styled.div(({ theme: { color, typography, background } }) => ({

interface TestDiscrepancyMessageProps {
browserTestStatus: CallStates;
storyId: StoryId;
testRunId: string;
}
export const TestDiscrepancyMessage = ({
browserTestStatus,
storyId,
testRunId,
}: TestDiscrepancyMessageProps) => {

export const TestDiscrepancyMessage = ({ browserTestStatus }: TestDiscrepancyMessageProps) => {
const api = useStorybookApi();
const docsUrl = api.getDocsUrl({
subpath: DOCUMENTATION_DISCREPANCY_LINK,
versioned: true,
renderer: true,
});
const message = `This component test passed in ${browserTestStatus === CallStates.DONE ? 'this browser' : 'CLI'}, but the tests failed in ${browserTestStatus === CallStates.ERROR ? 'this browser' : 'CLI'}.`;

useEffect(
() =>
api.emit(STORYBOOK_ADDON_TEST_CHANNEL, {
type: 'test-discrepancy',
payload: {
browserStatus: browserTestStatus === CallStates.DONE ? 'PASS' : 'FAIL',
cliStatus: browserTestStatus === CallStates.DONE ? 'FAIL' : 'PASS',
storyId,
testRunId,
},
}),
[api, browserTestStatus, storyId, testRunId]
);
const [passed, failed] =
browserTestStatus === CallStates.ERROR
? ['the CLI', 'this browser']
: ['this browser', 'the CLI'];

return (
<Wrapper>
{message}{' '}
This component test passed in {passed}, but the tests failed in {failed}.{' '}
<Link href={docsUrl} target="_blank" withArrow>
Learn what could cause this
</Link>
Expand Down
21 changes: 4 additions & 17 deletions code/addons/test/src/postinstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { readConfig, writeConfig } from 'storybook/internal/csf-tools';
import { colors, logger } from 'storybook/internal/node-logger';

// eslint-disable-next-line depend/ban-dependencies
import { execa } from 'execa';
import { $ } from 'execa';
import { findUp } from 'find-up';
import { dirname, extname, join, relative, resolve } from 'pathe';
import picocolors from 'picocolors';
Expand Down Expand Up @@ -227,22 +227,9 @@ export default async function postInstall(options: PostinstallOptions) {
}

if (shouldUninstall) {
await execa(
packageManager.getRemoteRunCommand(),
[
'storybook',
'remove',
addonInteractionsName,
'--package-manager',
options.packageManager,
'--config-dir',
options.configDir,
],
{
shell: true,
stdio: 'inherit',
}
);
await $({
stdio: 'inherit',
})`storybook remove ${addonInteractionsName} --package-manager ${options.packageManager} --config-dir ${options.configDir}`;
}
}

Expand Down
31 changes: 21 additions & 10 deletions code/addons/test/src/vitest-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
.replace('</head>', `${headHtmlSnippet ?? ''}</head>`)
.replace('<body>', `<body>${bodyHtmlSnippet ?? ''}`);
},
async config(inputConfig_DoNotMutate) {
async config(inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED) {
// ! We're not mutating the input config, instead we're returning a new partial config
// ! see https://vite.dev/guide/api-plugin.html#config
try {
Expand Down Expand Up @@ -155,8 +155,9 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
setupFiles: [
join(packageDir, 'dist/vitest-plugin/setup-file.mjs'),
// if the existing setupFiles is a string, we have to include it otherwise we're overwriting it
typeof inputConfig_DoNotMutate.test?.setupFiles === 'string' &&
inputConfig_DoNotMutate.test?.setupFiles,
typeof inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test
?.setupFiles === 'string' &&
inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test?.setupFiles,
].filter(Boolean) as string[],

...(finalOptions.storybookScript
Expand All @@ -181,7 +182,8 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
.map((path) => convertPathToPattern(path)),

// if the existing deps.inline is true, we keep it as-is, because it will inline everything
...(inputConfig_DoNotMutate.test?.server?.deps?.inline !== true
...(inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test?.server?.deps
?.inline !== true
? {
server: {
deps: {
Expand All @@ -192,7 +194,7 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
: {}),

browser: {
...inputConfig_DoNotMutate.test?.browser,
...inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test?.browser,
commands: {
getInitialGlobals: () => {
const envConfig = JSON.parse(process.env.VITEST_STORYBOOK_CONFIG ?? '{}');
Expand All @@ -209,8 +211,9 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
},
},
// if there is a test.browser config AND test.browser.screenshotFailures is not explicitly set, we set it to false
...(inputConfig_DoNotMutate.test?.browser &&
inputConfig_DoNotMutate.test.browser.screenshotFailures === undefined
...(inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test?.browser &&
inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test.browser
.screenshotFailures === undefined
? {
screenshotFailures: false,
}
Expand All @@ -219,7 +222,11 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
},

envPrefix: Array.from(
new Set([...(inputConfig_DoNotMutate.envPrefix || []), 'STORYBOOK_', 'VITE_'])
new Set([
...(inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.envPrefix || []),
'STORYBOOK_',
'VITE_',
])
),

resolve: {
Expand Down Expand Up @@ -258,8 +265,12 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin> => {
);

// alert the user of problems
if (inputConfig_DoNotMutate.test.include?.length > 0) {
console.warn(
if (
inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test.include?.length > 0
) {
// remove the user's existing include, because we're replacing it with our own heuristic based on main.ts#stories
inputConfig_ONLY_MUTATE_WHEN_STRICTLY_NEEDED_OR_YOU_WILL_BE_FIRED.test.include = [];
console.log(
Comment on lines +271 to +273
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: properly cleans up user's test.include array before showing warning, preventing duplicate test runs

picocolors.yellow(dedent`
Warning: Starting in Storybook 8.5.0-alpha.18, the "test.include" option in Vitest is discouraged in favor of just using the "stories" field in your Storybook configuration.

Expand Down
1 change: 1 addition & 0 deletions code/frameworks/experimental-nextjs-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
"dependencies": {
"@storybook/builder-vite": "workspace:*",
"@storybook/react": "workspace:*",
"@storybook/react-vite": "workspace:*",
"@storybook/test": "workspace:*",
"styled-jsx": "5.1.6",
"vite-plugin-storybook-nextjs": "^1.1.0"
Expand Down
9 changes: 6 additions & 3 deletions code/frameworks/experimental-nextjs-vite/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'node:path';
import type { PresetProperty } from 'storybook/internal/types';

import type { StorybookConfigVite } from '@storybook/builder-vite';
import { viteFinal as reactViteFinal } from '@storybook/react-vite/preset';

import { dirname, join } from 'path';
import vitePluginStorybookNextjs from 'vite-plugin-storybook-nextjs';
Expand Down Expand Up @@ -34,11 +35,13 @@ export const previewAnnotations: PresetProperty<'previewAnnotations'> = (entry =
};

export const viteFinal: StorybookConfigVite['viteFinal'] = async (config, options) => {
config.plugins = config.plugins || [];
const reactConfig = await reactViteFinal(config, options);
const { plugins = [] } = reactConfig;

const { nextConfigPath } = await options.presets.apply<FrameworkOptions>('frameworkOptions');

const nextDir = nextConfigPath ? path.dirname(nextConfigPath) : undefined;
config.plugins.push(vitePluginStorybookNextjs({ dir: nextDir }));
plugins.push(vitePluginStorybookNextjs({ dir: nextDir }));

return config;
return reactConfig;
};
1 change: 0 additions & 1 deletion code/frameworks/react-native-web-vite/src/preset.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-expect-error FIXME
import { viteFinal as reactViteFinal } from '@storybook/react-vite/preset';

import { esbuildFlowPlugin, flowPlugin } from '@bunchtogether/vite-plugin-flow';
Expand Down
10 changes: 10 additions & 0 deletions code/frameworks/react-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
},
"./package.json": "./package.json"
},
"typesVersions": {
"*": {
"*": [
"dist/index.d.ts"
],
"preset": [
"dist/preset.d.ts"
]
}
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/react-vite/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const core: PresetProperty<'core'> = {
renderer: getAbsolutePath('@storybook/react'),
};

export const viteFinal: StorybookConfig['viteFinal'] = async (config, { presets }) => {
export const viteFinal: NonNullable<StorybookConfig['viteFinal']> = async (config, { presets }) => {
const { plugins = [] } = config;

// Add docgen plugin
Expand Down
Loading