📖 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)
1. Inspect element in DevTools
2. Copy CSS selector
3. Type await page.click()
4. Run test. Fails (typo).
5. Fix selector. Repeat.
Codegen (Fast)
1. Launch Codegen
2. Click element in browser
3. Code appears instantly
4. Click "Assert" to verify
5. Copy code to spec file

🚀 Basic Codegen CLI

Launch the Codegen tool from your terminal.

bash
# 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.

Codegen Usage
// 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.

Codegen Usage
// 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.

bash
# 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#.

bash
# 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

  1. Use the Assert button. Don't just record actions; record assertions to verify state.
  2. Refactor immediately. Don't leave the raw generated code. Clean it up and extract locators into variables.
  3. Use --load-storage for auth. Keep your generated tests focused on the feature, not the login.
  4. Emulate devices. Use --device to 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

Beginner
What is Playwright Codegen?
Show Answer
Codegen is a Playwright CLI tool that opens a browser and records your interactions, automatically generating Playwright test code in real-time. It accelerates test creation by acting as a ghost writer.
Intermediate
How do you generate assertions using Codegen?
Show Answer
While recording, I hover over an element in the browser. In the Codegen Inspector toolbar, I click the "Assert" button. I can then choose to assert visibility or text content, and Codegen writes the expect statement automatically.
Advanced
How does Codegen determine which locators to generate?
Show Answer
Codegen uses a heuristic that prioritizes user-facing, resilient locators. It first tries 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.
Scenario
You need to record a test for a protected dashboard, but you don't want the login steps in the final code. How do you do this?
Show Answer
I would first log in manually and save the session state to a 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

🎯 Hands-On Practice Easy

Your First Recording

  1. Open your terminal and run npx playwright codegen https://demo.playwright.dev/todomvc.
  2. In the browser, type "Buy milk" and press Enter.
  3. Click the "Assert" button and hover over the todo item to assert visibility.
  4. Copy the generated code from the Inspector into a new spec file.
  5. Run the spec file to verify it passes.

🚀 Mini Project

🏗️ Multi-Language Generation

  1. Launch Codegen targeting a public site (e.g., example.com).
  2. Click "More information..." and copy the generated TypeScript code.
  3. Close Codegen. Relaunch it with --target=python.
  4. 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.

1. Which CLI command launches the Playwright Codegen tool?
A) npx playwright record
B) npx playwright inspector
C) npx playwright codegen
D) npx playwright generate
Answer: C — npx playwright codegen launches the browser and Inspector.
2. How do you generate an assertion visually in Codegen?
A) Type expect() in the terminal
B) Use the "Assert" button in the Inspector toolbar
C) Right-click the element and select "Assert"
D> Assertions cannot be generated
Answer: B — The "Assert" button allows you to hover over elements and generate expect statements.
3. Which flag is used to output Python code instead of TypeScript?
A) --python
B) --lang=py
C) --target=python
D) --format=python
Answer: C — The --target flag specifies the output language.
4. How can you launch Codegen already authenticated?
A) --auth=true
B) --load-storage=auth.json
C) --login
D) --session
Answer: B — Loading a storage state file injects the session cookies automatically.
5. What is a common mistake when using Codegen?
A) Using the Assert button too often
B) Blindly copying generated code without refactoring it
C) Emulating devices
D) Pausing the recording
Answer: B — Generated code is a starting point. It should be cleaned up and refactored into Page Objects.
6. How does Codegen prioritize locators?
A) It prefers CSS classes
B) It prefers XPath
C) It prefers getByRole with accessible names
D) It prefers random IDs
Answer: C — Codegen prioritizes user-facing, resilient locators like ARIA roles.
7. Can you pause a Codegen recording?
A) Yes, by clicking the "Record" button in the toolbar
B) No, you must close the browser
C) Yes, by pressing Escape
D) Only in VS Code
Answer: A — The "Record" button toggles recording on and off.
8. What does the --device flag do in Codegen?
A) Connects a physical mobile phone
B) Emulates a specific device (e.g., iPhone 14) in the browser
C) Changes the output language
D) Generates device-specific CSS
Answer: B — It uses Playwright's device descriptors to emulate viewport and touch events.
9. Is Codegen available in the VS Code extension?
A) Yes, it is deeply integrated
B) No, it is CLI only
C) Only in the paid version
D) Only for Python
Answer: A — The VS Code extension allows you to record directly into spec files.
10. Should you record a 5-minute user journey in one file?
A) Yes, it saves time
B) No, long generated tests are hard to maintain; record small interactions
C) Yes, if you use Python
D) No, Codegen has a 60-second limit
Answer: B — Break recordings into small, focused tests for better maintainability.

❓ 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 codegen to generate test code visually.
  • Use the "Assert" button to generate expect statements.
  • Use --load-storage to skip login during recording.
  • Use --target to output Python, Java, or C#.
  • Refactor generated code into Page Objects; don't leave it raw.
  • Use the VS Code extension for seamless integration.