browser()->timeout(45_000); uses(RefreshDatabase::class); it('Spec384 smokes baseline subject resolution reachability and action modal', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $tenant->forceFill(['name' => 'Spec384 Subject Resolution Environment'])->save(); $run = spec384BrowserSubjectResolutionRun($tenant); $resolutionPath = spec384BrowserPath(ManagedEnvironmentLinks::baselineSubjectResolutionUrl($tenant, [ 'operation_run_id' => (int) $run->getKey(), ])); $page = visit(spec384BrowserLoginUrl($user, $tenant, $resolutionPath)) ->resize(1440, 1100) ->waitForText('Baseline subject resolution') ->assertSee('Spec384 Subject Resolution Environment') ->assertSee('1 decision required') ->assertSee('Decision worklist') ->assertSee('Duplicate policy') ->assertSee('Unresolved Duplicate Candidates') ->assertSee('Binding required') ->assertSee('TenantPilot-only') ->assertSee('Open operation') ->assertSee('Open baseline compare') ->assertSee('Bind subject') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec384BrowserScreenshotName('01-baseline-subject-resolution')); spec384BrowserCopyScreenshot('01-baseline-subject-resolution'); $page ->click('Bind subject') ->waitForText('Record a TenantPilot-only subject binding') ->assertSee('Provider resource') ->assertSee('Operator note') ->assertSee('This does not mutate the provider tenant') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec384BrowserScreenshotName('02-baseline-subject-resolution-bind-modal')); spec384BrowserCopyScreenshot('02-baseline-subject-resolution-bind-modal'); $page ->resize(430, 900) ->assertScript('document.documentElement.scrollWidth <= window.innerWidth', true) ->assertNoJavaScriptErrors() ->screenshot(true, spec384BrowserScreenshotName('03-baseline-subject-resolution-mobile')); spec384BrowserCopyScreenshot('03-baseline-subject-resolution-mobile'); }); function spec384BrowserSubjectResolutionRun(ManagedEnvironment $tenant) { [$profile, $snapshot] = seedActiveBaselineForTenant($tenant); $leftIdentity = ResourceIdentity::providerResource('fake-provider', 'policy', 'candidate-left'); $rightIdentity = ResourceIdentity::providerResource('fake-provider', 'policy', 'candidate-right'); $leftDescriptor = BaselineSubjectResolutionFixtures::providerDescriptor($leftIdentity, 'Duplicate policy'); $rightDescriptor = BaselineSubjectResolutionFixtures::providerDescriptor($rightIdentity, 'Duplicate policy'); BaselineSubjectResolutionFixtures::inventoryCandidate( $tenant, $leftIdentity, 'Duplicate policy', ); BaselineSubjectResolutionFixtures::inventoryCandidate( $tenant, $rightIdentity, 'Duplicate policy', ); return seedBaselineCompareRun( tenant: $tenant, profile: $profile, snapshot: $snapshot, compareContext: [ 'result_semantics' => [ 'version' => 1, 'subject_outcomes' => [ BaselineSubjectResolutionFixtures::semanticOutcome([ 'reason' => 'unresolved_duplicate_candidates', 'actionability' => 'binding_required', 'readiness_impact' => 'customer_blocker', 'subject' => [ 'subject_domain' => 'baseline', 'subject_class' => SubjectClass::PolicyBacked->value, 'subject_type_key' => 'deviceConfiguration', 'subject_key' => 'legacy-display-key', 'display_label' => 'Duplicate policy', 'candidate_descriptors' => [ $leftDescriptor->toArray(), $rightDescriptor->toArray(), ], ], ]), ], ], ], status: OperationRunStatus::Completed->value, outcome: OperationRunOutcome::PartiallySucceeded->value, ); } function spec384BrowserLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect): string { return route('admin.local.smoke-login', [ 'email' => $user->email, 'tenant' => $tenant->external_id, 'workspace' => $tenant->workspace->slug, 'redirect' => $redirect, ]); } function spec384BrowserPath(string $url): string { $path = parse_url($url, PHP_URL_PATH) ?: '/admin'; $query = parse_url($url, PHP_URL_QUERY); return is_string($query) && $query !== '' ? $path.'?'.$query : $path; } function spec384BrowserScreenshotName(string $name): string { return 'spec384-'.$name; } function spec384BrowserCopyScreenshot(string $name): void { $filename = spec384BrowserScreenshotName($name).'.png'; $source = base_path('tests/Browser/Screenshots/'.$filename); $targetDirectory = repo_path('specs/384-baseline-subject-resolution-ui/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.$filename); } }