Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions packages/playwright/src/mcp/browser/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export type CLIOptions = {
cdpEndpoint?: string;
cdpHeader?: Record<string, string>;
cdpTimeout?: number;
chromiumSandbox?: boolean;
codegen?: 'typescript' | 'none';
config?: string;
consoleLevel?: 'error' | 'warning' | 'info' | 'debug';
Expand All @@ -59,6 +58,7 @@ export type CLIOptions = {
initPage?: string[];
isolated?: boolean;
imageResponses?: 'allow' | 'omit';
sandbox?: boolean;
outputDir?: string;
outputMode?: 'file' | 'stdout';
port?: number;
Expand Down Expand Up @@ -223,10 +223,10 @@ export function configFromCLIOptions(cliOptions: CLIOptions): Config & { configF
headless: cliOptions.headless,
};

// --chromium-sandbox was passed, enable the chromium sandbox
// --no-chromium-sandbox was passed, disable the chromium sandbox
if (cliOptions.chromiumSandbox !== undefined)
launchOptions.chromiumSandbox = cliOptions.chromiumSandbox;
// --sandbox was passed, enable the sandbox
// --no-sandbox was passed, disable the sandbox
if (cliOptions.sandbox !== undefined)
launchOptions.chromiumSandbox = cliOptions.sandbox;

if (cliOptions.proxyServer) {
launchOptions.proxy = {
Expand Down Expand Up @@ -338,7 +338,7 @@ export function configFromEnv(): Config & { configFile?: string } {
options.isolated = envToBoolean(process.env.PLAYWRIGHT_MCP_ISOLATED);
if (process.env.PLAYWRIGHT_MCP_IMAGE_RESPONSES)
options.imageResponses = enumParser<'allow' | 'omit'>('--image-responses', ['allow', 'omit'], process.env.PLAYWRIGHT_MCP_IMAGE_RESPONSES);
options.chromiumSandbox = envToBoolean(process.env.PLAYWRIGHT_MCP_CHROMIUM_SANDBOX);
options.sandbox = envToBoolean(process.env.PLAYWRIGHT_MCP_SANDBOX);
options.outputDir = envToString(process.env.PLAYWRIGHT_MCP_OUTPUT_DIR);
options.port = numberParser(process.env.PLAYWRIGHT_MCP_PORT);
options.proxyBypass = envToString(process.env.PLAYWRIGHT_MCP_PROXY_BYPASS);
Expand Down
8 changes: 4 additions & 4 deletions packages/playwright/src/mcp/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ export function decorateMCPCommand(command: Command, version: string) {
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
.option('--cdp-header <headers...>', 'CDP headers to send with the connect request, multiple can be specified.', headerParser)
.option('--cdp-timeout <timeout>', 'timeout in milliseconds for connecting to CDP endpoint, defaults to 30000ms', numberParser)
.option('--chromium-sandbox', 'enable the chromium sandbox. disable with --no-chromium-sandbox.')
.option('--no-chromium-sandbox', 'disable the chromium sandbox.')
.option('--codegen <lang>', 'specify the language to use for code generation, possible values: "typescript", "none". Default is "typescript".', enumParser.bind(null, '--codegen', ['none', 'typescript']))
.option('--config <path>', 'path to the configuration file.')
.option('--console-level <level>', 'level of console messages to return: "error", "warning", "info", "debug". Each level includes the messages of more severe levels.', enumParser.bind(null, '--console-level', ['error', 'warning', 'info', 'debug']))
Expand All @@ -53,11 +51,13 @@ export function decorateMCPCommand(command: Command, version: string) {
.option('--init-script <path...>', 'path to JavaScript file to add as an initialization script. The script will be evaluated in every page before any of the page\'s scripts. Can be specified multiple times.')
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
.option('--image-responses <mode>', 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".', enumParser.bind(null, '--image-responses', ['allow', 'omit']))
.option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')
.option('--output-dir <path>', 'path to the directory for output files.')
.option('--output-mode <mode>', 'whether to save snapshots, console messages, network logs to a file or to the standard output. Can be "file" or "stdout". Default is "stdout".', enumParser.bind(null, '--output-mode', ['file', 'stdout']))
.option('--port <port>', 'port to listen on for SSE transport.')
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
.option('--sandbox', 'enable the sandbox for all process types that are normally not sandboxed.')
.option('--save-session', 'Whether to save the Playwright MCP session into the output directory.')
.option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')
.option('--save-video <size>', 'Whether to save the video of the session into the output directory. For example "--save-video=800x600"', resolutionParser.bind(null, '--save-video'))
Expand All @@ -74,8 +74,8 @@ export function decorateMCPCommand(command: Command, version: string) {
.addOption(new ProgramOption('--vision', 'Legacy option, use --caps=vision instead').hideHelp())
.action(async options => {

// normalize the --no-chromium-sandbox option: chromiumSandbox = true => nothing was passed, chromiumSandbox = false => --no-chromium-sandbox was passed.
options.chromiumSandbox = options.chromiumSandbox === true ? undefined : false;
// normalize the --no-sandbox option: sandbox = true => nothing was passed, sandbox = false => --no-sandbox was passed.
options.sandbox = options.sandbox === true ? undefined : false;

setupExitWatchdog();

Expand Down
39 changes: 29 additions & 10 deletions packages/playwright/src/skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ playwright-cli goto https://playwright.dev
playwright-cli click e15
playwright-cli type "page.click"
playwright-cli press Enter
# take a screenshot
# take a screenshot (rarely used, as snapshot is more common)
playwright-cli screenshot
# close the browser
playwright-cli close
Expand Down Expand Up @@ -155,14 +155,7 @@ playwright-cli video-start
playwright-cli video-stop video.webm
```

### Install

```bash
playwright-cli install --skills
playwright-cli install-browser
```

### Configuration
## Open parameters
```bash
# Use specific browser when creating session
playwright-cli open --browser=chrome
Expand All @@ -186,7 +179,24 @@ playwright-cli close
playwright-cli delete-data
```

### Browser Sessions
## Snapshots

After each command, playwright-cli provides a snapshot of the current browser state.

```bash
> playwright-cli goto https://example.com
### Page
- Page URL: https://example.com/
- Page Title: Example Domain
### Snapshot
[Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
```

You can also take a snapshot on demand using `playwright-cli snapshot` command.

If `--filename` is not provided, a new snapshot file is created with a timestamp. Default to automatic file naming, use `--filename=` when artifact is a part of the workflow result.

## Browser Sessions

```bash
# create new browser session named "mysession" with persistent profile
Expand All @@ -204,6 +214,15 @@ playwright-cli close-all
playwright-cli kill-all
```

## Local installation

In some cases user might want to install playwright-cli locally. If running globally available `playwright-cli` binary fails, use `npx playwright-cli` to run the commands. For example:

```bash
npx playwright-cli open https://example.com
npx playwright-cli click e1
```

## Example: Form submission

```bash
Expand Down
14 changes: 7 additions & 7 deletions tests/mcp/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ test.describe(() => {
});
});

test('test chromiumSandbox configuration', async ({}) => {
async function sandboxOption(cli: any) {
const config: any = await resolveCLIConfig(cli);
return config.browser.launchOptions.chromiumSandbox;
}
async function sandboxOption(cli: any) {
const config: any = await resolveCLIConfig(cli);
return config.browser.launchOptions.chromiumSandbox;
}

test('test sandbox configuration', async ({}) => {
expect(await sandboxOption({ browser: 'chromium' })).toBe(process.platform !== 'linux');
expect(await sandboxOption({ browser: 'chromium', chromiumSandbox: true })).toBe(true);
expect(await sandboxOption({ browser: 'chrome', chromiumSandbox: false })).toBe(false);
expect(await sandboxOption({ browser: 'chromium', sandbox: true })).toBe(true);
expect(await sandboxOption({ browser: 'chrome', sandbox: false })).toBe(false);
expect(await sandboxOption({ browser: 'chrome' })).toBe(true);
expect(await sandboxOption({ browser: 'msedge' })).toBe(true);
});
Expand Down
Loading