e2e/CI: dual-engine suites, per-engine screenshots, SwiftShader retired, prod web suite, CI-coverage gate

Squash of experiment/ff-big-modules vs main.

Big-module routing removed: native-EH shrank kicad_editor below
SpiderMonkey's x86-64 code budget (runs 29355049705/29356152413 green on
stock Firefox), so BIG_MODULE_SPECS routing and the baseline-only-JIT
crutch are gone — kicad-firefox and kicad-chromium both run the full
suite, with the module compiled the way real users' browsers compile it.

Per-engine screenshots end to end: stableShot/shotPath write
test-results/<engine>/<name>.png; baselines move to
baseline-screenshots/{chromium,firefox}/ and the whole tools/screenshots
pipeline (compare/promote/manifest/spec-map/changelog/Discord) keys on
<engine>/<name>. Previously Firefox and Chromium renders of one spec
overwrote each other and Firefox renders were never actually gated.
Seeded from CI run 29421380806 (92 new firefox baselines, +24 chromium
web-suite shots); manifest generated from the baseline tree.

One merged playwright.config.ts (kicad/asyncify/coroutine/perf as
projects); ~25 dead npm scripts dropped. The web suite is gated in CI for
the first time ever (4 rotted specs fixed, 5 broken lib-bridge specs
triaged as fixme in docs/features/web-e2e-rot/); cheap lint step after
npm ci; last 26 blind-sleep violations fixed.

SwiftShader retired: CI Chromium renders WebGL on ANGLE → Mesa llvmpipe
(--use-gl=angle --use-angle=gl --ignore-gpu-blocklist; the blocklist flag
is mandatory — llvmpipe is blocklisted and WebGL is silently unavailable
without it) in BOTH configs. Under WORKERS=4 congestion SwiftShader
transiently failed the first post-board-load draw and the recovery
cascade ended in a silent permanent Cairo fallback — that engine flip was
the "~1.2% changedRatio both directions" occ-export baseline flake.
Validated 160/160 across two 80-repeat rigs; full analysis in
docs/features/wx-parity-bugs/occ-export-context-eviction.md. Chromium
baselines shift slightly on llvmpipe — promote once from the first green
run. Deflakes the new coverage exposed: presence baselines settle before
capture; presence fixtures declare current file formats; perf gets its
own outputDir so CI evidence survives; occ-export settles the board paint
before the export dialog; menu-item waits (waitForRenderedByLabel before
clickMenuItem) in 4 specs + the TESTING.md rule.

Web suite runs the PROD build, in parallel: webServer becomes backend
`start` + the standalone's e2e:preview (build-preview.mjs: link-wasm →
stash the public/wasm symlink aside during vite build, build-demo.mjs's
move — then vite preview as the persistent server). The wasm middleware
serves /wasm/* in preview and emits COOP/COEP/CORP itself (a pthread
worker script's own response must carry COEP or Chrome kills it with
ERR_BLOCKED_BY_RESPONSE). VITE_* flags bake at build time;
VITE_ALLOW_USER_OVERRIDE joins turbo globalEnv. fullyParallel + default
workers: 5.2m → 1.4m. Determinism fixes the parallel run exposed:
shared-page specs become serial groups; locks.spec grabs alice's exact
item via the new kicadCollabTestSelectByUuid hook (cross-tab "first
footprint" order is not a ysync invariant); quit specs poll page.url()
(quit supersedes its own navigation — NS_BINDING_ABORTED on Firefox).
Suite: 51 passed / 12 skipped / 0 failed in 1.6m.

CI-coverage gate (lint:ci-coverage): every tests/**/*.spec.ts must be
reachable from the npm scripts the workflows invoke — scraped from
.github/workflows/, resolved through package.json, coverage asked from
playwright --list itself. Rules: uncovered-spec + orphan-project (with a
documented LOCAL_ONLY_PROJECTS allowlist). Gating next to
lint:determinism; 138 spec files / 13 projects accounted for.

