From fed2475a86a035047678f97efa6fb254d861a0d6 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 3 Feb 2026 15:43:17 -0800 Subject: [PATCH] Enhance README with installation and feature details --- README.md | 507 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 480 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 1d55982..77ea238 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,486 @@ npm install -g @playwright/cli@latest playwright-cli --help ``` +### Installing skills + +Claude Code, GitHub # playwright-cli + +Playwright CLI with SKILLS + +### Playwright CLI vs Playwright MCP + +This package provides CLI interface into Playwright. If you are using **coding agents**, that is the best fit. + +- **CLI**: Modern **coding agents** increasingly favor CLI–based workflows exposed as SKILLs over MCP because CLI invocations are more token-efficient: they avoid loading large tool schemas and verbose accessibility trees into the model context, allowing agents to act through concise, purpose-built commands. This makes CLI + SKILLs better suited for high-throughput coding agents that must balance browser automation with large codebases, tests, and reasoning within limited context windows. + +- **MCP**: MCP remains relevant for specialized agentic loops that benefit from persistent state, rich introspection, and iterative reasoning over page structure, such as exploratory automation, self-healing tests, or long-running autonomous workflows where maintaining continuous browser context outweighs token cost concerns. Learn more about [Playwright MCP](https://github.com/microsoft/playwright-mcp). + +### Key Features + +- **Token-efficient**. Does not force page data into LLM. + +### Requirements +- Node.js 18 or newer +- Claude Code, GitHub Copilot, or any other coding agent. + +## Getting Started + +## Installation + +```bash +npm install -g @playwright/cli@latest +playwright-cli --help +``` + +### Installing skills + +Claude Code, GitHub Copilot and others will use the locally installed skills. + +```bash +playwright-cli install-skills +``` + +### Skills-less operation + +Point your agent at the CLI and let it cook. It'll read the skill off `playwright-cli --help` on its own: + +``` +Test the "add todo" flow on https://demo.playwright.dev/todomvc using playwright-cli. +Check playwright-cli --help for available commands. +``` + +## Demo + +``` +> Use playwright skills to test https://demo.playwright.dev/todomvc/. + Take screenshots for all successful and failing scenarios. +``` + +Your agent will be running commands, but it does not mean you can't play with it manually: + +``` +playwright-cli open https://demo.playwright.dev/todomvc/ --headed +playwright-cli type "Buy groceries" +playwright-cli press Enter +playwright-cli type "Water flowers" +playwright-cli press Enter +playwright-cli check e21 +playwright-cli check e35 +playwright-cli screenshot +``` + +## Headed operation + +Playwright CLI is headless by default. If you'd like to see the browser, pass `--headed` to `open`: + +```bash +playwright-cli open https://playwright.dev --headed +``` + +## Sessions + +Playwright CLI will use a dedicated persistent profile by default. It means that +your cookies and other storage state will be preserved between the calls. You can use different +instances of the browser for different projects with sessions. + +Following will result in two browsers with separate profiles being available. Pass `--session` to +the invocation to talk to a specific browser. + +```bash +playwright-cli open https://playwright.dev +playwright-cli --session=example open https://example.com +playwright-cli session-list +``` + +You can run your coding agent with the `PLAYWRIGHT_CLI_SESSION` environment variable: + +```bash +PLAYWRIGHT_CLI_SESSION=todo-app claude . +``` + +Or instruct it to prepend `--session` to the calls. + +Manage your sessions as follows: + +```bash +playwright-cli session-list # list all sessions +playwright-cli session-stop [name] # stop session +playwright-cli session-restart [name] # restart session +playwright-cli session-stop-all # stop all sessions +playwright-cli session-delete [name] # delete session data along with the profiles +``` + + + +## Commands + +### Core + +```bash +playwright-cli open https://example.com/ +playwright-cli close +playwright-cli type "search query" +playwright-cli click e3 +playwright-cli dblclick e7 +playwright-cli fill e5 "user@example.com" +playwright-cli drag e2 e8 +playwright-cli hover e4 +playwright-cli select e9 "option-value" +playwright-cli upload ./document.pdf +playwright-cli check e12 +playwright-cli uncheck e12 +playwright-cli snapshot +playwright-cli snapshot --filename=after-click.yaml +playwright-cli eval "document.title" +playwright-cli eval "el => el.textContent" e5 +playwright-cli dialog-accept +playwright-cli dialog-accept "confirmation text" +playwright-cli dialog-dismiss +playwright-cli resize 1920 1080 +``` + +### Navigation + +```bash +playwright-cli go-back +playwright-cli go-forward +playwright-cli reload +``` + +### Keyboard + +```bash +playwright-cli press Enter +playwright-cli press ArrowDown +playwright-cli keydown Shift +playwright-cli keyup Shift +``` + +### Mouse + +```bash +playwright-cli mousemove 150 300 +playwright-cli mousedown +playwright-cli mousedown right +playwright-cli mouseup +playwright-cli mouseup right +playwright-cli mousewheel 0 100 +``` + +### Save as + +```bash +playwright-cli screenshot +playwright-cli screenshot e5 +playwright-cli screenshot --filename=page.png +playwright-cli pdf --filename=page.pdf +``` + +### Tabs + +```bash +playwright-cli tab-list +playwright-cli tab-new +playwright-cli tab-new https://example.com/page +playwright-cli tab-close +playwright-cli tab-close 2 +playwright-cli tab-select 0 +``` + +### Storage + +```bash +playwright-cli state-save +playwright-cli state-save auth.json +playwright-cli state-load auth.json + +# Cookies +playwright-cli cookie-list +playwright-cli cookie-list --domain=example.com +playwright-cli cookie-get session_id +playwright-cli cookie-set session_id abc123 +playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure +playwright-cli cookie-delete session_id +playwright-cli cookie-clear + +# LocalStorage +playwright-cli localstorage-list +playwright-cli localstorage-get theme +playwright-cli localstorage-set theme dark +playwright-cli localstorage-delete theme +playwright-cli localstorage-clear + +# SessionStorage +playwright-cli sessionstorage-list +playwright-cli sessionstorage-get step +playwright-cli sessionstorage-set step 3 +playwright-cli sessionstorage-delete step +playwright-cli sessionstorage-clear +``` + +### Network + +```bash +playwright-cli route "**/*.jpg" --status=404 +playwright-cli route "https://api.example.com/**" --body='{"mock": true}' +playwright-cli route-list +playwright-cli unroute "**/*.jpg" +playwright-cli unroute +``` + +### DevTools + +```bash +playwright-cli console +playwright-cli console warning +playwright-cli network +playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])" +playwright-cli tracing-start +playwright-cli tracing-stop +playwright-cli video-start +playwright-cli video-stop video.webm +``` + +### Install + +```bash +playwright-cli install-browser +playwright-cli install-skills +``` + +### Configuration + +```bash +# Use specific browser when creating session +playwright-cli open --browser=chrome +playwright-cli open --browser=firefox +playwright-cli open --browser=webkit +playwright-cli open --browser=msedge +# Connect to browser via extension +playwright-cli open --extension + +# Configure the session +playwright-cli config --config my-config.json +playwright-cli config --headed --in-memory --browser=firefox +# Configure named session +playwright-cli --session=mysession config my-config.json +# Start with configured session +playwright-cli open --config=my-config.json +``` + + +## Configuration file + +The Playwright CLI can be configured using a JSON configuration file. You can specify the configuration file using the `--config` command line option: + +```bash +playwright-cli --config path/to/config.json open example.com +``` + +Playwright CLI will load config from `playwright-cli.json` by default so that you did not need to specify it every time. + +
+Configuration file schema + +```typescript +{ + /** + * The browser to use. + */ + browser?: { + /** + * The type of browser to use. + */ + browserName?: 'chromium' | 'firefox' | 'webkit'; + + /** + * Keep the browser profile in memory, do not save it to disk. + */ + isolated?: boolean; + + /** + * Path to a user data directory for browser profile persistence. + * Temporary directory is created by default. + */ + userDataDir?: string; + + /** + * Launch options passed to + * @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context + * + * This is useful for settings options like `channel`, `headless`, `executablePath`, etc. + */ + launchOptions?: playwright.LaunchOptions; + + /** + * Context options for the browser context. + * + * This is useful for settings options like `viewport`. + */ + contextOptions?: playwright.BrowserContextOptions; + + /** + * Chrome DevTools Protocol endpoint to connect to an existing browser instance in case of Chromium family browsers. + */ + cdpEndpoint?: string; + + /** + * CDP headers to send with the connect request. + */ + cdpHeaders?: Record; + + /** + * Timeout in milliseconds for connecting to CDP endpoint. Defaults to 30000 (30 seconds). Pass 0 to disable timeout. + */ + cdpTimeout?: number; + + /** + * Remote endpoint to connect to an existing Playwright server. + */ + remoteEndpoint?: string; + + /** + * Paths to TypeScript files to add as initialization scripts for Playwright page. + */ + initPage?: string[]; + + /** + * Paths to JavaScript files to add as initialization scripts. + * The scripts will be evaluated in every page before any of the page's scripts. + */ + initScript?: string[]; + }, + + /** + * If specified, saves the Playwright video of the session into the output directory. + */ + saveVideo?: { + width: number; + height: number; + }; + + /** + * The directory to save output files. + */ + outputDir?: string; + + /** + * Whether to save snapshots, console messages, network logs and other session logs to a file or to the standard output. Defaults to "stdout". + */ + outputMode?: 'file' | 'stdout'; + + console?: { + /** + * The level of console messages to return. Each level includes the messages of more severe levels. Defaults to "info". + */ + level?: 'error' | 'warning' | 'info' | 'debug'; + }, + + network?: { + /** + * List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked. + */ + allowedOrigins?: string[]; + + /** + * List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked. + */ + blockedOrigins?: string[]; + }; + + /** + * Specify the attribute to use for test ids, defaults to "data-testid". + */ + testIdAttribute?: string; + + timeouts?: { + /* + * Configures default action timeout: https://playwright.dev/docs/api/class-page#page-set-default-timeout. Defaults to 5000ms. + */ + action?: number; + + /* + * Configures default navigation timeout: https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout. Defaults to 60000ms. + */ + navigation?: number; + }; + + /** + * Whether to allow file uploads from anywhere on the file system. + * By default (false), file uploads are restricted to paths within the MCP roots only. + */ + allowUnrestrictedFileAccess?: boolean; + + /** + * Specify the language to use for code generation. + */ + codegen?: 'typescript' | 'none'; +} +``` + +
+ +## Environment + +| Environment | +|-------------| +| `PLAYWRIGHT_MCP_ALLOWED_HOSTS` comma-separated list of hosts this server is allowed to serve from. Defaults to the host the server is bound to. Pass '*' to disable the host check. | +| `PLAYWRIGHT_MCP_ALLOWED_ORIGINS` semicolon-separated list of TRUSTED origins to allow the browser to request. Default is to allow all. Important: *does not* serve as a security boundary and *does not* affect redirects. | +| `PLAYWRIGHT_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS` allow access to files outside of the workspace roots. Also allows unrestricted access to file:// URLs. By default access to file system is restricted to workspace root directories (or cwd if no roots are configured) only, and navigation to file:// URLs is blocked. | +| `PLAYWRIGHT_MCP_BLOCKED_ORIGINS` semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed. Important: *does not* serve as a security boundary and *does not* affect redirects. | +| `PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS` block service workers | +| `PLAYWRIGHT_MCP_BROWSER` browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge. | +| `PLAYWRIGHT_MCP_CAPS` comma-separated list of additional capabilities to enable, possible values: vision, pdf. | +| `PLAYWRIGHT_MCP_CDP_ENDPOINT` CDP endpoint to connect to. | +| `PLAYWRIGHT_MCP_CDP_HEADER` CDP headers to send with the connect request, multiple can be specified. | +| `PLAYWRIGHT_MCP_CODEGEN` specify the language to use for code generation, possible values: "typescript", "none". Default is "typescript". | +| `PLAYWRIGHT_MCP_CONFIG` path to the configuration file. | +| `PLAYWRIGHT_MCP_CONSOLE_LEVEL` level of console messages to return: "error", "warning", "info", "debug". Each level includes the messages of more severe levels. | +| `PLAYWRIGHT_MCP_DEVICE` device to emulate, for example: "iPhone 15" | +| `PLAYWRIGHT_MCP_EXECUTABLE_PATH` path to the browser executable. | +| `PLAYWRIGHT_MCP_EXTENSION` Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed. | +| `PLAYWRIGHT_MCP_GRANT_PERMISSIONS` List of permissions to grant to the browser context, for example "geolocation", "clipboard-read", "clipboard-write". | +| `PLAYWRIGHT_MCP_HEADLESS` run browser in headless mode, headed by default | +| `PLAYWRIGHT_MCP_HOST` host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces. | +| `PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS` ignore https errors | +| `PLAYWRIGHT_MCP_INIT_PAGE` path to TypeScript file to evaluate on Playwright page object | +| `PLAYWRIGHT_MCP_INIT_SCRIPT` 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. | +| `PLAYWRIGHT_MCP_ISOLATED` keep the browser profile in memory, do not save it to disk. | +| `PLAYWRIGHT_MCP_IMAGE_RESPONSES` whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow". | +| `PLAYWRIGHT_MCP_NO_SANDBOX` disable the sandbox for all process types that are normally sandboxed. | +| `PLAYWRIGHT_MCP_OUTPUT_DIR` path to the directory for output files. | +| `PLAYWRIGHT_MCP_OUTPUT_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". | +| `PLAYWRIGHT_MCP_PORT` port to listen on for SSE transport. | +| `PLAYWRIGHT_MCP_PROXY_BYPASS` comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com" | +| `PLAYWRIGHT_MCP_PROXY_SERVER` specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080" | +| `PLAYWRIGHT_MCP_SAVE_SESSION` Whether to save the Playwright MCP session into the output directory. | +| `PLAYWRIGHT_MCP_SAVE_TRACE` Whether to save the Playwright Trace of the session into the output directory. | +| `PLAYWRIGHT_MCP_SAVE_VIDEO` Whether to save the video of the session into the output directory. For example "--save-video=800x600" | +| `PLAYWRIGHT_MCP_SECRETS` path to a file containing secrets in the dotenv format | +| `PLAYWRIGHT_MCP_SHARED_BROWSER_CONTEXT` reuse the same browser context between all connected HTTP clients. | +| `PLAYWRIGHT_MCP_SNAPSHOT_MODE` when taking snapshots for responses, specifies the mode to use. Can be "incremental", "full", or "none". Default is incremental. | +| `PLAYWRIGHT_MCP_STORAGE_STATE` path to the storage state file for isolated sessions. | +| `PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE` specify the attribute to use for test ids, defaults to "data-testid" | +| `PLAYWRIGHT_MCP_TIMEOUT_ACTION` specify action timeout in milliseconds, defaults to 5000ms | +| `PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION` specify navigation timeout in milliseconds, defaults to 60000ms | +| `PLAYWRIGHT_MCP_USER_AGENT` specify user agent string | +| `PLAYWRIGHT_MCP_USER_DATA_DIR` path to the user data directory. If not specified, a temporary directory will be created. | +| `PLAYWRIGHT_MCP_VIEWPORT_SIZE` specify browser viewport size in pixels, for example "1280x720" | +Ccopilot and others will use the locally installed skills. + +```bash +playwright-cli install-skills +``` + +### Skills-less operation + +Point your agent at the CLI and let it cook. It'll read the skill off `playwright-cli --help` on its own: + +``` +Test the "add todo" flow on https://demo.playwright.dev/todomvc using playwright-cli. +Check playwright-cli --help for available commands. +``` + ## Demo ``` @@ -47,33 +527,6 @@ playwright-cli check e35 playwright-cli screenshot ``` -### Skills-less operation - -Point your agent at the CLI and let it cook. It'll read the skill off `playwright-cli --help` on its own: - -``` -Test the "add todo" flow on https://demo.playwright.dev/todomvc using playwright-cli. -Check playwright-cli --help for available commands. -``` - -### Installing skills - -Claude Code, GitHub copilot and others will let you install the Playwright skills into the agentic loop. - -#### plugin (recommended) -```bash -/plugin marketplace add microsoft/playwright-cli -/plugin install playwright-cli -``` - -#### manual - -```bash -mkdir -p .claude/skills/playwright-cli -curl -o .claude/skills/playwright-cli/SKILL.md \ - https://raw.githubusercontent.com/microsoft/playwright-cli/main/skills/playwright-cli/SKILL.md -``` - ## Headed operation Playwright CLI is headless by default. If you'd like to see the browser, pass `--headed` to `open`: