From 821a57b0a614edf63c7d1c6c0028bfe82e61b588 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 27 Mar 2026 18:49:23 -0700 Subject: [PATCH] chore: roll Playwright to 1.59.0-alpha-1774661115000 --- README.md | 27 +++-- package-lock.json | 26 ++--- package.json | 4 +- skills/playwright-cli/SKILL.md | 39 +++++-- .../references/element-attributes.md | 23 ++++ .../references/playwright-tests.md | 20 ++-- .../references/video-recording.md | 110 +++++++++++++++++- 7 files changed, 204 insertions(+), 45 deletions(-) create mode 100644 skills/playwright-cli/references/element-attributes.md diff --git a/README.md b/README.md index 59f3e2c..a9f1eba 100644 --- a/README.md +++ b/README.md @@ -267,9 +267,22 @@ After each command, playwright-cli provides a snapshot of the current browser st [Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml) ``` -You can also take a snapshot on demand using `playwright-cli snapshot` command. +You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed. -If `--filename` is not provided, a new snapshot file is created with a timestamp. Default to automatic file naming, use `--filename=` when artifact is a part of the workflow result. +```bash +# default - save to a file with timestamp-based name +playwright-cli snapshot + +# save to file, use when snapshot is a part of the workflow result +playwright-cli snapshot --filename=after-click.yaml + +# snapshot an element instead of the whole page +playwright-cli snapshot "#main" + +# limit snapshot depth for efficiency, take a partial snapshot afterwards +playwright-cli snapshot --depth=4 +playwright-cli snapshot e34 +``` ### Targeting elements @@ -283,17 +296,17 @@ playwright-cli snapshot playwright-cli click e15 ``` -You can also use css or role selectors, for example when explicitly asked for it. +You can also use css selectors or Playwright locators. ```bash # css selector playwright-cli click "#main > button.submit" -# role selector -playwright-cli click "role=button[name=Submit]" +# role locator +playwright-cli click "getByRole('button', { name: 'Submit' })" -# chaining css and role selectors -playwright-cli click "#footer >> role=button[name=Submit]" +# test id locator +playwright-cli click "getByTestId('submit-button')" ``` ### Sessions diff --git a/package-lock.json b/package-lock.json index e3edcff..29497c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,13 +10,13 @@ "license": "Apache-2.0", "dependencies": { "minimist": "^1.2.5", - "playwright": "1.59.0-alpha-1773608981000" + "playwright": "1.59.0-alpha-1774661115000" }, "bin": { "playwright-cli": "playwright-cli.js" }, "devDependencies": { - "@playwright/test": "1.59.0-alpha-1773608981000", + "@playwright/test": "1.59.0-alpha-1774661115000", "@types/node": "^25.2.1" }, "engines": { @@ -24,13 +24,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.59.0-alpha-1773608981000", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.0-alpha-1773608981000.tgz", - "integrity": "sha512-px+GAf8KIaMcPsCUPG3+xqPRSIPHgnizH7ygUjo6OXT1AigXTNCsIIVrPY3C5GjouM2MI4CQOkIKcSEjO84ZTg==", + "version": "1.59.0-alpha-1774661115000", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.0-alpha-1774661115000.tgz", + "integrity": "sha512-QBFp2ZzcHmWPh2WGRqHkunClDOliVOZJDgN558dxtEdrN8zt+enQZpUThTSjKYceRSfmETkG4hQDePFyr+IImQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.59.0-alpha-1773608981000" + "playwright": "1.59.0-alpha-1774661115000" }, "bin": { "playwright": "cli.js" @@ -73,12 +73,12 @@ } }, "node_modules/playwright": { - "version": "1.59.0-alpha-1773608981000", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.0-alpha-1773608981000.tgz", - "integrity": "sha512-nb+BzawNj48eH6NdxecsysLuhCAB/p18FG7LLJp3MBfRGUkCAFtax0CFo/BhD+r0V4+0EW7llPK0p4cJQEIwUQ==", + "version": "1.59.0-alpha-1774661115000", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.0-alpha-1774661115000.tgz", + "integrity": "sha512-IQHv2DWyy5pJ8CHflQmRZmkp7ma+i3oHcTqkE16pk8Q+g/VkW/DjgkQCBWu04wI/nlvFsk1YBb5xuwT72irwTg==", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.59.0-alpha-1773608981000" + "playwright-core": "1.59.0-alpha-1774661115000" }, "bin": { "playwright": "cli.js" @@ -91,9 +91,9 @@ } }, "node_modules/playwright-core": { - "version": "1.59.0-alpha-1773608981000", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.0-alpha-1773608981000.tgz", - "integrity": "sha512-w6E5Q0Wleek3Wp7gtlSPGXuKeQ5eg6QPPJNNwgMHQRpkxgqOwgN2mX7x6Z52HJE10HFC88U5HQzOLMbag928Lg==", + "version": "1.59.0-alpha-1774661115000", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.0-alpha-1774661115000.tgz", + "integrity": "sha512-vn4L6iNCt4wB1ZOfURmn5Szsb5xikcEXLNvqKl0WB35Yt8yHVTSIksmJU9+SnPR2C31bgacrXJpo5Fwsg2bw+w==", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" diff --git a/package.json b/package.json index 90ecb2f..b0e39db 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,12 @@ "test": "playwright test" }, "devDependencies": { - "@playwright/test": "1.59.0-alpha-1773608981000", + "@playwright/test": "1.59.0-alpha-1774661115000", "@types/node": "^25.2.1" }, "dependencies": { "minimist": "^1.2.5", - "playwright": "1.59.0-alpha-1773608981000" + "playwright": "1.59.0-alpha-1774661115000" }, "bin": { "playwright-cli": "playwright-cli.js" diff --git a/skills/playwright-cli/SKILL.md b/skills/playwright-cli/SKILL.md index 4865d33..bf105f2 100644 --- a/skills/playwright-cli/SKILL.md +++ b/skills/playwright-cli/SKILL.md @@ -35,7 +35,8 @@ playwright-cli goto https://playwright.dev playwright-cli type "search query" playwright-cli click e3 playwright-cli dblclick e7 -playwright-cli fill e5 "user@example.com" +# --submit presses Enter after filling the element +playwright-cli fill e5 "user@example.com" --submit playwright-cli drag e2 e8 playwright-cli hover e4 playwright-cli select e9 "option-value" @@ -43,9 +44,11 @@ playwright-cli upload ./document.pdf playwright-cli check e12 playwright-cli uncheck e12 playwright-cli snapshot -playwright-cli snapshot --filename=after-click.yaml playwright-cli eval "document.title" playwright-cli eval "el => el.textContent" e5 +# get element id, class, or any attribute not visible in the snapshot +playwright-cli eval "el => el.id" e5 +playwright-cli eval "el => el.getAttribute('data-testid')" e5 playwright-cli dialog-accept playwright-cli dialog-accept "confirmation text" playwright-cli dialog-dismiss @@ -149,10 +152,12 @@ playwright-cli console playwright-cli console warning playwright-cli network playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])" +playwright-cli run-code --filename=script.js playwright-cli tracing-start playwright-cli tracing-stop playwright-cli video-start -playwright-cli video-stop video.webm +playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000 +playwright-cli video-stop --filename=video.webm ``` ## Open parameters @@ -192,9 +197,22 @@ After each command, playwright-cli provides a snapshot of the current browser st [Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml) ``` -You can also take a snapshot on demand using `playwright-cli snapshot` command. +You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed. + +```bash +# default - save to a file with timestamp-based name +playwright-cli snapshot + +# save to file, use when snapshot is a part of the workflow result +playwright-cli snapshot --filename=after-click.yaml + +# snapshot an element instead of the whole page +playwright-cli snapshot "#main" -If `--filename` is not provided, a new snapshot file is created with a timestamp. Default to automatic file naming, use `--filename=` when artifact is a part of the workflow result. +# limit snapshot depth for efficiency, take a partial snapshot afterwards +playwright-cli snapshot --depth=4 +playwright-cli snapshot e34 +``` ## Targeting elements @@ -208,17 +226,17 @@ playwright-cli snapshot playwright-cli click e15 ``` -You can also use css or role selectors, for example when explicitly asked for it. +You can also use css selectors or Playwright locators. ```bash # css selector playwright-cli click "#main > button.submit" -# role selector -playwright-cli click "role=button[name=Submit]" +# role locator +playwright-cli click "getByRole('button', { name: 'Submit' })" -# chaining css and role selectors -playwright-cli click "#footer >> role=button[name=Submit]" +# test id +playwright-cli click "getByTestId('submit-button')" ``` ## Browser Sessions @@ -307,3 +325,4 @@ playwright-cli close * **Test generation** [references/test-generation.md](references/test-generation.md) * **Tracing** [references/tracing.md](references/tracing.md) * **Video recording** [references/video-recording.md](references/video-recording.md) +* **Inspecting element attributes** [references/element-attributes.md](references/element-attributes.md) diff --git a/skills/playwright-cli/references/element-attributes.md b/skills/playwright-cli/references/element-attributes.md new file mode 100644 index 0000000..4e9fa6b --- /dev/null +++ b/skills/playwright-cli/references/element-attributes.md @@ -0,0 +1,23 @@ +# Inspecting Element Attributes + +When the snapshot doesn't show an element's `id`, `class`, `data-*` attributes, or other DOM properties, use `eval` to inspect them. + +## Examples + +```bash +playwright-cli snapshot +# snapshot shows a button as e7 but doesn't reveal its id or data attributes + +# get the element's id +playwright-cli eval "el => el.id" e7 + +# get all CSS classes +playwright-cli eval "el => el.className" e7 + +# get a specific attribute +playwright-cli eval "el => el.getAttribute('data-testid')" e7 +playwright-cli eval "el => el.getAttribute('aria-label')" e7 + +# get a computed style property +playwright-cli eval "el => getComputedStyle(el).display" e7 +``` diff --git a/skills/playwright-cli/references/playwright-tests.md b/skills/playwright-cli/references/playwright-tests.md index 1be8c70..47627c2 100644 --- a/skills/playwright-cli/references/playwright-tests.md +++ b/skills/playwright-cli/references/playwright-tests.md @@ -12,24 +12,28 @@ PLAYWRIGHT_HTML_OPEN=never npm run special-test-command # Debugging Playwright Tests -To debug a failing test, run it with Playwright as usual, but set `PWPAUSE=cli` environment variable. This command will pause the test at the point of failure, and print the debugging instructions. +To debug a failing Playwright test, run it with `--debug=cli` option. This command will pause the test at the start and print the debugging instructions. **IMPORTANT**: run the command in the background and check the output until "Debugging Instructions" is printed. -Once instructions are printed, use `playwright-cli` to explore the page. Debugging instructions include a browser name that should be used in `playwright-cli` to attach to the page under test. +Once instructions containing a session name are printed, use `playwright-cli` to attach the session and explore the page. ```bash # Run the test -PLAYWRIGHT_HTML_OPEN=never PWPAUSE=cli npx playwright test +PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli +# ... +# ... debugging instructions for "tw-abcdef" session ... # ... -# Explore the page and interact if needed -playwright-cli --session=test open --attach=test-worker-abcdef -playwright-cli --session=test snapshot -playwright-cli --session=test click e14 +# Attach to the test +playwright-cli attach tw-abcdef ``` -Keep the test running in the background while you explore and look for a fix. After fixing the test, stop the background test run. +Keep the test running in the background while you explore and look for a fix. +The test is paused at the start, so you should step over or pause at a particular location +where the problem is most likely to be. Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code. This code appears in the output and can be copied directly into the test. Most of the time, a specific locator or an expectation should be updated, but it could also be a bug in the app. Use your judgement. + +After fixing the test, stop the background test run. Rerun to check that test passes. diff --git a/skills/playwright-cli/references/video-recording.md b/skills/playwright-cli/references/video-recording.md index 38391b3..de77603 100644 --- a/skills/playwright-cli/references/video-recording.md +++ b/skills/playwright-cli/references/video-recording.md @@ -5,17 +5,26 @@ Capture browser automation sessions as video for debugging, documentation, or ve ## Basic Recording ```bash +# Open browser first +playwright-cli open + # Start recording playwright-cli video-start -# Perform actions -playwright-cli open https://example.com +# Add a chapter marker for section transitions +playwright-cli video-chapter "Getting Started" --description="Opening the homepage" --duration=2000 + +# Navigate and perform actions +playwright-cli goto https://example.com playwright-cli snapshot playwright-cli click e1 + +# Add another chapter +playwright-cli video-chapter "Filling Form" --description="Entering test data" --duration=2000 playwright-cli fill e2 "test input" # Stop and save -playwright-cli video-stop demo.webm +playwright-cli video-stop --filename=demo.webm ``` ## Best Practices @@ -24,10 +33,101 @@ playwright-cli video-stop demo.webm ```bash # Include context in filename -playwright-cli video-stop recordings/login-flow-2024-01-15.webm -playwright-cli video-stop recordings/checkout-test-run-42.webm +playwright-cli video-stop --filename=recordings/login-flow-2024-01-15.webm +playwright-cli video-stop --filename=recordings/checkout-test-run-42.webm +``` + +### 2. Record entire hero scripts. + +When recording a video for the user or as a proof of work, it is best to create a code snippet and execute it with run-code. +It allows pulling appropriate pauses between the actions and annotating the video. There are new Playwright APIs for that. + +1) Perform scenario using CLI and take note of all locators and actions. You'll need those locators to request thier bounding boxes for highlight. +2) Create a file with the intended script for video (below). Use pressSequentially w/ delay for nice typing, make reasonable pauses. +3) Use playwright-cli run-code --file your-script.js + +**Important**: Overlays are `pointer-events: none` — they do not interfere with page interactions. You can safely keep sticky overlays visible while clicking, filling, or performing any actions on the page. + +```js +async page => { + await page.video().start({ path: 'video.webm', size: { width: 1280, height: 800 } }); + await page.goto('https://demo.playwright.dev/todomvc'); + + // Show a chapter card — blurs the page and shows a dialog. + // Blocks until duration expires, then auto-removes. + // Use this for simple use cases, but always feel free to hand-craft your own beautiful + // overlay via await page.overlay.show(). + await page.overlay.chapter('Adding Todo Items', { + description: 'We will add several items to the todo list.', + duration: 2000, + }); + + // Perform action + await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Walk the dog', { delay: 60 }); + await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter'); + await page.waitForTimeout(1000); + + // Show next chapter + await page.overlay.chapter('Verifying Results', { + description: 'Checking the item appeared in the list.', + duration: 2000, + }); + + // Add a sticky annotation that stays while you perform actions. + // Overlays are pointer-events: none, so they won't block clicks. + const annotation = await page.overlay.show(` +
+ ✓ Item added successfully +
+ `); + + // Perform more actions while the annotation is visible + await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Buy groceries', { delay: 60 }); + await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter'); + await page.waitForTimeout(1500); + + // Remove the annotation when done + await annotation.dispose(); + + // You can also highlight relevant locators and provide contextual annotations. + const bounds = await page.getByText('Walk the dog').boundingBox(); + await page.overlay.add(` +
+
+
Check it out, it is right above this text +
+ `, { duration: 2000 }); + + await page.video().stop(); +} ``` +Embrace creativity, overlays are powerful. + +### Overlay API Summary + +| Method | Use Case | +|--------|----------| +| `page.overlay.chapter(title, { description?, duration?, styleSheet? })` | Full-screen chapter card with blurred backdrop — ideal for section transitions | +| `page.overlay.show(html, { duration? })` | Custom HTML overlay — use for callouts, labels, highlights | +| `disposable.dispose()` | Remove a sticky overlay added without duration | +| `page.overlay.setVisible(false/true)` | Temporarily hide/show all overlays | + ## Tracing vs Video | Feature | Video | Tracing |