Skip to content

Commit

Permalink
Merge pull request #29434 from storybookjs/revert-29433-revert-29338-…
Browse files Browse the repository at this point in the history
…yann/addon-interactions-conflict

Addon Test: Error when addon interactions exists
  • Loading branch information
valentinpalkovic authored Oct 25, 2024
2 parents 5edc05e + c02fe50 commit 6098c01
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 51 deletions.
1 change: 0 additions & 1 deletion code/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ const config: StorybookConfig = {
addons: [
'@storybook/addon-themes',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-storysource',
'@storybook/addon-designs',
'@storybook/experimental-addon-test',
Expand Down
3 changes: 3 additions & 0 deletions code/addons/interactions/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ export const checkActionsLoaded = (configDir: string) => {
getConfig: (configFile) => serverRequire(configFile),
});
};

// This annotation is read by addon-test, so it can throw an error if both addons are used
export const ADDON_INTERACTIONS_IN_USE = true;
32 changes: 31 additions & 1 deletion code/addons/test/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TESTING_MODULE_WATCH_MODE_REQUEST,
} from 'storybook/internal/core-events';
import { oneWayHash, telemetry } from 'storybook/internal/telemetry';
import type { Options, StoryId } from 'storybook/internal/types';
import type { Options, PresetProperty, StoryId } from 'storybook/internal/types';

import picocolors from 'picocolors';
import { dedent } from 'ts-dedent';
Expand Down Expand Up @@ -99,3 +99,33 @@ export const experimental_serverChannel = async (channel: Channel, options: Opti

return channel;
};

export const previewAnnotations: PresetProperty<'previewAnnotations'> = async (
entry = [],
options
) => {
checkActionsLoaded(options.configDir);
return entry;
};

export const managerEntries: PresetProperty<'managerEntries'> = async (entry = [], options) => {
// Throw an error when addon-interactions is used.
// This is done by reading an annotation defined in addon-interactions, which although not ideal,
// is a way to handle addon conflict without having to worry about the order of which they are registered
const annotation = await options.presets.apply('ADDON_INTERACTIONS_IN_USE', false);
if (annotation) {
// eslint-disable-next-line local-rules/no-uncategorized-errors
const error = new Error(
dedent`
You have both "@storybook/addon-interactions" and "@storybook/experimental-addon-test" listed as addons in your Storybook config. This is not allowed, as @storybook/experimental-addon-test is a replacement for @storybook/addon-interactions.
Please remove "@storybook/addon-interactions" from the addons array in your main Storybook config at ${options.configDir} and remove the dependency from your package.json file.
`
);
error.name = 'AddonConflictError';
throw error;
}

// for whatever reason seems like the return type of managerEntries is not correct (it expects never instead of string[])
return entry as never;
};
2 changes: 1 addition & 1 deletion code/core/src/manager/components/sidebar/SidebarBottom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export const SidebarBottomBase = ({ api, notifications = [], status = {} }: Side
}, [api, testProviders, updateTestProvider, clearState]);

