'.$escapedContent.''; $document = new DOMDocument; $document->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); return $document->documentElement->getAttribute('data-line-text'); } describe('Log Viewer HTML Tag Preservation', function () { it('lets Blade escape deployment log data attributes only once', function () { $view = file_get_contents(__DIR__.'/../../resources/views/livewire/project/application/deployment/show.blade.php'); expect($view) ->toContain('data-log-content="{{ $searchableContent }}"') ->toContain('data-line-text="{{ $lineContent }}"') ->not->toContain('data-log-content="{{ htmlspecialchars($searchableContent) }}"') ->not->toContain('data-line-text="{{ htmlspecialchars($lineContent) }}"'); }); it('preserves literal html-like log text for client-side search reset and highlighting', function () { $logContent = '
A
'; expect(renderedDataLineTextValue($logContent))->toBe($logContent); }); it('does not strip tags with DOMParser based html decoding', function () { $views = [ __DIR__.'/../../resources/views/livewire/project/application/deployment/show.blade.php', __DIR__.'/../../resources/views/livewire/project/shared/get-logs.blade.php', ]; foreach ($views as $view) { expect(file_get_contents($view)) ->not->toContain('decodeHtml(text)') ->not->toContain('DOMParser().parseFromString'); } }); }); describe('Log Viewer XSS Prevention', function () { it('keeps script-like log output as text in Blade rendered markup', function () { $maliciousLog = ''; $escapedLog = e($maliciousLog); expect($escapedLog) ->toContain('<script>') ->not->toContain('