11/* eslint-disable no-empty-pattern */
2+ import { execSync } from 'node:child_process' ;
23import fs from 'node:fs' ;
34import os from 'node:os' ;
45import path from 'node:path' ;
@@ -16,6 +17,15 @@ export type { VSCode } from './fixtures/vscodeEvaluator';
1617
1718export const MaxTimeout = 10000 ;
1819
20+ /** Ensures the E2E runner is built before tests run */
21+ function ensureRunnerBuilt ( ) : void {
22+ const runnerDist = path . join ( __dirname , 'runner' , 'dist' , 'index.js' ) ;
23+ if ( ! fs . existsSync ( runnerDist ) ) {
24+ const rootDir = path . resolve ( __dirname , '../..' ) ;
25+ execSync ( 'pnpm run build:e2e-runner' , { cwd : rootDir , stdio : 'inherit' } ) ;
26+ }
27+ }
28+
1929/** Default VS Code settings applied to all E2E tests */
2030const defaultUserSettings : Record < string , unknown > = {
2131 // Disable telemetry
@@ -52,23 +62,17 @@ export interface LaunchOptions {
5262}
5363
5464export interface VSCodeInstance {
55- page : Page ;
56- electronApp : ElectronApplication ;
65+ electron : {
66+ app : ElectronApplication ;
67+ /** Path to the VS Code executable for this test instance */
68+ executablePath : string ;
69+ /** Launch arguments used for this VS Code instance (for reuse in sequence editor, etc.) */
70+ args : string [ ] ;
71+ /** Path to the workspace opened in VS Code */
72+ workspacePath : string ;
73+ } ;
5774 gitlens : GitLensPage ;
58- /**
59- * Evaluate a function in the VS Code Extension Host context.
60- * The function receives the `vscode` module as its first argument.
61- *
62- * @example
63- * ```ts
64- * await vscode.evaluate(vscode => {
65- * vscode.commands.executeCommand('gitlens.showCommitGraph');
66- * });
67- *
68- * const version = await vscode.evaluate(vscode => vscode.version);
69- * ```
70- */
71- evaluate : VSCodeEvaluator [ 'evaluate' ] ;
75+ page : Page ;
7276}
7377
7478/** Base fixtures for all E2E tests */
@@ -94,6 +98,9 @@ export const test = base.extend<BaseFixtures, WorkerFixtures>({
9498 // vscode launches VS Code with GitLens extension (shared per worker)
9599 vscode : [
96100 async ( { vscodeOptions } , use ) => {
101+ // Ensure the E2E runner is built (handles VS Code extension skipping globalSetup)
102+ ensureRunnerBuilt ( ) ;
103+
97104 const tempDir = await createTmpDir ( ) ;
98105 const vscodePath = await downloadAndUnzipVSCode ( vscodeOptions . vscodeVersion ?? 'stable' ) ;
99106 const extensionPath = path . join ( __dirname , '..' , '..' ) ;
@@ -112,7 +119,7 @@ export const test = base.extend<BaseFixtures, WorkerFixtures>({
112119 // Run setup callback if provided, otherwise open extension folder
113120 const workspacePath = vscodeOptions . setup ? await vscodeOptions . setup ( ) : extensionPath ;
114121
115- const electronApp = await _electron . launch ( {
122+ const options : { executablePath : string ; args : string [ ] } = {
116123 executablePath : vscodePath ,
117124 args : [
118125 '--no-sandbox' ,
@@ -127,7 +134,9 @@ export const test = base.extend<BaseFixtures, WorkerFixtures>({
127134 `--user-data-dir=${ userDataDir } ` ,
128135 workspacePath ,
129136 ] ,
130- } ) ;
137+ } satisfies Parameters < typeof _electron . launch > [ 0 ] ;
138+
139+ const electronApp = await _electron . launch ( options ) ;
131140
132141 // Connect to the VS Code test server using Playwright's internal API
133142 const evaluator = await VSCodeEvaluator . connect ( electronApp ) ;
@@ -140,10 +149,9 @@ export const test = base.extend<BaseFixtures, WorkerFixtures>({
140149 await gitlens . waitForActivation ( ) ;
141150
142151 await use ( {
143- page : page ,
144- electronApp : electronApp ,
152+ electron : { app : electronApp , ...options , workspacePath : workspacePath } ,
145153 gitlens : gitlens ,
146- evaluate : evaluate ,
154+ page : page ,
147155 } satisfies VSCodeInstance ) ;
148156
149157 // Cleanup
0 commit comments