1<?php
2
3namespace Facebook\WebDriver;
4
5use Facebook\WebDriver\Exception\NoSuchCookieException;
6use Facebook\WebDriver\Remote\DriverCommand;
7use Facebook\WebDriver\Remote\ExecuteMethod;
8use InvalidArgumentException;
9
10/**
11 * Managing stuff you would do in a browser.
12 */
13class WebDriverOptions
14{
15    /**
16     * @var ExecuteMethod
17     */
18    protected $executor;
19    /**
20     * @var bool
21     */
22    protected $isW3cCompliant;
23
24    public function __construct(ExecuteMethod $executor, $isW3cCompliant = false)
25    {
26        $this->executor = $executor;
27        $this->isW3cCompliant = $isW3cCompliant;
28    }
29
30    /**
31     * Add a specific cookie.
32     *
33     * @see Cookie for description of possible cookie properties
34     * @param Cookie|array $cookie Cookie object. May be also created from array for compatibility reasons.
35     * @return WebDriverOptions The current instance.
36     */
37    public function addCookie($cookie)
38    {
39        if (is_array($cookie)) { // @todo @deprecated remove in 2.0
40            $cookie = Cookie::createFromArray($cookie);
41        }
42        if (!$cookie instanceof Cookie) {
43            throw new InvalidArgumentException('Cookie must be set from instance of Cookie class or from array.');
44        }
45
46        $this->executor->execute(
47            DriverCommand::ADD_COOKIE,
48            ['cookie' => $cookie->toArray()]
49        );
50
51        return $this;
52    }
53
54    /**
55     * Delete all the cookies that are currently visible.
56     *
57     * @return WebDriverOptions The current instance.
58     */
59    public function deleteAllCookies()
60    {
61        $this->executor->execute(DriverCommand::DELETE_ALL_COOKIES);
62
63        return $this;
64    }
65
66    /**
67     * Delete the cookie with the given name.
68     *
69     * @param string $name
70     * @return WebDriverOptions The current instance.
71     */
72    public function deleteCookieNamed($name)
73    {
74        $this->executor->execute(
75            DriverCommand::DELETE_COOKIE,
76            [':name' => $name]
77        );
78
79        return $this;
80    }
81
82    /**
83     * Get the cookie with a given name.
84     *
85     * @param string $name
86     * @throws NoSuchCookieException In W3C compliant mode if no cookie with the given name is present
87     * @return Cookie|null The cookie, or null in JsonWire mode if no cookie with the given name is present
88     */
89    public function getCookieNamed($name)
90    {
91        if ($this->isW3cCompliant) {
92            $cookieArray = $this->executor->execute(
93                DriverCommand::GET_NAMED_COOKIE,
94                [':name' => $name]
95            );
96
97            if (!is_array($cookieArray)) { // Microsoft Edge returns null even in W3C mode => emulate proper behavior
98                throw new NoSuchCookieException('no such cookie');
99            }
100
101            return Cookie::createFromArray($cookieArray);
102        }
103
104        $cookies = $this->getCookies();
105        foreach ($cookies as $cookie) {
106            if ($cookie['name'] === $name) {
107                return $cookie;
108            }
109        }
110
111        return null;
112    }
113
114    /**
115     * Get all the cookies for the current domain.
116     *
117     * @return Cookie[] The array of cookies presented.
118     */
119    public function getCookies()
120    {
121        $cookieArrays = $this->executor->execute(DriverCommand::GET_ALL_COOKIES);
122        if (!is_array($cookieArrays)) { // Microsoft Edge returns null if there are no cookies...
123            return [];
124        }
125
126        $cookies = [];
127        foreach ($cookieArrays as $cookieArray) {
128            $cookies[] = Cookie::createFromArray($cookieArray);
129        }
130
131        return $cookies;
132    }
133
134    /**
135     * Return the interface for managing driver timeouts.
136     *
137     * @return WebDriverTimeouts
138     */
139    public function timeouts()
140    {
141        return new WebDriverTimeouts($this->executor, $this->isW3cCompliant);
142    }
143
144    /**
145     * An abstraction allowing the driver to manipulate the browser's window
146     *
147     * @return WebDriverWindow
148     * @see WebDriverWindow
149     */
150    public function window()
151    {
152        return new WebDriverWindow($this->executor, $this->isW3cCompliant);
153    }
154
155    /**
156     * Get the log for a given log type. Log buffer is reset after each request.
157     *
158     * @param string $log_type The log type.
159     * @return array The list of log entries.
160     * @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-type
161     */
162    public function getLog($log_type)
163    {
164        return $this->executor->execute(
165            DriverCommand::GET_LOG,
166            ['type' => $log_type]
167        );
168    }
169
170    /**
171     * Get available log types.
172     *
173     * @return array The list of available log types.
174     * @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-type
175     */
176    public function getAvailableLogTypes()
177    {
178        return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES);
179    }
180}
181