annotate vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php @ 0:c75dbcec494b

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