Skip to content

fix(build): playwright extension parses the Playwright 1.58+ install --dry-run output - #4881

Queued
NERLOE wants to merge 3 commits into
triggerdotdev:mainfrom
NERLOE:fix/playwright-extension-1-58-dry-run
Queued

fix(build): playwright extension parses the Playwright 1.58+ install --dry-run output#4881
NERLOE wants to merge 3 commits into
triggerdotdev:mainfrom
NERLOE:fix/playwright-extension-1-58-dry-run

Conversation

@NERLOE

@NERLOE NERLOE commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #3089

Problem

The playwright build extension reads npx playwright install --dry-run to find each browser's install directory and download URL. Playwright 1.58 changed the per-browser header, so the extension's grep finds nothing and the image build fails at that step with exit code 1:

< 1.58   browser: chromium-headless-shell version 143.0.7499.4
>= 1.58  Chrome Headless Shell 151.0.7922.34 (playwright chromium-headless-shell v1234)

There is a second problem hiding behind the first. The old blocks were five lines (install location, download url, two fallback urls, blank), so grep -A5 was exact. The Chrome-for-Testing blocks in 1.58+ (chromium and chromium-headless-shell, the default install) are three lines (install location, download url, blank; Firefox and WebKit still print the fallbacks), so -A5 runs into the next browser's Install location: line. The downstream grep "Install location:" | cut | xargs then joins two paths and basename returns the next browser's directory: with the header grep alone fixed, chromium-headless-shell gets unpacked into firefox-<build>/. Any grep-only fix (including the pnpm patch shared in #3089) has this bug.

Fix

  • The header match accepts both formats: grep -E "browser: <name> |\(playwright <name> v". The trailing space / v keep chromium from matching the chromium-headless-shell block in either format.
  • The context window is narrowed to -A2, the two lines the extension actually reads. Both formats put Install location: and Download url: immediately after the header.
  • A unit test asserts the generated header pattern selects each browser's block in both formats and never another browser's.

I left the sed "s/mac-arm64/linux/g" rewrite alone, and I do not think the "dead linux64 URLs" report in #3089 is reachable from the extension. The --dry-run executes inside the Linux build container, so the URL it prints is already the Linux one and there is nothing for the rewrite to match. Checked by running the same command in a container:

$ docker run --rm --platform linux/amd64 node:22-bookworm-slim \
    sh -c 'npx -y playwright@1.62.0 install --dry-run'
Chrome Headless Shell 151.0.7922.34 (playwright chromium-headless-shell v1234)
  Download url:        https://cdn.playwright.dev/builds/cft/151.0.7922.34/linux64/chrome-headless-shell-linux64.zip
Firefox 153.0 (playwright firefox v1538)
  Download url:        https://cdn.playwright.dev/dbazure/download/playwright/builds/firefox/1538/firefox-debian-12.zip

Rewriting mac-arm64 to linux64 would also be wrong for < 1.58, where the Linux artifact is …-linux.zip, so changing it would trade a dead branch for an incorrect one.

Verification

Ran the generated extraction (grep -A2 -m1 -E … | grep "Install location:" | cut | xargs | basename, and the same for Download url:) against real --dry-run output from Playwright 1.57.0 and 1.62.0, for all four browser keys:

output browser directory url
1.57 chromium chromium-1200 chromium-linux.zip
1.57 chromium-headless-shell chromium_headless_shell-1200 chromium-headless-shell-linux.zip
1.57 firefox firefox-1497 firefox-linux.zip
1.57 webkit webkit-2227 webkit-ubuntu-20.04.zip
1.62 chromium chromium-1234 chrome-linux.zip
1.62 chromium-headless-shell chromium_headless_shell-1234 chrome-headless-shell-linux.zip
1.62 firefox firefox-1538 firefox-linux.zip
1.62 webkit webkit-2336 webkit-mac-26-arm64.zip

(The webkit 1.62 URL shows the mac name only because my sample output came from a Mac; in the build container the dry-run prints Linux URLs.)

End to end: built a node:22-bookworm-slim image (linux/amd64) that runs the extension's generated RUN steps verbatim for chromium-headless-shell against Playwright 1.62.0, then launched the browser through Playwright with PLAYWRIGHT_BROWSERS_PATH=/ms-playwright:

install dir: chromium_headless_shell-1234
Downloading from https://cdn.playwright.dev/builds/cft/151.0.7922.34/linux64/chrome-headless-shell-linux64.zip
/ms-playwright/chromium_headless_shell-1234/chrome-headless-shell-linux64
title: pw-e2e-ok | version: 151.0.7922.34

So the Chrome-for-Testing archive layout unpacks into the directory Playwright's registry expects, and the browser starts.

Changeset

@trigger.dev/build patch.

🤖 Generated with Claude Code

…utput

Playwright 1.58 changed the per-browser header printed by
`playwright install --dry-run` from `browser: <name> version <v>` to
`<Product> <v> (playwright <name> v<build>)`, so the extension's grep
found nothing and the image build failed at that step.

The header match now accepts both formats. The context window after the
header is also narrowed to the two lines the extension reads (install
location and download url): the new blocks are shorter than the old
five-line ones, so the previous window ran into the next browser's
install location and would have unpacked the archive into the wrong
directory.

Fixes triggerdotdev#3089

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b9dd0f0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 27 packages
Name Type
@trigger.dev/build Patch
trigger.dev Patch
@trigger.dev/python Patch
@internal/dashboard-agent Patch
@trigger.dev/core Patch
@trigger.dev/react-hooks Patch
@trigger.dev/redis-worker Patch
@trigger.dev/rsc Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/sdk Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer Patch
@trigger.dev/rbac Patch
@trigger.dev/sso Patch
@internal/clickhouse Patch
@internal/llm-model-catalog Patch
@internal/metrics-pipeline Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/run-store Patch
@internal/schedule-engine Patch
@internal/tracing Patch
@internal/webhook-engine Patch
@internal/webhook-sources Patch
@internal/testcontainers Patch
@internal/cache Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Team

Run ID: 00086a3a-46e5-4d8d-80ab-307d010a1c68

📥 Commits

Reviewing files that changed from the base of the PR and between b9dd0f0 and 3720e4b.

📒 Files selected for processing (2)
  • packages/build/src/extensions/playwright.test.ts
  • packages/build/src/extensions/playwright.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (39)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (22, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (19, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (15, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (24, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (10, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (20, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (12, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (6, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (23, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (7, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (5, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (8, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (17, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (21, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (14, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (18, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (16, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (13, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (9, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (11, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (1, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (3, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (4, 24)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (2, 24)
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-ubuntu-latest-x64-4x - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-ubuntu-latest-x64-4x - npm)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (1, 3)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (3, 3)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-windows-latest-x64-8x - pnpm)
  • GitHub Check: internal / 🧪 Unit Tests: Internal
  • GitHub Check: e2e / 🧪 CLI v3 tests (warp-windows-latest-x64-8x - npm)
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (2, 2)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (2, 3)
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (1, 2)
  • GitHub Check: fk-cascade-guard / fk-cascade-guard
  • GitHub Check: runops-guard / runops-guard
  • GitHub Check: code-quality / code-quality
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (7)
We use vitest exclusively.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • packages/build/src/extensions/playwright.test.ts
**Prefer static imports over dynamic imports.**

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • packages/build/src/extensions/playwright.ts
  • packages/build/src/extensions/playwright.test.ts
Add crumbs as you write code — not just when debugging.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • packages/build/src/extensions/playwright.ts
  • packages/build/src/extensions/playwright.test.ts
Use vitest for all tests in the Trigger.dev repository

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Files:

  • packages/build/src/extensions/playwright.test.ts
Use function declarations instead of default exports

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Files:

  • packages/build/src/extensions/playwright.ts
  • packages/build/src/extensions/playwright.test.ts
Use types over interfaces for TypeScript Avoid using enums; prefer string unions or const objects instead

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Files:

  • packages/build/src/extensions/playwright.ts
  • packages/build/src/extensions/playwright.test.ts
When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs Do not use high-cardinality attributes in OTEL metr...

📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)

Files:

  • packages/build/src/extensions/playwright.ts
  • packages/build/src/extensions/playwright.test.ts
🪛 ast-grep (0.45.2)
packages/build/src/extensions/playwright.test.ts

[warning] 24-24: Do not use variable for regular expressions
Context: new RegExp(dryRunHeaderPattern(browser))
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.

(regexp-non-literal-typescript)


[warning] 31-31: Do not use variable for regular expressions
Context: new RegExp(dryRunHeaderPattern(browser))
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.

(regexp-non-literal-typescript)

🔇 Additional comments (2)
packages/build/src/extensions/playwright.ts (1)

199-210: LGTM!

Also applies to: 333-335

packages/build/src/extensions/playwright.test.ts (1)

2-2: LGTM!

Also applies to: 21-32


Walkthrough

The Playwright build extension now matches legacy and Playwright 1.58+ playwright install --dry-run headers. The generated grep command uses the exported dryRunHeaderPattern helper. Tests verify browser-specific matching across both formats without cross-browser matches. A patch changeset records the compatibility update.

Merge Risk: 🔵 Low · up to 3720e

The PR updates browser-output parsing for Playwright 1.58+ and is otherwise a localized change, but the modified parsing block still lacks the required crumb instrumentation, which may make build failures harder to diagnose; it is mergeable with explicit owner follow-up.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: updating the Playwright extension to parse the Playwright 1.58+ install output.
Description check ✅ Passed The description is mostly complete. It identifies issue #3089, explains the problem, documents the fix, and provides detailed verification results. It does not include the template checklist or screen…
Linked Issues check ✅ Passed The changes satisfy issue #3089. The parser supports both pre-1.58 and 1.58+ header formats, limits extraction to the required two lines, prevents adjacent browser blocks from being included, and adds…
Out of Scope Changes check ✅ Passed The changes are within scope. They modify the Playwright parser, add focused unit coverage, and include the required package changeset. No unrelated code changes are identified.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files.
Full details: Description check

Explanation

The description is mostly complete. It identifies issue #3089, explains the problem, documents the fix, and provides detailed verification results. It does not include the template checklist or screenshots section, but these omissions are non-critical for this change.

Full details: Linked Issues check

Explanation

The changes satisfy issue #3089. The parser supports both pre-1.58 and 1.58+ header formats, limits extraction to the required two lines, prevents adjacent browser blocks from being included, and adds tests for the supported browser formats.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

…test

Only the Chrome-for-Testing blocks shrank in 1.58+; Firefox and WebKit
still print the fallback urls. The window is two lines because that is
all the extension reads, not because every block is that short.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
coderabbitai[bot]

This comment was marked as resolved.

@NERLOE
NERLOE marked this pull request as ready for review September 2, 2026 22:50

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

Lift the pattern into dryRunHeaderPattern() so the test exercises it
without a hand-built BuildContext.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ericallam
ericallam added this pull request to the merge queue Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Playwright extension breaks with Playwright 1.58+ (--dry-run output format change)

2 participants