Skip to content

Commit

Permalink
Merge pull request #339 from storybookjs/feat/multiple-roots-monorepo
Browse files Browse the repository at this point in the history
Support importing stories from separate packages
  • Loading branch information
yannbf authored Aug 3, 2023
2 parents c19da16 + 90fb7b2 commit 6dc3a4e
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 25 deletions.
19 changes: 12 additions & 7 deletions src/config/jest-playwright.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import path from 'path';
import { getProjectRoot } from '@storybook/core-common';

const TEST_RUNNER_PATH = process.env.STORYBOOK_TEST_RUNNER_PATH || '@storybook/test-runner';

/**
* IMPORTANT NOTE:
Expand All @@ -25,11 +28,11 @@ const getJestPlaywrightConfig = () => {
);
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',
globalSetup: require.resolve(TEST_RUNNER_PATH + '/playwright/global-setup.js'),
globalTeardown: require.resolve(TEST_RUNNER_PATH + '/playwright/global-teardown.js'),
testEnvironment: require.resolve(TEST_RUNNER_PATH + '/playwright/custom-environment.js'),
setupFilesAfterEnv: [
'@storybook/test-runner/playwright/jest-setup.js',
require.resolve(TEST_RUNNER_PATH + '/playwright/jest-setup.js'),
expectPlaywrightPath,
path.join(presetBasePath, 'lib', 'extends.js'),
],
Expand Down Expand Up @@ -66,13 +69,15 @@ export const getJestConfig = () => {

const reporters = STORYBOOK_JUNIT ? ['default', jestJunitPath] : ['default'];

const testMatch = (STORYBOOK_STORIES_PATTERN && STORYBOOK_STORIES_PATTERN.split(';')) || [];

let config = {
rootDir: process.cwd(),
rootDir: getProjectRoot(),
roots: TEST_ROOT ? [TEST_ROOT] : undefined,
reporters,
testMatch: STORYBOOK_STORIES_PATTERN && STORYBOOK_STORIES_PATTERN.split(';'),
testMatch,
transform: {
'^.+\\.stories\\.[jt]sx?$': '@storybook/test-runner/playwright/transform',
'^.+\\.stories\\.[jt]sx?$': require.resolve(TEST_RUNNER_PATH + '/playwright/transform'),
'^.+\\.[jt]sx?$': swcJestPath,
},
snapshotSerializers: [jestSerializerHtmlPath],
Expand Down
24 changes: 13 additions & 11 deletions src/playwright/transformPlaywright.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import dedent from 'ts-dedent';
import path from 'path';
import * as coreCommon from '@storybook/core-common';
import * as storybookMain from '../util/getStorybookMain';

import { transformPlaywright } from './transformPlaywright';

jest.mock('@storybook/core-common');
jest.mock('@storybook/core-common', () => ({
...jest.requireActual('@storybook/core-common'),
getProjectRoot: jest.fn(() => '/foo/bar'),
normalizeStories: jest.fn(() => [
{
titlePrefix: 'Example',
files: '**/*.stories.@(mdx|tsx|ts|jsx|js)',
directory: './stories/basic',
importPathMatcher:
/^\.[\\/](?:stories\/basic(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(mdx|tsx|ts|jsx|js))$/,
},
]),
}));

expect.addSnapshotSerializer({
print: (val: any) => val.trim(),
Expand All @@ -24,15 +35,6 @@ describe('Playwright', () => {
},
],
}));
jest.spyOn(coreCommon, 'normalizeStories').mockImplementation(() => [
{
titlePrefix: 'Example',
files: '**/*.stories.@(mdx|tsx|ts|jsx|js)',
directory: './stories/basic',
importPathMatcher:
/^\.[\\/](?:stories\/basic(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(mdx|tsx|ts|jsx|js))$/,
},
]);
});

const filename = './stories/basic/Header.stories.js';
Expand Down
22 changes: 19 additions & 3 deletions src/util/getStorybookMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ import * as storybookMain from './getStorybookMain';