Product fixes kept from the investigations (reachable on real GPUs too):
wx 7799fd1be5 — paint flags clear before dispatch + Invalidate always
propagates; kicad 3dcfea5e45 — SwiftShader pass-boundary flush +
per-instance font texture + first-frame GL-error drain (GAL recovery
recovers instead of falling back to Cairo) + the user-facing eeschema
switch navigates again under __EMSCRIPTEN__ (project-sync's
FaceRegistered gate had rerouted it into the hidden sync player; caught
by the newly-gated web suite).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018eUxiPApHgGiu9NFyQfhAq
This commit is contained in:
Viktor Vaczi 2026-07-17 12:10:40 +02:00
commit 63ed1f3c1f
556 changed files with 2470 additions and 1389 deletions

View file

@ -19,17 +19,21 @@ This builds `apps/minimal_test.{html,js,wasm}` and standalone test apps.
```bash
npm install
npm test # wx e2e specs + the asyncify race harness
npm test # setup:kicad + the full merged run (same projects as CI)
```
KiCad application tests are a separate, heavier suite (they need the
docker-built KiCad WASM): `npm run test:kicad`. Run only the wx e2e specs with
`npm run test:wx`.
One merged config (`playwright.config.ts`) drives every wasm suite as
Playwright *projects*; `npm run test:e2e` runs the CI set: `wx-chromium`,
`kicad-firefox`, `kicad-chromium`, `asyncify-firefox`, `coroutine-firefox`.
The KiCad specs (heavier — they need the docker-built KiCad WASM) run on BOTH
engines; `npm run test:kicad` is the firefox-only shortcut. The React web app
suite is separate: `npm run test:web` (see `playwright-web.config.ts`).
To run specific tests:
To run a subset, pick a project (and optionally a spec):
```bash
npx playwright test menu.spec.ts # Run menu tests only
npx playwright test --grep "wxTimer" # Run tests matching pattern
npx playwright test --project=wx-chromium menu.spec.ts # wx menu tests only
npx playwright test --project=kicad-firefox kicad/pcbnew.spec.ts
npx playwright test --project=wx-chromium --grep "wxTimer"
```
## Test Structure
@ -49,12 +53,14 @@ tests/
│ ├── wxwidgets.spec.ts # Comprehensive UI interaction tests
│ └── ...
├── logs/ # Test logs (auto-generated)
├── test-results/ # Screenshots (auto-generated)
├── baseline-screenshots/ # Reference screenshots for comparison
├── test-results/{chromium,firefox}/ # Screenshots per engine (auto-generated)
├── baseline-screenshots/{chromium,firefox}/ # Committed reference screenshots per engine
├── screenshot-manifest.json # Authoritative {name, engine} list (npm run screenshots:manifest)
├── apps/ # Built WASM test applications
│ ├── minimal_test.html # Main test app
│ └── standalone/ # Individual component test apps
└── playwright.config.ts # Playwright configuration
├── playwright.config.ts # THE merged config (wx / kicad / asyncify / coroutine / perf projects)
└── playwright-web.config.ts # React web-app suite (own server stack)
```
## Logging
@ -76,10 +82,15 @@ Example log format:
## Screenshots
Tests capture screenshots to `test-results/`. Compare against baselines:
Tests capture raw PNGs to `test-results/<engine>/` (engine-scoped via
`stableShot`/`shotPath`). The offline gate compares them against the committed
per-engine baselines:
```bash
../scripts/compare-screenshots.sh
npm run screenshots:check
```
CI's Linux render is the source of truth — update baselines by promoting a CI
run (`npm run screenshots:promote -- --run <ci-run-id>`), never by copying
local renders. Rules and details: `TESTING.md`.
## Viewing the App Directly

View file

@ -1,8 +1,11 @@
# Testing rules
Determinism rules for the Playwright specs (`tests/e2e`, `tests/kicad`, `tests/web`).
Enforced by `npm run lint:determinism` (`tools/lint-determinism.ts`). Run specs from `tests/`
via `npm run test:kicad` (firefox) / `npm run test:e2e` (chromium) — not playwright directly.
Enforced by `npm run lint:determinism` (`tools/lint-determinism.ts`, gating in CI). Run specs
from `tests/` via `npm run test:e2e` (the full CI project set: wx-chromium, kicad-firefox,
kicad-chromium, asyncify-firefox, coroutine-firefox) or `npm run test:kicad` (kicad-firefox
only) — not playwright directly. One spec on one engine:
`npx playwright test --project=kicad-firefox kicad/pcbnew.spec.ts`.
## Waits — never blind
@ -14,6 +17,13 @@ via `npm run test:kicad` (firefox) / `npm run test:e2e` (chromium) — not playw
- The **only** allowed `waitForTimeout` is an irreducible interaction dwell — a canvas/keyboard
commit with no JS-observable signal — and it MUST carry a same-line marker:
`// eslint-disable-line -- documented interaction dwell: <why>`.
- **Menu clicks: wait for the specific item, not a count.** Popup items register in the element
registry progressively as they paint, so a coarse gate ("N menuitems rendered") can pass before
the item you're about to click exists — and `clickMenuItem` is single-shot. Before every
`clickMenuItem(page, 'X')`, `await waitForRenderedByLabel(page, 'X', { elementType: 'menuitem' })`
(same matcher as the click). `clickMenuItemByText` already waits internally and needs no guard.
A submenu click needs its own wait: the parent menu's still-rendered items satisfy any count gate
before the submenu paints.
## No defensive branches
@ -26,10 +36,16 @@ via `npm run test:kicad` (firefox) / `npm run test:e2e` (chromium) — not playw
## Screenshots — `stableShot`, compared offline
- Capture with **`stableShot(page, 'name.png', { fullPage })`** — it settles the render (in-page
canvas-hash over animation frames) then writes a raw PNG to `test-results/`. It does **not**
assert. Never use Playwright's `toHaveScreenshot`.
- Comparison is offline: `npm run screenshots:check` diffs `test-results/` against the committed
baselines in `tests/baseline-screenshots/` (+ `3d-regression/`, `gal-regression/`).
canvas-hash over animation frames) then writes a raw PNG to
`test-results/<engine>/` (`chromium`/`firefox`, derived from the running browser — the same
spec on two engines writes two files). It does **not** assert. Never use Playwright's
`toHaveScreenshot`. Raw `page.screenshot`/fs writers must route through
`shotPath(page, 'name.png')` for the same engine scoping.
- Comparison is offline and per-engine: `npm run screenshots:check` diffs
`test-results/<engine>/` against the committed baselines in
`tests/baseline-screenshots/<engine>/` (+ `3d-regression/`, `gal-regression/`).
`tests/screenshot-manifest.json` (regen: `npm run screenshots:manifest`) is the authoritative
{name, engine} list — CI fails the lint step if it drifts from the baseline tree.
- **CI's Linux render is the source of truth**; baselines are promoted from CI
(`npm run screenshots:promote -- --run <ci-run-id>`). A local (Mac) check shows font/render
noise and is not the gate.
@ -37,9 +53,27 @@ via `npm run test:kicad` (firefox) / `npm run test:e2e` (chromium) — not playw
## Retries
- **`retries: 0`** in both configs. A failure is real; don't mask it with a retry.
- **`retries: 0`** in both configs (`playwright.config.ts` — the merged wasm-suite config —
and `playwright-web.config.ts`). A failure is real; don't mask it with a retry.
## Every spec runs in CI — `lint:ci-coverage`
`npm run lint:ci-coverage` (`tools/lint-ci-coverage.ts`, gating in CI next to the
determinism lint) proves every `*.spec.ts` under `tests/` is actually executed by CI:
it scrapes the `npm run test:…` invocations from `.github/workflows/`, resolves them
through `package.json` to their `playwright test --config/--project` flags, and asks
Playwright itself (`--list`) which files those runs cover. No hand-maintained lists —
adding a spec in a brand-new directory is exactly what it catches.
When it fires:
- `uncovered-spec` — your new spec matches no CI-run project. Put it in a covered
`testDir`, adjust a project's `testMatch`, or add the project to a CI npm script.
- `orphan-project` — you added a config project no CI script selects. Wire it into a
CI script, or (for deliberately-local system-browser projects) add it to
`LOCAL_ONLY_PROJECTS` in the lint with a comment saying why.
## Where things are
- Per-test logs (JS console + cpp): `tests/logs/{wxwidgets,kicad}/<test-name>/`.
- Guard: `npm run lint:determinism`. Screenshot gate: `npm run screenshots:check`.
- Guards: `npm run lint:determinism`, `npm run lint:ci-coverage`.
Screenshot gate: `npm run screenshots:check`.

