browser()->timeout(60_000); beforeEach(function (): void { Storage::fake('exports'); }); function spec397BrowserScreenshotName(string $name): string { return 'spec397-receipt-page-reduction-'.$name; } function spec397CopyBrowserScreenshot(string $name): void { $filename = spec397BrowserScreenshotName($name).'.png'; $source = base_path('tests/Browser/Screenshots/'.$filename); $targetDirectory = repo_path('specs/397-receipt-page-reduction/artifacts/screenshots'); if (! is_dir($targetDirectory)) { @mkdir($targetDirectory, 0755, true); } if (! is_file($source)) { $source = \Pest\Browser\Support\Screenshot::path($filename); } for ($attempt = 0; $attempt < 10 && ! is_file($source); $attempt++) { usleep(100_000); clearstatcache(true, $source); } if (is_file($source) && is_dir($targetDirectory) && is_writable($targetDirectory)) { @copy($source, $targetDirectory.DIRECTORY_SEPARATOR.$name.'.png'); } } /** * @return array{snapshot: BaselineSnapshot, profile: BaselineProfile} */ function spec397BrowserBaselineSnapshot(ManagedEnvironment $tenant): array { $profile = BaselineProfile::factory()->active()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'name' => 'Spec397 Browser Baseline', ]); $policyTypeCounts = []; $snapshot = BaselineSnapshot::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'baseline_profile_id' => (int) $profile->getKey(), 'summary_jsonb' => [ 'total_items' => 10, 'fidelity_counts' => ['content' => 10, 'meta' => 0], 'gaps' => ['count' => 0, 'by_reason' => []], ], ]); foreach (range(1, 10) as $index) { $policyType = sprintf('spec397BrowserPolicyType%02d', $index); $policyTypeCounts[$policyType] = 1; $subjectKey = baselineProviderResourceSubjectKeyForTest($policyType, sprintf('spec397-browser-policy-%02d', $index)); BaselineSnapshotItem::factory()->create([ 'baseline_snapshot_id' => (int) $snapshot->getKey(), 'policy_type' => $policyType, 'subject_key' => $subjectKey, 'subject_external_id' => BaselineSubjectKey::workspaceSafeSubjectExternalId($policyType, $subjectKey), 'meta_jsonb' => [ 'display_name' => sprintf('Spec397 Browser Policy %02d', $index), 'evidence' => [ 'fidelity' => 'content', 'source' => 'policy_version', 'observed_at' => now()->toIso8601String(), ], ], ]); } $snapshot->forceFill([ 'summary_jsonb' => array_merge($snapshot->summary_jsonb, [ 'policy_type_counts' => $policyTypeCounts, ]), ])->save(); return ['snapshot' => $snapshot->refresh(), 'profile' => $profile]; } function spec397BrowserRestoreRun(ManagedEnvironment $tenant): RestoreRun { $backupSet = BackupSet::factory()->create([ 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Spec397 Browser Backup', 'status' => 'completed', 'item_count' => 10, ]); $operationRun = OperationRun::factory()->forTenant($tenant)->create([ 'type' => OperationRunType::RestoreExecute->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'completed_at' => now(), ]); $items = []; foreach (range(1, 10) as $index) { $items[] = [ 'status' => 'applied', 'policy_identifier' => sprintf('Spec397 Restore Policy %02d', $index), 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', 'assignment_summary' => [ 'success' => 1, 'failed' => 0, 'skipped' => 0, ], 'settings_apply' => [ 'applied' => 1, 'failed' => 0, 'manual_required' => 0, ], 'graph_error_message' => sprintf('spec397 raw restore payload %02d', $index), ]; } return RestoreRun::factory()->for($tenant, 'tenant')->for($backupSet)->create([ 'status' => 'completed', 'operation_run_id' => (int) $operationRun->getKey(), 'requested_by' => 'Spec397 Browser Operator', 'results' => [ 'foundations' => [], 'items' => $items, ], 'metadata' => [ 'total' => 10, 'succeeded' => 10, 'failed' => 0, 'skipped' => 0, 'partial' => 0, 'non_applied' => 0, ], 'completed_at' => now(), ]); } function spec397BrowserRunningRestoreRun(ManagedEnvironment $tenant): RestoreRun { $backupSet = BackupSet::factory()->create([ 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Spec397 Browser Running Backup', 'status' => 'completed', 'item_count' => 2, ]); $operationRun = OperationRun::factory()->forTenant($tenant)->create([ 'type' => OperationRunType::RestoreExecute->value, 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'started_at' => now(), 'completed_at' => null, ]); return RestoreRun::factory()->for($tenant, 'tenant')->for($backupSet)->create([ 'status' => RestoreRunStatus::Running->value, 'operation_run_id' => (int) $operationRun->getKey(), 'requested_by' => 'Spec397 Browser Operator', 'results' => [ 'foundations' => [], 'items' => [], ], 'metadata' => [], 'started_at' => now(), 'completed_at' => null, ]); } function spec397BrowserReviewPack(ManagedEnvironment $tenant, User $user, EvidenceSnapshot $snapshot): ReviewPack { $review = composeEnvironmentReviewForTest($tenant, $user, $snapshot); $review = markEnvironmentReviewCustomerSafeReady($review); Storage::disk('exports')->put('review-packs/spec397-browser-ready.zip', 'PK-spec397-browser'); $pack = ReviewPack::factory()->ready()->create([ 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'environment_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => 'review-packs/spec397-browser-ready.zip', 'file_disk' => 'exports', 'options' => [ 'include_pii' => false, 'include_operations' => true, ], 'summary' => array_replace_recursive(is_array($review->summary) ? $review->summary : [], [ 'finding_count' => 1, 'report_count' => 2, 'operation_count' => 1, 'evidence_resolution' => [ 'outcome' => 'resolved', 'snapshot_id' => (int) $snapshot->getKey(), 'snapshot_fingerprint' => (string) $snapshot->fingerprint, ], ]), ]); $review->forceFill([ 'current_export_review_pack_id' => (int) $pack->getKey(), ])->save(); return $pack->refresh(); } function spec397BrowserStoredReport(ManagedEnvironment $tenant): StoredReport { return StoredReport::factory() ->permissionPosture([ 'posture_score' => 88, 'required_count' => 4, 'granted_count' => 3, 'permissions' => [ ['key' => 'DeviceManagementConfiguration.Read.All', 'status' => 'granted'], ['key' => 'DeviceManagementApps.ReadWrite.All', 'status' => 'missing'], ], ]) ->create([ 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => 'spec397-browser-report-fingerprint', ]); } it('Spec397 smokes reduced receipt defaults across changed detail surfaces', function (): void { [$user, $tenant] = createUserWithTenant( role: 'owner', workspaceRole: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); $evidenceSnapshot = seedEnvironmentReviewEvidence($tenant, findingCount: 1, driftCount: 0); ['snapshot' => $baselineSnapshot] = spec397BrowserBaselineSnapshot($tenant); $restoreRun = spec397BrowserRestoreRun($tenant); $runningRestoreRun = spec397BrowserRunningRestoreRun($tenant); $reviewPack = spec397BrowserReviewPack($tenant, $user, $evidenceSnapshot); $storedReport = spec397BrowserStoredReport($tenant); $this->actingAs($user)->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [ (string) $tenant->workspace_id => (int) $tenant->getKey(), ], ]); $page = visit(EvidenceSnapshotResource::getUrl('view', ['record' => $evidenceSnapshot], tenant: $tenant, panel: 'admin')) ->resize(1440, 1100) ->waitForText('Outcome summary') ->assertSee('Evidence basis and readiness') ->assertSee('Evidence coverage summary') ->assertSee('Internal evidence dimensions') ->assertDontSee('Artifact source') ->assertScript("document.body.textContent.indexOf('Evidence coverage summary') < document.body.textContent.indexOf('Internal evidence dimensions')", true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec397BrowserScreenshotName('01-evidence-snapshot-detail')); spec397CopyBrowserScreenshot('01-evidence-snapshot-detail'); $page = visit(BaselineSnapshotResource::getUrl('view', ['record' => $baselineSnapshot], panel: 'admin')) ->resize(1440, 1100) ->waitForText('Outcome summary') ->assertSee('Coverage summary') ->assertSee('Captured governed subjects') ->assertSee('Showing the first 8 governed subjects for receipt review.') ->assertSee('2 additional subjects stay in the internal detail path.') ->assertDontSee('Spec397 Browser Policy 09') ->assertScript("document.body.textContent.indexOf('Coverage summary') < document.body.textContent.indexOf('Captured governed subjects')", true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec397BrowserScreenshotName('02-baseline-snapshot-detail')); spec397CopyBrowserScreenshot('02-baseline-snapshot-detail'); $page = visit(RestoreRunResource::getUrl('view', ['record' => $restoreRun], tenant: $tenant, panel: 'admin')) ->resize(1440, 1100) ->waitForText('Needs attention') ->assertSee('Restore result summary') ->assertSee('View technical run details') ->assertSee('Confirm operation proof and capture post-run evidence before closing this as recovered.') ->assertSee('Spec397 Restore Policy 08') ->assertDontSee('Spec397 Restore Policy 09') ->assertDontSee('Operation proof available') ->assertDontSee('spec397 raw restore payload') ->assertScript('document.querySelector("[data-testid=\"restore-run-proof-panel\"] details")?.open === false', true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec397BrowserScreenshotName('03-restore-run-detail')); spec397CopyBrowserScreenshot('03-restore-run-detail'); $page ->click('[data-next-action-target="restore-run-technical-details"]') ->assertScript('document.getElementById("restore-run-technical-details")?.open === true', true) ->assertSee('Post-run evidence unavailable') ->assertSee('Open Evidence snapshots and use Create snapshot for this environment. Do not close the restore as recovered until the post-run snapshot is available.') ->assertSee('Open evidence snapshots') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); $page = visit(RestoreRunResource::getUrl('view', ['record' => $runningRestoreRun], tenant: $tenant, panel: 'admin')) ->resize(1440, 1100) ->waitForText('Running') ->assertSee('Monitor restore progress') ->assertSee('View technical run details') ->assertDontSee('View operation progress') ->assertDontSee('Open operation') ->assertDontSee('Operation proof in progress') ->assertScript('document.querySelector("[data-testid=\"restore-run-proof-panel\"] details")?.open === false', true) ->assertScript('(() => { const surface = document.querySelector("[data-testid=\"restore-run-detail-surface\"]"); return !!surface && Array.from(surface.querySelectorAll("a[href*=\"operations\"]")).every((a) => a.closest("[data-testid=\"restore-run-proof-panel\"] details")?.open === false); })()', true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec397BrowserScreenshotName('03b-restore-run-running-detail')); spec397CopyBrowserScreenshot('03b-restore-run-running-detail'); $page ->click('[data-next-action-target="restore-run-technical-details"]') ->assertScript('document.getElementById("restore-run-technical-details")?.open === true', true) ->assertSee('Operation proof in progress') ->assertSee('Open operation') ->assertSee('Wait until operation proof is completed, then capture a post-run evidence snapshot before closing this restore as recovered.') ->assertDontSee('Open evidence snapshots') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); $page = visit(ReviewPackResource::getUrl('view', ['record' => $reviewPack], tenant: $tenant, panel: 'admin')) ->resize(1440, 1100) ->waitForText('Outcome summary') ->assertSee('Output guidance') ->assertSee('Pack readiness and contents') ->assertSee('Evidence basis') ->assertSee('Evidence completeness') ->assertSee('Technical pack details') ->assertDontSee('Internal evidence details') ->assertDontSee('View internal evidence details') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec397BrowserScreenshotName('04-review-pack-detail')); spec397CopyBrowserScreenshot('04-review-pack-detail'); $page = visit(StoredReportResource::getUrl('view', ['record' => $storedReport], tenant: $tenant, panel: 'admin')) ->resize(1440, 1100) ->waitForText('Outcome summary') ->assertSee('Report scope and readiness') ->assertSee('Permission posture summary') ->assertSee('Internal report artifact') ->assertSee('Internal payload details') ->assertDontSee('Raw payload') ->assertScript("document.body.textContent.indexOf('Permission posture summary') < document.body.textContent.indexOf('Internal report artifact')", true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec397BrowserScreenshotName('05-stored-report-detail')); spec397CopyBrowserScreenshot('05-stored-report-detail'); });