storybook icon indicating copy to clipboard operation
storybook copied to clipboard

[addon-storyshots] storyshots found 0 stories: TypeError: Cannot destructure property 'instrument' of 'undefined' as it is undefined.

Open ldeveber opened this issue 2 years ago • 12 comments

Describe the bug A clear and concise description of what the bug is.

I upgraded jest from 26.6.3 to 27.0.6. All other tests are passing (after adding testEnvironment: 'jest-environment-jsdom', to my jest.config.js), its only the storybook snapshots that are failing.

 FAIL  tests/Storyshots.test.js
  ● Test suite failed to run

    storyshots found 0 stories

      18 | });
      19 |
    > 20 | initStoryshots({
         | ^
      21 |   configPath: path.resolve(__dirname, '../.storybook'),
      22 |   framework: 'react',
      23 |   // integrityOptions: { cwd: path.resolve(__dirname, '../stories') },

      at testStorySnapshots (node_modules/@storybook/addon-storyshots/dist/ts3.9/api/index.js:86:15)
      at Object.<anonymous> (tests/Storyshots.test.js:20:1)

  console.warn
    Unexpected error while loading ./components/Alert.stories.js: TypeError: Cannot destructure property 'instrument' of 'undefined' as it is undefined.

      at Object.warn (node_modules/@storybook/client-logger/dist/cjs/index.js:67:65)
      at node_modules/@storybook/core-client/dist/cjs/preview/loadCsf.js:92:34
          at Array.forEach (<anonymous>)
      at node_modules/@storybook/core-client/dist/cjs/preview/loadCsf.js:85:20
          at Array.forEach (<anonymous>)
      at node_modules/@storybook/core-client/dist/cjs/preview/loadCsf.js:84:12
      at ConfigApi.configure (node_modules/@storybook/client-api/dist/cjs/config_api.js:26:7)

To Reproduce Please create a reproduction by running npx sb@next repro and following the instructions. Read our documentation to learn more about creating reproductions. Paste your repository and deployed reproduction here. We prioritize issues with reproductions over those without.

System Please paste the results of npx sb@next info here.

=^.^= npx sb@next info

Environment Info:

  System:
    OS: macOS 11.4
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 14.17.1 - ~/.nvm/versions/node/v14.17.1/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v14.17.1/bin/yarn
    npm: 6.14.13 - ~/.nvm/versions/node/v14.17.1/bin/npm
  Browsers:
    Chrome: 92.0.4515.159
    Safari: 14.1.1
  npmPackages:
    @storybook/addon-a11y: ^6.3.7 => 6.3.7 
    @storybook/addon-essentials: ^6.3.7 => 6.3.7 
    @storybook/addon-links: ^6.3.7 => 6.3.7 
    @storybook/addon-storyshots: ^6.3.7 => 6.3.7 
    @storybook/addon-storysource: ^6.3.7 => 6.3.7 
    @storybook/addons: ^6.3.7 => 6.3.7 
    @storybook/builder-webpack5: ^6.3.7 => 6.3.7 
    @storybook/core: ^6.3.7 => 6.3.7 
    @storybook/manager-webpack5: ^6.3.7 => 6.3.7 
    @storybook/react: ^6.3.7 => 6.3.7 
    @storybook/source-loader: ^6.3.7 => 6.3.7 

=^.^= 

Additional context Add any other context about the problem here.

I tried to reproduce it with the new repo but I'm going to have to come back to that in a bit >_<

ldeveber avatar Aug 25 '21 16:08 ldeveber

Just ran into this with 6.4.0-alpha.30 in our Angular app, (we are also using addon-storyshots) so I wonder if it's related to this line

cloakedninjas avatar Sep 09 '21 12:09 cloakedninjas

Facing similar issue with mdx stories as well. I am using latest stable storybook version i.e. 6.3.8.

Kathuria avatar Sep 14 '21 12:09 Kathuria

Just ran into this with 6.4.0-alpha.30 in our Angular app, (we are also using addon-storyshots) so I wonder if it's related to this line

I looked into the issue a bit more...after Jest 27, the API of process changed, instrument is in the TransformOptions now.

Also, Jest don't export ScriptTransformer class anymore, instead they export async function createScriptTransformer. https://github.com/facebook/jest/pull/11163

But if we change to use createScriptTransformer, the process function needs to be processAsync, which requires ESM 🤔 ... I don't have a solution yet, just put my observation to the table and see if someone can help.

Someone has pointed this out in jest repo... https://github.com/facebook/jest/issues/11458#issuecomment-899406963

ArvinH avatar Sep 26 '21 07:09 ArvinH

~Hi @Hypnosphi could you take a look of this issue? consider the injectFileName are written by you in https://github.com/storybookjs/storybook/pull/8000~

~I'm happy to help fix this issue but I'm having trouble on understand the logic in injectFileName, especially on why exactly do we need to chain the transformer, would you please shed some light on this?~

Okay I guess I figure it out... because we want the story file be processed by other transformer first and then append exports.default.parameters.fileName to the result...so we use getNextTransformer to remove injectFileName transformer and create another transformer that contains the rest of transformer, then do transformSource.

Guess I can open an issue to the jest repo then

ArvinH avatar Oct 04 '21 14:10 ArvinH

Any workaround for getting Jest 27 to work with mdx stories?

Tiberriver256 avatar Dec 30 '21 16:12 Tiberriver256

Same issue here :(

orrgottlieb avatar Jan 04 '22 19:01 orrgottlieb

I wrote a makeshift jest-transform to get around it.

// https://github.com/storybookjs/storybook/blob/v6.4.14/addons/storyshots/storyshots-core/injectFileName.js#L12
function findTransform(transform, fileName) {
  const self = transform.find(([pattern]) =>
    new RegExp(pattern).test(fileName),
  );
  const transformExcludeSelf = transform.filter(t => t !== self);
  return transformExcludeSelf.find(([pattern]) => new RegExp(pattern).test(fileName));
}

function generateCJS(fileName, { code }) {
  return `${code};
if(exports.default != null) {
  exports.default.parameters = exports.default.parameters || {};
  exports.default.parameters.fileName = '${fileName.replace(/\\/g, '\\\\')}';
}
`;
}

module.exports = {
  process(src, fileName, config) {
    const [,transformFileName] = findTransform(config.config.transform, fileName);
    const processed = require(transformFileName).default.process(src, fileName, config);
    return generateCJS(fileName, processed);
  },
};

jest.config.js:

  transform: {
    '^.+\\.stories\\.tsx?$': '<rootDir>/injectFileName.js',
    // '^.+\\.stories\\.tsx?$': '@storybook/addon-storyshots/injectFileName',
    '^.+\\.[jt]sx?$': 'babel-jest',
  },

eiel avatar Jan 28 '22 15:01 eiel

@eiel That definitely did not work for me and just caused more errors. :/

matthew-dean avatar Apr 14 '22 21:04 matthew-dean

I've created a basic repro using 6.4.22 + the Vite builder here: https://github.com/aendra-rininsland/storybook-vite-storyshots-react-repro

Everything works fine out of the box, it's only when I add the MDX story that everything goes to pot. Downgrading Jest to 26 fixes everything.

aendra-rininsland avatar May 11 '22 12:05 aendra-rininsland

https://www.npmjs.com/package/jest-chain-transform is a better approach than trying to do it inside of another transformer that has logic.

Note that it won't work with ESM transformers (or native ESM in code) (but injectFilename doesn't either)

'use strict';

const dedent = require('dedent');

// simplified version of https://github.com/storybookjs/storybook/blob/82696f194790378720ecb5e946f4bb3636a9e0df/addons/storyshots/storyshots-core/injectFileName.js
module.exports = {
  process(src, fileName) {
    return {
      code: dedent`${src};
if(exports.default != null) {
  exports.default.parameters = exports.default.parameters || {};
  exports.default.parameters.fileName = '${fileName.replace(/\\/g, '\\\\')}';
}
`,
    };
  },
};

Jest probably should have a way of chaining transformers natively

SimenB avatar May 19 '22 07:05 SimenB

Hello.

Same problem for me with jest 28 and storybook 6.5 with MDX stories

FlorianBurgevin avatar Jun 02 '22 15:06 FlorianBurgevin

I got this issue a few days back when I try to update all my dependencies, looks like StoryShots is not compatible with Jest 27 and beyond.

But because of this answer image and this discussion https://github.com/storybookjs/storybook/discussions/18119 I wanted to try the approach of using @storybook/react-testing to bring the composed stories and "manually" create DOM snapshots with Jest.

It went well but still required to create a test file per component, so I refactored my approach and manage to have similar result as StoryShots and this is my final file: https://github.com/glrodasz/cero-components/blob/master/storybook.test.js

The config is still specified for my project but maybe can help you

What I'm doing is the following:

  1. Load all the story files and resolved their modules import
  2. Loop over the stories of each component and take the CSF stories to use composeStories from @storybook/testing-react
  3. Create individual snapshot files using jest-specific-snapshot

If you were using StoryShots only to create DOM snapshots this will do the same for you without StoryShots addon.

glrodasz avatar Aug 05 '22 15:08 glrodasz

The future of storyshots is the test-runner: https://storybook.js.org/docs/react/writing-tests/test-runner#page-top

And use the play function for expectations: https://storybook.js.org/docs/react/writing-stories/play-function#page-top

We will not be making any improvement / changes to storyshots.

ndelangen avatar Jan 17 '23 23:01 ndelangen