Exploring Playwright’s Feature “Copy Prompt”
Playwright's new "Copy prompt" feature simplifies debugging by generating detailed prompts for LLMs like ChatGPT. This enhances testing efficiency and precision.
Join the DZone community and get the full member experience.
Join For FreeWeb automation testing demands both efficient processes and precise outcomes. Microsoft developed Playwright as an open-source framework, which gained recognition for its powerful browser automation across Chromium, Firefox, and WebKit. Playwright consistently releases new features through ongoing updates that optimize workflows for both developers and testers.
The new “Copy prompt” feature introduced in version 1.51 enhances debugging processes through the capabilities of large language models (LLMs). This blog will explain this feature’s functionality and workings before demonstrating its practical application through an example.
What Is the “Copy Prompt” Feature?
Playwright introduced the “Copy prompt” feature, which streamlines the debugging process. The feature shows up as a button within the Playwright HTML report and both trace viewer and UI mode. The button becomes accessible next to error details whenever a test fails and produces an error. The button action generates a clipboard-ready prompt containing both the error message and the surrounding context for troubleshooting.
Developers can achieve faster results through LLM platforms such as ChatGPT or Grok by using this prompt, which eliminates the need to create queries manually.
Why This Feature Matters
Debugging is often one of the most time-consuming aspects of test automation. A failing test might throw an error like TimeoutError: waiting for selector “button.submit” failed
, leaving you to figure out whether the selector is wrong, the page didn’t load correctly, or some other issue is at play.
Traditionally, you’d need to:
- Read the error message and stack trace.
- Investigate the test code and the application under test.
- Find the cause and search for solutions — perhaps by Googling or asking a colleague.
- Iterate until the issue is resolved.
With “Copy prompt,” Playwright eliminates much of this manual effort. The pre-filled prompt includes not just the error but also relevant metadata — like the test name, browser context, and potentially even snippets of the failing code. This enriched context allows an LLM to provide more accurate and specific suggestions, transforming a tedious process into a single click-and-paste operation.
How It Works
Let’s break down where and how you can use this feature:
- HTML report. After running your tests with the command
npx playwright test — reporter=html
, an HTML report is generated. If a test fails, you can open the report, locate the error, and find the “Copy prompt” button next to it. - Trace viewer. Playwright’s trace viewer (Command:
npx playwright show-trace trace.zip
) provides a detailed timeline of actions, network requests, and errors. When an error is highlighted, the button appears, ready to copy a prompt based on the trace data. - UI mode. Running the command
npx playwright test — ui
launches an interactive interface where you can execute and debug tests. Errors here also come with the “Copy prompt” option, integrating seamlessly into the visual workflow.
Once clicked, the button copies a structured prompt to your clipboard. You can then paste it into an LLM interface — say, Claude, ChatGPT, or Grok — and get a response tailored to your specific issue.
A Practical Example
To illustrate how “Copy prompt” works, let’s walk through a real-world scenario. Suppose you’re writing a Playwright test to verify a login and logout feature on a sample website.
Here’s the test code:
import { test, expect } from '@playwright/test';
test('Sauce test', async ({ page }) => {
await page.goto('https://www.saucedemo.com/');
await page.locator('[data-test="username"]').click();
await page.locator('[data-test="username"]').fill('standard_user');
await page.locator('[data-test="password"]').click();
await page.locator('[data-test="password"]').fill('secret_sauce');
await expect(page.locator('form')).toMatchAriaSnapshot(`
- textbox "Username": standard_user
- textbox "Password": secret_sauce
- button "Login"
`);
await page.locator('[data-test="login-button"]').click();
await page.locator('button', { name: 'Open Menu' }).click();
await page.locator('[data-test="logout-sidebar-link"]').click();
});
You run the test with npx playwright test tests/sauce.spec.js — reporter=html
, and it fails. The HTML report shows an error.
# Instructions
- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.
# Test info
- Name: Sauce test
- Location: /Users/xxx.xx/Documents/pwdemo/tests/sauce.spec.js:3:5
# Error details
```
Error: locator.click: Error: strict mode violation: locator('button') resolved to 8 elements:
1) <button type="button" id="react-burger-menu-btn">Open Menu</button> aka getByRole('button', { name: 'Open Menu' })
2) <button type="button" tabindex="-1" id="react-burger-cross-btn">Close Menu</button> aka getByText('Close Menu')
3) <button id="add-to-cart-sauce-labs-backpack" name="add-to-cart-sauce-labs-backpack" data-test="add-to-cart-sauce-labs-backpack" class="btn btn_primary btn_small btn_inventory ">Add to cart</button> aka locator('[data-test="add-to-cart-sauce-labs-backpack"]')
4) <button id="add-to-cart-sauce-labs-bike-light" name="add-to-cart-sauce-labs-bike-light" data-test="add-to-cart-sauce-labs-bike-light" class="btn btn_primary btn_small btn_inventory ">Add to cart</button> aka locator('[data-test="add-to-cart-sauce-labs-bike-light"]')
5) <button id="add-to-cart-sauce-labs-bolt-t-shirt" name="add-to-cart-sauce-labs-bolt-t-shirt" data-test="add-to-cart-sauce-labs-bolt-t-shirt" class="btn btn_primary btn_small btn_inventory ">Add to cart</button> aka locator('[data-test="add-to-cart-sauce-labs-bolt-t-shirt"]')
6) <button id="add-to-cart-sauce-labs-fleece-jacket" name="add-to-cart-sauce-labs-fleece-jacket" class="btn btn_primary btn_small btn_inventory " data-test="add-to-cart-sauce-labs-fleece-jacket">Add to cart</button> aka locator('[data-test="add-to-cart-sauce-labs-fleece-jacket"]')
7) <button id="add-to-cart-sauce-labs-onesie" name="add-to-cart-sauce-labs-onesie" data-test="add-to-cart-sauce-labs-onesie" class="btn btn_primary btn_small btn_inventory ">Add to cart</button> aka locator('[data-test="add-to-cart-sauce-labs-onesie"]')
8) <button class="btn btn_primary btn_small btn_inventory " id="add-to-cart-test.allthethings()-t-shirt-(red)" name="add-to-cart-test.allthethings()-t-shirt-(red)" data-test="add-to-cart-test.allthethings()-t-shirt-(red)">Add to cart</button> aka locator('[data-test="add-to-cart-test\\.allthethings\\(\\)-t-shirt-\\(red\\)"]')
Call log:
- waiting for locator('button')
at /Users/xx.xx/Documents/pwdemo/tests/sauce.spec.js:15:55
```
# Page snapshot
```yaml
- button "Open Menu"
- img "Open Menu"
- text: Swag Labs Products Name (A to Z)
- combobox:
- option "Name (A to Z)" [selected]
- option "Name (Z to A)"
- option "Price (low to high)"
- option "Price (high to low)"
- link "Sauce Labs Backpack":
- img "Sauce Labs Backpack"
- link "Sauce Labs Backpack"
- text: carry.allTheThings() with the sleek, streamlined Sly Pack that melds uncompromising style with unequaled laptop and tablet protection. $29.99
- button "Add to cart"
- link "Sauce Labs Bike Light":
- img "Sauce Labs Bike Light"
- link "Sauce Labs Bike Light"
- text: A red light isn't the desired state in testing but it sure helps when riding your bike at night. Water-resistant with 3 lighting modes, 1 AAA battery included. $9.99
- button "Add to cart"
- link "Sauce Labs Bolt T-Shirt":
- img "Sauce Labs Bolt T-Shirt"
- link "Sauce Labs Bolt T-Shirt"
- text: Get your testing superhero on with the Sauce Labs bolt T-shirt. From American Apparel, 100% ringspun combed cotton, heather gray with red bolt. $15.99
- button "Add to cart"
- link "Sauce Labs Fleece Jacket":
- img "Sauce Labs Fleece Jacket"
- link "Sauce Labs Fleece Jacket"
- text: It's not every day that you come across a midweight quarter-zip fleece jacket capable of handling everything from a relaxing day outdoors to a busy day at the office. $49.99
- button "Add to cart"
- link "Sauce Labs Onesie":
- img "Sauce Labs Onesie"
- link "Sauce Labs Onesie"
- text: Rib snap infant onesie for the junior automation engineer in development. Reinforced 3-snap bottom closure, two-needle hemmed sleeved and bottom won't unravel. $7.99
- button "Add to cart"
- link "Test.allTheThings() T-Shirt (Red)":
- img "Test.allTheThings() T-Shirt (Red)"
- link "Test.allTheThings() T-Shirt (Red)"
- text: This classic Sauce Labs t-shirt is perfect to wear when cozying up to your keyboard to automate a few tests. Super-soft and comfy ringspun combed cotton. $15.99
- button "Add to cart"
- contentinfo:
- list:
- listitem:
- link "Twitter"
- listitem:
- link "Facebook"
- listitem:
- link "LinkedIn"
- text: © 2025 Sauce Labs. All Rights Reserved. Terms of Service | Privacy Policy
```
# Test source
```ts
1 | import { test, expect } from '@playwright/test';
2 |
3 | test('Sauce test', async ({ page }) => {
4 | await page.goto('https://www.saucedemo.com/');
5 | await page.locator('[data-test="username"]').click();
6 | await page.locator('[data-test="username"]').fill('standard_user');
7 | await page.locator('[data-test="password"]').click();
8 | await page.locator('[data-test="password"]').fill('secret_sauce');
9 | await expect(page.locator('form')).toMatchAriaSnapshot(`
10 | - textbox "Username": standard_user
11 | - textbox "Password": secret_sauce
12 | - button "Login"
13 | `);
14 | await page.locator('[data-test="login-button"]').click();
> 15 | await page.locator('button', { name: 'Open Menu' }).click();
| ^ Error: locator.click: Error: strict mode violation: locator('button') resolved to 8 elements:
16 | await page.locator('[data-test="logout-sidebar-link"]').click();
17 | });
```
Paste the above error message in LLM, e.g., (ChatGPT).

