diff --git a/CHANGELOG.md b/CHANGELOG.md index f403d3c..922958e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ ### Added - Targeted browser installation through `playwright-install [browser...]` +### Fixed +- Failure screenshots are named after the failing test again on PHPUnit 10 and newer + ## [1.4.0] - 2026-08-10 ### Added diff --git a/src/Testing/PlaywrightTestCaseTrait.php b/src/Testing/PlaywrightTestCaseTrait.php index a8f97a5..7de60d3 100644 --- a/src/Testing/PlaywrightTestCaseTrait.php +++ b/src/Testing/PlaywrightTestCaseTrait.php @@ -93,8 +93,7 @@ protected function tearDownPlaywright(): void $status = $this->status(); if ($status->isFailure() || $status->isError()) { - $testName = method_exists($this, 'getName') && is_string($this->getName()) ? $this->getName() : 'test'; - $this->captureFailureArtifacts($testName); + $this->captureFailureArtifacts($this->resolveTestName()); } $this->safeClose($this->context); @@ -180,6 +179,31 @@ private function shouldTrace(): bool return '' !== $value && '0' !== $value; } + private function resolveTestName(): string + { + foreach (['name', 'getName'] as $method) { + if (!method_exists($this, $method)) { + continue; + } + + $name = $this->{$method}(); + + if (is_string($name) && '' !== $name) { + return self::sanitizeFileName($name); + } + } + + return 'test'; + } + + private static function sanitizeFileName(string $name): string + { + $sanitized = preg_replace('/[^A-Za-z0-9._-]+/', '_', $name) ?? ''; + $sanitized = trim($sanitized, '_.'); + + return '' === $sanitized ? 'test' : $sanitized; + } + private function captureFailureArtifacts(string $testName): void { $dir = getcwd().'/test-failures'; diff --git a/tests/Unit/Testing/PlaywrightTestCaseTest.php b/tests/Unit/Testing/PlaywrightTestCaseTest.php index 78879ce..19f5dd9 100644 --- a/tests/Unit/Testing/PlaywrightTestCaseTest.php +++ b/tests/Unit/Testing/PlaywrightTestCaseTest.php @@ -59,4 +59,43 @@ public function testSetUpCallsSetUpPlaywright(): void $this->assertTrue($setUpMethod->hasReturnType()); $this->assertEquals('void', $setUpMethod->getReturnType()->getName()); } + + public function testResolveTestNameUsesTheRunningTestName(): void + { + $case = new class('testExample') extends PlaywrightTestCase { + public function testExample(): void + { + } + }; + + $method = new \ReflectionMethod($case, 'resolveTestName'); + + $this->assertSame('testExample', $method->invoke($case)); + } + + public function testResolveTestNameStaysUsableAsAFileName(): void + { + $case = new class('testExample with data set "a/b"') extends PlaywrightTestCase { + public function testExample(): void + { + } + }; + + $method = new \ReflectionMethod($case, 'resolveTestName'); + + $this->assertSame('testExample_with_data_set_a_b', $method->invoke($case)); + } + + public function testResolveTestNameFallsBackWhenTheNameIsEmpty(): void + { + $case = new class('') extends PlaywrightTestCase { + public function testExample(): void + { + } + }; + + $method = new \ReflectionMethod($case, 'resolveTestName'); + + $this->assertSame('test', $method->invoke($case)); + } }