Security update for permissions_by_term
[yaffs-website] / vendor / instaclick / php-webdriver / lib / WebDriver / Container.php
1 <?php
2 /**
3  * Copyright 2004-2017 Facebook. All Rights Reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * @package WebDriver
18  *
19  * @author Justin Bishop <jubishop@gmail.com>
20  * @author Anthon Pang <apang@softwaredevelopment.ca>
21  * @author Fabrizio Branca <mail@fabrizio-branca.de>
22  */
23
24 namespace WebDriver;
25
26 use WebDriver\Exception as WebDriverException;
27
28 /**
29  * Abstract WebDriver\Container class
30  *
31  * @package WebDriver
32  */
33 abstract class Container extends AbstractWebDriver
34 {
35     /**
36      * {@inheritdoc}
37      */
38     public function __construct($url = 'http://localhost:4444/wd/hub')
39     {
40         parent::__construct($url);
41
42         $locatorStrategy = new \ReflectionClass('WebDriver\LocatorStrategy');
43         $this->strategies  = $locatorStrategy->getConstants();
44     }
45
46     /**
47      * Find element: /session/:sessionId/element (POST)
48      * Find child element: /session/:sessionId/element/:id/element (POST)
49      * Search for element on page, starting from the document root.
50      *
51      * @param string $using the locator strategy to use
52      * @param string $value the search target
53      *
54      * @return \WebDriver\Element
55      *
56      * @throws \WebDriver\Exception if element not found, or invalid XPath
57      */
58     public function element($using = null, $value = null)
59     {
60         $locatorJson = $this->parseArgs('element', func_get_args());
61
62         try {
63             $result = $this->curl(
64                 'POST',
65                 '/element',
66                 $locatorJson
67             );
68         } catch (WebDriverException\NoSuchElement $e) {
69             throw WebDriverException::factory(
70                 WebDriverException::NO_SUCH_ELEMENT,
71                 sprintf(
72                     "Element not found with %s, %s\n\n%s",
73                     $locatorJson['using'],
74                     $locatorJson['value'],
75                     $e->getMessage()
76                 ),
77                 $e
78             );
79         }
80
81         $element = $this->webDriverElement($result['value']);
82
83         if ($element === null) {
84             throw WebDriverException::factory(
85                 WebDriverException::NO_SUCH_ELEMENT,
86                 sprintf(
87                     "Element not found with %s, %s\n",
88                     $locatorJson['using'],
89                     $locatorJson['value']
90                 )
91             );
92         }
93
94         return $element;
95     }
96
97     /**
98      * Find elements: /session/:sessionId/elements (POST)
99      * Find child elements: /session/:sessionId/element/:id/elements (POST)
100      * Search for multiple elements on page, starting from the document root.
101      *
102      * @param string $using the locator strategy to use
103      * @param string $value the search target
104      *
105      * @return array
106      *
107      * @throws \WebDriver\Exception if invalid XPath
108      */
109     public function elements($using = null, $value = null)
110     {
111         $locatorJson = $this->parseArgs('elements', func_get_args());
112
113         $result = $this->curl(
114             'POST',
115             '/elements',
116             $locatorJson
117         );
118
119         if (!is_array($result['value'])) {
120             return array();
121         }
122
123         return array_filter(
124             array_map(
125                 array($this, 'webDriverElement'),
126                 $result['value']
127             )
128         );
129     }
130
131     /**
132      * Parse arguments allowing either separate $using and $value parameters, or
133      * as an array containing the JSON parameters
134      *
135      * @param string $method method name
136      * @param array  $argv   arguments
137      *
138      * @return array
139      *
140      * @throws \WebDriver\Exception if invalid number of arguments to the called method
141      */
142     private function parseArgs($method, $argv)
143     {
144         $argc = count($argv);
145
146         switch ($argc) {
147             case 2:
148                 $using = $argv[0];
149                 $value = $argv[1];
150                 break;
151
152             case 1:
153                 $arg = $argv[0];
154
155                 if (is_array($arg)) {
156                     $using = $arg['using'];
157                     $value = $arg['value'];
158                     break;
159                 }
160
161                 // fall through
162             default:
163                 throw WebDriverException::factory(
164                     WebDriverException::JSON_PARAMETERS_EXPECTED,
165                     sprintf('Invalid arguments to %s method: %s', $method, print_r($argv, true))
166                 );
167         }
168
169         return $this->locate($using, $value);
170     }
171
172     /**
173      * Return JSON parameter for element / elements command
174      *
175      * @param string $using locator strategy
176      * @param string $value search target
177      *
178      * @return array
179      *
180      * @throws \WebDriver\Exception if invalid locator strategy
181      */
182     public function locate($using, $value)
183     {
184         if (!in_array($using, $this->strategies)) {
185             throw WebDriverException::factory(
186                 WebDriverException::UNKNOWN_LOCATOR_STRATEGY,
187                 sprintf('Invalid locator strategy %s', $using)
188             );
189         }
190
191         return array(
192             'using' => $using,
193             'value' => $value,
194         );
195     }
196
197     /**
198      * Return WebDriver\Element wrapper for $value
199      *
200      * @param mixed $value
201      *
202      * @return \WebDriver\Element|null
203      */
204     protected function webDriverElement($value)
205     {
206         return array_key_exists('ELEMENT', (array) $value)
207             ? new Element(
208                 $this->getElementPath($value['ELEMENT']), // url
209                 $value['ELEMENT'] // id
210             )
211             : null;
212     }
213
214     /**
215      * {@inheritdoc}
216      */
217     public function __call($name, $arguments)
218     {
219         if (count($arguments) === 1 && in_array(str_replace('_', ' ', $name), $this->strategies)) {
220             return $this->locate($name, $arguments[0]);
221         }
222
223         // fallback to executing WebDriver commands
224         return parent::__call($name, $arguments);
225     }
226
227     /**
228      * Get wire protocol URL for an element
229      *
230      * @param string $elementId
231      *
232      * @return string
233      */
234     abstract protected function getElementPath($elementId);
235 }