Passed
Push — 1.x ( 13d0d8...e7706b )
by Kevin
01:47
created

BrowserExtension::executeAfterLastTest()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 9
c 1
b 0
f 0
nc 5
nop 0
dl 0
loc 16
rs 9.6111
1
<?php
2
3
namespace Zenstruck\Browser\Test;
4
5
use PHPUnit\Runner\AfterLastTestHook;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Runner\AfterLastTestHook was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use PHPUnit\Runner\AfterTestErrorHook;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Runner\AfterTestErrorHook was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use PHPUnit\Runner\AfterTestFailureHook;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Runner\AfterTestFailureHook was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use PHPUnit\Runner\AfterTestHook;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Runner\AfterTestHook was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use PHPUnit\Runner\BeforeFirstTestHook;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Runner\BeforeFirstTestHook was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use PHPUnit\Runner\BeforeTestHook;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Runner\BeforeTestHook was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Zenstruck\Browser;
12
13
/**
14
 * @author Kevin Bond <[email protected]>
15
 */
16
final class BrowserExtension implements BeforeFirstTestHook, BeforeTestHook, AfterTestHook, AfterTestErrorHook, AfterTestFailureHook, AfterLastTestHook
17
{
18
    /** @var Browser[] */
19
    private static array $registeredBrowsers = [];
20
    private static bool $enabled = false;
21
    private array $savedArtifacts = [];
22
23
    /**
24
     * @internal
25
     */
26
    public static function registerBrowser(Browser $browser): void
27
    {
28
        if (!self::$enabled) {
29
            return;
30
        }
31
32
        self::$registeredBrowsers[] = $browser;
33
    }
34
35
    public function executeBeforeFirstTest(): void
36
    {
37
        self::$enabled = true;
38
    }
39
40
    public function executeBeforeTest(string $test): void
41
    {
42
        self::reset();
43
    }
44
45
    public function executeAfterTest(string $test, float $time): void
46
    {
47
        foreach (self::$registeredBrowsers as $browser) {
48
            foreach ($browser->savedArtifacts() as $category => $artifacts) {
49
                if (!\count($artifacts)) {
50
                    continue;
51
                }
52
53
                $this->savedArtifacts[$test][$category] = $artifacts;
54
            }
55
        }
56
57
        self::reset();
58
    }
59
60
    public function executeAfterLastTest(): void
61
    {
62
        if (empty($this->savedArtifacts)) {
63
            return;
64
        }
65
66
        echo "\n\nSaved Browser Artifacts:";
67
68
        foreach ($this->savedArtifacts as $test => $categories) {
69
            echo "\n\n  {$test}";
70
71
            foreach ($categories as $category => $artifacts) {
72
                echo "\n    {$category}:";
73
74
                foreach ($artifacts as $artifact) {
75
                    echo "\n      * {$artifact}:";
76
                }
77
            }
78
        }
79
    }
80
81
    public function executeAfterTestError(string $test, string $message, float $time): void
82
    {
83
        self::dumpBrowsers($test, 'error');
84
    }
85
86
    public function executeAfterTestFailure(string $test, string $message, float $time): void
87
    {
88
        self::dumpBrowsers($test, 'failure');
89
    }
90
91
    private static function dumpBrowsers(string $test, string $type): void
92
    {
93
        if (empty(self::$registeredBrowsers)) {
94
            return;
95
        }
96
97
        $filename = \sprintf('%s_%s', $type, self::normalizeTestName($test));
98
99
        foreach (self::$registeredBrowsers as $i => $browser) {
100
            try {
101
                $browser->dumpCurrentState("{$filename}__{$i}");
102
            } catch (\Throwable $e) {
103
                // noop - swallow exceptions related to dumping the current state so as to not
104
                // lose the actual error/failure.
105
            }
106
        }
107
    }
108
109
    private static function normalizeTestName(string $name): string
110
    {
111
        \preg_match('#^([\w:\\\]+)(.+\#(\d+).+)?$#', $name, $matches);
112
113
        $normalized = \strtr($matches[1], '\\:', '-_');
114
115
        if (isset($matches[3])) {
116
            $normalized .= '__data-set-'.$matches[3];
117
        }
118
119
        return $normalized;
120
    }
121
122
    private static function reset(): void
123
    {
124
        self::$registeredBrowsers = [];
125
    }
126
}
127