Skip to content

Commit

Permalink
Merge pull request #174 from storybookjs/support-jest-28
Browse files Browse the repository at this point in the history
Update jest to 28
  • Loading branch information
yannbf authored Aug 26, 2022
2 parents 09ab522 + cf971d5 commit 380ed6c
Show file tree
Hide file tree
Showing 6 changed files with 825 additions and 772 deletions.
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ Storybook test runner turns all of your stories into executable tests.
- [Features](#features)
- [How it works](#how-it-works)
- [Getting started](#getting-started)
- [Jest compatibility](#jest-compatibility)
- [CLI Options](#cli-options)
- [Configuration](#configuration)
- [Ejecting configuration](#ejecting-configuration)
- [Jest-playwright options](#jest-playwright-options)
- [Jest options](#jest-options)
- [Test reporters](#test-reporters)
- [Running against a deployed Storybook](#running-against-a-deployed-storybook)
- [Index.json mode](#indexjson-mode)
Expand Down Expand Up @@ -102,16 +103,6 @@ yarn test-storybook
> TARGET_URL=http://localhost:9009 yarn test-storybook
> ```
### Jest compatibility
The Storybook test runner comes with Jest installed as an internal dependency. In case you are also using Jest as a dependency in your project, in order to avoid possible conflicts, you should use a compatible version of the test runner.
| Jest version | Test runner version |
| ------------ | ------------------- |
| ^26.6.3 | ^0.6.2 |
| ^27.0.0 | ^0.6.2 |
| ^28.0.0 | ^0.7.0 and higher |
## CLI Options
```plaintext
Expand Down Expand Up @@ -139,15 +130,26 @@ Usage: test-storybook [options]
| `--outputFile` | Write test results to a file when the --json option is also specified. <br/>`test-storybook --json --outputFile results.json` |
| `--junit` | Indicates that test information should be reported in a junit file. <br/>`test-storybook --**junit**` |

## Configuration
## Ejecting configuration

The test runner is based on [Jest](https://jestjs.io/) and will accept most of the [CLI options](https://jestjs.io/docs/cli) that Jest does, like `--watch`, `--watchAll`, `--maxWorkers`, etc. It works out of the box, but if you want better control over its configuration, you can eject its configuration by running `test-storybook --eject` to create a local `test-runner-jest.config.js` file in the root folder of your project. This file will be used by the test runner.

The configuration file will accept options for two runners:

#### Jest-playwright options

The test runner uses [jest-playwright](https://github.com/playwright-community/jest-playwright) and you can pass [testEnvironmentOptions](https://github.com/playwright-community/jest-playwright#configuration) to further configure it.

The test runner is based on [Jest](https://jestjs.io/) and will accept most of the [CLI options](https://jestjs.io/docs/cli) that Jest does, like `--watch`, `--watchAll`, `--maxWorkers`, etc.
#### Jest options

The test runner works out of the box, but if you want better control over its configuration, you can run `test-storybook --eject` to create a local `test-runner-jest.config.js` file in the root folder of your project, which will be used by the test runner.
The Storybook test runner comes with Jest installed as an internal dependency. You can pass Jest options based on the version of Jest that comes with the test runner.

The test runner uses [jest-playwright](https://github.com/playwright-community/jest-playwright) and you can pass [testEnvironmentOptions](https://github.com/playwright-community/jest-playwright#configuration) to further configure it, such as how it's done above to run tests against all browsers instead of just chromium. For this you must eject the test runner configuration.
| Test runner version | Jest version |
| ------------------- | ------------------ |
| ^0.6.2 | ^26.6.3 or ^27.0.0 |
| ^0.7.0 | ^28.0.0 |

> **NOTE:** The Jest options relate to the version of Jest that come in the test runner. You can check the [Jest compatibility table](#jest-compatibility) for reference.
> If you're already using a compatible version of Jest, the test runner will use it, instead of installing a duplicate version in your node_modules folder.
## Test reporters

Expand Down
33 changes: 7 additions & 26 deletions bin/test-storybook.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,31 +97,14 @@ function sanitizeURL(url) {
return finalURL;
}

const checkForIncompatibilities = () => {
try {
const jestVersion = require(path.join('jest', 'package.json')).version;
const isJestCompatible =
semver.satisfies(jestVersion, '^26.6.3') || semver.satisfies(jestVersion, '^27.0.0');
if (!isJestCompatible) {
throw new Error('INCOMPATIBLE_VERSION', { cause: jestVersion });
}
} catch (err) {
if (err.message === 'INCOMPATIBLE_VERSION') {
error(dedent`We detected that your project is using Jest ${err.cause}, which is incompatible with this version of the test runner.
You can find more info at: https://github.com/storybookjs/test-runner#jest-compatibility
`);
} else {
error(
`There was an issue while trying to resolve the Jest version of your project. Please file an issue at https://github.com/storybookjs/test-runner/issues`
);
}
process.exit(1);
}
};

async function executeJestPlaywright(args) {
const jest = require('jest');
// Always prefer jest installed via the test runner. If it's hoisted, it will get it from root node_modules
const jestPath = path.dirname(
require.resolve('jest', {
paths: [path.join(__dirname, '../@storybook/test-runner/node_modules')],
})
);
const jest = require(jestPath);
let argv = args.slice(2);

const jestConfigPath = fs.existsSync('test-runner-jest.config.js')
Expand Down Expand Up @@ -222,8 +205,6 @@ function ejectConfiguration() {
}

const main = async () => {
checkForIncompatibilities();

const { jestOptions, runnerOptions } = getCliOptions();

if (runnerOptions.eject) {
Expand Down
25 changes: 12 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook\"",
"test-storybook:ci-failures": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"TEST_FAILURES=1 yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook:failures\"",
"test-storybook:ci-coverage": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook --coverage\"",
"test-storybook:ci-json": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook:json\"",
"test-storybook:ci-json": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && SKIP_SNAPSHOTS=true yarn test-storybook:json\"",
"generate-dynamic-stories": "node scripts/generate-dynamic-stories.js",
"prepare": "husky install"
},
Expand All @@ -64,7 +64,7 @@
"@babel/preset-typescript": "^7.13.0",
"@babel/template": "^7.14.5",
"@babel/types": "^7.14.8",
"@jest/types": "^27.0.6",
"@jest/types": "^28.1.3",
"@storybook/addon-coverage": "^0.0.1",
"@storybook/addon-essentials": "^6.5.0",
"@storybook/addon-interactions": "^6.5.0",
Expand All @@ -78,19 +78,19 @@
"@types/jest": "^27.0.3",
"@types/node": "^16.4.1",
"auto": "^10.3.0",
"babel-jest": "^27.0.6",
"babel-jest": "^28.1.3",
"babel-loader": "^8.1.0",
"babel-plugin-istanbul": "^6.1.1",
"concurrently": "^7.0.0",
"husky": "^8.0.0",
"jest-image-snapshot": "^4.5.1",
"jest-image-snapshot": "^5.1.0",
"lint-staged": "^13.0.3",
"prettier": "^2.3.1",
"prop-types": "^15.7.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.4",
"ts-jest": "^28.0.8",
"typescript": "^4.2.4",
"wait-on": "^6.0.0"
},
Expand All @@ -108,26 +108,25 @@
"icon": "https://user-images.githubusercontent.com/321738/63501763-88dbf600-c4cc-11e9-96cd-94adadc2fd72.png"
},
"dependencies": {
"@storybook/core-common": "^6.5.0",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/csf-tools": "^6.5.0",
"@storybook/store": "^6.5.0",
"can-bind-to-host": "^1.1.1",
"commander": "^9.0.0",
"global": "^4.4.0",
"jest": "^26.6.3 || ^27.0.0",
"jest": "^28.0.0",
"jest-junit": "^14.0.0",
"jest-playwright-preset": "^1.7.2",
"jest-playwright-preset": "^2.0.0",
"jest-runner": "^28.0.0",
"jest-serializer-html": "^7.1.0",
"jest-watch-typeahead": "^1.0.0",
"jest-watch-typeahead": "^2.0.0",
"node-fetch": "^2",
"playwright": "^1.14.0",
"semver": "^7.3.7",
"tempy": "^1.0.1",
"ts-dedent": "^2.0.0"
},
"peerDependencies": {
"@storybook/core-common": "^6.5.0",
"@storybook/csf-tools": "^6.5.0",
"@storybook/store": "^6.5.0"
},
"auto": {
"plugins": [
"npm",
Expand Down
4 changes: 2 additions & 2 deletions playwright/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { transform: babelTransform } = require('@babel/core');
const { transformPlaywright } = require('../dist/cjs/playwright/transformPlaywright');

module.exports = {
process(src, filename, config) {
process(src, filename) {
const csfTest = transformPlaywright(src, filename);

const result = babelTransform(csfTest, {
Expand All @@ -16,6 +16,6 @@ module.exports = {
],
});

return result ? result.code : src;
return { code: result ? result.code : src };
},
};
44 changes: 39 additions & 5 deletions src/config/jest-playwright.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
import path from 'path';

/**
* IMPORTANT NOTE:
* Depending on the user's project and package manager, it's possible that jest-playwright-preset
* is going to be located in @storybook/test-runner/node_modules OR in the root node_modules
*
* By setting `preset: 'jest-playwright-preset` the change of resolution issues is higher, because
* the lib might be installed inside of @storybook/test-runner/node_modules but references as if it was
* in the root node_modules.
*
* This function does the same thing as `preset: 'jest-playwright-preset` but makes sure that the
* necessary moving parts are all required within the correct path.
* */
const getJestPlaywrightConfig = () => {
const presetBasePath = path.dirname(
require.resolve('jest-playwright-preset', {
paths: [path.join(__dirname, '../../node_modules')],
})
);
const expectPlaywrightPath = path.dirname(
require.resolve('expect-playwright', {
paths: [path.join(__dirname, '../../node_modules')],
})
);
return {
runner: path.join(presetBasePath, 'runner.js'),
globalSetup: '@storybook/test-runner/playwright/global-setup.js',
globalTeardown: '@storybook/test-runner/playwright/global-teardown.js',
testEnvironment: '@storybook/test-runner/playwright/custom-environment.js',
setupFilesAfterEnv: [
'@storybook/test-runner/playwright/jest-setup.js',
expectPlaywrightPath,
path.join(presetBasePath, 'lib', 'extends.js'),
],
};
};

export const getJestConfig = () => {
const {
TEST_ROOT,
Expand All @@ -19,11 +57,6 @@ export const getJestConfig = () => {
'^.+\\.stories\\.[jt]sx?$': '@storybook/test-runner/playwright/transform',
'^.+\\.[jt]sx?$': 'babel-jest',
},
preset: 'jest-playwright-preset',
globalSetup: '@storybook/test-runner/playwright/global-setup.js',
globalTeardown: '@storybook/test-runner/playwright/global-teardown.js',
testEnvironment: '@storybook/test-runner/playwright/custom-environment.js',
setupFilesAfterEnv: ['@storybook/test-runner/playwright/jest-setup.js'],
snapshotSerializers: ['jest-serializer-html'],
testEnvironmentOptions: {
'jest-playwright': {
Expand All @@ -38,6 +71,7 @@ export const getJestConfig = () => {
require.resolve('jest-watch-typeahead/testname'),
],
watchPathIgnorePatterns: ['coverage', '.nyc_output', '.cache'],
...getJestPlaywrightConfig(),
};

if (TEST_MATCH) {
Expand Down
Loading

0 comments on commit 380ed6c

Please sign in to comment.