Skip to content

Commit da06dac

Browse files
committed
fix(migration): preserve browser provider peer deps and fix version warning (#1236)
When migrating from vitest, @vitest/browser-playwright and @vitest/browser-webdriverio are removed but their required runtime peer dependencies (playwright, webdriverio) were lost. Now the migration automatically adds them to devDependencies. Also patches @vitest/browser version string to use VP_VERSION env var, eliminating the spurious "Running mixed versions" warning. Closes #1190
1 parent f031ac7 commit da06dac

8 files changed

Lines changed: 103 additions & 4 deletions

File tree

.github/workflows/e2e-test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ jobs:
299299
command: |
300300
vp test
301301
vp check --fix
302+
- name: vitest-playwright-repro
303+
node-version: 24
304+
command: |
305+
npx playwright install chromium
306+
vp test
302307
exclude:
303308
# frm-stack uses Docker (testcontainers) which doesn't work the same way on Windows
304309
- os: windows-latest

ecosystem-ci/repo.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,10 @@
108108
"branch": "main",
109109
"hash": "419653665e4f0688ad3cac68a34673fdd0632b55",
110110
"forceFreshMigration": true
111+
},
112+
"vitest-playwright-repro": {
113+
"repository": "https://github.com/why-reproductions-are-required/vitest-playwright-repro.git",
114+
"branch": "main",
115+
"hash": "f7252170025c01ec482fa9ad43e09b965f46928f"
111116
}
112117
}

packages/cli/snap-tests-global/migration-from-vitest-config/snap.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default defineConfig({
4444
"devDependencies": {
4545
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
4646
"vitest": "npm:@voidzero-dev/vite-plus-test@latest",
47+
"playwright": "*",
4748
"vite-plus": "latest"
4849
},
4950
"pnpm": {

packages/cli/snap-tests-global/migration-from-vitest-files/snap.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ VITE+ - The Unified Toolchain for the Web
1919
"devDependencies": {
2020
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
2121
"vitest": "npm:@voidzero-dev/vite-plus-test@latest",
22+
"playwright": "*",
2223
"vite-plus": "latest"
2324
},
2425
"pnpm": {

packages/cli/snap-tests-global/migration-merge-vite-config-ts/snap.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export default defineConfig({
7070
"@vitejs/plugin-react": "^4.2.0",
7171
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
7272
"vitest": "npm:@voidzero-dev/vite-plus-test@latest",
73+
"playwright": "*",
7374
"vite-plus": "latest"
7475
},
7576
"pnpm": {

packages/cli/src/migration/__tests__/migrator.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,60 @@ describe('rewritePackageJson', () => {
129129
rewritePackageJson(pkg, PackageManager.yarn, true);
130130
expect(pkg).toMatchSnapshot();
131131
});
132+
133+
it('should preserve playwright when removing @vitest/browser-playwright', async () => {
134+
const pkg = {
135+
devDependencies: {
136+
'@vitest/browser': '^4.0.0',
137+
'@vitest/browser-playwright': '^4.0.0',
138+
vitest: '^4.0.0',
139+
},
140+
};
141+
rewritePackageJson(pkg, PackageManager.pnpm);
142+
expect(pkg.devDependencies).toHaveProperty('playwright', '*');
143+
expect(pkg.devDependencies).not.toHaveProperty('@vitest/browser');
144+
expect(pkg.devDependencies).not.toHaveProperty('@vitest/browser-playwright');
145+
});
146+
147+
it('should preserve webdriverio when removing @vitest/browser-webdriverio', async () => {
148+
const pkg = {
149+
devDependencies: {
150+
'@vitest/browser': '^4.0.0',
151+
'@vitest/browser-webdriverio': '^4.0.0',
152+
vitest: '^4.0.0',
153+
},
154+
};
155+
rewritePackageJson(pkg, PackageManager.pnpm);
156+
expect(pkg.devDependencies).toHaveProperty('webdriverio', '*');
157+
expect(pkg.devDependencies).not.toHaveProperty('@vitest/browser-webdriverio');
158+
});
159+
160+
it('should not overwrite playwright if already in devDependencies', async () => {
161+
const pkg = {
162+
devDependencies: {
163+
'@vitest/browser-playwright': '^4.0.0',
164+
playwright: '^1.40.0',
165+
vitest: '^4.0.0',
166+
},
167+
};
168+
rewritePackageJson(pkg, PackageManager.pnpm);
169+
expect(pkg.devDependencies).toHaveProperty('playwright', '^1.40.0');
170+
});
171+
172+
it('should not add playwright if already in dependencies', async () => {
173+
const pkg = {
174+
dependencies: {
175+
playwright: '^1.40.0',
176+
},
177+
devDependencies: {
178+
'@vitest/browser-playwright': '^4.0.0',
179+
vitest: '^4.0.0',
180+
},
181+
};
182+
rewritePackageJson(pkg, PackageManager.pnpm);
183+
expect(pkg.dependencies).toHaveProperty('playwright', '^1.40.0');
184+
expect(pkg.devDependencies).not.toHaveProperty('playwright');
185+
});
132186
});
133187

134188
describe('parseNvmrcVersion', () => {

packages/cli/src/migration/migrator.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ const REMOVE_PACKAGES = [
7878
'@vitest/browser-webdriverio',
7979
] as const;
8080

81+
// When a browser provider package is removed, its runtime peer dependency
82+
// must be preserved in devDependencies so browser tests continue to work.
83+
const BROWSER_PROVIDER_PEER_DEPS: Record<string, string> = {
84+
'@vitest/browser-playwright': 'playwright',
85+
'@vitest/browser-webdriverio': 'webdriverio',
86+
};
87+
8188
function warnMigration(message: string, report?: MigrationReport) {
8289
addMigrationWarning(report, message);
8390
if (!report) {
@@ -1203,14 +1210,27 @@ export function rewritePackageJson(
12031210
}
12041211
// remove packages that are replaced with vite-plus
12051212
for (const name of REMOVE_PACKAGES) {
1206-
if (pkg.devDependencies?.[name]) {
1207-
delete pkg.devDependencies[name];
1213+
const wasInDevDeps = !!pkg.devDependencies?.[name];
1214+
const wasInDeps = !!pkg.dependencies?.[name];
1215+
if (wasInDevDeps) {
1216+
delete pkg.devDependencies![name];
12081217
needVitePlus = true;
12091218
}
1210-
if (pkg.dependencies?.[name]) {
1211-
delete pkg.dependencies[name];
1219+
if (wasInDeps) {
1220+
delete pkg.dependencies![name];
12121221
needVitePlus = true;
12131222
}
1223+
// e.g., removing @vitest/browser-playwright should keep `playwright` in devDeps
1224+
const peerDep = BROWSER_PROVIDER_PEER_DEPS[name];
1225+
if (
1226+
(wasInDevDeps || wasInDeps) &&
1227+
peerDep &&
1228+
!pkg.devDependencies?.[peerDep] &&
1229+
!pkg.dependencies?.[peerDep]
1230+
) {
1231+
pkg.devDependencies ??= {};
1232+
pkg.devDependencies[peerDep] = '*';
1233+
}
12141234
}
12151235
if (needVitePlus) {
12161236
// add vite-plus to devDependencies

packages/test/build.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,18 @@ async function patchVitestBrowserPackage() {
16371637
);
16381638
}
16391639

1640+
// 5. Patch version to use VP_VERSION, preventing the "Running mixed versions" warning
1641+
const versionPattern = /var version = "(\d+\.\d+\.\d+[^"]*)"/;
1642+
const beforeVersion = content;
1643+
content = content.replace(versionPattern, 'var version = process.env.VP_VERSION || "$1"');
1644+
if (content === beforeVersion) {
1645+
throw new Error(
1646+
'Failed to patch version in @vitest/browser/index.js: pattern not found. ' +
1647+
'This likely means vitest code has changed and the patch needs to be updated.',
1648+
);
1649+
}
1650+
console.log(' Patched version to use VP_VERSION env var');
1651+
16401652
await writeFile(browserIndexPath, content, 'utf-8');
16411653
console.log(' Successfully patched @vitest/browser/index.js');
16421654
}

0 commit comments

Comments
 (0)