Passed
Pull Request — 1.x (#3)
by Kevin
02:01
created

HasBrowser::kernelBrowser()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 2
nop 0
dl 0
loc 33
rs 9.4222
c 0
b 0
f 0
1
<?php
2
3
namespace Zenstruck\Browser\Test;
4
5
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
6
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
7
use Symfony\Component\BrowserKit\HttpBrowser as HttpBrowserClient;
8
use Symfony\Component\Panther\Client as PantherClient;
9
use Symfony\Component\Panther\PantherTestCase;
10
use Zenstruck\Browser\HttpBrowser;
11
use Zenstruck\Browser\KernelBrowser;
12
use Zenstruck\Browser\PantherBrowser;
13
14
/**
15
 * @author Kevin Bond <[email protected]>
16
 */
17
trait HasBrowser
18
{
19
    /** @var HttpBrowserClient[] */
20
    private static array $httpBrowserClients = [];
21
    private static ?PantherClient $primaryPantherClient = null;
22
23
    /**
24
     * @internal
25
     * @after
26
     */
27
    final public static function _resetBrowserClients(): void
28
    {
29
        self::$httpBrowserClients = [];
30
        self::$primaryPantherClient = null;
31
    }
32
33
    protected function pantherBrowser(): PantherBrowser
34
    {
35
        $browser = PantherBrowser::create(function() {
36
            if (!$this instanceof PantherTestCase) {
37
                throw new \RuntimeException(\sprintf('The "%s" method can only be used on TestCases that extend "%s".', __METHOD__, PantherTestCase::class));
38
            }
39
40
            $class = $_SERVER['PANTHER_BROWSER_CLASS'] ?? PantherBrowser::class;
41
42
            if (!\is_a($class, PantherBrowser::class, true)) {
43
                throw new \RuntimeException(\sprintf('"PANTHER_BROWSER_CLASS" env variable must reference a class that extends %s.', PantherBrowser::class));
44
            }
45
46
            if (self::$primaryPantherClient) {
47
                return new $class(static::createAdditionalPantherClient());
48
            }
49
50
            self::$primaryPantherClient = static::createPantherClient(
51
                ['browser' => $_SERVER['PANTHER_BROWSER'] ?? static::CHROME]
0 ignored issues
show
Bug introduced by
The constant Zenstruck\Browser\Test\HasBrowser::CHROME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
52
            );
53
54
            return new $class(self::$primaryPantherClient);
55
        });
56
57
        BrowserExtension::registerBrowser($browser);
58
59
        return $browser
60
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
61
            ->setScreenshotDir($_SERVER['BROWSER_SCREENSHOT_DIR'] ?? './var/browser/screenshots')
62
            ->setConsoleLogDir($_SERVER['BROWSER_CONSOLE_LOG_DIR'] ?? './var/browser/console-logs')
63
        ;
64
    }
65
66
    protected function httpBrowser(): HttpBrowser
67
    {
68
        $browser = HttpBrowser::create(function() {
69
            $class = $_SERVER['HTTP_BROWSER_CLASS'] ?? HttpBrowser::class;
70
71
            if (!\is_a($class, HttpBrowser::class, true)) {
72
                throw new \RuntimeException(\sprintf('"HTTP_BROWSER_CLASS" env variable must reference a class that extends %s.', HttpBrowser::class));
73
            }
74
75
            $baseUri = $_SERVER['HTTP_BROWSER_URI'] ?? null;
76
77
            if (!$baseUri && !$this instanceof PantherTestCase) {
78
                throw new \RuntimeException(\sprintf('If not using "HTTP_BROWSER_URI", your TestCase must extend "%s".', PantherTestCase::class));
79
            }
80
81
            if (!$baseUri) {
82
                self::startWebServer();
83
84
                $baseUri = self::$baseUri;
85
            }
86
87
            // copied from PantherTestCaseTrait::createHttpBrowserClient()
88
            $client = new HttpBrowserClient();
89
            $urlComponents = \parse_url($baseUri);
90
            $host = $urlComponents['host'];
91
92
            if (isset($urlComponents['port'])) {
93
                $host .= ":{$urlComponents['port']}";
94
            }
95
96
            $client->setServerParameter('HTTP_HOST', $host);
97
98
            if ('https' === ($urlComponents['scheme'] ?? 'http')) {
99
                $client->setServerParameter('HTTPS', 'true');
100
            }
101
102
            /** @var HttpBrowser $browser */
103
            $browser = new $class(self::$httpBrowserClients[] = $client);
104
105
            if (!$this instanceof KernelTestCase) {
106
                return $browser;
107
            }
108
109
            if (!static::$booted) {
0 ignored issues
show
Bug introduced by
The property booted is declared protected in Symfony\Bundle\FrameworkBundle\Test\KernelTestCase and cannot be accessed from this context.
Loading history...
110
                static::bootKernel();
111
            }
112
113
            if (static::$container->has('profiler')) {
0 ignored issues
show
Bug introduced by
The property container is declared protected in Symfony\Bundle\FrameworkBundle\Test\KernelTestCase and cannot be accessed from this context.
Loading history...
114
                $browser->setProfiler(static::$container->get('profiler'));
0 ignored issues
show
Bug introduced by
It seems like static::container->get('profiler') can also be of type null; however, parameter $profiler of Zenstruck\Browser\HttpBrowser::setProfiler() does only seem to accept Symfony\Component\HttpKernel\Profiler\Profiler, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

114
                $browser->setProfiler(/** @scrutinizer ignore-type */ static::$container->get('profiler'));
Loading history...
115
            }
116
117
            return $browser;
118
        });
119
120
        BrowserExtension::registerBrowser($browser);
121
122
        return $browser
123
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
124
        ;
125
    }
126
127
    protected function kernelBrowser(): KernelBrowser
128
    {
129
        if (!$this instanceof KernelTestCase) {
130
            throw new \RuntimeException(\sprintf('The "%s" method can only be used on TestCases that extend "%s".', __METHOD__, KernelTestCase::class));
131
        }
132
133
        $browser = KernelBrowser::create(function() {
134
            $class = $_SERVER['KERNEL_BROWSER_CLASS'] ?? KernelBrowser::class;
135
136
            if (!\is_a($class, KernelBrowser::class, true)) {
137
                throw new \RuntimeException(\sprintf('"KERNEL_BROWSER_CLASS" env variable must reference a class that extends %s.', KernelBrowser::class));
138
            }
139
140
            if ($this instanceof WebTestCase) {
141
                static::ensureKernelShutdown();
142
143
                return new $class(static::createClient());
144
            }
145
146
            // reboot kernel before starting browser
147
            static::bootKernel();
148
149
            if (!static::$container->has('test.client')) {
150
                throw new \RuntimeException('The Symfony test client is not enabled.');
151
            }
152
153
            return new $class(static::$container->get('test.client'));
154
        });
155
156
        BrowserExtension::registerBrowser($browser);
157
158
        return $browser
159
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
160
        ;
161
    }
162
}
163