diff --git a/.changeset/playwright-extension-dry-run-1-58.md b/.changeset/playwright-extension-dry-run-1-58.md new file mode 100644 index 00000000000..4ea983116b9 --- /dev/null +++ b/.changeset/playwright-extension-dry-run-1-58.md @@ -0,0 +1,5 @@ +--- +"@trigger.dev/build": patch +--- + +The `playwright` build extension now works with Playwright 1.58 and later. 1.58 changed the `playwright install --dry-run` output, which made deploy image builds fail while downloading the browsers. diff --git a/packages/build/src/extensions/playwright.test.ts b/packages/build/src/extensions/playwright.test.ts new file mode 100644 index 00000000000..73716883e76 --- /dev/null +++ b/packages/build/src/extensions/playwright.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from "vitest"; +import { dryRunHeaderPattern } from "./playwright.js"; + +// Real `playwright install --dry-run` headers, before and after the 1.58 format change. +const HEADERS = { + "1.57": { + chromium: "browser: chromium version 143.0.7499.4", + "chromium-headless-shell": "browser: chromium-headless-shell version 143.0.7499.4", + firefox: "browser: firefox version 144.0.2", + webkit: "browser: webkit version 26.0", + }, + "1.62": { + chromium: "Chrome for Testing 151.0.7922.34 (playwright chromium v1234)", + "chromium-headless-shell": + "Chrome Headless Shell 151.0.7922.34 (playwright chromium-headless-shell v1234)", + firefox: "Firefox 153.0 (playwright firefox v1538)", + webkit: "WebKit 26.5 (playwright webkit v2336)", + }, +} as const; + +const browsers = Object.keys(HEADERS["1.57"]) as Array; + +describe("playwright extension dry-run header pattern", () => { + it.each(browsers)("selects the %s block in both output formats", (browser) => { + const pattern = new RegExp(dryRunHeaderPattern(browser)); + + expect(pattern.test(HEADERS["1.57"][browser])).toBe(true); + expect(pattern.test(HEADERS["1.62"][browser])).toBe(true); + }); + + it.each(browsers)("does not select another browser's block for %s", (browser) => { + const pattern = new RegExp(dryRunHeaderPattern(browser)); + + for (const other of browsers.filter((b) => b !== browser)) { + expect(pattern.test(HEADERS["1.57"][other])).toBe(false); + expect(pattern.test(HEADERS["1.62"][other])).toBe(false); + } + }); +}); diff --git a/packages/build/src/extensions/playwright.ts b/packages/build/src/extensions/playwright.ts index 0931a4855c7..8a390fcd8d5 100644 --- a/packages/build/src/extensions/playwright.ts +++ b/packages/build/src/extensions/playwright.ts @@ -196,6 +196,19 @@ export function playwright(options: PlaywrightExtensionOptions = {}) { return new PlaywrightExtension(options); } +/** + * Extended regex selecting a browser's block header in `playwright install --dry-run` output. + * + * Playwright < 1.58 prints `browser: version `; 1.58+ prints + * ` (playwright v)`. The trailing space / `v` keep + * `chromium` from matching the `chromium-headless-shell` block. + * + * @internal + */ +export function dryRunHeaderPattern(browser: string): string { + return `browser: ${browser} |\\(playwright ${browser} v`; +} + /** * Background: * @@ -317,7 +330,9 @@ class PlaywrightExtension implements BuildExtension { Array.from(browsersToInstall).forEach((browser) => { instructions.push( - `RUN grep -A5 -m1 "browser: ${browser}" /tmp/browser-info.txt > /tmp/${browser}-info.txt`, + // Only the two lines after the header (install location, download url) + // are read, so the window stops there. + `RUN grep -A2 -m1 -E "${dryRunHeaderPattern(browser)}" /tmp/browser-info.txt > /tmp/${browser}-info.txt`, `RUN INSTALL_DIR=$(grep "Install location:" /tmp/${browser}-info.txt | cut -d':' -f2- | xargs) && \ DIR_NAME=$(basename "$INSTALL_DIR") && \