BrowserExtension   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 2
Metric Value
eloc 40
dl 0
loc 114
rs 10
c 5
b 0
f 2
wmc 23

10 Methods

Rating   Name   Duplication   Size   Complexity  
A registerBrowser() 0 7 2
A executeAfterLastTest() 0 16 5
A dumpBrowsers() 0 12 4
A reset() 0 3 1
A executeAfterTestFailure() 0 3 1
A executeBeforeFirstTest() 0 3 1
A normalizeTestName() 0 14 3
A executeAfterTestError() 0 3 1
A executeAfterTest() 0 13 4
A executeBeforeTest() 0 3 1
1
<?php
2
3
namespace Zenstruck\Browser\Test;
4
5
use PHPUnit\Runner\AfterLastTestHook;
6
use PHPUnit\Runner\AfterTestErrorHook;
7
use PHPUnit\Runner\AfterTestFailureHook;
8
use PHPUnit\Runner\AfterTestHook;
9
use PHPUnit\Runner\BeforeFirstTestHook;
10
use PHPUnit\Runner\BeforeTestHook;
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
22
    /** @var array<string,array<string,string[]>> */
23
    private array $savedArtifacts = [];
24
25
    /**
26
     * @internal
27
     */
28
    public static function registerBrowser(Browser $browser): void
29
    {
30
        if (!self::$enabled) {
31
            return;
32
        }
33
34
        self::$registeredBrowsers[] = $browser;
35
    }
36
37
    public function executeBeforeFirstTest(): void
38
    {
39
        self::$enabled = true;
40
    }
41
42
    public function executeBeforeTest(string $test): void
43
    {
44
        self::reset();
45
    }
46
47
    public function executeAfterTest(string $test, float $time): void
48
    {
49
        foreach (self::$registeredBrowsers as $browser) {
50
            foreach ($browser->savedArtifacts() as $category => $artifacts) {
51
                if (!\count($artifacts)) {
52
                    continue;
53
                }
54
55
                $this->savedArtifacts[$test][$category] = $artifacts;
56
            }
57
        }
58
59
        self::reset();
60
    }
61
62
    public function executeAfterLastTest(): void
63
    {
64
        if (empty($this->savedArtifacts)) {
65
            return;
66
        }
67
68
        echo "\n\nSaved Browser Artifacts:";
69
70
        foreach ($this->savedArtifacts as $test => $categories) {
71
            echo "\n\n  {$test}";
72
73
            foreach ($categories as $category => $artifacts) {
74
                echo "\n    {$category}:";
75
76
                foreach ($artifacts as $artifact) {
77
                    echo "\n      * {$artifact}:";
78
                }
79
            }
80
        }
81
    }
82
83
    public function executeAfterTestError(string $test, string $message, float $time): void
84
    {
85
        self::dumpBrowsers($test, 'error');
86
    }
87
88
    public function executeAfterTestFailure(string $test, string $message, float $time): void
89
    {
90
        self::dumpBrowsers($test, 'failure');
91
    }
92
93
    private static function dumpBrowsers(string $test, string $type): void
94
    {
95
        if (empty(self::$registeredBrowsers)) {
96
            return;
97
        }
98
99
        $filename = \sprintf('%s_%s', $type, self::normalizeTestName($test));
100
101
        foreach (self::$registeredBrowsers as $i => $browser) {
102
            try {
103
                $browser->dumpCurrentState("{$filename}__{$i}");
104
            } catch (\Throwable $e) {
105
                // noop - swallow exceptions related to dumping the current state so as to not
106
                // lose the actual error/failure.
107
            }
108
        }
109
    }
110
111
    private static function normalizeTestName(string $name): string
112
    {
113
        // Try to match for a numeric data set index. If it didn't, match for a string one.
114
        if (!\preg_match('#^([\w:\\\]+)(.+\#(\d+).+)?$#', $name, $matches)) {
115
            \preg_match('#^([\w:\\\]+)(.+"([\w ]+)".+)?$#', $name, $matches);
116
        }
117
118
        $normalized = \strtr($matches[1], '\\:', '-_');
119
120
        if (isset($matches[3])) {
121
            $normalized .= '__data-set-'.\strtr($matches[3], '\\: ', '-_-');
122
        }
123
124
        return $normalized;
125
    }
126
127
    private static function reset(): void
128
    {
129
        self::$registeredBrowsers = [];
130
    }
131
}
132