Skip to content

date: 2026-06-06 tags: [testing, pest, browser, playwright, fakes, inertia] status: active graduated_to:

Pest 4 browser tests run the app in-process — test-side fakes reach the rendered page

Symptom — Unclear whether Http::fake() / Carbon::setTestNow() / $this->app->bind(...) set in a test would apply to requests a real browser makes, or whether the browser hits a separately-booted server where they'd be ignored. The whole "deterministic UI testing with our existing fakes" approach hinged on this.

Root causepest-plugin-browser's LaravelHttpServer.php embeds an amphp SocketHttpServer::createForDirectAccess in the same PHP process as the test and dispatches each browser request through the same app()->make(HttpKernel::class) — no artisan serve, no per-request container reset. Only the Playwright automation layer is a separate (Node) process, so the container, facade fakes and Carbon test-now are shared.

Fix — Bind fakes exactly like a feature test: app()->instance(TaskClient::class, (new FakeTodoistClient)->withTasks([...])), $this->travelTo(...), factories + RefreshDatabase, then visit('/') renders against them. Proven in 51a3e15assertSee on a faked Todoist task passed end-to-end.

Guardtests/Browser/DashboardSmokeTest.php (the fake-honored case). Belongs in the UI-testing docs (epic #250, Sprint 1).