From 952dba5774039c78c2c62ab8ff421b360de278a9 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Mon, 19 Feb 2024 12:08:07 +0100 Subject: [PATCH 1/2] Warn when argTypesRegex is used together with the visual test addon --- .../src/utils/get-storybook-info.ts | 2 +- code/lib/core-server/package.json | 1 + code/lib/core-server/src/build-dev.ts | 9 +- .../src/utils/warnWhenUsingArgTypesRegex.ts | 54 ++++++++++++ code/yarn.lock | 84 +++++++++++++++++++ 5 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts diff --git a/code/lib/core-common/src/utils/get-storybook-info.ts b/code/lib/core-common/src/utils/get-storybook-info.ts index 642db99a7485..2c90d90fd674 100644 --- a/code/lib/core-common/src/utils/get-storybook-info.ts +++ b/code/lib/core-common/src/utils/get-storybook-info.ts @@ -94,7 +94,7 @@ export const findConfigFile = (prefix: string, configDir: string) => { return extension ? `${filePrefix}.${extension}` : null; }; -const getConfigInfo = (packageJson: PackageJson, configDir?: string) => { +export const getConfigInfo = (packageJson: PackageJson, configDir?: string) => { let storybookConfigDir = configDir ?? '.storybook'; const storybookScript = packageJson.scripts?.['storybook']; if (storybookScript && !configDir) { diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index ff37db230991..dc024488a7f8 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -56,6 +56,7 @@ }, "dependencies": { "@aw-web-design/x-default-browser": "1.4.126", + "@babel/core": "^7.23.9", "@discoveryjs/json-ext": "^0.5.3", "@storybook/builder-manager": "workspace:*", "@storybook/channels": "workspace:*", diff --git a/code/lib/core-server/src/build-dev.ts b/code/lib/core-server/src/build-dev.ts index 67990ff2d430..cfab99ef9f2e 100644 --- a/code/lib/core-server/src/build-dev.ts +++ b/code/lib/core-server/src/build-dev.ts @@ -11,7 +11,7 @@ import { import prompts from 'prompts'; import invariant from 'tiny-invariant'; import { global } from '@storybook/global'; -import { telemetry, oneWayHash } from '@storybook/telemetry'; +import { oneWayHash, telemetry } from '@storybook/telemetry'; import { join, relative, resolve } from 'path'; import { deprecate } from '@storybook/node-logger'; @@ -22,9 +22,10 @@ import { storybookDevServer } from './dev-server'; import { outputStats } from './utils/output-stats'; import { outputStartupInformation } from './utils/output-startup-information'; import { updateCheck } from './utils/update-check'; -import { getServerPort, getServerChannelUrl } from './utils/server-address'; +import { getServerChannelUrl, getServerPort } from './utils/server-address'; import { getManagerBuilder, getPreviewBuilder } from './utils/get-builders'; import { warnOnIncompatibleAddons } from './utils/warnOnIncompatibleAddons'; +import { warnWhenUsingArgTypesRegex } from './utils/warnWhenUsingArgTypesRegex'; import { buildOrThrow } from './utils/build-or-throw'; export async function buildDevStandalone( @@ -93,6 +94,10 @@ export async function buildDevStandalone( console.warn('Storybook failed to check addon compatibility', e); } + try { + await warnWhenUsingArgTypesRegex(packageJson, configDir, config); + } catch (e) {} + // Load first pass: We need to determine the builder // We need to do this because builders might introduce 'overridePresets' which we need to take into account // We hope to remove this in SB8 diff --git a/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts b/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts new file mode 100644 index 000000000000..1518dd3f8aca --- /dev/null +++ b/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts @@ -0,0 +1,54 @@ +import type { PackageJson, StorybookConfig } from '@storybook/types'; +import { getConfigInfo } from '@storybook/core-common'; +import { readFile } from 'fs-extra'; +import * as babel from '@babel/core'; +import type { BabelFile } from '@babel/core'; +import { babelParse } from '@storybook/csf-tools'; +import dedent from 'ts-dedent'; +import chalk from 'chalk'; + +export async function warnWhenUsingArgTypesRegex( + packageJson: PackageJson, + configDir: string, + config: StorybookConfig +) { + const { previewConfig } = getConfigInfo(packageJson, configDir); + const previewContent = previewConfig ? await readFile(previewConfig, 'utf8') : ''; + + const hasVisualTestAddon = + config?.addons?.some((it) => + typeof it === 'string' + ? it === '@chromatic-com/storybook' + : it.name === '@chromatic-com/storybook' + ) ?? false; + + if (hasVisualTestAddon && previewConfig && previewContent.includes('argTypesRegex')) { + // @ts-expect-error File is not yet exposed, see https://github.com/babel/babel/issues/11350#issuecomment-644118606 + const file: BabelFile = new babel.File( + { filename: previewConfig }, + { code: previewContent, ast: babelParse(previewContent) } + ); + + file.path.traverse({ + Identifier: (path) => { + if (path.node.name === 'argTypesRegex') { + const message = dedent` + ${chalk.bold('Attention')}: We've detected that you're using ${chalk.cyan( + 'actions.argTypesRegex' + )} together with the visual test addon: + + ${path.buildCodeFrameError(previewConfig).message} + + We recommend removing the ${chalk.cyan( + 'argTypesRegex' + )} and assigning explicit action with the ${chalk.cyan( + 'fn' + )} function from ${chalk.cyan('@storybook/test')} instead. + The build used by the addon for snapshot testing doesn't take the regex into account, which can cause hard to debug problems when a snapshot depends on the presence of action props. + `; + console.warn(message); + } + }, + }); + } +} diff --git a/code/yarn.lock b/code/yarn.lock index 86f09cd405d2..8b5a956afd3f 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -467,6 +467,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/core@npm:7.23.9" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.23.5" + "@babel/generator": "npm:^7.23.6" + "@babel/helper-compilation-targets": "npm:^7.23.6" + "@babel/helper-module-transforms": "npm:^7.23.3" + "@babel/helpers": "npm:^7.23.9" + "@babel/parser": "npm:^7.23.9" + "@babel/template": "npm:^7.23.9" + "@babel/traverse": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 03883300bf1252ab4c9ba5b52f161232dd52873dbe5cde9289bb2bb26e935c42682493acbac9194a59a3b6cbd17f4c4c84030db8d6d482588afe64531532ff9b + languageName: node + linkType: hard + "@babel/generator@npm:7.23.0": version: 7.23.0 resolution: "@babel/generator@npm:7.23.0" @@ -740,6 +763,17 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/helpers@npm:7.23.9" + dependencies: + "@babel/template": "npm:^7.23.9" + "@babel/traverse": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" + checksum: f69fd0aca96a6fb8bd6dd044cd8a5c0f1851072d4ce23355345b9493c4032e76d1217f86b70df795e127553cf7f3fcd1587ede9d1b03b95e8b62681ca2165b87 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.23.4": version: 7.23.4 resolution: "@babel/highlight@npm:7.23.4" @@ -760,6 +794,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/parser@npm:7.23.9" + bin: + parser: ./bin/babel-parser.js + checksum: 7df97386431366d4810538db4b9ec538f4377096f720c0591c7587a16f6810e62747e9fbbfa1ff99257fd4330035e4fb1b5b77c7bd3b97ce0d2e3780a6618975 + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.22.15, @babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.23.3" @@ -2220,6 +2263,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/template@npm:7.23.9" + dependencies: + "@babel/code-frame": "npm:^7.23.5" + "@babel/parser": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" + checksum: 0e8b60119433787742bc08ae762bbd8d6755611c4cabbcb7627b292ec901a55af65d93d1c88572326069efb64136ef151ec91ffb74b2df7689bbab237030833a + languageName: node + linkType: hard + "@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.23.7, @babel/traverse@npm:^7.4.5": version: 7.23.7 resolution: "@babel/traverse@npm:7.23.7" @@ -2238,6 +2292,24 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/traverse@npm:7.23.9" + dependencies: + "@babel/code-frame": "npm:^7.23.5" + "@babel/generator": "npm:^7.23.6" + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-function-name": "npm:^7.23.0" + "@babel/helper-hoist-variables": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/parser": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: d1615d1d02f04d47111a7ea4446a1a6275668ca39082f31d51f08380de9502e19862be434eaa34b022ce9a17dbb8f9e2b73a746c654d9575f3a680a7ffdf5630 + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.11.5, @babel/types@npm:^7.18.9, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.4, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.23.6, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.6.1, @babel/types@npm:^7.7.2, @babel/types@npm:^7.8.3, @babel/types@npm:^7.9.6": version: 7.23.6 resolution: "@babel/types@npm:7.23.6" @@ -2249,6 +2321,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/types@npm:7.23.9" + dependencies: + "@babel/helper-string-parser": "npm:^7.23.4" + "@babel/helper-validator-identifier": "npm:^7.22.20" + to-fast-properties: "npm:^2.0.0" + checksum: edc7bb180ce7e4d2aea10c6972fb10474341ac39ba8fdc4a27ffb328368dfdfbf40fca18e441bbe7c483774500d5c05e222cec276c242e952853dcaf4eb884f7 + languageName: node + linkType: hard + "@base2/pretty-print-object@npm:1.0.1": version: 1.0.1 resolution: "@base2/pretty-print-object@npm:1.0.1" @@ -5538,6 +5621,7 @@ __metadata: resolution: "@storybook/core-server@workspace:lib/core-server" dependencies: "@aw-web-design/x-default-browser": "npm:1.4.126" + "@babel/core": "npm:^7.23.9" "@discoveryjs/json-ext": "npm:^0.5.3" "@storybook/addon-docs": "workspace:*" "@storybook/builder-manager": "workspace:*" From 15c84372baaf9a27d5186bb547a1e3888542f7ac Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Mon, 19 Feb 2024 14:59:55 +0100 Subject: [PATCH 2/2] Add link to docs --- code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts b/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts index 1518dd3f8aca..fa336373a8a4 100644 --- a/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts +++ b/code/lib/core-server/src/utils/warnWhenUsingArgTypesRegex.ts @@ -43,7 +43,9 @@ export async function warnWhenUsingArgTypesRegex( 'argTypesRegex' )} and assigning explicit action with the ${chalk.cyan( 'fn' - )} function from ${chalk.cyan('@storybook/test')} instead. + )} function from ${chalk.cyan('@storybook/test')} instead: + https://storybook.js.org/docs/essentials/actions#via-storybooktest-fn-spy-function + The build used by the addon for snapshot testing doesn't take the regex into account, which can cause hard to debug problems when a snapshot depends on the presence of action props. `; console.warn(message);