1<?php
2
3namespace Facebook\WebDriver\Chrome;
4
5use Facebook\WebDriver\Local\LocalWebDriver;
6use Facebook\WebDriver\Remote\DesiredCapabilities;
7use Facebook\WebDriver\Remote\Service\DriverCommandExecutor;
8use Facebook\WebDriver\Remote\WebDriverCommand;
9
10class ChromeDriver extends LocalWebDriver
11{
12    /** @var ChromeDevToolsDriver */
13    private $devTools;
14
15    /**
16     * Creates a new ChromeDriver using default configuration.
17     * This includes starting a new chromedriver process each time this method is called. However this may be
18     * unnecessary overhead - instead, you can start the process once using ChromeDriverService and pass
19     * this instance to startUsingDriverService() method.
20     *
21     * @todo Remove $service parameter. Use `ChromeDriver::startUsingDriverService` to pass custom $service instance.
22     * @return static
23     */
24    public static function start(DesiredCapabilities $desired_capabilities = null, ChromeDriverService $service = null)
25    {
26        if ($service === null) { // TODO: Remove the condition (always create default service)
27            $service = ChromeDriverService::createDefaultService();
28        }
29
30        return static::startUsingDriverService($service, $desired_capabilities);
31    }
32
33    /**
34     * Creates a new ChromeDriver using given ChromeDriverService.
35     * This is usable when you for example don't want to start new chromedriver process for each individual test
36     * and want to reuse the already started chromedriver, which will lower the overhead associated with spinning up
37     * a new process.
38
39     * @return static
40     */
41    public static function startUsingDriverService(
42        ChromeDriverService $service,
43        DesiredCapabilities $capabilities = null
44    ) {
45        if ($capabilities === null) {
46            $capabilities = DesiredCapabilities::chrome();
47        }
48
49        $executor = new DriverCommandExecutor($service);
50        $newSessionCommand = WebDriverCommand::newSession(
51            [
52                'capabilities' => [
53                    'firstMatch' => [(object) $capabilities->toW3cCompatibleArray()],
54                ],
55                'desiredCapabilities' => (object) $capabilities->toArray(),
56            ]
57        );
58
59        $response = $executor->execute($newSessionCommand);
60
61        /*
62         * TODO: in next major version we may not need to use this method, because without OSS compatibility the
63         * driver creation is straightforward.
64         */
65        return static::createFromResponse($response, $executor);
66    }
67
68    /**
69     * @todo Remove in next major version. The class is internally no longer used and is kept only to keep BC.
70     * @deprecated Use start or startUsingDriverService method instead.
71     * @codeCoverageIgnore
72     * @internal
73     */
74    public function startSession(DesiredCapabilities $desired_capabilities)
75    {
76        $command = WebDriverCommand::newSession(
77            [
78                'capabilities' => [
79                    'firstMatch' => [(object) $desired_capabilities->toW3cCompatibleArray()],
80                ],
81                'desiredCapabilities' => (object) $desired_capabilities->toArray(),
82            ]
83        );
84        $response = $this->executor->execute($command);
85        $value = $response->getValue();
86
87        if (!$this->isW3cCompliant = isset($value['capabilities'])) {
88            $this->executor->disableW3cCompliance();
89        }
90
91        $this->sessionID = $response->getSessionID();
92    }
93
94    /**
95     * @return ChromeDevToolsDriver
96     */
97    public function getDevTools()
98    {
99        if ($this->devTools === null) {
100            $this->devTools = new ChromeDevToolsDriver($this);
101        }
102
103        return $this->devTools;
104    }
105}
106