Once we paste the issue and ask to fix it to the LLM, the LLM will automatically fix the code and provide the updated code. Let's see what the issue was and how the issue is fixed.
Issue Explanation
The error occurs because the locator page.locator('button')
resolves to 8 different buttons on the page, violating Playwright’s strict mode, which requires a unique element match.
Root Cause
- The test attempts to click on
button
using{ name: 'Open Menu' }
, but the syntax is incorrect. - The correct way to target the “Open Menu” button is by using
getByRole('button', { name: 'Open Menu' })
or its unique attribute selector.
Fix
Modify the selector to target the “Open Menu” button explicitly using Playwright best practices.
await page.getByRole('button', { name: 'Open Menu' }).click();
// OR
await page.locator('#react-burger-menu-btn').click();
Here’s an updated version of your test where you can see we have replaced the locator of the hamburger to await page.locator(‘#react-burger-menu-btn’)
.
import { test, expect } from '@playwright/test';
test('Sauce test', async ({ page }) => {
await page.goto('https://www.saucedemo.com/');
await page.locator('[data-test="username"]').click();
await page.locator('[data-test="username"]').fill('standard_user');
await page.locator('[data-test="password"]').click();
await page.locator('[data-test="password"]').fill('secret_sauce');
await expect(page.locator('form')).toMatchAriaSnapshot(`
- textbox "Username": standard_user
- textbox "Password": secret_sauce
- button "Login"
`);
await page.locator('[data-test="login-button"]').click();
await page.locator('#react-burger-menu-btn').click();
await page.locator('[data-test="logout-sidebar-link"]').click();
});
Execute the above code again, and you will see that the test case has passed.
Conclusion
The “Copy prompt” empowers developers to leverage LLMs for quick, actionable solutions for seamless debugging. Generating detailed, context-rich prompts with a single click empowers developers to leverage LLMs for quick, actionable solutions, cutting down on manual troubleshooting time. Embrace the “Copy prompt” on your next Playwright project, and let's simplify your debugging and elevate your testing experience.
Opinions expressed by DZone contributors are their own.
Comments