Skip to content

Commit 76ea8e0

Browse files
authored
fix(cli): automatically enable headed mode when keepWindow is true (#1030)
1 parent 03ca920 commit 76ea8e0

File tree

3 files changed

+98
-5
lines changed

3 files changed

+98
-5
lines changed

packages/cli/src/cli-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Usage:
5555
},
5656
'keep-window': {
5757
type: 'boolean',
58-
description: `Keep the browser window open after the script finishes. This is useful when debugging, but will consume more resources, default is ${defaultConfig.keepWindow}`,
58+
description: `Keep the browser window open after the script finishes. This option automatically enables --headed mode. This is useful when debugging, but will consume more resources, default is ${defaultConfig.keepWindow}`,
5959
},
6060
'share-browser-context': {
6161
type: 'boolean',

packages/cli/src/config-factory.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,21 @@ export async function createConfig(
147147
);
148148

149149
// Apply command line overrides with higher priority than file configuration
150+
const keepWindow = options?.keepWindow ?? parsedConfig.keepWindow;
151+
const headed = options?.headed ?? parsedConfig.headed;
152+
153+
// If keepWindow is true, automatically enable headed mode
154+
const finalHeaded = keepWindow || headed;
155+
150156
return {
151157
files: parsedConfig.files,
152158
concurrent: options?.concurrent ?? parsedConfig.concurrent,
153159
continueOnError: options?.continueOnError ?? parsedConfig.continueOnError,
154160
summary: options?.summary ?? parsedConfig.summary,
155161
shareBrowserContext:
156162
options?.shareBrowserContext ?? parsedConfig.shareBrowserContext,
157-
headed: options?.headed ?? parsedConfig.headed,
158-
keepWindow: options?.keepWindow ?? parsedConfig.keepWindow,
163+
headed: finalHeaded,
164+
keepWindow: keepWindow,
159165
dotenvOverride: options?.dotenvOverride ?? parsedConfig.dotenvOverride,
160166
dotenvDebug: options?.dotenvDebug ?? parsedConfig.dotenvDebug,
161167
globalConfig,
@@ -171,15 +177,21 @@ export async function createFilesConfig(
171177
const timestamp = Date.now();
172178
const defaultSummary = `summary-${timestamp}.json`;
173179

180+
const keepWindow = options.keepWindow ?? defaultConfig.keepWindow;
181+
const headed = options.headed ?? defaultConfig.headed;
182+
183+
// If keepWindow is true, automatically enable headed mode
184+
const finalHeaded = keepWindow || headed;
185+
174186
return {
175187
files,
176188
concurrent: options.concurrent ?? defaultConfig.concurrent,
177189
continueOnError: options.continueOnError ?? defaultConfig.continueOnError,
178190
summary: options.summary ?? defaultSummary,
179191
shareBrowserContext:
180192
options.shareBrowserContext ?? defaultConfig.shareBrowserContext,
181-
headed: options.headed ?? defaultConfig.headed,
182-
keepWindow: options.keepWindow ?? defaultConfig.keepWindow,
193+
headed: finalHeaded,
194+
keepWindow: keepWindow,
183195
dotenvOverride: options.dotenvOverride ?? defaultConfig.dotenvOverride,
184196
dotenvDebug: options.dotenvDebug ?? defaultConfig.dotenvDebug,
185197
globalConfig: {

packages/cli/tests/unit-test/config-factory.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,50 @@ summary: "yaml-summary.json"
137137
});
138138

139139
describe('createConfig', () => {
140+
test('should automatically enable headed when keepWindow is true', async () => {
141+
const mockYamlContent = `
142+
files:
143+
- file1.yml
144+
keepWindow: true
145+
headed: false
146+
`;
147+
const mockParsedYaml = {
148+
files: ['file1.yml'],
149+
concurrent: 1,
150+
continueOnError: false,
151+
headed: false,
152+
keepWindow: true,
153+
dotenvOverride: false,
154+
dotenvDebug: false,
155+
summary: 'parsed.json',
156+
shareBrowserContext: false,
157+
};
158+
vi.mocked(readFileSync).mockReturnValue(mockYamlContent);
159+
vi.mocked(yamlLoad).mockReturnValue(mockParsedYaml);
160+
vi.mocked(matchYamlFiles).mockResolvedValue(['file1.yml']);
161+
162+
// Test 1: keepWindow from config file should enable headed
163+
const result1 = await createConfig('/test/index.yml');
164+
expect(result1.keepWindow).toBe(true);
165+
expect(result1.headed).toBe(true);
166+
167+
// Test 2: keepWindow from command line should enable headed
168+
const result2 = await createConfig('/test/index.yml', {
169+
keepWindow: true,
170+
headed: false,
171+
});
172+
expect(result2.keepWindow).toBe(true);
173+
expect(result2.headed).toBe(true);
174+
175+
// Test 3: keepWindow false should not affect headed
176+
const result3 = await createConfig('/test/index.yml', {
177+
keepWindow: false,
178+
headed: true,
179+
});
180+
expect(result3.keepWindow).toBe(false);
181+
expect(result3.headed).toBe(true);
182+
});
183+
140184
test('should merge command-line options over config file options', async () => {
141185
const mockYamlContent = `
142186
files:
@@ -189,6 +233,43 @@ concurrent: 2
189233
});
190234

191235
describe('createFilesConfig', async () => {
236+
test('should automatically enable headed when keepWindow is true', async () => {
237+
const patterns = ['test.yml'];
238+
const expandedFiles = ['test.yml'];
239+
vi.mocked(matchYamlFiles).mockResolvedValue(expandedFiles);
240+
241+
// Test 1: keepWindow true should enable headed
242+
const result1 = await createFilesConfig(patterns, {
243+
keepWindow: true,
244+
headed: false,
245+
});
246+
expect(result1.keepWindow).toBe(true);
247+
expect(result1.headed).toBe(true);
248+
249+
// Test 2: keepWindow true with headed undefined should enable headed
250+
const result2 = await createFilesConfig(patterns, {
251+
keepWindow: true,
252+
});
253+
expect(result2.keepWindow).toBe(true);
254+
expect(result2.headed).toBe(true);
255+
256+
// Test 3: keepWindow false should not affect headed true
257+
const result3 = await createFilesConfig(patterns, {
258+
keepWindow: false,
259+
headed: true,
260+
});
261+
expect(result3.keepWindow).toBe(false);
262+
expect(result3.headed).toBe(true);
263+
264+
// Test 4: Both false should remain false
265+
const result4 = await createFilesConfig(patterns, {
266+
keepWindow: false,
267+
headed: false,
268+
});
269+
expect(result4.keepWindow).toBe(false);
270+
expect(result4.headed).toBe(false);
271+
});
272+
192273
test('should create config with default options and expand patterns', async () => {
193274
const patterns = ['test1.yml', 'test*.yml'];
194275
const expandedFiles = ['test1.yml', 'testA.yml', 'testB.yml'];

0 commit comments

Comments
 (0)