Skip to content
7 changes: 4 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1177,8 +1177,7 @@ jobs:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('web/package-lock.json') }}
- name: install chromium
# Skips the browser download on a cache hit; still apt-installs deps.
run: npx playwright install --with-deps chromium
run: bash e2e/install-chromium.sh
- name: build production dashboard for plain HTTP browser check
run: npm run build
- name: TypeScript editor on plain HTTP
Expand Down Expand Up @@ -2271,8 +2270,10 @@ jobs:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('web/package-lock.json') }}
- name: install playwright browser
working-directory: web
run: |
cd web && npm ci && npx playwright install --with-deps chromium
npm ci
bash e2e/install-chromium.sh
- name: i18n catalogs for the live dashboard
# The live job serves the dashboard with plain vite, which never builds
# the gitignored language list and catalogs (spec 019 T037).
Expand Down
42 changes: 22 additions & 20 deletions .github/workflows/visual-diff.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ jobs:
visual-diff:
name: design vs browser visual diff
runs-on: ubuntu-latest
# Include the same system fonts used by the hosted runner alongside the
# complete Playwright font set used for design and clipping comparisons.
container: &screenshot_runtime
image: mcr.microsoft.com/playwright:v1.65.0-noble@sha256:6e3fb709361521eb27161606e6da6d2674e5e89fa16516cb37d6fdd91372273d
volumes:
- /usr/share/fonts:/usr/local/share/fonts/runner:ro
permissions:
contents: read
timeout-minutes: 20
Expand All @@ -47,16 +53,20 @@ jobs:
- name: install dependencies
run: npm ci

- name: playwright browser cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('web/package-lock.json') }}
restore-keys: |
playwright-${{ runner.os }}-${{ runner.arch }}-

- name: install chromium
run: npx playwright install --with-deps chromium
- &verify_screenshot_browser
name: verify the locked screenshot browser
run: |
node --input-type=module <<'JS'
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
const json = path => JSON.parse(readFileSync(path, 'utf8'));
assert.equal(
json('/ms-playwright/.docker-info').driverVersion,
json('node_modules/playwright/package.json').version,
'Update the screenshot image digest when upgrading Playwright',
);
JS
bash e2e/install-chromium.sh

- name: capture browser screenshots
run: npm run screenshots:design
Expand Down Expand Up @@ -86,6 +96,7 @@ jobs:
pseudo-locale:
name: en-XA screenshots (spec 019)
runs-on: ubuntu-latest
container: *screenshot_runtime
permissions:
contents: read
timeout-minutes: 30
Expand All @@ -106,16 +117,7 @@ jobs:
- name: install dependencies
run: npm ci

- name: playwright browser cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('web/package-lock.json') }}
restore-keys: |
playwright-${{ runner.os }}-${{ runner.arch }}-

- name: install chromium
run: npx playwright install --with-deps chromium
- *verify_screenshot_browser

- name: capture en-XA screenshots and check clipping
run: npm run screenshots:pseudo
Expand Down
6 changes: 6 additions & 0 deletions changelog/unreleased/917-browser-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### Browser checks on hosted runners

The dashboard’s mock, live Kubernetes and screenshot jobs now verify that the
locked Chromium build can render a screenshot and record video. Runners with a
working browser skip Ubuntu package installation. If the probe fails, CI
installs the distribution dependencies and repeats the probe before testing.
37 changes: 37 additions & 0 deletions web/e2e/install-chromium.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail

# Run from web/ after npm ci. Use the browser and FFmpeg from the locked CLI.
playwright=./node_modules/.bin/playwright

probe_browser() {
timeout --kill-after=5s 45s node --input-type=module <<'JS'
import { stat } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { chromium } from 'playwright';

const browser = await chromium.launch();
try {
const page = await browser.newPage({ recordVideo: { dir: tmpdir() } });
await page.setContent('<button>Français</button>');
await page.getByRole('button', { name: 'Français' }).screenshot();
const video = page.video();
await page.close();
if ((await stat(await video.path())).size === 0) throw new Error('Chromium recorded an empty video');
await video.delete();
} finally {
await browser.close();
}
JS
}

# Hosted runners normally have Chromium's native libraries. Only contact the
# distro mirrors if the installed browser cannot render and record a page.
timeout --kill-after=10s 4m "$playwright" install chromium
if probe_browser; then
exit 0
fi

echo "Chromium's runtime probe failed; installing Playwright's distribution dependencies." >&2
timeout --kill-after=10s 4m "$playwright" install --with-deps chromium
probe_browser
Loading