import { getStorybookMetadata } from './getStorybookMetadata';

jest.mock('@storybook/core-common', () => ({
...jest.requireActual('@storybook/core-common'),
getProjectRoot: jest.fn(() => '/foo/bar'),
normalizeStories: jest.fn(() => [
{
titlePrefix: 'Example',
files: '**/*.stories.@(mdx|tsx|ts|jsx|js)',
directory: './stories/basic',
importPathMatcher:
/^\.[\\/](?:stories\/basic(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(mdx|tsx|ts|jsx|js))$/,
},
]),
}));

describe('getStorybookMetadata', () => {
afterAll(() => {
process.env.STORYBOOK_CONFIG_DIR = undefined;
Expand Down Expand Up @@ -32,7 +46,7 @@ describe('getStorybookMetadata', () => {
process.env.STORYBOOK_CONFIG_DIR = '.storybook';
const { storiesPaths } = getStorybookMetadata();
expect(storiesPaths).toMatchInlineSnapshot(
`"<rootDir>/stories/basic/**/*.@(mdx|stories.@(tsx|ts|jsx|js))"`
`"/foo/bar/stories/basic/**/*.stories.@(mdx|tsx|ts|jsx|js)"`
);
});

Expand All @@ -44,7 +58,9 @@ describe('getStorybookMetadata', () => {
jest.spyOn(storybookMain, 'getStorybookMain').mockReturnValueOnce(mockedMain);
process.env.STORYBOOK_CONFIG_DIR = '.storybook';
const { storiesPaths } = getStorybookMetadata();
expect(storiesPaths).toMatchInlineSnapshot(`"<rootDir>/**/stories/*.stories.@(js|ts)"`);
expect(storiesPaths).toMatchInlineSnapshot(
`"/foo/bar/stories/basic/**/*.stories.@(mdx|tsx|ts|jsx|js)"`
);
});

it('should return storiesPath from mixed CSF2 and CSF3 style config', () => {
Expand All @@ -62,7 +78,7 @@ describe('getStorybookMetadata', () => {
process.env.STORYBOOK_CONFIG_DIR = '.storybook';
const { storiesPaths } = getStorybookMetadata();
expect(storiesPaths).toMatchInlineSnapshot(
`"<rootDir>/stories/basic/**/*.@(mdx|stories.@(tsx|ts|jsx|js));<rootDir>/stories/complex/*.stories.@(js|ts)"`
`"/foo/bar/stories/basic/**/*.stories.@(mdx|tsx|ts|jsx|js)"`
);
});

Expand Down
8 changes: 4 additions & 4 deletions src/util/getStorybookMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { relative, resolve } from 'path';
import { normalizeStories } from '@storybook/core-common';
import { join } from 'path';
import { normalizeStories, getProjectRoot } from '@storybook/core-common';
import { getStorybookMain } from './getStorybookMain';

export const getStorybookMetadata = () => {
const workingDir = resolve();
const workingDir = getProjectRoot();
const configDir = process.env.STORYBOOK_CONFIG_DIR;

const main = getStorybookMain(configDir);
Expand All @@ -17,7 +17,7 @@ export const getStorybookMetadata = () => {

const storiesPaths = normalizedStoriesEntries
.map((entry) => entry.directory + '/' + entry.files)
.map((dir) => '<rootDir>/' + relative(workingDir, dir))
.map((dir) => join(workingDir, dir))
.join(';');

// @ts-ignore -- this is added in @storybook/core-common@6.5, which we don't depend on
Expand Down
3 changes: 3 additions & 0 deletions test-runner-jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// !!! This file is used as an override to the test-runner configuration for this repo only !!!
// If you want to create your own override for your project, run test-storybook eject instead
const path = require('path');
// we override the path here so that when running the test-runner locally, it resolves to local files instead when calling require.resolve
process.env.STORYBOOK_TEST_RUNNER_PATH = path.resolve(__dirname);

const { getJestConfig } = require('./dist');

Expand Down

0 comments on commit 6dc3a4e

Please sign in to comment.