Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
merge_group:
types: [checks_requested]
jobs:
run-all-tests:
unit-tests:
runs-on: ubuntu-latest
timeout-minutes: 10

Expand Down Expand Up @@ -41,17 +41,55 @@ jobs:
- name: Run Unit Tests
run: pnpm test

visual-regression-tests:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
renderMode: [webgl, canvas]

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 20

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-

- name: Install dependencies
run: pnpm install

- name: Install Playwright Browser
run: cd visual-regression && pnpm exec playwright install chromium

- name: Run Visual Regression Tests
run: pnpm run test:visual --color -w 4
- name: Run Visual Regression Tests (${{ matrix.renderMode }})
run: pnpm run test:visual --color -w 4 --renderMode ${{ matrix.renderMode }}
env:
RUNTIME_ENV: ci

- name: Upload failed-results as artifact
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: failed-results
name: failed-results-${{ matrix.renderMode }}
path: visual-regression/failed-results/
10 changes: 7 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,14 @@ export default async function test({ renderer, testRoot }: ExampleSettings) {

1. Add test file in `examples/tests/` (e.g., `shader-my-feature.ts`)
2. Export `automation` function that calls `settings.snapshot()`
3. Run `pnpm test:visual --capture` to generate snapshot
3. Run `pnpm test:visual --capture` to generate snapshots — both backends
(WebGL and Canvas2D) are captured by default. If the feature is
WebGL-only, export `renderModes: ('webgl' | 'canvas')[] = ['webgl']`
from the test module with a comment stating why
4. Manually verify output in `visual-regression/certified-snapshots/`
5. Commit certified snapshot with your code
6. CI will fail if future changes break rendering
(both the `chromium-*` and `chromium-*-canvas` directories)
5. Commit certified snapshots with your code
6. CI will fail if future changes break rendering on either backend

## What to NEVER Do

Expand Down
10 changes: 9 additions & 1 deletion visual-regression/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ Regression Test Case Snapshots (Snapshots).

Within the `certified-snapshots` directory are subdirectories defining
which browser and runtime environment (RUNTIME_ENV environment variable) was
used to generate their contained snapshots in the format `${browser}-${env}`.
used to generate their contained snapshots in the format `${browser}-${env}`
(WebGL backend) or `${browser}-${env}-canvas` (Canvas2D backend).

The supported runtime environments are `ci` (generated from a Linux-based Docker
container) and `local` (generated by the local machine environment).

Both render backends are tested by default (`--renderMode all`). Use
`--renderMode webgl` or `--renderMode canvas` to run a single backend. Tests
can opt out of a backend by exporting
`renderModes: ('webgl' | 'canvas')[]` from their module in `examples/tests/`
(e.g. the `rtt-*` tests are WebGL-only because `renderToTexture` is a noop on
the Canvas2D backend).

`ci` snapshots are checked into the repo and are the basis of a GitHub
Actions PR status check.

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 1 addition & 4 deletions visual-regression/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,7 @@ const argv = yargs(hideBin(process.argv))
renderMode: {
type: 'string',
alias: 'r',
// Defaults to webgl-only. Switch to 'all' (here or via --renderMode)
// once canvas baselines have been captured and committed, otherwise
// canvas compare runs fail for lack of reference snapshots.
default: 'webgl',
default: 'all',
choices: ['webgl', 'canvas', 'all'],
description:
'Renderer mode to test ("webgl", "canvas", or "all" for both)',
Expand Down
Loading