1"use strict";(self.webpackChunkplaywright_dev=self.webpackChunkplaywright_dev||[]).push([["4133"],{23930(e,n,t){t.r(n),t.d(n,{metadata:()=>i,default:()=>d,frontMatter:()=>l,contentTitle:()=>s,toc:()=>c,assets:()=>o});var i=JSON.parse('{"id":"commands/codegen","title":"Codegen & Highlighting","description":"Every playwright-cli action prints the Playwright code it just ran. That generated code is the raw","source":"@site/agent-cli/commands/codegen.mdx","sourceDirName":"commands","slug":"/commands/codegen","permalink":"/agent-cli/commands/codegen","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Codegen & Highlighting"},"sidebar":"agentCli","previous":{"title":"Screenshots & PDF","permalink":"/agent-cli/commands/screenshots-pdf"},"next":{"title":"Tracing","permalink":"/agent-cli/commands/tracing"}}'),a=t(74848),r=t(28453);let l={title:"Codegen & Highlighting"},s="Codegen & Highlighting",o={},c=[{value:"Generated code",id:"generated-code",level:2},{value:"Recording user actions",id:"recording-user-actions",level:2},{value:"Generating a locator",id:"generating-a-locator",level:2},{value:"Highlighting elements",id:"highlighting-elements",level:2},{value:"Test generation workflow",id:"test-generation-workflow",level:2}];function h(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"codegen--highlighting",children:"Codegen & Highlighting"})}),"\n",(0,a.jsxs)(n.p,{children:["Every ",(0,a.jsx)(n.code,{children:"playwright-cli"})," action prints the Playwright code it just ran. That generated code is the raw\nmaterial for tests \u2014 this page covers it, plus the commands that support authoring: recording a\nflow the user performs by hand, turning a ref into a locator, and highlighting elements on the page."]}),"\n",(0,a.jsx)(n.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ playwright-cli fill e1 \"[email protected]\"\n### Ran Playwright code\nawait page.getByRole('textbox', { name: 'Email' }).fill('[email protected]');\n### Page\n- Page URL: https://example.com/login\n...\n\n$ playwright-cli click e3\n### Ran Playwright code\nawait page.getByRole('button', { name: 'Sign In' }).click();\n"})}),"\n",(0,a.jsx)(n.p,{children:"Collect those lines into a test and add the assertions:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-typescript",children:"import { test, expect } from '@playwright/test';\n\ntest('login flow', async ({ page }) => {\n await page.goto('https://example.com/login');\n await page.getByRole('textbox', { name: 'Email' }).fill('[email protected]');\n await page.getByRole('textbox', { name: 'Password' }).fill('password123');\n await page.getByRole('button', { name: 'Sign In' }).click();\n\n await expect(page).toHaveURL(/.*dashboard/);\n});\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The generated code prefers role-based locators, which survive markup changes far better than CSS\nselectors. Set ",(0,a.jsx)(n.code,{children:"codegen"})," in the ",(0,a.jsx)(n.a,{href:"/agent-cli/configuration",children:"config file"})," to emit ",(0,a.jsx)(n.code,{children:"python"}),", ",(0,a.jsx)(n.code,{children:"java"})," or\n",(0,a.jsx)(n.code,{children:"csharp"})," instead of TypeScript, or ",(0,a.jsx)(n.code,{children:"none"})," to suppress the code section entirely."]}),"\n",(0,a.jsx)(n.h2,{id:"recording-user-actions",children:"Recording user actions"}),"\n",(0,a.jsx)(n.p,{children:"When the flow is easier to demonstrate than to describe \u2014 a drag interaction, a canvas gesture, a\nlogin with a hardware key \u2014 hand the browser to the user and record what they do."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"playwright-cli open https://example.com --headed\nplaywright-cli recording-start\n# the user performs the flow in the browser window\nplaywright-cli recording-stop\n"})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"recording-stop"})," prints everything the user did as Playwright code:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-txt",children:"Recording stopped. Recorded actions:\n\nawait page.getByRole('link', { name: 'Products' }).click();\nawait page.getByRole('textbox', { name: 'Search' }).fill('laptop');\nawait page.getByRole('textbox', { name: 'Search' }).press('Enter');\n"})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"recording-start"})," brings the browser window to the front, so run it against a headed session."]}),"\n",(0,a.jsx)(n.h2,{id:"generating-a-locator",children:"Generating a locator"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"generate-locator"})," turns a ref or a selector into the locator you would write in a test:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ playwright-cli generate-locator e5\n# getByRole('button', { name: 'Add to cart' })\n\n$ playwright-cli --raw generate-locator \"#checkout button.primary\"\n# getByRole('button', { name: 'Checkout' })\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Pair it with ",(0,a.jsx)(n.a,{href:"/agent-cli/commands/console-eval",children:(0,a.jsx)(n.code,{children:"eval"})})," when you need the underlying attributes \u2014 an ",(0,a.jsx)(n.code,{children:"id"}),",\na ",(0,a.jsx)(n.code,{children:"data-testid"}),", a class \u2014 that the snapshot does not show:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"playwright-cli eval \"el => el.getAttribute('data-testid')\" e5\n"})}),"\n",(0,a.jsx)(n.h2,{id:"highlighting-elements",children:"Highlighting elements"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"highlight"})," draws a persistent overlay around an element. It is useful for showing the user which\nelement you mean, and for making a target obvious in a screenshot or a\n",(0,a.jsx)(n.a,{href:"/agent-cli/commands/video-recording",children:"recorded video"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'playwright-cli highlight e5\nplaywright-cli highlight e5 --style="outline: 3px dashed red"\n\nplaywright-cli highlight e5 --hide # hide one element\'s highlight\nplaywright-cli highlight --hide # hide every highlight on the page\
1n'})}),"\n",(0,a.jsx)(n.p,{children:"Highlights are overlays, not page changes: they do not intercept clicks, so you can leave them up\nwhile interacting with the page."}),"\n",(0,a.jsx)(n.h2,{id:"test-generation-workflow",children:"Test generation workflow"}),"\n",(0,a.jsxs)(n.p,{children:["The installed ",(0,a.jsx)(n.a,{href:"/agent-cli/skills",children:"skill"})," documents a fuller plan \u2192 generate \u2192 heal loop, which builds\non the same mechanic:"]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Plan"})," \u2014 explore the app with the CLI and write a spec file describing what to test."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Generate"})," \u2014 replay the spec step by step, collecting the generated code into test files."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Heal"})," \u2014 run the failing test with ",(0,a.jsx)(n.code,{children:"--debug=cli"}),", ",(0,a.jsx)(n.a,{href:"/agent-cli/commands/test-debugging",children:"attach"})," to the paused\npage, and use the freshly generated code to repair the stale locator or expectation."]}),"\n"]})]})}function d(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(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.