Robotic Verification & Multi-Variate E2E Testing
playwright inspector robots with zero-tolerance false-failure policy
Published: 2026-06-26 | Project: East High Performance Centre | Discipline: Autonomous SWE & Adversarial QA
Author: Nicholas Alexander MacAskill — Founder & CTO, Flocano Labs | Canonical: https://www.nicholasmacaskill.com/dossier/ehpc-playwright-verification
Philosophy: Robotic Verification
East High Performance Centre does not rely on "it looks good to me." Every significant feature ships with a Verification Robot — a Playwright script that acts as a real user, clicks through the UI, and asserts database state. Unit tests can pass while the API is broken; only full E2E tests prove the face (UI) and brain (database) are talking correctly.
The Verification Hierarchy
| Level | Tool | Purpose |
|---|---|---|
| 1. Static | tsc --noEmit | Catch type mismatches before runtime |
| 2. Unit | Jest / Vitest | Isolate utility functions and math logic |
| 3. E2E | Playwright | Launch real browsers, log in, click, verify DB |
The Multi-Variate Rule
If a change touches both the frontend and the backend, you must create or update a dedicated Playwright spec (tests/feature-name.spec.ts). No merge without a green robot.Five-Phase Test Development
1. UI Discovery — inspect component source before writing any selector 2. Selector Strategy — prefer data-testid > role/label > regex text > exact text 3. Single-Test Development — write one test, run it, pass it, then write the next 4. Headless Validation — every new test must pass in CI headless mode 5. data-testid Enforcement — critical paths (auth, payments, bookings, roles) require stable test IDs
DB-Backed Verification Pattern
Tests provision real Supabase users via the Admin API, seed state, assert UI behavior, then clean up in afterAll:
test.describe('Schedule Visibility & Isolation', () => {
test.beforeAll(async () => {
const { data: authA } = await supabase.auth.admin.createUser({
email: `test-coach-ben-${Date.now()}@east.com`,
password: 'password123',
user_metadata: { first_name: 'Ben', role: 'coach' }
});
await supabase.from('profiles').upsert({ id: authA.user.id, role: 'coach' });
});
test('Admin Schedule respects strict ID filtering', async ({ page }) => {
await supabase.from('availability').insert({ coach_id: coachA.id, /* ... */ });
await page.goto('/admin/schedule');
// Assert only Coach A's slots are visible when filtered
});
test.afterAll(async () => {
await supabase.from('availability').delete().in('id', slotsToDelete);
await supabase.auth.admin.deleteUser(coachA.id);
});
});Environment Routing
playwright.config.ts dynamically selects .env.test, .env.local, or .env.production.latest based on PLAYWRIGHT_TEST_BASE_URL, with global setup/teardown hooks and single-worker execution to prevent CPU starvation during DB-heavy flows. Launch-critical paths — Stripe payments, realtime subscriptions, schedule booking, and RLS family access — each carry dedicated verification robots certified before production deploy.