From b0c51ddf19f449cbde888f71e72ef3e96233ada0 Mon Sep 17 00:00:00 2001 From: jackwener Date: Mon, 16 Mar 2026 12:58:18 +0800 Subject: [PATCH] fix: use Playwright MCP --executable-path flag (kebab-case) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract buildMcpArgs() helper and fix --executablePath → --executable-path to match the Playwright MCP CLI's expected flag format. Closes #16 Co-authored-by: KasumiChen --- src/browser.test.ts | 19 +++++++++++++++++++ src/browser.ts | 17 +++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/browser.test.ts b/src/browser.test.ts index 2b16dd7..1f402e5 100644 --- a/src/browser.test.ts +++ b/src/browser.test.ts @@ -49,6 +49,25 @@ describe('browser helpers', () => { expect(__test__.appendLimited('12345', '67890', 8)).toBe('34567890'); }); + it('builds Playwright MCP args with kebab-case executable path', () => { + expect(__test__.buildMcpArgs({ + mcpPath: '/tmp/cli.js', + executablePath: '/mnt/c/Program Files/Google/Chrome/Application/chrome.exe', + })).toEqual([ + '/tmp/cli.js', + '--extension', + '--executable-path', + '/mnt/c/Program Files/Google/Chrome/Application/chrome.exe', + ]); + + expect(__test__.buildMcpArgs({ + mcpPath: '/tmp/cli.js', + })).toEqual([ + '/tmp/cli.js', + '--extension', + ]); + }); + it('times out slow promises', async () => { await expect(__test__.withTimeout(new Promise(() => {}), 10, 'timeout')).rejects.toThrow('timeout'); }); diff --git a/src/browser.ts b/src/browser.ts index 368819d..e306eb8 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -442,13 +442,13 @@ export class PlaywrightMCP { })); }, timeout * 1000); - const mcpArgs: string[] = [mcpPath, '--extension']; + const mcpArgs = buildMcpArgs({ + mcpPath, + executablePath: process.env.OPENCLI_BROWSER_EXECUTABLE_PATH, + }); if (process.env.OPENCLI_VERBOSE) { console.error(`[opencli] Extension token: ${extensionToken ? `configured (fingerprint ${tokenFingerprint})` : 'missing'}`); } - if (process.env.OPENCLI_BROWSER_EXECUTABLE_PATH) { - mcpArgs.push('--executablePath', process.env.OPENCLI_BROWSER_EXECUTABLE_PATH); - } debugLog(`Spawning node ${mcpArgs.join(' ')}`); this._proc = spawn('node', mcpArgs, { @@ -664,6 +664,14 @@ function appendLimited(current: string, chunk: string, limit: number): string { return next.slice(-limit); } +function buildMcpArgs(input: { mcpPath: string; executablePath?: string | null }): string[] { + const args = [input.mcpPath, '--extension']; + if (input.executablePath) { + args.push('--executable-path', input.executablePath); + } + return args; +} + function withTimeout(promise: Promise, timeoutMs: number, message: string): Promise { return new Promise((resolve, reject) => { const timer = setTimeout(() => reject(new Error(message)), timeoutMs); @@ -685,6 +693,7 @@ export const __test__ = { extractTabEntries, diffTabIndexes, appendLimited, + buildMcpArgs, withTimeout, };