toStartWith('http')->not->toBeEmpty(); } else { // Build mode — manifest MUST exist expect(file_exists($manifestPath))->toBeTrue( 'Neither public/hot (dev) nor public/build/manifest.json (build) exists. ' . 'Vite must be running OR `npm run build` must have produced static assets.' ); } }); it('build manifest has entry for resources/css/app.css and at least one js entry', function () { $manifestPath = base_path('public/build/manifest.json'); if (! file_exists($manifestPath)) { // If only running dev, skip skip — assert dev hot file then expect(file_exists(base_path('public/hot')))->toBeTrue(); return; } $manifest = json_decode(file_get_contents($manifestPath), true); expect($manifest)->toBeArray()->not->toBeEmpty(); expect($manifest)->toHaveKey('resources/css/app.css'); expect($manifest['resources/css/app.css'])->toHaveKey('file'); $hasJs = collect($manifest)->contains(fn($e) => isset($e['file']) && str_ends_with($e['file'], '.js')); expect($hasJs)->toBeTrue('Build manifest must include at least one .js entry'); }); it('login page HTML references at least one CSS asset', function () { $response = $this->get('/login'); $response->assertOk(); preg_match_all('/href="([^"]+\.css)"/', $response->getContent(), $matches); expect($matches[1])->not->toBeEmpty('Login page must reference at least one CSS file via @vite'); });