* fix: stabilize and diagnose browser CI gate - Replace networkidle screenshot wait (5s client timeout, flaky with long-lived connections) with readyState + fonts-loaded wait and fixed settle in a StableScreenshot helper. - Export standalone diff/expected/actual PNGs on visual mismatch so CI artifacts are directly viewable (vendor only writes an HTML diff view). - Create .env in CI test jobs; without it Laravel's env bootstrap emits a file_get_contents warning on every test. - Bump checkout/cache actions to v5 (Node 20 deprecation). - Gitignore tests/Browser/Screenshots. * docs: track browser CI gate task status in tasks.md
69 lines
2.1 KiB
PHP
69 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Support;
|
|
|
|
use Pest\Browser\Api\AwaitableWebpage;
|
|
use Pest\Browser\Exceptions\BrowserExpectationFailedException;
|
|
use Pest\Browser\Support\Screenshot;
|
|
use Pest\TestSuite;
|
|
use PHPUnit\Framework\ExpectationFailedException;
|
|
|
|
trait StableScreenshot
|
|
{
|
|
/**
|
|
* Asserts the page matches its visual baseline without relying on the
|
|
* networkidle load state, which is inherently flaky (long-lived connections
|
|
* like fonts, polling, or keep-alive can keep it from ever firing and cause
|
|
* spurious timeouts at the 5s client default).
|
|
*
|
|
* On mismatch the vendor only writes an HTML diff view with base64-embedded
|
|
* images, so this helper additionally exports standalone diff/expected/actual
|
|
* PNG files that are directly viewable in CI artifacts.
|
|
*/
|
|
public function assertStableScreenshotMatches(AwaitableWebpage $awaitable): void
|
|
{
|
|
$page = $awaitable->page();
|
|
|
|
$page->addStyleTag('* {
|
|
transition: none !important;
|
|
animation: none !important;
|
|
font-family: Arial, sans-serif !important;
|
|
body {
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
}
|
|
}');
|
|
|
|
$page->waitForFunction(
|
|
'document.readyState === "complete"'
|
|
.' && document.fonts.status === "loaded"'
|
|
);
|
|
|
|
usleep(300_000);
|
|
|
|
try {
|
|
$page->expectScreenshot(true, false);
|
|
} catch (ExpectationFailedException $exception) {
|
|
$this->exportMismatchScreenshots();
|
|
|
|
throw BrowserExpectationFailedException::from($page, $exception);
|
|
}
|
|
}
|
|
|
|
private function exportMismatchScreenshots(): void
|
|
{
|
|
[$snapshotName] = TestSuite::getInstance()->snapshots->get();
|
|
|
|
$base = pathinfo($snapshotName, PATHINFO_FILENAME);
|
|
$htmlPath = Screenshot::dir().'/ImageDiffView/'.$base.'.html';
|
|
|
|
if (! is_file($htmlPath)) {
|
|
return;
|
|
}
|
|
|
|
MismatchScreenshotExporter::export($htmlPath, Screenshot::dir());
|
|
}
|
|
}
|