Testing in WP Rig: E2E, Spatial Regression, PHPUnit & Budgets

WP Rig ships a layered quality stack: Playwright end-to-end tests across three browsers, deterministic spatial regression checks, Jest unit tests for build tooling, PHPUnit for PHP, PHPStan static analysis, and Lighthouse CI performance budgets — all wired into a single pre-flight gate. This post covers each layer and when to reach for it.

End-to-end testing (Playwright)

E2E tests follow WordPress Core testing standards and run against your local environment (override the URL with WP_BASE_URL):

npm run test:e2e                # full suite: chromium + firefox + webkit
npm run test:e2e:ui             # interactive Playwright UI
npm run test:e2e:debug          # step-through debugging
npm run test:e2e:codegen        # record new tests in the browser
  • 3-browser matrix: chromium, firefox, and webkit, with screenshot baselines recorded for all three. Workers cap at 4 (1 on CI) so the local WordPress harness stays responsive.
  • WebKit notes handled in-spec: synthetic Tab doesn’t reach clipped skip-links (explicit focus() is used), and the desktop visual-nav watch skips the deepest 5-level flyout hover chain.

The default suites

  • Smoke tests — homepage loads, site title visible, navigation present, with visual regression.
  • Accessibility — automated axe-core audits on key pages (404, archive).
  • Navigation — basic navigation behavior and ARIA attribute changes.
  • Visual navigation — a headed watch suite that hovers, keyboard-traverses, and resizes across all viewports with visual pacing.
  • Mobile navigation — multi-viewport hamburger/submenu testing with injected 5-level fixtures (below).

Spatial & visual regression

Pixel snapshots break when fonts or OS rendering differ. WP Rig’s spatial suite instead reasons about geometry via Playwright boundingBox() — environment-independent by design:

  • No horizontal overflow: scrollWidth must never exceed viewport width.
  • Structural regions (header / main / sidebar / footer) must not collide — resolved paradigm-agnostically for classic and block markup alike.
  • Content siblings in .entry-content must stack cleanly.
  • Every assertion takes a pixel tolerance (default 2px) so hairline borders never register as collisions.

Six page audits (home, single, theme-unit stress page, archive, search, 404) run across four viewports tracking the WP 7.1 settings.viewport scale — 375, 480, 782, 1280 — plus a mobile-menu-open audit:

npm run test:e2e:spatial         # headless, all browser projects
npm run test:e2e:spatial:watch   # headed, watch live

Mobile navigation testing

The mobile navigation suite validates hamburger toggles and nested submenus in both classic and block navigation modes: multi-viewport responsiveness (375×667 → 1280×800), self-contained 5-level deep submenu fixtures (deterministic regardless of database content), containment assertions, .open-left collision repositioning, and Alt + Click developer menu locking:

npm run test:e2e:mobile-nav        # headless / CI
npm run test:e2e:mobile-nav:watch  # live headed browser
# filters: MOBILE=1 npm run test:e2e:nav:watch · SLOWMO=1200 for pacing

Visual navigation watch mode

For humans, the watch suites pop a real browser window and walk the navigation with highlighting and pacing — desktop hovers, L1–L5 dropdowns, keyboard traversal, smooth viewport transitions (1280×800 → 768×1024 → 412×915 → 375×667), and mobile menu interactions:

npm run test:e2e:nav:watch           # desktop + mobile
npm run test:e2e:nav:watch:mobile    # 375x750 viewport
npm run test:e2e:nav:watch:desktop   # 1280x800 viewport

JS unit tests (Jest)

Build tooling has its own Jest suite — paradigm resolution, the bake wrapper, overlay merges, the spatial utilities: npm run test:scripts. And npm run test:prod-build runs a full production-bundle verification (setup → bundle → jest → teardown).

PHP testing: PHPUnit + PHPStan

  • composer test:unit — PHPUnit unit tests.
  • composer test:integration — integration tests (requires the WP test environment: composer setup-wp-tests).
  • composer test:all — unit + integration + PHPStan in one run.
  • composer phpstan — static analysis (level calibrated to the codebase, with a baseline: phpstan:baseline).

Performance budgets (Lighthouse CI)

npm run test:perf runs Lighthouse against the homepage, a sample page, and a single post — 3 runs each for stable averages — asserts against budgets in .lighthouserc.cjs, and uploads a shareable report. Budgets (LCP, CLS, TBT, category scores) are editable per project; the config auto-resolves your local proxyURL. See Performance & the Asset Pipeline for what these metrics measure in WP Rig terms.

The pre-flight gate: ai:check

One command runs the full battery before you submit work:

npm run ai:check   # e2e + screenshots + lint:blocks + lint:patterns + lint:css + lint:js

It exits 0 only when the entire matrix — 134 e2e tests across three browsers plus every linter — is green. Theme review discipline (WordPress.org guidelines, WPThemeReview ruleset, Theme Unit Test data) is covered in the audit:* commands — see npm run for the list.

Performance & the Asset Pipeline, Theme Paradigms (why specs stay paradigm-agnostic), and the rig CLI for the full command list.