annotate vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 1fec387a4317
children
rev   line source
Chris@14 1 <?php
Chris@14 2 /**
Chris@14 3 * Copyright 2004-2017 Facebook. All Rights Reserved.
Chris@14 4 *
Chris@14 5 * Licensed under the Apache License, Version 2.0 (the "License");
Chris@14 6 * you may not use this file except in compliance with the License.
Chris@14 7 * You may obtain a copy of the License at
Chris@14 8 *
Chris@14 9 * http://www.apache.org/licenses/LICENSE-2.0
Chris@14 10 *
Chris@14 11 * Unless required by applicable law or agreed to in writing, software
Chris@14 12 * distributed under the License is distributed on an "AS IS" BASIS,
Chris@14 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Chris@14 14 * See the License for the specific language governing permissions and
Chris@14 15 * limitations under the License.
Chris@14 16 *
Chris@14 17 * @package WebDriver
Chris@14 18 *
Chris@14 19 * @author Justin Bishop <jubishop@gmail.com>
Chris@14 20 * @author Anthon Pang <apang@softwaredevelopment.ca>
Chris@14 21 * @author Fabrizio Branca <mail@fabrizio-branca.de>
Chris@14 22 * @author Tsz Ming Wong <tszming@gmail.com>
Chris@14 23 */
Chris@14 24
Chris@14 25 namespace WebDriver;
Chris@14 26
Chris@14 27 use WebDriver\Exception as WebDriverException;
Chris@14 28
Chris@14 29 /**
Chris@14 30 * Abstract WebDriver\AbstractWebDriver class
Chris@14 31 *
Chris@14 32 * @package WebDriver
Chris@14 33 */
Chris@14 34 abstract class AbstractWebDriver
Chris@14 35 {
Chris@14 36 /**
Chris@14 37 * URL
Chris@14 38 *
Chris@14 39 * @var string
Chris@14 40 */
Chris@14 41 protected $url;
Chris@14 42
Chris@14 43 /**
Chris@14 44 * Return array of supported method names and corresponding HTTP request methods
Chris@14 45 *
Chris@14 46 * @return array
Chris@14 47 */
Chris@14 48 abstract protected function methods();
Chris@14 49
Chris@14 50 /**
Chris@14 51 * Return array of obsolete method names and corresponding HTTP request methods
Chris@14 52 *
Chris@14 53 * @return array
Chris@14 54 */
Chris@14 55 protected function obsoleteMethods()
Chris@14 56 {
Chris@14 57 return array();
Chris@14 58 }
Chris@14 59
Chris@14 60 /**
Chris@14 61 * Constructor
Chris@14 62 *
Chris@14 63 * @param string $url URL to Selenium server
Chris@14 64 */
Chris@14 65 public function __construct($url = 'http://localhost:4444/wd/hub')
Chris@14 66 {
Chris@14 67 $this->url = $url;
Chris@14 68 }
Chris@14 69
Chris@14 70 /**
Chris@14 71 * Magic method which returns URL to Selenium server
Chris@14 72 *
Chris@14 73 * @return string
Chris@14 74 */
Chris@14 75 public function __toString()
Chris@14 76 {
Chris@14 77 return $this->url;
Chris@14 78 }
Chris@14 79
Chris@14 80 /**
Chris@14 81 * Returns URL to Selenium server
Chris@14 82 *
Chris@14 83 * @return string
Chris@14 84 */
Chris@14 85 public function getURL()
Chris@14 86 {
Chris@14 87 return $this->url;
Chris@14 88 }
Chris@14 89
Chris@14 90 /**
Chris@14 91 * Curl request to webdriver server.
Chris@14 92 *
Chris@14 93 * @param string $requestMethod HTTP request method, e.g., 'GET', 'POST', or 'DELETE'
Chris@14 94 * @param string $command If not defined in methods() this function will throw.
Chris@14 95 * @param array $parameters If an array(), they will be posted as JSON parameters
Chris@14 96 * If a number or string, "/$params" is appended to url
Chris@14 97 * @param array $extraOptions key=>value pairs of curl options to pass to curl_setopt()
Chris@14 98 *
Chris@14 99 * @return array array('value' => ..., 'info' => ...)
Chris@14 100 *
Chris@14 101 * @throws \WebDriver\Exception if error
Chris@14 102 */
Chris@14 103 protected function curl($requestMethod, $command, $parameters = null, $extraOptions = array())
Chris@14 104 {
Chris@14 105 if ($parameters && is_array($parameters) && $requestMethod !== 'POST') {
Chris@14 106 throw WebDriverException::factory(
Chris@14 107 WebDriverException::NO_PARAMETERS_EXPECTED,
Chris@14 108 sprintf(
Chris@14 109 'The http request method called for %s is %s but it has to be POST if you want to pass the JSON parameters %s',
Chris@14 110 $command,
Chris@14 111 $requestMethod,
Chris@14 112 json_encode($parameters)
Chris@14 113 )
Chris@14 114 );
Chris@14 115 }
Chris@14 116
Chris@14 117 $url = sprintf('%s%s', $this->url, $command);
Chris@14 118
Chris@14 119 if ($parameters && (is_int($parameters) || is_string($parameters))) {
Chris@14 120 $url .= '/' . $parameters;
Chris@14 121 }
Chris@14 122
Chris@14 123 list($rawResult, $info) = ServiceFactory::getInstance()->getService('service.curl')->execute($requestMethod, $url, $parameters, $extraOptions);
Chris@14 124
Chris@14 125 $httpCode = $info['http_code'];
Chris@14 126
Chris@14 127 // According to https://w3c.github.io/webdriver/webdriver-spec.html all 4xx responses are to be considered
Chris@14 128 // an error and return plaintext, while 5xx responses are json encoded
Chris@14 129 if ($httpCode >= 400 && $httpCode <= 499) {
Chris@14 130 throw WebDriverException::factory(
Chris@14 131 WebDriverException::CURL_EXEC,
Chris@14 132 'Webdriver http error: ' . $httpCode . ', payload :' . substr($rawResult, 0, 1000)
Chris@14 133 );
Chris@14 134 }
Chris@14 135
Chris@14 136 $result = json_decode($rawResult, true);
Chris@14 137
Chris@14 138 if (!empty($rawResult) && $result === null && json_last_error() != JSON_ERROR_NONE) {
Chris@14 139 throw WebDriverException::factory(
Chris@14 140 WebDriverException::CURL_EXEC,
Chris@14 141 'Payload received from webdriver is not valid json: ' . substr($rawResult, 0, 1000)
Chris@14 142 );
Chris@14 143 }
Chris@14 144
Chris@14 145 if (is_array($result) && !array_key_exists('status', $result)) {
Chris@14 146 throw WebDriverException::factory(
Chris@14 147 WebDriverException::CURL_EXEC,
Chris@14 148 'Payload received from webdriver is valid but unexpected json: ' . substr($rawResult, 0, 1000)
Chris@14 149 );
Chris@14 150 }
Chris@14 151
Chris@14 152 $value = (is_array($result) && array_key_exists('value', $result)) ? $result['value'] : null;
Chris@14 153 $message = (is_array($value) && array_key_exists('message', $value)) ? $value['message'] : null;
Chris@14 154
Chris@14 155 // if not success, throw exception
Chris@14 156 if ((int) $result['status'] !== 0) {
Chris@14 157 throw WebDriverException::factory($result['status'], $message);
Chris@14 158 }
Chris@14 159
Chris@14 160 $sessionId = isset($result['sessionId'])
Chris@14 161 ? $result['sessionId']
Chris@14 162 : (isset($value['webdriver.remote.sessionid'])
Chris@14 163 ? $value['webdriver.remote.sessionid']
Chris@14 164 : null
Chris@14 165 );
Chris@14 166
Chris@14 167 return array(
Chris@14 168 'value' => $value,
Chris@14 169 'info' => $info,
Chris@14 170 'sessionId' => $sessionId,
Chris@14 171 'sessionUrl' => $sessionId ? $this->url . '/session/' . $sessionId : $info['url'],
Chris@14 172 );
Chris@14 173 }
Chris@14 174
Chris@14 175 /**
Chris@14 176 * Magic method that maps calls to class methods to execute WebDriver commands
Chris@14 177 *
Chris@14 178 * @param string $name Method name
Chris@14 179 * @param array $arguments Arguments
Chris@14 180 *
Chris@14 181 * @return mixed
Chris@14 182 *
Chris@14 183 * @throws \WebDriver\Exception if invalid WebDriver command
Chris@14 184 */
Chris@14 185 public function __call($name, $arguments)
Chris@14 186 {
Chris@14 187 if (count($arguments) > 1) {
Chris@14 188 throw WebDriverException::factory(
Chris@14 189 WebDriverException::JSON_PARAMETERS_EXPECTED,
Chris@14 190 'Commands should have at most only one parameter, which should be the JSON Parameter object'
Chris@14 191 );
Chris@14 192 }
Chris@14 193
Chris@14 194 if (preg_match('/^(get|post|delete)/', $name, $matches)) {
Chris@14 195 $requestMethod = strtoupper($matches[0]);
Chris@14 196 $webdriverCommand = strtolower(substr($name, strlen($requestMethod)));
Chris@14 197 } else {
Chris@14 198 $webdriverCommand = $name;
Chris@14 199 $requestMethod = $this->getRequestMethod($webdriverCommand);
Chris@14 200 }
Chris@14 201
Chris@14 202 $methods = $this->methods();
Chris@14 203
Chris@14 204 if (!in_array($requestMethod, (array) $methods[$webdriverCommand])) {
Chris@14 205 throw WebDriverException::factory(
Chris@14 206 WebDriverException::INVALID_REQUEST,
Chris@14 207 sprintf(
Chris@14 208 '%s is not an available http request method for the command %s.',
Chris@14 209 $requestMethod,
Chris@14 210 $webdriverCommand
Chris@14 211 )
Chris@14 212 );
Chris@14 213 }
Chris@14 214
Chris@14 215 $result = $this->curl(
Chris@14 216 $requestMethod,
Chris@14 217 '/' . $webdriverCommand,
Chris@14 218 array_shift($arguments)
Chris@14 219 );
Chris@14 220
Chris@14 221 return $result['value'];
Chris@14 222 }
Chris@14 223
Chris@14 224 /**
Chris@14 225 * Get default HTTP request method for a given WebDriver command
Chris@14 226 *
Chris@14 227 * @param string $webdriverCommand
Chris@14 228 *
Chris@14 229 * @return string
Chris@14 230 *
Chris@14 231 * @throws \WebDriver\Exception if invalid WebDriver command
Chris@14 232 */
Chris@14 233 private function getRequestMethod($webdriverCommand)
Chris@14 234 {
Chris@14 235 if (!array_key_exists($webdriverCommand, $this->methods())) {
Chris@14 236 throw WebDriverException::factory(
Chris@14 237 array_key_exists($webdriverCommand, $this->obsoleteMethods())
Chris@14 238 ? WebDriverException::OBSOLETE_COMMAND : WebDriverException::UNKNOWN_COMMAND,
Chris@14 239 sprintf('%s is not a valid WebDriver command.', $webdriverCommand)
Chris@14 240 );
Chris@14 241 }
Chris@14 242
Chris@14 243 $methods = $this->methods();
Chris@14 244 $requestMethods = (array) $methods[$webdriverCommand];
Chris@14 245
Chris@14 246 return array_shift($requestMethods);
Chris@14 247 }
Chris@14 248 }