---
title: WebGPU screenshots with agent-browser
description: Use `agent-browser` to verify and capture vgpu previews that run WebGPU on Linux, including containers without a GPU. This complements [Browser testing with Playwright WebGPU](browser-testing.docs.md): use Playwright for API tests and this CDP automation recipe for visual captures.
---

# WebGPU screenshots with agent-browser



## Install and validate the environment

Install `agent-browser` (the verified version is v0.33.0). It automates Chromium through CDP. On Linux or in a container, install Vulkan and virtual-display dependencies before capturing screenshots:

```bash
npm i -g agent-browser@latest
apt-get install -y libvulkan1 mesa-vulkan-drivers xvfb xauth
agent-browser doctor --webgpu --headed
```

`doctor` runs a two-stage render and screenshot probe with a pixel check. In this sandbox, rendering passed with `google swiftshader` and the screenshot passed with `rgb(255,0,0)`.

Do not use headless Chrome without `--webgpu` to verify WebGPU. It does not expose WebGPU by default and can silently produce a black canvas.

## Choose the WebGPU mode

Always use `--webgpu` for the preset. It enables `--enable-unsafe-webgpu` on every platform. On Linux, it also selects software Vulkan through SwiftShader:

```text
--enable-features=Vulkan
--use-angle=vulkan
--use-vulkan=swiftshader
--use-webgpu-adapter=swiftshader
--disable-vulkan-surface
```

SwiftShader does not require a GPU or `/dev/dri`. It is slower than hardware: wait about six seconds and two `requestAnimationFrame` calls before capturing heavy previews, especially `fluid`, `fft-ocean`, and `raymarched-fractal`.

On Linux, headless mode with `--webgpu` renders, but headless Chrome captures the canvas as black; this is an upstream limitation. Add `--headed`. If `DISPLAY` is absent and Xvfb is installed, agent-browser automatically starts a virtual display.

```bash
agent-browser --session vgpu-webgpu --webgpu --headed open http://localhost:3001/preview/gradient
agent-browser --session vgpu-webgpu --webgpu --headed screenshot gradient.png
```

To prefer hardware Vulkan when it is available, override the preset adapters with user arguments; user arguments win over the preset:

```bash
agent-browser --webgpu --args "--use-vulkan=native,--use-webgpu-adapter=default" open http://localhost:3001
```

You can also enable the preset through an environment variable or configuration:

```bash
AGENT_BROWSER_WEBGPU=1 agent-browser --headed open http://localhost:3001
# agent-browser.json: { "webgpu": true }
```

## Capture and validate one preview

Isolate each job in a dedicated session and close it when finished. `screenshot` can succeed even when WebGPU failed and the image is black, so always validate pixels and application state.

```bash
SESSION=vgpu-webgpu
URL=http://localhost:3001/preview/gradient

agent-browser --session "$SESSION" --webgpu --headed open "$URL"
agent-browser --session "$SESSION" --webgpu --headed wait 6000
agent-browser --session "$SESSION" --webgpu --headed eval 'new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)))'
agent-browser --session "$SESSION" --webgpu --headed screenshot gradient.png
identify -format '%[fx:standard_deviation]\n' gradient.png
agent-browser --session "$SESSION" close
```

A low or zero standard deviation indicates a uniform or black capture. Also inspect vgpu error overlays: `Preview error`, `WebGPU is not available`, and `No WebGPU adapter was found`.

`agent-browser` does not support `text=` selectors. Use CSS selectors instead; a `text=` attempt can fail silently, which is another reason pixel validation must be the assertion of record.

`agent-browser eval` returns JSON-escaped output. Unescape it before grepping or parsing it:

```bash
META=$(agent-browser --session "$SESSION" --webgpu --headed eval 'JSON.stringify({ text: document.body.innerText, hasCanvas: Boolean(document.querySelector("canvas")), webgpu: Boolean(navigator.gpu) })')
printf '%s' "$META" | sed 's/\\"/"/g' | grep -E 'Preview error|WebGPU is not available|No WebGPU adapter was found'
```

## Capture every vgpu preview

With the documentation server already running from `apps/docs` on port 3001, this recipe rendered and captured all nine `/preview/<slug>` previews in this sweep through SwiftShader. The simplified loop waits for initialization, requires a canvas, captures, and rejects uniform pixels:

```bash
SESSION=vgpu-previews
BASE_URL=http://localhost:3001
for slug in gradient triangle-led-front anti-aliasing black-hole fluid instanced-rendering batch-rendering fft-ocean raymarched-fractal; do
  agent-browser --session "$SESSION" --webgpu --headed open "$BASE_URL/preview/$slug"
  agent-browser --session "$SESSION" --webgpu --headed wait 6000
  agent-browser --session "$SESSION" --webgpu --headed eval 'new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)))'
  agent-browser --session "$SESSION" --webgpu --headed eval 'JSON.stringify({hasCanvas:Boolean(document.querySelector("canvas")),webgpu:Boolean(navigator.gpu),text:document.body.innerText})' | sed 's/\\"/"/g' | grep -q '"hasCanvas":true'
  agent-browser --session "$SESSION" --webgpu --headed screenshot "$slug.png"
  identify -format '%[fx:standard_deviation]\n' "$slug.png" | awk '$1 > 50'
done
agent-browser --session "$SESSION" close
```

Do not omit pixel checks or error-overlay checks for individual previews. For a complete automation flow with logs, retries, `navigator.gpu`, and a WebGPU context check, keep this sequence and record console output and errors before closing the session.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)