chore: support channel and executable path params (#90)

Fixes https://github.com/microsoft/playwright-mcp/issues/89
This commit is contained in:
Pavel Feldman
2025-03-31 15:30:08 -07:00
committed by GitHub
parent d316441142
commit 9042c03faa
6 changed files with 69 additions and 2 deletions

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
import { fork } from 'child_process';
import path from 'path';
import * as playwright from 'playwright';
export type ContextOptions = {
@@ -69,6 +72,25 @@ export class Context {
this._console.length = 0;
}
async install(): Promise<string> {
const channel = this._options.launchOptions?.channel || 'chrome';
const cli = path.join(require.resolve('playwright/package.json'), '..', 'cli.js');
const child = fork(cli, ['install', channel], {
stdio: 'pipe',
});
const output: string[] = [];
child.stdout?.on('data', data => output.push(data.toString()));
child.stderr?.on('data', data => output.push(data.toString()));
return new Promise((resolve, reject) => {
child.on('close', code => {
if (code === 0)
resolve(channel);
else
reject(new Error(`Failed to install browser: ${output.join('')}`));
});
});
}
existingPage(): playwright.Page {
if (!this._page)
throw new Error('Navigate to a location to create a page');
@@ -119,11 +141,21 @@ export class Context {
return { browser, page };
}
const context = await playwright.chromium.launchPersistentContext(this._options.userDataDir, this._options.launchOptions);
const context = await this._launchPersistentContext();
const [page] = context.pages();
return { page };
}
private async _launchPersistentContext(): Promise<playwright.BrowserContext> {
try {
return await playwright.chromium.launchPersistentContext(this._options.userDataDir, this._options.launchOptions);
} catch (error: any) {
if (error.message.includes('Executable doesn\'t exist'))
throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
throw error;
}
}
async allFramesSnapshot() {
const page = this.existingPage();
const visibleFrames = await page.locator('iframe').filter({ visible: true }).all();