storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.95k stars 9.21k forks source link

addon-storyshots doesn't work with Vue3 #14094

Closed d-koppenhagen closed 3 years ago

d-koppenhagen commented 3 years ago

Describe the bug Setting up addon-storyshots using jest, storybook and Vue3 fails.

Executing the test will produce the following output:

TEST_MODE=storybook jest

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

    Couldn't find an appropriate framework loader -- do you need to set the `framework` option?

      24 | }
      25 |
    > 26 | initStoryshots({
         | ^
      27 |   suite: 'Image storyshots',
      28 |   test: imageSnapshot({
      29 |     storybookUrl: 'http://localhost:6006',

      at Object.loadFramework [as default] (node_modules/@storybook/addon-storyshots/dist/frameworks/frameworkLoader.js:24:15)
      at testStorySnapshots (node_modules/@storybook/addon-storyshots/dist/api/index.js:60:39)
      at Object.<anonymous> (tests/storybook/storybook.test.js:26:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        6.198 s
Ran all test suites.

Vue3 support should have been landed with this MR.

The problem seems to be that the addon can't find the loader @storybook/vue as when using vue3, the loader is named @storybook/vue3.

I tried to add the @storybook/vue additionally by adding the following to my package.json file

    "@storybook/vue3": "^6.2.0-beta.5",
 +   "@storybook/vue": "^6.2.0-beta.5",

After this a different error does occur:

TEST_MODE=storybook jest

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

    Cannot find module 'vue/dist/vue.common.js' from 'node_modules/@storybook/addon-storyshots/dist/frameworks/vue/loader.js'

    Require stack:
      node_modules/@storybook/vue/dist/cjs/client/preview/index.js
      node_modules/@storybook/vue/dist/cjs/client/index.js
      node_modules/@storybook/addon-storyshots/dist/frameworks/vue/loader.js
      node_modules/@storybook/addon-storyshots/dist/frameworks/frameworkLoader.js
      node_modules/@storybook/addon-storyshots/dist/api/index.js
      node_modules/@storybook/addon-storyshots/dist/index.js
      tests/storybook/storybook.test.js

      at Resolver.resolveModule (node_modules/jest/node_modules/jest-resolve/build/index.js:306:11)
      at node_modules/@storybook/addon-storyshots/dist/frameworks/vue/loader.js:21:48
      at Object.<anonymous> (node_modules/@storybook/vue/dist/cjs/client/preview/index.js:16:35)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        6.145 s
Ran all test suites.

System

Environment Info:

  System:
    OS: macOS 11.0.1
    CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  Binaries:
    Node: 14.8.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.7 - /usr/local/bin/npm
  Browsers:
    Chrome: 88.0.4324.192
    Safari: 14.0.1
  npmPackages:
    @storybook/addon-actions: ^6.2.0-beta.5 => 6.2.0-beta.5 
    @storybook/addon-essentials: ^6.2.0-beta.5 => 6.2.0-beta.5 
    @storybook/addon-links: ^6.2.0-beta.5 => 6.2.0-beta.5 
    @storybook/addon-storyshots: ^6.1.20 => 6.1.20 
    @storybook/addon-storyshots-puppeteer: ^6.2.0-beta.5 => 6.2.0-beta.5 
    @storybook/vue: ^6.2.0-beta.5 => 6.2.0-beta.5 
    @storybook/vue3: ^6.2.0-beta.5 => 6.2.0-beta.5 

Additional context

File configuration:

package.json:

{
  "name": "vue-test-demo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:snapshot": "TEST_MODE=snapshot vue-cli-service test:unit",
    "test:visual": "TEST_MODE=visual vue-cli-service test:unit",
    "test:storybook": "TEST_MODE=storybook jest",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint",
    "clear-jest-cache": "./node_modules/jest/bin/jest.js --clearCache",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.13.8",
    "@storybook/addon-actions": "^6.2.0-beta.5",
    "@storybook/addon-essentials": "^6.2.0-beta.5",
    "@storybook/addon-links": "^6.2.0-beta.5",
    "@storybook/addon-storyshots": "^6.1.20",
    "@storybook/addon-storyshots-puppeteer": "^6.2.0-beta.5",
    "@storybook/vue3": "^6.2.0-beta.5",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-e2e-cypress": "^4.5.11",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "^4.5.11",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/test-utils": "^2.0.0-0",
    "babel-eslint": "^10.1.0",
    "babel-loader": "^8.2.2",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0-0",
    "jest": "^26.6.3",
    "jest-image-snapshot": "^4.4.0",
    "puppeteer": "^8.0.0",
    "typescript": "~3.9.3",
    "vue-jest": "^5.0.0-0",
    "vue-loader": "^16.1.2"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {},
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)",
          "**/tests/{unit,snapshot,visual,storybook}/**/*.spec.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

tests/setup.js:

const { toMatchImageSnapshot } = require('jest-image-snapshot');

// eslint-disable-next-line no-undef
expect.extend({ toMatchImageSnapshot });

tests/storybook/jest.config.js:

const { TEST_MODE } = process.env;

let testMatch;

switch (TEST_MODE) {
  case 'snapshot':
    testMatch = ['<rootDir>/tests/snapshot/**/*.(spec|test).[tj]s?(x)'];
    break;
  case 'visual':
    testMatch = ['<rootDir>/tests/visual/**/*.(spec|test).[tj]s?(x)'];
    break;
  case 'storybook':
    testMatch = ['<rootDir>/tests/storybook/**/*.(spec|test).[tj]s?(x)'];
    break;
  default:
    testMatch = ['<rootDir>/tests/unit/**/*.(spec|test).[tj]s?(x)'];
    break;
}

module.exports = {
  preset: '@vue/cli-plugin-unit-jest',
  testMatch,
  transform: {
    '^.+\\.vue$': 'vue-jest'
  },
  setupFilesAfterEnv: ['<rootDir>/tests/setup.js'],
}

storybook.test.js:

import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';

const getMatchOptions = ({context : {kind, story}, url}) => {
  return {
    failureThreshold: 0.2,
    failureThresholdType: 'percent',
  }
}
const beforeScreenshot = (page, {context : {kind, story}, url}) => {
  return new Promise(resolve =>
    setTimeout(() => {
      resolve();
    }, 600)
  )
}

const afterScreenshot = ({image, context}) => {
  return new Promise(resolve =>
    setTimeout(() => {
      resolve();
    }, 600)
  )
}

initStoryshots({
  suite: 'Image storyshots',
  test: imageSnapshot({
    storybookUrl: 'http://localhost:6006',
    getMatchOptions,
    beforeScreenshot
  })
});
shilman commented 3 years ago

You need to specify the vue3 framework:

https://github.com/storybookjs/storybook/blob/next/examples/vue-3-cli/vuethreeshots.test.js#L5

@jonniebigodes do you know where to document this?

jonniebigodes commented 3 years ago

@shilman I'll make a pull request tomorrow (Wednesday) addressing this and link this issue.

d-koppenhagen commented 3 years ago

Great! Meanwhile I was able to set things up by providing the framework option as @shilman pointed out.

jonniebigodes commented 3 years ago

Closing this issue as the documentation was updated to address this issue. @d-koppenhagen feel free to let me know if this is still an issue for you and I'll gladly re-open the issue and revisit and update the documentation.

Stay safe