const testProvidersArray = Object.values(testProviders);
if (!hasWarnings && !hasErrors && !testProvidersArray.length) {
if (!hasWarnings && !hasErrors && !testProvidersArray.length && !notifications.length) {
return null;
}

Expand Down
6 changes: 3 additions & 3 deletions code/e2e-tests/addon-interactions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { expect, test } from '@playwright/test';
import process from 'process';

import { SbPage } from './util';
import { SbPage, hasVitestIntegration } from './util';

const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001';
const templateName = process.env.STORYBOOK_TEMPLATE_NAME || '';

test.describe('addon-interactions', () => {
// TODO: fix the skip statement below when we introduce a sandbox that tests interactions
test.skip(
templateName !== 'todo-sandbox-with-addon-interactions',
hasVitestIntegration,
`Skipping ${templateName}, which does not have addon-interactions set up.`
);

test.beforeEach(async ({ page }) => {
await page.goto(storybookUrl);
await new SbPage(page, expect).waitUntilLoaded();
Expand Down
7 changes: 6 additions & 1 deletion code/e2e-tests/addon-test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { expect, test } from '@playwright/test';
import process from 'process';

import { SbPage } from './util';
import { SbPage, hasVitestIntegration } from './util';

const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001';
const templateName = process.env.STORYBOOK_TEMPLATE_NAME || '';

test.describe('addon-test', () => {
test.skip(
!hasVitestIntegration,
`Skipping ${templateName}, which does not have addon-test set up.`
);

test.beforeEach(async ({ page }) => {
await page.goto(storybookUrl);
await new SbPage(page, expect).waitUntilLoaded();
Expand Down
10 changes: 7 additions & 3 deletions code/e2e-tests/preview-api.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, test } from '@playwright/test';
import process from 'process';

import { SbPage } from './util';
import { SbPage, hasVitestIntegration } from './util';

const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001';
const templateName = process.env.STORYBOOK_TEMPLATE_NAME || '';
Expand All @@ -26,8 +26,12 @@ test.describe('preview-api', () => {
await expect(sbPage.page.locator('.sidebar-container')).toBeVisible();

// wait for the play function to complete
await sbPage.viewAddonPanel('Component tests');
const interactionsTab = page.locator('#tabbutton-storybook-test-panel');
await sbPage.viewAddonPanel(hasVitestIntegration ? 'Component tests' : 'Interactions');
const interactionsTab = page.locator(
hasVitestIntegration
? '#tabbutton-storybook-test-panel'
: '#tabbutton-storybook-interactions-panel'
);
await expect(interactionsTab).toBeVisible();
const panel = sbPage.panelContent();
const runStatusBadge = panel.locator('[aria-label="Status of the test run"]');
Expand Down
8 changes: 8 additions & 0 deletions code/e2e-tests/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { toId } from '@storybook/csf';

import type { Expect, Page } from '@playwright/test';

import { allTemplates } from '../lib/cli-storybook/src/sandbox-templates';

export class SbPage {
readonly page: Page;

Expand Down Expand Up @@ -142,3 +144,9 @@ export class SbPage {
return this.previewIframe().locator('body');
}
}

const templateName: keyof typeof allTemplates = process.env.STORYBOOK_TEMPLATE_NAME || ('' as any);

const templates = allTemplates;
export const hasVitestIntegration =
!templates[templateName]?.skipTasks?.includes('vitest-integration');
2 changes: 1 addition & 1 deletion scripts/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { createOptions, getCommand, getOptionsOrPrompt } from './utils/options';

const sandboxDir = process.env.SANDBOX_ROOT || SANDBOX_DIRECTORY;

export const extraAddons = ['a11y', 'storysource'];
export const extraAddons = ['@storybook/addon-a11y', '@storybook/addon-storysource'];

export type Path = string;
export type TemplateDetails = {
Expand Down
25 changes: 8 additions & 17 deletions scripts/tasks/sandbox-parts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ import dedent from 'ts-dedent';
import { babelParse } from '../../code/core/src/babel/babelParse';
import { detectLanguage } from '../../code/core/src/cli/detect';
import { SupportedLanguage } from '../../code/core/src/cli/project_types';
import {
JsPackageManagerFactory,
removeAddon,
versions as storybookPackages,
} from '../../code/core/src/common';
import { JsPackageManagerFactory, versions as storybookPackages } from '../../code/core/src/common';
import type { ConfigFile } from '../../code/core/src/csf-tools';
import { writeConfig } from '../../code/core/src/csf-tools';
import type { TemplateKey } from '../../code/lib/cli-storybook/src/sandbox-templates';
Expand Down Expand Up @@ -181,8 +177,13 @@ export const init: Task['run'] = async (

if (!skipTemplateStories) {
for (const addon of addons) {
const addonName = `@storybook/addon-${addon}`;
await executeCLIStep(steps.add, { argument: addonName, cwd, dryRun, debug });
await executeCLIStep(steps.add, {
argument: addon,
cwd,
dryRun,
debug,
optionValues: { yes: true },
});
}
}
};
Expand Down Expand Up @@ -395,13 +396,6 @@ const getVitestPluginInfo = (details: TemplateDetails) => {

export async function setupVitest(details: TemplateDetails, options: PassedOptionValues) {
const { sandboxDir, template } = details;
// Remove interactions addon to avoid issues with Vitest
// TODO: add an if statement when we introduce a sandbox that tests interactions
await removeAddon('@storybook/addon-interactions', {
cwd: details.sandboxDir,
configDir: join(details.sandboxDir, '.storybook'),
});

const packageJsonPath = join(sandboxDir, 'package.json');
const packageJson = await readJson(packageJsonPath);

Expand Down Expand Up @@ -803,9 +797,6 @@ export const extendMain: Task['run'] = async ({ template, sandboxDir, key }, { d
mainConfig.setFieldValue(['stories'], updatedStories);
}

const addons = mainConfig.getFieldValue(['addons']);
mainConfig.setFieldValue(['addons'], [...addons, '@storybook/experimental-addon-test']);

if (template.expected.builder === '@storybook/builder-vite') {
setSandboxViteFinal(mainConfig);
}
Expand Down
50 changes: 28 additions & 22 deletions scripts/tasks/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,33 @@ export const sandbox: Task = {
setupVitest,
} = await import('./sandbox-parts');

const extraDeps = [
...(details.template.modifications?.extraDependencies ?? []),
// The storybook package forwards some CLI commands to @storybook/cli with npx.
// Adding the dep makes sure that even npx will use the linked workspace version.
'@storybook/cli',
];

const shouldAddVitestIntegration = !details.template.skipTasks?.includes('vitest-integration');

if (shouldAddVitestIntegration) {
extraDeps.push('happy-dom', 'vitest', 'playwright', '@vitest/browser');

if (details.template.expected.framework.includes('nextjs')) {
extraDeps.push('@storybook/experimental-nextjs-vite', 'jsdom');
}

// if (details.template.expected.renderer === '@storybook/svelte') {
// extraDeps.push(`@testing-library/svelte`);
// }
//
// if (details.template.expected.framework === '@storybook/angular') {
// extraDeps.push('@testing-library/angular', '@analogjs/vitest-angular');
// }

options.addon = [...options.addon, '@storybook/experimental-addon-test'];
}

let startTime = now();
await create(details, options);
const createTime = now() - startTime;
Expand Down Expand Up @@ -83,28 +110,7 @@ export const sandbox: Task = {
await addStories(details, options);
}

const extraDeps = [
...(details.template.modifications?.extraDependencies ?? []),
// The storybook package forwards some CLI commands to @storybook/cli with npx.
// Adding the dep makes sure that even npx will use the linked workspace version.
'@storybook/cli',
'@storybook/experimental-addon-test',
];
if (!details.template.skipTasks?.includes('vitest-integration')) {
extraDeps.push('happy-dom', 'vitest', 'playwright', '@vitest/browser');

if (details.template.expected.framework.includes('nextjs')) {
extraDeps.push('@storybook/experimental-nextjs-vite', 'jsdom');
}

// if (details.template.expected.renderer === '@storybook/svelte') {
// extraDeps.push(`@testing-library/svelte`);
// }
//
// if (details.template.expected.framework === '@storybook/angular') {
// extraDeps.push('@testing-library/angular', '@analogjs/vitest-angular');
// }

if (shouldAddVitestIntegration) {
await setupVitest(details, options);
}

Expand Down
4 changes: 3 additions & 1 deletion scripts/utils/cli-step.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export const steps = {
description: 'Adding addon',
icon: '+',
hasArgument: true,
options: createOptions({}),
options: createOptions({
yes: { type: 'boolean' },
}),
},
link: {
command: 'link',
Expand Down

0 comments on commit 6098c01

Please sign in to comment.