From ca8349d6b70c1aae378e74db4db27180b10a3fc0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 10 Mar 2026 03:06:07 -0400 Subject: [PATCH 1/4] Remove maxDiffPixelRatio tolerance from screenshot tests Snapshots are generated and compared within CI on the same platform, so pixel-ratio tolerance shouldn't be needed. If tests fail, it will help identify the actual source of non-determinism rather than masking it with tolerance. --- www/playwright.config.ts | 1 - www/tests/fixtures/app-fixture.ts | 4 ++-- www/tests/raster-layer.spec.ts | 6 +----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/www/playwright.config.ts b/www/playwright.config.ts index 81a38ecf..9051a6a2 100644 --- a/www/playwright.config.ts +++ b/www/playwright.config.ts @@ -14,7 +14,6 @@ export default defineConfig({ expect: { toHaveScreenshot: { - maxDiffPixelRatio: 0.03, threshold: 0.2, }, }, diff --git a/www/tests/fixtures/app-fixture.ts b/www/tests/fixtures/app-fixture.ts index 1b61591d..4f321ba0 100644 --- a/www/tests/fixtures/app-fixture.ts +++ b/www/tests/fixtures/app-fixture.ts @@ -86,9 +86,9 @@ export class AppPage { await this.waitForNextFrame(); } - async expectScreenshot(name: string, options?: { maxDiffPixelRatio?: number }) { + async expectScreenshot(name: string) { await this.stabilizeForScreenshot(); - await expect(this.page).toHaveScreenshot(name, options); + await expect(this.page).toHaveScreenshot(name); } async clickOnCanvas(xFrac: number, yFrac: number) { diff --git a/www/tests/raster-layer.spec.ts b/www/tests/raster-layer.spec.ts index 38201fa6..3ab52bfe 100644 --- a/www/tests/raster-layer.spec.ts +++ b/www/tests/raster-layer.spec.ts @@ -61,10 +61,6 @@ for (const filePath of geotiffFiles) { await appPage.loadGeoTIFFFile(`./dist/geotiff-test-data/${filePath}`); - // Remote raster data can have minor non-deterministic rendering differences - const options = filePath.startsWith("real_data/") - ? { maxDiffPixelRatio: 0.05 } - : undefined; - await appPage.expectScreenshot(snapshotName(filePath), options); + await appPage.expectScreenshot(snapshotName(filePath)); }); } From a94e1905e9f70e97e48cd9f440561c3b3ca318c8 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 10 Mar 2026 03:56:43 -0400 Subject: [PATCH 2/4] Use SwiftShader for deterministic WebGL rendering in CI GPU rendering with --use-angle=default produces 1-3% pixel differences between CI runs due to hardware GPU non-determinism. SwiftShader is a CPU-based WebGL implementation bundled with Chromium that produces deterministic output, eliminating the need for maxDiffPixelRatio tolerance. --- www/playwright.config.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/www/playwright.config.ts b/www/playwright.config.ts index 9051a6a2..7ef2a3cd 100644 --- a/www/playwright.config.ts +++ b/www/playwright.config.ts @@ -31,7 +31,12 @@ export default defineConfig({ ...devices["Desktop Chrome"], viewport: { width: 1280, height: 720 }, launchOptions: { - args: ["--enable-gpu", "--use-angle=default"], + args: [ + "--enable-gpu", + ...(process.env.CI + ? ["--use-angle=swiftshader"] + : ["--use-angle=default"]), + ], }, }, }, From 74bf3275facb988e25c58519fabfe7c37d208dd3 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 10 Mar 2026 04:23:41 -0400 Subject: [PATCH 3/4] Re-run Playwright with --update-snapshots on failure to capture new baselines --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 993f4e37..62df89bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,6 +81,9 @@ jobs: run: cd www && npx playwright install --with-deps chromium - name: Run Playwright tests run: cd www && npx playwright test + - name: Update Playwright snapshots + if: failure() + run: cd www && npx playwright test --update-snapshots - name: Upload Playwright report uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} From 20df811e333fc70589425d411aae3e975fd3cbf6 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 10 Mar 2026 05:12:54 -0400 Subject: [PATCH 4/4] Revert SwiftShader, consolidate maxDiffPixelRatio to global config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SwiftShader (CPU-based WebGL) is too slow for this app — screenshot stabilization times out. Hardware GPU rendering is inherently non-deterministic between CI runs, so maxDiffPixelRatio is necessary. Consolidate tolerance to a single global 0.05 (was 0.03 global + 0.05 per-test for real_data/). Remove the per-test override and options plumbing from expectScreenshot since all tests use the same tolerance. --- .github/workflows/build.yml | 3 --- www/playwright.config.ts | 9 +++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62df89bc..993f4e37 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,9 +81,6 @@ jobs: run: cd www && npx playwright install --with-deps chromium - name: Run Playwright tests run: cd www && npx playwright test - - name: Update Playwright snapshots - if: failure() - run: cd www && npx playwright test --update-snapshots - name: Upload Playwright report uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} diff --git a/www/playwright.config.ts b/www/playwright.config.ts index 7ef2a3cd..414f80c4 100644 --- a/www/playwright.config.ts +++ b/www/playwright.config.ts @@ -14,6 +14,8 @@ export default defineConfig({ expect: { toHaveScreenshot: { + // Hardware GPU rendering is inherently non-deterministic between runs + maxDiffPixelRatio: 0.05, threshold: 0.2, }, }, @@ -31,12 +33,7 @@ export default defineConfig({ ...devices["Desktop Chrome"], viewport: { width: 1280, height: 720 }, launchOptions: { - args: [ - "--enable-gpu", - ...(process.env.CI - ? ["--use-angle=swiftshader"] - : ["--use-angle=default"]), - ], + args: ["--enable-gpu", "--use-angle=default"], }, }, },