Back to the blogWhat Is Playwright Codegen? 2 Ways to Get Test Code Written
By WonyoungJuly 28, 20267 minOn this page
- 2 ways to have the test code written for you
- What Playwright codegen does
- How codegen decides what to click
- What else codegen gives you
- What changes when you ask an AI
- Where the 2 approaches meet
- 3 things left after the code exists
- What that gap actually needs
- What this series will cover next
- Try it now
- Frequently asked questions
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.
- 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.
| Codegen | Asking an AI | |
|---|---|---|
| How | You click in a real browser | You describe it in words |
| Based on | What actually happened | Your codebase and your prompt |
| Browser | Must be open | Not needed |
| Output | Runnable code | Runnable 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.ioTwo 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.
Click 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.ioIf 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.
Generation 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.
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.


