Passed
Pull Request — 1.x (#32)
by Wouter
01:47
created

HasBrowser::pantherBrowser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 16
c 2
b 0
f 0
nc 3
nop 3
dl 0
loc 26
rs 9.7333
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
            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...
105
                $browser->setProfiler(static::$container->get('profiler'));
106
            }
107
        }
108
109
        BrowserExtension::registerBrowser($browser);
110
111
        return $browser
112
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
113
        ;
114
    }
115
116
    protected function browser(array $options = []): KernelBrowser
117
    {
118
        if (!$this instanceof KernelTestCase) {
119
            throw new \RuntimeException(\sprintf('The "%s" method can only be used on TestCases that extend "%s".', __METHOD__, KernelTestCase::class));
120
        }
121
122
        $class = $_SERVER['KERNEL_BROWSER_CLASS'] ?? KernelBrowser::class;
123
124
        if (!\is_a($class, KernelBrowser::class, true)) {
125
            throw new \RuntimeException(\sprintf('"KERNEL_BROWSER_CLASS" env variable must reference a class that extends %s.', KernelBrowser::class));
126
        }
127
128
        if ($this instanceof WebTestCase) {
129
            static::ensureKernelShutdown();
130
131
            $browser = new $class(static::createClient($options));
132
        } else {
133
            // reboot kernel before starting browser
134
            static::bootKernel($options);
135
136
            if (!static::$container->has('test.client')) {
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...
137
                throw new \RuntimeException('The Symfony test client is not enabled.');
138
            }
139
140
            $browser = new $class(static::$container->get('test.client'));
141
        }
142
143
        BrowserExtension::registerBrowser($browser);
144
145
        return $browser
146
            ->setSourceDir($_SERVER['BROWSER_SOURCE_DIR'] ?? './var/browser/source')
147
        ;
148
    }
149
}
150