View file

@ -387,73 +387,56 @@ cd tests/apps && ./build-test-apps.sh
## Baseline Screenshots
The test suite captures screenshots during test runs for visual regression testing. These screenshots are compared against a baseline to detect unexpected visual changes.
The test suite captures raw PNGs during test runs for visual regression testing,
compared offline against committed per-engine baselines (the calibrated gate in
`tools/screenshots/`).
### Directory Structure
```
tests/
├── baseline-screenshots/ # Known-good reference screenshots (146+ files)
├── test-results/ # Screenshots from latest test run
└── apps/
└── e2e/ # Playwright test specs
├── baseline-screenshots/
│ ├── chromium/ # Known-good references, Chromium render
│ └── firefox/ # Known-good references, Firefox render
├── test-results/
│ ├── chromium/ # Latest run's captures per engine
│ └── firefox/
└── screenshot-manifest.json # Authoritative {name, engine} list
```
Specs write via `stableShot(page, 'name.png')` / `shotPath(page, 'name.png')`
(`e2e/utils/element-tracker.ts`) — the engine subdir is derived from the running
browser, so the same spec on two engines produces two independent captures.
### Comparing Screenshots
Use the comparison script to check for visual regressions:
```bash
./scripts/compare-screenshots.sh
cd tests
npm run screenshots:check
```
This will:
- Compare all baseline screenshots with current test results
- Report identical, different, and missing screenshots
- Show file size differences (useful for detecting changes)
Example output:
```
=== Screenshot Comparison ===
Baseline: /path/to/tests/baseline-screenshots
Test Results: /path/to/tests/test-results
=== Comparing Baseline Screenshots ===
DIFFERENT: dialogs-msgbox-info-open.png (baseline: 47468B, current: 47478B, diff: 10B / .02%)
=== Summary ===
Total baseline screenshots: 121
Identical: 54
Different: 67
Missing from test results: 0
```
### Understanding Differences
Small byte differences (<2%) are typically caused by:
- **Timestamps** in event logs (e.g., `[19:45:35]` vs `[18:49:35]`)
- **PNG compression** variations between runs
- **Anti-aliasing** differences
These are **not** visual regressions. Visually inspect screenshots if you see larger differences.
This diffs `test-results/<engine>/` against `baseline-screenshots/<engine>/` with
per-engine calibrated noise floors and reports CHANGED / ADDED / REMOVED (removed
detection is driven by the manifest). On each main push, CI posts the same report
(triptych images labeled `[chromium]`/`[firefox]`) to Discord.
### Updating Baseline Screenshots
After verifying changes are intentional, update the baseline:
CI's Linux render is the source of truth — never copy local (Mac) renders into
the baselines. Promote from a CI run instead (churn-free: only meaningfully
changed images restage, and the manifest regenerates automatically):
```bash
# Copy current screenshots to baseline
cp tests/test-results/*.png tests/baseline-screenshots/
# Or selectively update specific screenshots
cp tests/test-results/dialog-*.png tests/baseline-screenshots/
cd tests
npm run screenshots:promote -- --run <ci-run-id>
git commit
```
### Running Tests with Screenshots
```bash
cd tests
npm test # wx e2e specs + asyncify harness (kicad: npm run test:kicad)
npm test # setup + the full merged run (all CI projects)
npx playwright test --ui # Interactive mode with screenshot preview
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

View file

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

View file

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Some files were not shown because too many files have changed in this diff Show more