Specnote
Back to the blog
playwright codegenplaywrightSpecnote

What Is Playwright Codegen? 2 Ways to Get Test Code Written

By WonyoungJuly 28, 20267 min
On this page

To check anything with Playwright, you first have to write the check down — "open the login page → enter an email → confirm the welcome message appears." The catch is that it has to be written in a programming language, not in plain English. That written-down version is called test code, and the machine reads it to drive the browser for you.

Which means you have to be able to write it. So there are 2 ways to have it written for you. One ships inside Playwright — codegen, where you simply click in a browser and your actions get written down as code. The other is asking an AI in plain language. Both genuinely work. This post covers what each one gives you, and then what is left after the code exists.

Key takeaways
  • Codegen records your clicks and typing as code. It also saves logged-in state and emulates device, language, timezone, and location.
  • Asking an AI produces code without opening a browser at all. Both cut the time to your first working test dramatically.
  • What neither one carries is what comes after: reading it, fixing it when the UI changes, and running it on every deploy. Those stay with you.

2 ways to have the test code written for you

Part 1 covered what Playwright is and how far Playwright MCP takes you. It ended with a recommendation: if you can read and write code, use Playwright through code.

So how does that code start? You don't type it from scratch. There are 2 ways to have it written for you.

CodegenAsking an AI
HowYou click in a real browserYou describe it in words
Based onWhat actually happenedYour codebase and your prompt
BrowserMust be openNot needed
OutputRunnable codeRunnable code

The 2 are not competitors. In practice people record a skeleton with codegen and hand it to an AI to clean up and extend.

What Playwright codegen does

If Playwright is already installed, one line in the terminal starts it. Installation steps and the full option list live in the official docs.

npx playwright codegen specnote.io

Two windows open. One is an ordinary browser; the other is the Inspector, the recording window. Click the login button and type an email, and those actions stack up as code on the right.

It records more than clicks and typing:

  • Navigation — it follows URL changes
  • Selects and toggles — dropdowns, checkboxes, radio buttons
  • File uploads
  • Assertions — you can add a check like "is 'Welcome' visible" while recording

You can take the output in the language you want. JavaScript and TypeScript are the default; Python, Java, and .NET (C#) are also supported.

How codegen decides what to click

This is the most important part of codegen. When you click a button, something has to decide how the code will refer to that button.

Codegen picks based on how a person perceives the element. If the screen says "Log in" on a button, the code comes out as:

page.getByRole('button', { name: 'Log in' })

Meaning "the element with the button role whose accessible name is Log in." Not an internal name a developer assigned — the name a screen reader would announce.

There is a clear upside. You can restructure the internals and the code keeps working as long as the visible text stays. And anyone reading the code can see what is being clicked.

There is also where a later problem starts. Rename that button from "Log in" to "Get started" and the code no longer finds it.

How Playwright codegen turns clicks into code — browser actions stack up in the Inspector, and elements are referenced by the name shown on screenClick in the browser, get the code

What else codegen gives you

Beyond plain recording, a few things are worth knowing. They save real time.

Pick locator. Hover over an element without recording and it shows you the code that refers to it. Useful when you only need to fix one line in existing code.

Saved login state. You don't have to record the login flow every time. --save-storage writes the logged-in state to a file, and --load-storage restores it so recording starts already signed in.

Emulation. You can record under a specific viewport, device, color scheme, language, timezone, or geolocation — "what a mobile user in Italy sees," for instance.

npx playwright codegen --device="iPhone 15" --lang="it-IT" specnote.io

If you want the fastest way to learn Playwright, this is it — record once before reading the docs and the shape of the code lands visually first. The full option list is in the codegen docs.

What changes when you ask an AI

These days people often ask an AI before reaching for codegen. "Write me a test for the signup flow," and code appears.

What the AI does better:

  • No browser needed. You can write tests for features that don't exist yet.
  • It reads your codebase and matches your project's conventions.
  • It covers several cases at once — not just the happy path but wrong password, empty field, and so on.

What codegen does better:

  • It records what actually happened, so it only references elements that really exist on screen.
  • An AI that never opened the page sometimes guesses at selectors. The code looks right and then fails to find the element at runtime.

So in practice they get mixed: codegen to confirm the real elements, the AI to organize and extend.

Where the 2 approaches meet

At this point generating code looks close to solved. It largely is. Producing the code is no longer the hard part.

What comes next is. Whether it came from codegen or an AI, both approaches hand you code and stop there. What you do with that code is still yours.

Where codegen and AI both stop — reading, fixing, and repeating stay with the personGeneration is done. What is left isn't.

3 things left after the code exists

1. You have to read it. To trust a result you need to know what the code actually checks. Whether "passed" means "signup completed" or "the signup button was clickable" is only visible in the code. Those are very different claims.

2. You have to fix it when the UI changes. As shown above, the code refers to elements by the name shown on screen. Rename a button or restructure a screen and you have to find that line and update it. The more features you add, the more lines there are to update.

3. You have to run it on every deploy. Code does not run itself. Either you wire it into CI or a person triggers it each time. Wiring takes setup; triggering takes remembering.

For someone who reads code, these 3 are routine work. Not hard — just time.

The problem is that for someone who cannot read code, all 3 are walls. The code exists, but they can't read it, can't fix it, and can't tell when it last ran.

What that gap actually needs

Someone who cannot read code does not need a better code generator. Generation is already good enough.

What they need is for the output not to be code at all. What gets checked has to survive in language a person can read, a person has to approve those criteria, and what was approved has to repeat on every deploy by itself.

That is the part Specnote takes. Flows are written as ordinary sentences, pass criteria are read and approved by someone who cannot read code, and approved runs repeat automatically on each deploy.

If you can read code, starting with codegen is the better move. It is free, you control more of it, and everything above is genuinely useful.

What this series will cover next

  • Locators — why small UI changes stop a test, and how to write ones that last
  • Trace viewer — what a failure leaves behind, and how to rewind it
  • Fixtures — starting every run from the same state
  • CI integration — running automatically on every push

Try it now

Leave sentences behind, not code

Write what should be checked in plain language and approve the pass criteria, and every deploy checks against that same bar.

Start free →

Frequently asked questions

  • What is Playwright codegen?

    It is a built-in Playwright feature that records your clicks and typing in a real browser and writes them out as test code. Running npx playwright codegen <url> opens the browser and the recording window together.

  • Codegen or asking an AI — which is better?

    They serve different purposes. Codegen records what actually happened, so it only references elements that exist on screen. An AI can generate without opening a browser and covers several cases at once. In practice people confirm real elements with codegen and let the AI organize the rest.

  • Can I use codegen output as-is?

    It will run. Still, read what it checks. "The button was clicked" and "signup completed" are different assertions, and without reading the code you cannot tell which one you got.

  • Do I have to record the login flow every time?

    No. --save-storage saves the logged-in state to a file, and --load-storage restores it so you can start recording already signed in.

  • Why does codegen output stop working later?

    Because it refers to elements by the name shown on screen. Rename a button or restructure a screen and that line no longer finds its target. The next post in this series covers locators in detail.

  • Can I use codegen if I can't read code?

    You can get as far as recording and producing code. What remains are the 3 things above — reading what it checks, fixing it when the UI changes, running it on every deploy. If those are walls, look for an approach whose output isn't code.

Keep reading

If you enjoyed this post