3 * Copyright 2004-2017 Facebook. All Rights Reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @author Justin Bishop <jubishop@gmail.com>
20 * @author Anthon Pang <apang@softwaredevelopment.ca>
21 * @author Fabrizio Branca <mail@fabrizio-branca.de>
26 use WebDriver\Exception as WebDriverException;
29 * Abstract WebDriver\Container class
33 abstract class Container extends AbstractWebDriver
38 public function __construct($url = 'http://localhost:4444/wd/hub')
40 parent::__construct($url);
42 $locatorStrategy = new \ReflectionClass('WebDriver\LocatorStrategy');
43 $this->strategies = $locatorStrategy->getConstants();
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.
51 * @param string $using the locator strategy to use
52 * @param string $value the search target
54 * @return \WebDriver\Element
56 * @throws \WebDriver\Exception if element not found, or invalid XPath
58 public function element($using = null, $value = null)
60 $locatorJson = $this->parseArgs('element', func_get_args());
63 $result = $this->curl(
68 } catch (WebDriverException\NoSuchElement $e) {
69 throw WebDriverException::factory(
70 WebDriverException::NO_SUCH_ELEMENT,
72 "Element not found with %s, %s\n\n%s",
73 $locatorJson['using'],
74 $locatorJson['value'],
81 $element = $this->webDriverElement($result['value']);
83 if ($element === null) {
84 throw WebDriverException::factory(
85 WebDriverException::NO_SUCH_ELEMENT,
87 "Element not found with %s, %s\n",
88 $locatorJson['using'],
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.
102 * @param string $using the locator strategy to use
103 * @param string $value the search target
107 * @throws \WebDriver\Exception if invalid XPath
109 public function elements($using = null, $value = null)
111 $locatorJson = $this->parseArgs('elements', func_get_args());
113 $result = $this->curl(
119 if (!is_array($result['value'])) {
125 array($this, 'webDriverElement'),
132 * Parse arguments allowing either separate $using and $value parameters, or
133 * as an array containing the JSON parameters
135 * @param string $method method name
136 * @param array $argv arguments
140 * @throws \WebDriver\Exception if invalid number of arguments to the called method
142 private function parseArgs($method, $argv)
144 $argc = count($argv);
155 if (is_array($arg)) {
156 $using = $arg['using'];
157 $value = $arg['value'];
163 throw WebDriverException::factory(
164 WebDriverException::JSON_PARAMETERS_EXPECTED,
165 sprintf('Invalid arguments to %s method: %s', $method, print_r($argv, true))
169 return $this->locate($using, $value);
173 * Return JSON parameter for element / elements command
175 * @param string $using locator strategy
176 * @param string $value search target
180 * @throws \WebDriver\Exception if invalid locator strategy
182 public function locate($using, $value)
184 if (!in_array($using, $this->strategies)) {
185 throw WebDriverException::factory(
186 WebDriverException::UNKNOWN_LOCATOR_STRATEGY,
187 sprintf('Invalid locator strategy %s', $using)
198 * Return WebDriver\Element wrapper for $value
200 * @param mixed $value
202 * @return \WebDriver\Element|null
204 protected function webDriverElement($value)
206 return array_key_exists('ELEMENT', (array) $value)
208 $this->getElementPath($value['ELEMENT']), // url
209 $value['ELEMENT'] // id
217 public function __call($name, $arguments)
219 if (count($arguments) === 1 && in_array(str_replace('_', ' ', $name), $this->strategies)) {
220 return $this->locate($name, $arguments[0]);
223 // fallback to executing WebDriver commands
224 return parent::__call($name, $arguments);
228 * Get wire protocol URL for an element
230 * @param string $elementId
234 abstract protected function getElementPath($elementId);