get('/admin/login') ->assertSuccessful() ->assertSee('js/tenantpilot/unhandled-rejection-logger.js', escape: false); }); it('ships a window unhandledrejection logger with structured payload output', function (): void { $js = file_get_contents(public_path('js/tenantpilot/unhandled-rejection-logger.js')); expect($js)->toBeString(); expect($js) ->toContain('__tenantpilotUnhandledRejectionLoggerApplied') ->toContain("window.addEventListener('unhandledrejection'") ->toContain('window.fetch = async (...args) =>') ->toContain('XMLHttpRequest.prototype.open = function (method, url, ...rest)') ->toContain('const transport = resolveTransportMetadata(normalizedReason)') ->toContain('requestUrl: transport?.requestUrl ?? null') ->toContain('requestMethod: transport?.method ?? null') ->toContain('transportType: transport?.transportType ?? null') ->toContain('requestUrl: payload.requestUrl') ->toContain('isExpectedBackgroundTransportFailure') ->toContain("document.visibilityState !== 'visible'") ->toContain('document.hasFocus') ->toContain('event.preventDefault()') ->toContain('status === 419') ->toContain('Page Expired') ->toContain('status === 404') ->toContain('Not Found') ->toContain('const dedupeKey = toStableJson({') ->toContain('reason: payload.reason') ->toContain('TenantPilot unhandled promise rejection') ->toContain('JSON.stringify') ->not->toContain('recentKeys.has(payloadJson)') ->not->toContain('recentKeys.set(payloadJson, nowMs)'); });