Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 10.1.0-beta.2

- Automigration: Update description and link for addon-a11y-addon-test - [#33133](https://github.com/storybookjs/storybook/pull/33133), thanks @valentinpalkovic!
- CLI: Fix Vitest v3 installs and refactor AddonVitestService; align create‑storybook usage - [#33131](https://github.com/storybookjs/storybook/pull/33131), thanks @valentinpalkovic!
- CLI: Update postAction hook to use command parameter for logfile retrieval - [#33137](https://github.com/storybookjs/storybook/pull/33137), thanks @valentinpalkovic!
- Core: Fix `getDocsUrl` for canary versions - [#33128](https://github.com/storybookjs/storybook/pull/33128), thanks @ghengeveld!

## 10.1.0-beta.1

- Addon-Vitest: Ensure Storybook starts correctly across platforms by using shell in spawn - [#33116](https://github.com/storybookjs/storybook/pull/33116), thanks @valentinpalkovic!
Expand Down
14 changes: 5 additions & 9 deletions code/addons/vitest/src/postinstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,10 @@ export default async function postInstall(options: PostinstallOptions) {
const allDeps = packageManager.getAllDependencies();
// only install these dependencies if they are not already installed

const addonVitestService = new AddonVitestService();
const addonVitestService = new AddonVitestService(packageManager);

// Use AddonVitestService for compatibility validation
const compatibilityResult = await addonVitestService.validateCompatibility({
packageManager,
framework: info.framework,
builder: info.builder,
});
Expand Down Expand Up @@ -97,7 +96,7 @@ export default async function postInstall(options: PostinstallOptions) {
// Skip all dependency management when flag is set (called from init command)
if (!options.skipDependencyManagement) {
// Use AddonVitestService for dependency collection
const versionedDependencies = await addonVitestService.collectDependencies(packageManager);
const versionedDependencies = await addonVitestService.collectDependencies();

// Print informational messages for Next.js
if (info.framework === SupportedFramework.NEXTJS) {
Expand Down Expand Up @@ -139,12 +138,9 @@ export default async function postInstall(options: PostinstallOptions) {
// Install Playwright browser binaries using AddonVitestService
if (!options.skipDependencyManagement) {
if (!options.skipInstall) {
const { errors: playwrightErrors } = await addonVitestService.installPlaywright(
packageManager,
{
yes: options.yes,
}
);
const { errors: playwrightErrors } = await addonVitestService.installPlaywright({
yes: options.yes,
});
errors.push(...playwrightErrors);
} else {
logger.warn(dedent`
Expand Down
59 changes: 25 additions & 34 deletions code/core/src/cli/AddonVitestService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ describe('AddonVitestService', () => {

beforeEach(() => {
vi.clearAllMocks();
service = new AddonVitestService();
vi.mocked(getProjectRoot).mockReturnValue('/test/project');

mockPackageManager = {
getAllDependencies: vi.fn(),
getInstalledVersion: vi.fn(),
runPackageCommand: vi.fn(),
} as Partial<JsPackageManager> as JsPackageManager;

service = new AddonVitestService(mockPackageManager);
vi.mocked(getProjectRoot).mockReturnValue('/test/project');

// Setup default mocks for logger and prompt
vi.mocked(logger.info).mockImplementation(() => {});
vi.mocked(logger.log).mockImplementation(() => {});
Expand All @@ -55,7 +55,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null) // @vitest/coverage-v8
.mockResolvedValueOnce(null); // @vitest/coverage-istanbul

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

expect(deps).toContain('vitest');
// When vitest version is null, defaults to vitest 4+ behavior
Expand All @@ -75,7 +75,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // @vitest/coverage-v8
.mockResolvedValueOnce(null); // @vitest/coverage-istanbul

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

expect(deps).not.toContain('vitest');
expect(deps).not.toContain('@vitest/browser');
Expand All @@ -91,7 +91,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null) // @vitest/coverage-v8
.mockResolvedValueOnce(null); // @vitest/coverage-istanbul

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

// Should only contain base packages, not framework-specific ones
expect(deps).toContain('vitest');
Expand All @@ -109,7 +109,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null) // @vitest/coverage-v8
.mockResolvedValueOnce(null); // @vitest/coverage-istanbul

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

expect(deps.every((d) => !d.includes('nextjs-vite'))).toBe(true);
});
Expand All @@ -121,7 +121,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // @vitest/coverage-v8
.mockResolvedValueOnce(null); // @vitest/coverage-istanbul

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

expect(deps.every((d) => !d.includes('coverage'))).toBe(true);
});
Expand All @@ -133,7 +133,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // @vitest/coverage-istanbul
.mockResolvedValueOnce(null); // vitest version

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

expect(deps.every((d) => !d.includes('coverage'))).toBe(true);
});
Expand All @@ -145,7 +145,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null) // @vitest/coverage-v8
.mockResolvedValueOnce(null); // @vitest/coverage-istanbul

const deps = await service.collectDependencies(mockPackageManager);
const deps = await service.collectDependencies();

expect(deps).toContain('vitest@3.2.0');
// Version 3.2.0 < 4.0.0, so uses @vitest/browser
Expand All @@ -161,7 +161,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // vitest
.mockResolvedValueOnce(null); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(true);
expect(result.reasons).toBeUndefined();
Expand All @@ -172,7 +172,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('4.0.0') // vitest
.mockResolvedValueOnce(null); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(true);
expect(result.reasons).toBeUndefined();
Expand All @@ -183,7 +183,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('2.5.0') // vitest
.mockResolvedValueOnce(null); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(false);
expect(result.reasons).toBeDefined();
Expand All @@ -195,7 +195,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // vitest
.mockResolvedValueOnce('2.0.0'); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(true);
});
Expand All @@ -205,7 +205,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // vitest
.mockResolvedValueOnce('1.9.0'); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(false);
expect(result.reasons).toBeDefined();
Expand All @@ -217,7 +217,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('3.0.0') // vitest
.mockResolvedValueOnce(null); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(true);
});
Expand All @@ -227,7 +227,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null) // vitest
.mockResolvedValueOnce(null); // msw

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(true);
});
Expand All @@ -237,7 +237,7 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('2.0.0') // vitest <3.0.0
.mockResolvedValueOnce('1.0.0'); // msw <2.0.0

const result = await service.validatePackageVersions(mockPackageManager);
const result = await service.validatePackageVersions();

expect(result.compatible).toBe(false);
expect(result.reasons).toBeDefined();
Expand All @@ -253,7 +253,6 @@ describe('AddonVitestService', () => {

it('should return compatible for valid Vite-based framework', async () => {
const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.REACT_VITE,
builder: SupportedBuilder.VITE,
});
Expand All @@ -263,7 +262,6 @@ describe('AddonVitestService', () => {

it('should return compatible for react-vite with Vite builder', async () => {
const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.REACT_VITE,
builder: SupportedBuilder.VITE,
});
Expand All @@ -273,7 +271,6 @@ describe('AddonVitestService', () => {

it('should return incompatible for non-Vite builder (except Next.js)', async () => {
const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.REACT_WEBPACK5,
builder: SupportedBuilder.WEBPACK5,
});
Expand All @@ -288,7 +285,6 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null); // msw

const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.NEXTJS,
builder: SupportedBuilder.WEBPACK5,
});
Expand All @@ -300,7 +296,6 @@ describe('AddonVitestService', () => {

it('should return incompatible for unsupported framework', async () => {
const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.ANGULAR,
builder: SupportedBuilder.VITE,
});
Expand All @@ -317,7 +312,6 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce(null); // msw

const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.NEXTJS_VITE,
builder: SupportedBuilder.VITE,
});
Expand All @@ -330,7 +324,6 @@ describe('AddonVitestService', () => {
vi.mocked(find.any).mockReturnValueOnce('vitest.workspace.json');

const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.REACT_VITE,
builder: SupportedBuilder.VITE,
projectRoot: '.storybook',
Expand All @@ -344,7 +337,6 @@ describe('AddonVitestService', () => {
vi.mocked(find.any).mockReturnValueOnce('vitest.workspace.json');

const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.REACT_VITE,
builder: SupportedBuilder.VITE,
});
Expand All @@ -359,7 +351,6 @@ describe('AddonVitestService', () => {
.mockResolvedValueOnce('1.0.0'); // msw <2.0.0

const result = await service.validateCompatibility({
packageManager: mockPackageManager,
framework: SupportedFramework.ANGULAR,
builder: SupportedBuilder.WEBPACK5,
});
Expand All @@ -381,7 +372,7 @@ describe('AddonVitestService', () => {
vi.mocked(prompt.confirm).mockResolvedValue(true);
vi.mocked(prompt.executeTaskWithSpinner).mockResolvedValue(undefined);

const { errors } = await service.installPlaywright(mockPackageManager);
const { errors } = await service.installPlaywright();

expect(errors).toEqual([]);
expect(prompt.confirm).toHaveBeenCalledWith({
Expand Down Expand Up @@ -409,7 +400,7 @@ describe('AddonVitestService', () => {
}
);

await service.installPlaywright(mockPackageManager);
await service.installPlaywright();

expect(mockPackageManager.runPackageCommand).toHaveBeenCalledWith({
args: ['playwright', 'install', 'chromium', '--with-deps'],
Expand All @@ -424,7 +415,7 @@ describe('AddonVitestService', () => {
vi.mocked(prompt.confirm).mockResolvedValue(true);
vi.mocked(prompt.executeTaskWithSpinner).mockRejectedValue(error);

const { errors } = await service.installPlaywright(mockPackageManager);
const { errors } = await service.installPlaywright();

expect(errors).toEqual(['Error stack trace']);
});
Expand All @@ -435,7 +426,7 @@ describe('AddonVitestService', () => {
vi.mocked(prompt.confirm).mockResolvedValue(true);
vi.mocked(prompt.executeTaskWithSpinner).mockRejectedValue(error);

const { errors } = await service.installPlaywright(mockPackageManager);
const { errors } = await service.installPlaywright();

expect(errors).toEqual(['Installation failed']);
});
Expand All @@ -444,15 +435,15 @@ describe('AddonVitestService', () => {
vi.mocked(prompt.confirm).mockResolvedValue(true);
vi.mocked(prompt.executeTaskWithSpinner).mockRejectedValue('String error');

const { errors } = await service.installPlaywright(mockPackageManager);
const { errors } = await service.installPlaywright();

expect(errors).toEqual(['String error']);
});

it('should skip installation when user declines', async () => {
vi.mocked(prompt.confirm).mockResolvedValue(false);

const { errors } = await service.installPlaywright(mockPackageManager);
const { errors } = await service.installPlaywright();

expect(errors).toEqual([]);
expect(prompt.executeTaskWithSpinner).not.toHaveBeenCalled();
Expand All @@ -463,7 +454,7 @@ describe('AddonVitestService', () => {
vi.mocked(prompt.confirm).mockResolvedValue(true);
vi.mocked(prompt.executeTaskWithSpinner).mockResolvedValue(undefined);

await service.installPlaywright(mockPackageManager);
await service.installPlaywright();

expect(prompt.confirm).toHaveBeenCalled();
expect(prompt.executeTaskWithSpinner).toHaveBeenCalled();
Expand Down
Loading
Loading