chore: roll playwright to latest (#269)

This commit is contained in:
Pavel Feldman
2025-04-28 13:44:24 -07:00
committed by GitHub
parent bf7dbabca4
commit b02370df2f
5 changed files with 83 additions and 21 deletions

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
import net from 'net';
import * as playwright from 'playwright';
import yaml from 'yaml';
@@ -26,7 +28,7 @@ import type { ModalState, Tool, ToolActionResult } from './tools/tool';
export type ContextOptions = {
browserName?: 'chromium' | 'firefox' | 'webkit';
userDataDir: string;
launchOptions?: playwright.LaunchOptions;
launchOptions?: playwright.LaunchOptions & playwright.BrowserContextOptions;
cdpEndpoint?: string;
remoteEndpoint?: string;
};
@@ -42,6 +44,7 @@ export class Context {
readonly options: ContextOptions;
private _browser: playwright.Browser | undefined;
private _browserContext: playwright.BrowserContext | undefined;
private _createBrowserContextPromise: Promise<{ browser?: playwright.Browser, browserContext: playwright.BrowserContext }> | undefined;
private _tabs: Tab[] = [];
private _currentTab: Tab | undefined;
private _modalStates: (ModalState & { tab: Tab })[] = [];
@@ -259,6 +262,7 @@ ${code.join('\n')}
return;
const browserContext = this._browserContext;
const browser = this._browser;
this._createBrowserContextPromise = undefined;
this._browserContext = undefined;
this._browser = undefined;
@@ -280,6 +284,15 @@ ${code.join('\n')}
}
private async _createBrowserContext(): Promise<{ browser?: playwright.Browser, browserContext: playwright.BrowserContext }> {
if (!this._createBrowserContextPromise)
this._createBrowserContextPromise = this._innerCreateBrowserContext();
return this._createBrowserContextPromise;
}
private async _innerCreateBrowserContext(): Promise<{ browser?: playwright.Browser, browserContext: playwright.BrowserContext }> {
if (this.options.browserName === 'chromium')
(this.options.launchOptions as any).webSocketPort = await findFreePort();
if (this.options.remoteEndpoint) {
const url = new URL(this.options.remoteEndpoint);
if (this.options.browserName)
@@ -468,3 +481,14 @@ class PageSnapshot {
export async function generateLocator(locator: playwright.Locator): Promise<string> {
return (locator as any)._generateLocatorString();
}
async function findFreePort() {
return new Promise((resolve, reject) => {
const server = net.createServer();
server.listen(0, () => {
const { port } = server.address() as net.AddressInfo;
server.close(() => resolve(port));
});
server.on('error', reject);
});
}

View File

@@ -34,7 +34,7 @@ import screen from './tools/screen';
import type { Tool, ToolCapability } from './tools/tool';
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
import type { LaunchOptions } from 'playwright';
import type { LaunchOptions, BrowserContextOptions } from 'playwright';
const snapshotTools: Tool<any>[] = [
...common(true),
@@ -84,6 +84,7 @@ export async function createServer(options?: Options): Promise<Server> {
case 'chrome-beta':
case 'chrome-canary':
case 'chrome-dev':
case 'chromium':
case 'msedge':
case 'msedge-beta':
case 'msedge-canary':
@@ -91,9 +92,6 @@ export async function createServer(options?: Options): Promise<Server> {
browserName = 'chromium';
channel = options.browser;
break;
case 'chromium':
browserName = 'chromium';
break;
case 'firefox':
browserName = 'firefox';
break;
@@ -106,10 +104,12 @@ export async function createServer(options?: Options): Promise<Server> {
}
const userDataDir = options?.userDataDir ?? await createUserDataDir(browserName);
const launchOptions: LaunchOptions = {
const launchOptions: LaunchOptions & BrowserContextOptions = {
headless: !!(options?.headless ?? (os.platform() === 'linux' && !process.env.DISPLAY)),
channel,
executablePath: options?.executablePath,
viewport: null,
...{ assistantMode: true },
};
const allTools = options?.vision ? screenshotTools : snapshotTools;