Advanced Codegen — The Ghost Writer
Stop writing boilerplate locators and action steps by hand. Master Playwright Codegen to record interactions, generate assertions visually, and accelerate test creation across multiple languages.
📖 The Story: The Boilerplate Burnout
A QA engineer named Alex was assigned to write tests for a massive, 50-page enterprise onboarding flow. For three weeks, Alex stared at Chrome DevTools, copying and pasting CSS selectors, typing await page.click('#...'), and manually writing expect statements.
Alex was suffering from Boilerplate Burnout. The tests worked, but progress was agonizingly slow. One typo in a selector meant re-running the test and watching it fail.
Then, a colleague introduced Alex to Playwright Codegen. Alex opened the terminal, typed npx playwright codegen, and clicked through the onboarding flow in the browser. The Codegen Inspector window instantly translated those clicks into perfect, resilient Playwright TypeScript code. Alex even used the "Assert" button to generate expect statements by simply hovering over elements. What took three weeks was finished in two days.
If you are typing locators by hand, you are doing it the hard way. Let the browser write the code for you.
🎯 Why Use Codegen?
Lightning Fast
Generate 100 lines of accurate test code in 30 seconds by simply clicking around the app.
Resilient Locators
Codegen automatically prefers role-based and text locators, avoiding brittle CSS classes.
Visual Assertions
Generate expect statements by clicking elements in the Inspector, no syntax lookup needed.
Multi-Language
Output code in JavaScript, TypeScript, Python, Java, or C# on the fly.
🌍 Real World Example
A developer adds a complex "Date Picker" widget to the app. Writing the test manually requires figuring out the exact CSS classes for the calendar grid, the next/prev month buttons, and the day cells. With Codegen, you simply launch the recorder, click "Next Month", and click "15". Codegen generates the exact sequence of page.getByRole clicks needed to interact with that specific widget, saving 20 minutes of DOM inspection.
🧒 Explain Like I'm 10
Imagine you want to write a book about a princess, but you don't know how to spell well. You hire a "ghost writer". You act out the story with your toys, and the ghost writer writes down everything you do in perfect English.
Codegen is your ghost writer. You play with the website (clicking and typing), and Codegen writes down the code needed to make the computer do exactly what you just did.
🎓 Professional Explanation
Playwright Codegen is a CLI tool (npx playwright codegen) that launches a dedicated browser instance and an Inspector window. The Inspector attaches to the browser via CDP (Chrome DevTools Protocol) to monitor DOM events. When you interact with an element, Codegen analyzes the DOM node and its ancestors to generate the most resilient, user-facing locator (prioritizing ARIA roles, accessible names, and text content over brittle CSS selectors). It outputs the corresponding Playwright API calls in real-time.
📊 Manual vs Codegen Flow
Test Creation Workflow
Manual (Slow)
await page.click()Codegen (Fast)
🚀 Basic Codegen CLI
Launch the Codegen tool from your terminal.
# Launches a browser and the Codegen Inspector npx playwright codegen # Launch codegen directly to a specific URL npx playwright codegen https://your-app.com/login # Emulate a specific device (e.g., iPhone 14) npx playwright codegen --device="iPhone 14" playwright.dev
👁️ Generating Assertions Visually
One of the most powerful features of Codegen is generating assertions without writing code. When the Inspector is open, you can hover over any element and use the toolbar to generate assertions.
// 1. Hover over an element (e.g., a success message) // 2. In the Codegen toolbar, click the "Assert" icon (Eye/Checkmark) // 3. Choose "Assert visibility" or "Assert text" // Codegen instantly writes: await expect(page.getByText('Success')).toBeVisible();
This ensures you never forget the exact syntax for an assertion and guarantees the locator used for the action is the same one used for the assertion.
⏸️ Pausing for Complex Logic
Sometimes you need to perform an action that Codegen shouldn't record (like logging in manually, or waiting for a complex animation). You can pause the recording.
// 1. Click the "Record" button (red circle) in the Codegen toolbar to pause. // 2. Do whatever you need to do in the browser (e.g., manually log in). // 3. Click "Record" again to resume. // 4. Codegen will continue writing code from your next click. // Alternatively, if you have a test running, type in the terminal: // page.pause() // This opens the Inspector and allows you to step through actions.
🔐 Recording with Authentication
If you need to record tests for a protected area, you don't want to record the login flow every time. You can load a saved authentication state.
# Load a previously saved storageState (auth.json) into Codegen
npx playwright codegen --load-storage=auth.json https://your-app.com/dashboard
This launches the browser already authenticated, so you can immediately start recording the dashboard flow without the login steps cluttering your generated code.
🐍 Targeting Multiple Languages
Codegen isn't just for JavaScript/TypeScript. You can output code in Python, Java, or C#.
# Output Python code npx playwright codegen --target=python playwright.dev # Output Java code npx playwright codegen --target=java playwright.dev # Output C# code npx playwright codegen --target=csharp playwright.dev
⚠️ Common Mistakes
Mistake 1: Blindly Copying Generated Code
Codegen is a starting point, not a final product. It often generates rigid sequences. You should refactor the generated code into Page Objects, add custom messages to assertions, and remove unnecessary waits.
Mistake 2: Recording Too Much
Don't record an entire 5-minute user journey in one file. Record small, focused interactions (e.g., "Add to Cart") and save them as individual tests. Long generated tests are extremely hard to maintain.
✅ Best Practices
- Use the Assert button. Don't just record actions; record assertions to verify state.
- Refactor immediately. Don't leave the raw generated code. Clean it up and extract locators into variables.
- Use
--load-storagefor auth. Keep your generated tests focused on the feature, not the login. - Emulate devices. Use
--deviceto generate tests specifically tailored for mobile interactions.
🏗️ Senior Engineer Deep Dive
How Codegen Prioritizes Locators
Codegen doesn't just grab the first ID it sees. It follows a strict heuristic prioritizing user-facing attributes. It prefers getByRole with an accessible name. If that fails, it looks for getByLabel or getByText. It avoids CSS classes and XPath unless absolutely necessary. This ensures the generated code is resilient to refactoring and follows accessibility best practices.
VS Code Extension Integration
Codegen is deeply integrated into the Playwright VS Code extension. You can highlight a line of code in your spec file, click "Record", and the browser will launch, execute up to that line, and let you record the next steps directly into the file. This bridges the gap between manual recording and test architecture.
💼 Interview Questions
Show Answer
Show Answer
expect statement automatically.Show Answer
getByRole with an accessible name. If unavailable, it falls back to getByLabel or getByText. It actively avoids brittle CSS classes or IDs to ensure the test survives UI refactoring.Show Answer
auth.json file using Playwright. Then, I would launch Codegen with the --load-storage=auth.json flag. The browser will open already authenticated, and I can record the dashboard flow without the login clutter.🏋️ Practical Exercise
Your First Recording
- Open your terminal and run
npx playwright codegen https://demo.playwright.dev/todomvc. - In the browser, type "Buy milk" and press Enter.
- Click the "Assert" button and hover over the todo item to assert visibility.
- Copy the generated code from the Inspector into a new spec file.
- Run the spec file to verify it passes.
🚀 Mini Project
🏗️ Multi-Language Generation
- Launch Codegen targeting a public site (e.g.,
example.com). - Click "More information..." and copy the generated TypeScript code.
- Close Codegen. Relaunch it with
--target=python. - Perform the exact same click. Compare the generated Python code to the TypeScript code.
📝 Quiz
Test your understanding. Click an option to check your answer.
npx playwright recordnpx playwright inspectornpx playwright codegennpx playwright generatenpx playwright codegen launches the browser and Inspector.expect() in the terminalexpect statements.--python--lang=py--target=python--format=python--target flag specifies the output language.--auth=true--load-storage=auth.json--login--sessiongetByRole with accessible names--device flag do in Codegen?❓ FAQ
Q: Can Codegen record file uploads?
A: Codegen cannot record the OS file picker dialog. However, if you click an upload button, it will generate the setInputFiles code with a placeholder path that you must fill in manually.
Q: Does Codegen work with iframes?
A: Yes! If you click inside an iframe, Codegen will automatically detect it and generate the frameLocator syntax in your code.
📦 Summary
🎯 Key Takeaways
- Use
npx playwright codegento generate test code visually. - Use the "Assert" button to generate
expectstatements. - Use
--load-storageto skip login during recording. - Use
--targetto output Python, Java, or C#. - Refactor generated code into Page Objects; don't leave it raw.
- Use the VS Code extension for seamless integration.
