feat(storage): allow passing storage state for isolated contexts (#409)
Fixes https://github.com/microsoft/playwright-mcp/issues/403 Ref https://github.com/microsoft/playwright-mcp/issues/367
This commit is contained in:
@@ -28,11 +28,12 @@ export type CLIOptions = {
|
||||
browser?: string;
|
||||
caps?: string;
|
||||
cdpEndpoint?: string;
|
||||
ephemeral?: boolean;
|
||||
isolated?: boolean;
|
||||
executablePath?: string;
|
||||
headless?: boolean;
|
||||
device?: string;
|
||||
userDataDir?: string;
|
||||
storageState?: string;
|
||||
port?: number;
|
||||
host?: string;
|
||||
vision?: boolean;
|
||||
@@ -102,12 +103,14 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise<Conf
|
||||
if (browserName === 'chromium')
|
||||
(launchOptions as any).cdpPort = await findFreePort();
|
||||
|
||||
const contextOptions: BrowserContextOptions | undefined = cliOptions.device ? devices[cliOptions.device] : undefined;
|
||||
const contextOptions: BrowserContextOptions = cliOptions.device ? devices[cliOptions.device] : {};
|
||||
if (cliOptions.storageState)
|
||||
contextOptions.storageState = cliOptions.storageState;
|
||||
|
||||
return {
|
||||
browser: {
|
||||
browserName,
|
||||
ephemeral: cliOptions.ephemeral,
|
||||
isolated: cliOptions.isolated,
|
||||
userDataDir: cliOptions.userDataDir,
|
||||
launchOptions,
|
||||
contextOptions,
|
||||
|
||||
@@ -341,22 +341,22 @@ ${code.join('\n')}
|
||||
|
||||
if (this.config.browser?.cdpEndpoint) {
|
||||
const browser = await playwright.chromium.connectOverCDP(this.config.browser.cdpEndpoint);
|
||||
const browserContext = this.config.browser.ephemeral ? await browser.newContext() : browser.contexts()[0];
|
||||
const browserContext = this.config.browser.isolated ? await browser.newContext() : browser.contexts()[0];
|
||||
return { browser, browserContext };
|
||||
}
|
||||
|
||||
return this.config.browser?.ephemeral ?
|
||||
await launchEphemeralContext(this.config.browser) :
|
||||
return this.config.browser?.isolated ?
|
||||
await createIsolatedContext(this.config.browser) :
|
||||
await launchPersistentContext(this.config.browser);
|
||||
}
|
||||
}
|
||||
|
||||
async function launchEphemeralContext(browserConfig: Config['browser']): Promise<BrowserContextAndBrowser> {
|
||||
async function createIsolatedContext(browserConfig: Config['browser']): Promise<BrowserContextAndBrowser> {
|
||||
try {
|
||||
const browserName = browserConfig?.browserName ?? 'chromium';
|
||||
const browserType = playwright[browserName];
|
||||
const browser = await browserType.launch(browserConfig?.launchOptions);
|
||||
const browserContext = await browser.newContext();
|
||||
const browserContext = await browser.newContext(browserConfig?.contextOptions);
|
||||
return { browser, browserContext };
|
||||
} catch (error: any) {
|
||||
if (error.message.includes('Executable doesn\'t exist'))
|
||||
|
||||
@@ -28,7 +28,8 @@ program
|
||||
.option('--browser <browser>', 'Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
||||
.option('--caps <caps>', 'Comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.')
|
||||
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
||||
.option('--ephemeral', 'Keep the browser profile in memory, do not save it to disk.')
|
||||
.option('--isolated', 'Keep the browser profile in memory, do not save it to disk.')
|
||||
.option('--storage-state <path>', 'Path to the storage state file for isolated sessions.')
|
||||
.option('--executable-path <path>', 'Path to the browser executable.')
|
||||
.option('--headless', 'Run browser in headless mode, headed by default')
|
||||
.option('--device <device>', 'Device to emulate, for example: "iPhone 15"')
|
||||
|
||||
Reference in New Issue
Block a user