PageSourceSearch

https://playwright.dev/assets/js/dd56b7c5.41e799eb.js

js playwright.dev collected 2026-09-24 06:54:28 UTC 20,494 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkplaywright_dev=self.webpackChunkplaywright_dev||[]).push([["2260"],{84709(e,l,i){i.r(l),i.d(l,{metadata:()=>s,default:()=>h,frontMatter:()=>a,contentTitle:()=>r,toc:()=>c,assets:()=>o});var s=JSON.parse('{"id":"getting-started-cli","title":"Coding agents","description":"Introduction","source":"@site/versioned_docs/version-stable/getting-started-cli.mdx","sourceDirName":".","slug":"/getting-started-cli","permalink":"/docs/getting-started-cli","draft":false,"unlisted":false,"tags":[],"version":"stable","frontMatter":{"id":"getting-started-cli","title":"Coding agents"}}'),n=i(74848),t=i(28453);i(13554),i(41647),i(83137);let a={id:"getting-started-cli",title:"Coding agents"},r,o={},c=[{value:"Introduction",id:"introduction",level:2},{value:"<code>playwright-cli</code> vs Playwright MCP",id:"playwright-cli-vs-playwright-mcp",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installation",id:"installation",level:2},{value:"Installing skills",id:"installing-skills",level:3},{value:"Skills-less operation",id:"skills-less-operation",level:3},{value:"First Steps",id:"first-steps",level:2},{value:"Interactive demo",id:"interactive-demo",level:3},{value:"Manual walkthrough",id:"manual-walkthrough",level:3},{value:"Core Commands",id:"core-commands",level:2},{value:"Interacting with pages",id:"interacting-with-pages",level:3},{value:"Targeting elements",id:"targeting-elements",level:3},{value:"Screenshots and snapshots",id:"screenshots-and-snapshots",level:3},{value:"Navigation",id:"navigation",level:3},{value:"Keyboard and mouse",id:"keyboard-and-mouse",level:3},{value:"Tabs",id:"tabs",level:3},{value:"Network",id:"network",level:3},{value:"Storage",id:"storage",level:3},{value:"DevTools",id:"devtools",level:3},{value:"Sessions",id:"sessions",level:2},{value:"Named sessions",id:"named-sessions",level:3},{value:"Session management",id:"session-management",level:3},{value:"Monitoring",id:"monitoring",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Headed mode",id:"headed-mode",level:3},{value:"Browser selection",id:"browser-selection",level:3},{value:"Configuration file",id:"configuration-file",level:3},{value:"Browser extension",id:"browser-extension",level:3},{value:"Quick Reference",id:"quick-reference",level:2},{value:"What&#39;s Next",id:"whats-next",level:2}];function d(e){let l={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(l.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsxs)(l.p,{children:["Playwright comes with ",(0,n.jsx)(l.code,{children:"playwright-cli"}),", a command-line interface for browser automation designed for coding agents. It provides token-efficient browser control through concise CLI commands and installable skills, making it ideal for agents that need to balance browser automation with large codebases and reasoning within limited context windows."]}),"\n",(0,n.jsxs)(l.h3,{id:"playwright-cli-vs-playwright-mcp",children:[(0,n.jsx)(l.code,{children:"playwright-cli"})," vs Playwright MCP"]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsxs)(l.li,{children:[(0,n.jsx)(l.strong,{children:(0,n.jsx)(l.code,{children:"playwright-cli"})})," is best for ",(0,n.jsx)(l.strong,{children:"coding agents"})," (Claude Code, GitHub Copilot, etc.) that favor token-efficient, skill-based workflows. CLI commands avoid loading large tool schemas and verbose accessibility trees into the model context."]}),"\n",(0,n.jsxs)(l.li,{children:[(0,n.jsx)(l.strong,{children:"MCP"})," is best for specialized agentic loops that benefit from persistent state and iterative reasoning over page structure, such as exploratory automation or long-running autonomous workflows. See the ",(0,n.jsx)(l.a,{href:"/docs/getting-started-mcp",children:"MCP getting started guide"}),"."]}),"\n"]}),"\n",(0,n.jsx)(l.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsx)(l.p,{children:"Before you begin, make sure you have the following installed:"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsxs)(l.li,{children:[(0,n.jsx)(l.a,{href:"https://nodejs.org/",children:"Node.js"})," 20 or newer"]}),"\n",(0,n.jsx)(l.li,{children:"A coding agent: Claude Code, GitHub Copilot, or similar"}),"\n"]}),"\n",(0,n.jsx)(l.h2,{id:"installation",children:"Installation"}),"\n",(0,n.jsxs)(l.p,{children:["Install ",(0,n.jsx)(l.code,{children:"playwright-cli"})," globally:"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"npm install -g @playwright/cli@latest\nplaywright-cli --help\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Alternatively, install ",(0,n.jsx)(l.code,{children:"@playwright/cli"})," as a local dependency and use ",(0,n.jsx)(l.code,{children:"npx"}),":"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"npm install -D @playwright/cli@latest\nnpx playwright cli --help\n"})}),"\n",(0,n.jsx)(l.h3,{id:"installing-skills",children:"Installing skills"}),"\n",(0,n.jsx)(l.p,{children:"Coding agents like Claude Code and GitHub Copilot can use locally installed skills for richer context about available commands:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli install --skills\n"})}),"\n",(0,n.jsxs)(l.p,{children:["To share the skills across all your projects, add the ",(0,n.jsx)(l.code,{children:"-g"})," flag to install them into your home directory (",(0,n.jsx)(l.code,{children:"~/.claude/skills"})," or, with ",(0,n.jsx)(l.code,{children:"--skills=agents"}),", ",(0,n.jsx)(l.code,{children:"~/.agents/skills"}),"):"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli install --skills -g\n"})}),"\n",(0,n.jsx)(l.h3,{id:"skills-less-operation",children:"Skills-less operation"}),"\n",(0,n.jsx)(l.p,{children:"You can also point your agent at the CLI directly and let it discover commands on its own:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-txt",children:'Test the "add todo" flow on https://demo.playwright.dev/todomvc using playwright-cli.\nCheck playwright-cli --help for available commands.\n'})}),"\n",(0,n.jsx)(l.h2,{id:"first-steps",children:"First Steps"}),"\n",(0,n.jsx)(l.h3,{id:"interactive-demo",children:"Interactive demo"}
1),"\n",(0,n.jsx)(l.p,{children:"Try asking your coding agent:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-txt",children:"Use playwright skills to test https://demo.playwright.dev/todomvc/.\nTake screenshots for all successful and failing scenarios.\n"})}),"\n",(0,n.jsx)(l.h3,{id:"manual-walkthrough",children:"Manual walkthrough"}),"\n",(0,n.jsx)(l.p,{children:"You can also run commands manually to see how the CLI works:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:'playwright-cli open https://demo.playwright.dev/todomvc/ --headed\nplaywright-cli type "Buy groceries"\nplaywright-cli press Enter\nplaywright-cli type "Water flowers"\nplaywright-cli press Enter\nplaywright-cli check e21\nplaywright-cli screenshot\n'})}),"\n",(0,n.jsx)(l.p,{children:"After each command, the CLI outputs a snapshot of the current page state:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-txt",children:"### Page\n- Page URL: https://demo.playwright.dev/todomvc/#/\n- Page Title: React \u2022 TodoMVC\n### Snapshot\n[Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)\n"})}),"\n",(0,n.jsx)(l.h2,{id:"core-commands",children:"Core Commands"}),"\n",(0,n.jsx)(l.h3,{id:"interacting-with-pages",children:"Interacting with pages"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli open [url]               # open browser, optionally navigate to url\nplaywright-cli goto <url>               # navigate to a url\nplaywright-cli click <ref> [button]     # click an element\nplaywright-cli type <text>              # type text into editable element\nplaywright-cli fill <ref> <text>        # fill text into editable element\nplaywright-cli select <ref> <value>     # select an option in a dropdown\nplaywright-cli check <ref>              # check a checkbox or radio button\nplaywright-cli uncheck <ref>            # uncheck a checkbox\nplaywright-cli hover <ref>              # hover over element\nplaywright-cli drag <startRef> <endRef> # drag and drop between elements\nplaywright-cli upload <files...>        # upload one or multiple files\nplaywright-cli close                    # close the page\n"})}),"\n",(0,n.jsx)(l.h3,{id:"targeting-elements",children:"Targeting elements"}),"\n",(0,n.jsx)(l.p,{children:"Use element refs from snapshots to target elements:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli snapshot                 # get snapshot with element refs\nplaywright-cli click e15                # click using a ref\n"})}),"\n",(0,n.jsx)(l.p,{children:"You can also use CSS or role selectors:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:'playwright-cli click "#main > button.submit"\nplaywright-cli click "role=button[name=Submit]"\nplaywright-cli click "#footer >> role=button[name=Submit]"\n'})}),"\n",(0,n.jsx)(l.h3,{id:"screenshots-and-snapshots",children:"Screenshots and snapshots"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli snapshot                 # capture page snapshot\nplaywright-cli snapshot --filename=f    # save snapshot to specific file\nplaywright-cli screenshot               # screenshot of the current page\nplaywright-cli screenshot [ref]         # screenshot of a specific element\nplaywright-cli screenshot --filename=f  # save with specific filename\nplaywright-cli screenshot --hires       # capture using device pixels\nplaywright-cli pdf                      # save page as PDF\n"})}),"\n",(0,n.jsx)(l.h3,{id:"navigation",children:"Navigation"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli go-back                  # go back\nplaywright-cli go-forward               # go forward\nplaywright-cli reload                   # reload the page\n"})}),"\n",(0,n.jsx)(l.h3,{id:"keyboard-and-mouse",children:"Keyboard and mouse"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli press <key>              # press a key (e.g. Enter, ArrowLeft)\nplaywright-cli keydown <key>            # key down\nplaywright-cli keyup <key>              # key up\nplaywright-cli mousemove <x> <y>        # move mouse\nplaywright-cli mousedown [button]       # mouse button down\nplaywright-cli mouseup [button]         # mouse button up\nplaywright-cli mousewheel <dx> <dy>     # scroll\n"})}),"\n",(0,n.jsx)(l.h3,{id:"tabs",children:"Tabs"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli tab-list                 # list all tabs\nplaywright-cli tab-new [url]            # create a new tab\nplaywright-cli tab-select <index>       # select a tab\nplaywright-cli tab-close [index]        # close a tab\n"})}),"\n",(0,n.jsx)(l.h3,{id:"network",children:"Network"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli requests                 # list network requests since page load\nplaywright-cli request <num>            # show full details of a single request\nplaywright-cli route <pattern> [opts]   # mock network requests\nplaywright-cli route-list               # list active routes\nplaywright-cli unroute [pattern]        # remove routes\n"})}),"\n",(0,n.jsx)(l.h3,{id:"storage",children:"Storage"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli state-save [filename]    # save storage state (cookie
1s, localStorage)\nplaywright-cli state-load <filename>    # load storage state\n\n# Cookies\nplaywright-cli cookie-list [--domain]   # list cookies\nplaywright-cli cookie-get <name>        # get a cookie\nplaywright-cli cookie-set <name> <val>  # set a cookie\nplaywright-cli cookie-delete <name>     # delete a cookie\nplaywright-cli cookie-clear             # clear all cookies\n\n# localStorage\nplaywright-cli localstorage-list        # list entries\nplaywright-cli localstorage-get <key>   # get value\nplaywright-cli localstorage-set <k> <v> # set value\nplaywright-cli localstorage-delete <k>  # delete entry\nplaywright-cli localstorage-clear       # clear all\n"})}),"\n",(0,n.jsx)(l.h3,{id:"devtools",children:"DevTools"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli console [min-level]      # list console messages\nplaywright-cli eval <func> [ref]        # evaluate JavaScript on page\nplaywright-cli run-code <code>          # run Playwright code snippet\nplaywright-cli tracing-start            # start trace recording\nplaywright-cli tracing-stop             # stop trace recording\nplaywright-cli video-start              # start video recording\nplaywright-cli video-chapter <title>    # add chapter marker to video\nplaywright-cli video-stop --filename=f  # stop video recording\n"})}),"\n",(0,n.jsx)(l.h2,{id:"sessions",children:"Sessions"}),"\n",(0,n.jsxs)(l.p,{children:["The CLI keeps the browser profile in memory by default \u2014 cookies and storage state are preserved between calls within a session but lost when the browser closes. Use ",(0,n.jsx)(l.code,{children:"--persistent"})," to save the profile to disk."]}),"\n",(0,n.jsx)(l.h3,{id:"named-sessions",children:"Named sessions"}),"\n",(0,n.jsx)(l.p,{children:"Run multiple browser instances for different projects:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli open https://playwright.dev\nplaywright-cli -s=example open https://example.com --persistent\nplaywright-cli list                     # list all sessions\n"})}),"\n",(0,n.jsx)(l.p,{children:"You can configure your coding agent to use a specific session:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"PLAYWRIGHT_CLI_
1SESSION=todo-app claude .\n"})}),"\n",(0,n.jsx)(l.h3,{id:"session-management",children:"Session management"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli list                     # list all sessions\nplaywright-cli close-all                # close all browsers\nplaywright-cli kill-all                 # forcefully kill all browser processes\nplaywright-cli -s=name delete-data      # delete user data for a named session\n"})}),"\n",(0,n.jsx)(l.h2,{id:"monitoring",children:"Monitoring"}),"\n",(0,n.jsxs)(l.p,{children:["Use ",(0,n.jsx)(l.code,{children:"playwright-cli show"})," to open a visual dashboard for observing and controlling all running browser sessions:"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli show\n"})}),"\n",(0,n.jsx)(l.p,{children:"The dashboard provides:"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsxs)(l.li,{children:[(0,n.jsx)(l.strong,{children:"Session grid"})," \u2014 all active sessions grouped by workspace, each with a live screencast preview, session name, current URL, and page title. Click any session to zoom in."]}),"\n",(0,n.jsxs)(l.li,{children:[(0,n.jsx)(l.strong,{children:"Session detail"})," \u2014 a live view of the selected session with tab bar, navigation controls, and full remote control. Click into the viewport to take over mouse and keyboard; press Escape to release."]}),"\n"]}),"\n",(0,n.jsx)(l.h2,{id:"configuration",children:"Configuration"}),"\n",(0,n.jsx)(l.h3,{id:"headed-mode",children:"Headed mode"}),"\n",(0,n.jsx)(l.p,{children:"The CLI runs headless by default. To see the browser:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli open https://playwright.dev --headed\n"})}),"\n",(0,n.jsx)(l.h3,{id:"browser-selection",children:"Browser selection"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli open --browser=chrome    # use specific browser\nplaywright-cli open --browser=firefox\nplaywright-cli open --browser=webkit\nplaywright-cli open --browser=msedge\n"})}),"\n",(0,n.jsx)(l.h3,{id:"configuration-file",children:"Configuration file"}),"\n",(0,n.jsx)(l.p,{children:"For advanced settings, use a JSON config file:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli --config path/to/config.json open example.com\n"})}),"\n",(0,n.jsxs)(l.p,{children:["The CLI also loads ",(0,n.jsx)(l.code,{children:".playwright/cli.config.json"})," automatically if present. The config file supports browser options, context options, network rules, timeouts, and more. Run ",(0,n.jsx)(l.code,{children:"playwright-cli --help"})," for the full list of options."]}),"\n",(0,n.jsx)(l.h3,{id:"browser-extension",children:"Browser extension"}),"\n",(0,n.jsx)(l.p,{children:"Connect to your existing browser tabs instead of launching a new browser:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-bash",children:"playwright-cli attach --extension\n"})}),"\n",(0,n.jsxs)(l.p,{children:["This requires the ",(0,n.jsx)(l.a,{href:"https://github.com/microsoft/playwright/blob/main/packages/extension/README.md",children:"Playwright Extension"})," to be installed."]}),"\n",(0,n.jsx)(l.h2,{id:"quick-reference",children:"Quick Reference"}),"\n",(0,n.jsxs)(l.table,{children:[(0,n.jsx)(l.thead,{children:(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.th,{children:"Action"}),(0,n.jsx)(l.th,{children:"Command"})]})}),(0,n.jsxs)(l.tbody,{children:[(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Install CLI"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"npm install -g @playwright/cli@latest"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Install skills"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli install --skills"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Open a page"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli open https://example.com"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Click an element"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli click e15"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Type text"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:'playwright-cli type "hello world"'})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Take a screenshot"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli screenshot"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Get page snapshot"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli snapshot"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Run headed"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli open https://example.com --headed"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Use Firefox"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli open --browser=firefox"})})]}),(0,n.jsxs)(l.tr,{children:[(0,n.jsx)(l.td,{children:(0,n.jsx)(l.strong,{children:"Monitor sessions"})}),(0,n.jsx)(l.td,{children:(0,n.jsx)(l.code,{children:"playwright-cli show"})})]})]})]}),"\n",(0,n.jsx)(l.h2,{id:"whats-next",children:"What's Next"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"/docs/writing-tests",children:"Write tests using web-first assertions, page fixtures, and locators"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"/docs/ci-intro",children:"Run your tests on CI"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"/docs/trace-viewer",children:"Learn more about the Trace Viewer"})}),"\n"]})]})}function h(e={}){let{wrapper:l}={...(0,t.R)(),...e.components};return l?(0,n.jsx)(l,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.