Files
gstack/browse/test/playwright-core-patch.test.ts
Garry TanandClaude Fable 5 436adb72d3 fix(deps): bun-patch playwright-core 1.62.1 — windowsHide at launch + taskkill (#2160, #1989)
The repo's first patchedDependencies entry. playwright-core's bundled
process launcher (lib/coreBundle.js in the 1.62.x layout) spawns browser
children without windowsHide — Node defaults it to FALSE for
child_process.spawn — so Chromium children could flash a console window on
Windows, and its force-kill path shells `taskkill /pid <pid> /T /F`
through cmd.exe with the same omission. Both sites now pass
windowsHide: true via patches/playwright-core@1.62.1.patch (generated with
`bun patch` / `bun patch --commit`).

Coherence verified end-to-end: rm -rf node_modules && bun install applies
the patch cleanly (both sites present in the reinstalled tree), and a real
chromium.launch() through the patched bundle works.
browse/test/playwright-core-patch.test.ts pins the three-legged invariant
statically — package.json's patchedDependencies key is VERSION-KEYED
against the installed playwright-core, the patch file exists and carries
both sites, bun.lock records the patch, and the installed bundle actually
has it applied — so a future playwright bump that forgets to re-target the
patch fails CI with the exact key to regenerate (revert pairing: dropping
the c25 bump requires dropping this patch too).

Tests: playwright-core-patch 4 pass, 0 fail.

Fixes #2160, #1989.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 10:59:08 -07:00

63 lines
2.9 KiB
TypeScript

/**
* #2160/#1989: playwright-core is bun-patched to pass windowsHide at its two
* Windows-visible child_process sites — the browser launch spawn (Node
* defaults windowsHide to FALSE for spawn, so browser children could flash a
* console window) and the force-kill taskkill spawnSync. This is the repo's
* first patchedDependencies entry; these static checks pin the three-legged
* coherence (patch file ↔ package.json ↔ installed tree) so a playwright
* bump that forgets to re-target the patch fails CI instead of silently
* dropping it. NOTE: bumping playwright (c25-style) REQUIRES regenerating
* this patch against the new version — see the revert pairing in the wave
* plan (reverting the bump means dropping the patch too).
*/
import { describe, expect, test } from 'bun:test';
import * as fs from 'fs';
import * as path from 'path';
const ROOT = path.resolve(import.meta.dir, '..', '..');
function installedPlaywrightCoreVersion(): string {
const pkg = JSON.parse(fs.readFileSync(
path.join(ROOT, 'node_modules', 'playwright-core', 'package.json'), 'utf-8',
));
return pkg.version as string;
}
describe('playwright-core windowsHide patch (#2160, #1989)', () => {
test('package.json declares the patch for the installed version', () => {
const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf-8'));
const version = installedPlaywrightCoreVersion();
const key = `playwright-core@${version}`;
expect(pkg.patchedDependencies).toBeDefined();
// Version-keyed on purpose: if playwright is bumped without re-targeting
// the patch, this fails with the exact key that needs regenerating.
expect(pkg.patchedDependencies[key]).toBe(`patches/playwright-core@${version}.patch`);
});
test('the patch file exists and carries both windowsHide sites', () => {
const version = installedPlaywrightCoreVersion();
const patchPath = path.join(ROOT, 'patches', `playwright-core@${version}.patch`);
expect(fs.existsSync(patchPath)).toBe(true);
const patch = fs.readFileSync(patchPath, 'utf-8');
// Launch spawnOptions site.
expect(patch).toContain('+ windowsHide: true,');
// taskkill force-kill site.
expect(patch).toContain('shell: true, windowsHide: true');
});
test('bun.lock is coherent: the lockfile records the patched dependency', () => {
const lock = fs.readFileSync(path.join(ROOT, 'bun.lock'), 'utf-8');
const version = installedPlaywrightCoreVersion();
expect(lock).toContain(`patches/playwright-core@${version}.patch`);
});
test('the INSTALLED tree actually has the patch applied (bun install ran it)', () => {
const bundle = fs.readFileSync(
path.join(ROOT, 'node_modules', 'playwright-core', 'lib', 'coreBundle.js'), 'utf-8',
);
expect(bundle).toContain('gstack patch (#2160/#1989)');
expect(bundle).toContain('shell: true, windowsHide: true');
});
});