HasBrowser::browser()   A
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 19
c 2
b 0
f 0
nc 7
nop 2
dl 0
loc 36
rs 9.0111
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(array $options = [], array $kernelOptions = [], array $managerOptions = []): PantherBrowser
34
    {
35
        $class = $_SERVER['PANTHER_BROWSER_CLASS'] ?? PantherBrowser::class;
36
37
        if (!\is_a($class, PantherBrowser::class, true)) {
38
            throw new \RuntimeException(\sprintf('"PANTHER_BROWSER_CLASS" env variable must reference a class that extends %s.', PantherBrowser::class));
39
        }
40
41
        if (self::$primaryPantherClient) {
42
            $browser = new $class(static::createAdditionalPantherClient());
43
        } else {
44
            self::$primaryPantherClient = static::createPantherClient(
45
                \array_merge(['browser' => $_SERVER['PANTHER_BROWSER'] ?? static::CHROME], $options),
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...
46
                $kernelOptions,
47
                $managerOptions
48
            );
49
50
            $browser = new $class(self::$primaryPantherClient);
51
        }
52
53
        BrowserExtension::registerBrowser($browser);
54
55
        return $browser
56
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
57
            ->setScreenshotDir($_SERVER['BROWSER_SCREENSHOT_DIR'] ?? './var/browser/screenshots')
58
            ->setConsoleLogDir($_SERVER['BROWSER_CONSOLE_LOG_DIR'] ?? './var/browser/console-logs')
59
        ;
60
    }
61
62
    protected function httpBrowser(array $kernelOptions = [], array $pantherOptions = []): HttpBrowser
63
    {
64
        $class = $_SERVER['HTTP_BROWSER_CLASS'] ?? HttpBrowser::class;
65
66
        if (!\is_a($class, HttpBrowser::class, true)) {
67
            throw new \RuntimeException(\sprintf('"HTTP_BROWSER_CLASS" env variable must reference a class that extends %s.', HttpBrowser::class));
68
        }
69
70
        $baseUri = $_SERVER['HTTP_BROWSER_URI'] ?? null;
71
72
        if (!$baseUri && !$this instanceof PantherTestCase) {
73
            throw new \RuntimeException(\sprintf('If not using "HTTP_BROWSER_URI", your TestCase must extend "%s".', PantherTestCase::class));
74
        }
75
76
        if (!$baseUri) {
77
            self::startWebServer($pantherOptions);
78
79
            $baseUri = self::$baseUri;
80
        }
81
82
        // copied from PantherTestCaseTrait::createHttpBrowserClient()
83
        $client = new HttpBrowserClient();
84
        $urlComponents = \parse_url($baseUri);
85
        $host = $urlComponents['host'];
86
87
        if (isset($urlComponents['port'])) {
88
            $host .= ":{$urlComponents['port']}";
89
        }
90
91
        $client->setServerParameter('HTTP_HOST', $host);
92
93
        if ('https' === ($urlComponents['scheme'] ?? 'http')) {
94
            $client->setServerParameter('HTTPS', 'true');
95
        }
96
97
        $browser = new $class(self::$httpBrowserClients[] = $client);
98
99
        if ($this instanceof KernelTestCase) {
100
            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...
101
                static::bootKernel($kernelOptions);
102
            }
103
104
            $container = \method_exists(static::class, 'getContainer') ? static::getContainer() : static::$container;
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...
105
106
            if ($container->has('profiler')) {
107
                $browser->setProfiler($container->get('profiler'));
108
            }
109
        }
110
111
        BrowserExtension::registerBrowser($browser);
112
113
        return $browser
114
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
115
        ;
116
    }
117
118
    protected function browser(array $kernelOptions = [], array $server = []): KernelBrowser
119
    {
120
        if (!$this instanceof KernelTestCase) {
121
            throw new \RuntimeException(\sprintf('The "%s" method can only be used on TestCases that extend "%s".', __METHOD__, KernelTestCase::class));
122
        }
123
124
        $class = $_SERVER['KERNEL_BROWSER_CLASS'] ?? KernelBrowser::class;
125
126
        if (!\is_a($class, KernelBrowser::class, true)) {
127
            throw new \RuntimeException(\sprintf('"KERNEL_BROWSER_CLASS" env variable must reference a class that extends %s.', KernelBrowser::class));
128
        }
129
130
        if ($this instanceof WebTestCase) {
131
            static::ensureKernelShutdown();
132
133
            $browser = new $class(static::createClient($kernelOptions, $server));
134
        } else {
135
            // reboot kernel before starting browser
136
            static::bootKernel($kernelOptions);
137
138
            $container = \method_exists(static::class, 'getContainer') ? static::getContainer() : static::$container;
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...
139
140
            if (!$container->has('test.client')) {
141
                throw new \RuntimeException('The Symfony test client is not enabled.');
142
            }
143
144
            $client = $container->get('test.client');
145
            $client->setServerParameters($server);
146
147
            $browser = new $class($client);
148
        }
149
150
        BrowserExtension::registerBrowser($browser);
151
152
        return $browser
153
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
154
        ;
155
    }
156
}
157