Guides

A browser through the script step

examples/playwright/checkout.mjs drives real Chromium with Playwright: it signs in on vero-testserver's /checkout page, places an order through the form, and returns the order id the page shows. examples/playwright.yaml runs it as a script step and then checks the order with an http step. Playwright is not part of vero: you provide Node >=20, npm, the package and its matching browser. vero starts node checkout.mjs, speaks vero.script/v1 over stdio, and reports the script's results.

Running it

Build first using Getting started, from a checkout root with Node >=20 and npm installed. See Running the examples for the other plans. Install the pinned package and its matching Chromium shell:

npm ci --prefix examples/playwright
npx --prefix examples/playwright playwright-core install --only-shell chromium

In Terminal 1, start the plain fixture in the foreground:

bin/vero-testserver

In Terminal 2 at the checkout root:

ORDERS_API_KEY=example-key-1234 bin/vero run examples/playwright.yaml

Stop the fixture with Ctrl-C afterward. Browser cache directories vary by platform; use PLAYWRIGHT_BROWSERS_PATH as an optional absolute-directory override. The plan passes that path through input because the script child receives only PATH, HOME, and LANG from the parent, plus vero's own VERO_SCRIPT_TOKEN; it sets the browser path before loading playwright-core. Chromium and playwright-core must match: the pinned 1.63.0 package expects revision 1243. A mismatch fails at browser launch.

On Linux, missing browser system libraries may require npx --prefix examples/playwright playwright-core install --with-deps --only-shell chromium. This can install system packages and may need administrative privileges; run it only if your environment needs those libraries.

Repository-test note: The project's browser tests can use Nix-provided browsers through VERO_TEST_BROWSERS and make test-browser; they stay out of make check so that target needs no network and no browser. Neither Nix nor VERO_TEST_BROWSERS is needed for this example.

What the step gives up

With a real browser, the script step has these costs:

  • What the script checked is invisible. vero sees the step events the script writes. The example emits one per action, so it reports passed; a script that emits none and says ok: true is passed (unverified), browser or not.
  • Timing is the script's. There is no httptrace inside Chromium; checkoutMs is what the script measured.
  • Redaction is of text only. The page logs the API key and its session token to its console, the script forwards console lines as log events, and vero scrubs both there and in the event log. The key is a secretRef. The token is the login task's result, marked { secret: body.token }. A screenshot, a trace or a video the script saves is not scrubbed.
  • Cancellation reaches the browser indirectly. Playwright starts Chromium in a process group of its own, so vero's kill of the script's group does not touch it. On a timeout, vero's SIGTERM reaches node, Playwright's own signal handler closes the browser, and nothing is left. A script that ignores SIGTERM is killed with SIGKILL after 5 s; Chromium then exits by itself within about 80 ms, when its control pipe closes, and vero waits up to a second before calling anything a leak. A browser that survived that second would be reported as a leak, not killed.

This page is docs/content/guides/playwright.md in the repository.

verodocs