WebDriverBase.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. // Copyright 2004-present Facebook. All Rights Reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. abstract class WebDriverBase {
  16. public static function throwException($status_code, $message, $results) {
  17. switch ($status_code) {
  18. case 0:
  19. // Success
  20. break;
  21. case 1:
  22. throw new IndexOutOfBoundsWebDriverError($message, $results);
  23. case 2:
  24. throw new NoCollectionWebDriverError($message, $results);
  25. case 3:
  26. throw new NoStringWebDriverError($message, $results);
  27. case 4:
  28. throw new NoStringLengthWebDriverError($message, $results);
  29. case 5:
  30. throw new NoStringWrapperWebDriverError($message, $results);
  31. case 6:
  32. throw new NoSuchDriverWebDriverError($message, $results);
  33. case 7:
  34. throw new NoSuchElementWebDriverError($message, $results);
  35. case 8:
  36. throw new NoSuchFrameWebDriverError($message, $results);
  37. case 9:
  38. throw new UnknownCommandWebDriverError($message, $results);
  39. case 10:
  40. throw new ObsoleteElementWebDriverError($message, $results);
  41. case 11:
  42. throw new ElementNotDisplayedWebDriverError($message, $results);
  43. case 12:
  44. throw new InvalidElementStateWebDriverError($message, $results);
  45. case 13:
  46. throw new UnhandledWebDriverError($message, $results);
  47. case 14:
  48. throw new ExpectedWebDriverError($message, $results);
  49. case 15:
  50. throw new ElementNotSelectableWebDriverError($message, $results);
  51. case 16:
  52. throw new NoSuchDocumentWebDriverError($message, $results);
  53. case 17:
  54. throw new UnexpectedJavascriptWebDriverError($message, $results);
  55. case 18:
  56. throw new NoScriptResultWebDriverError($message, $results);
  57. case 19:
  58. throw new XPathLookupWebDriverError($message, $results);
  59. case 20:
  60. throw new NoSuchCollectionWebDriverError($message, $results);
  61. case 21:
  62. throw new TimeOutWebDriverError($message, $results);
  63. case 22:
  64. throw new NullPointerWebDriverError($message, $results);
  65. case 23:
  66. throw new NoSuchWindowWebDriverError($message, $results);
  67. case 24:
  68. throw new InvalidCookieDomainWebDriverError($message, $results);
  69. case 25:
  70. throw new UnableToSetCookieWebDriverError($message, $results);
  71. case 26:
  72. throw new UnexpectedAlertOpenWebDriverError($message, $results);
  73. case 27:
  74. throw new NoAlertOpenWebDriverError($message, $results);
  75. case 28:
  76. throw new ScriptTimeoutWebDriverError($message, $results);
  77. case 29:
  78. throw new InvalidElementCoordinatesWebDriverError($message, $results);
  79. case 30:
  80. throw new IMENotAvailableWebDriverError($message, $results);
  81. case 31:
  82. throw new IMEEngineActivationFailedWebDriverError($message, $results);
  83. case 32:
  84. throw new InvalidSelectorWebDriverError($message, $results);
  85. }
  86. }
  87. abstract protected function methods();
  88. protected $url;
  89. public function __construct($url = 'http://localhost:4444/wd/hub') {
  90. $this->url = $url;
  91. }
  92. public function __toString() {
  93. return $this->url;
  94. }
  95. public function getURL() {
  96. return $this->url;
  97. }
  98. /**
  99. * Curl request to webdriver server.
  100. *
  101. * $http_method 'GET', 'POST', or 'DELETE'
  102. * $command If not defined in methods() this function will throw.
  103. * $params If an array(), they will be posted as JSON parameters
  104. * If a number or string, "/$params" is appended to url
  105. * $extra_opts key=>value pairs of curl options to pass to curl_setopt()
  106. */
  107. protected function curl(
  108. $http_method,
  109. $command,
  110. $params = null,
  111. $extra_opts = array()) {
  112. if ($params && is_array($params) && $http_method !== 'POST') {
  113. throw new Exception(sprintf(
  114. 'The http method called for %s is %s but it has to be POST' .
  115. ' if you want to pass the JSON params %s',
  116. $command,
  117. $http_method,
  118. json_encode($params)));
  119. }
  120. $url = sprintf('%s%s', $this->url, $command);
  121. if ($params && (is_int($params) || is_string($params))) {
  122. $url .= '/' . $params;
  123. }
  124. $curl = curl_init($url);
  125. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  126. curl_setopt(
  127. $curl,
  128. CURLOPT_HTTPHEADER,
  129. array(
  130. 'Content-Type: application/json;charset=UTF-8',
  131. 'Accept: application/json'));
  132. if ($http_method === 'POST') {
  133. curl_setopt($curl, CURLOPT_POST, true);
  134. if ($params && is_array($params)) {
  135. curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
  136. }
  137. } else if ($http_method == 'DELETE') {
  138. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  139. }
  140. foreach ($extra_opts as $option => $value) {
  141. curl_setopt($curl, $option, $value);
  142. }
  143. $raw_results = trim(WebDriverEnvironment::CurlExec($curl));
  144. $info = curl_getinfo($curl);
  145. if ($error = curl_error($curl)) {
  146. $msg = sprintf(
  147. 'Curl error thrown for http %s to %s',
  148. $http_method,
  149. $url);
  150. if ($params && is_array($params)) {
  151. $msg .= sprintf(' with params: %s', json_encode($params));
  152. }
  153. throw new WebDriverCurlException($msg . "\n\n" . $error);
  154. }
  155. curl_close($curl);
  156. $results = json_decode($raw_results, true);
  157. $value = null;
  158. if (is_array($results) && array_key_exists('value', $results)) {
  159. $value = $results['value'];
  160. }
  161. $message = null;
  162. if (is_array($value) && array_key_exists('message', $value)) {
  163. $message = $value['message'];
  164. }
  165. self::throwException($results['status'], $message, $results);
  166. return array('value' => $value, 'info' => $info);
  167. }
  168. public function __call($name, $arguments) {
  169. if (count($arguments) > 1) {
  170. throw new Exception(
  171. 'Commands should have at most only one parameter,' .
  172. ' which should be the JSON Parameter object');
  173. }
  174. if (preg_match('/^(get|post|delete)/', $name, $matches)) {
  175. $http_method = strtoupper($matches[0]);
  176. $webdriver_command = strtolower(substr($name, strlen($http_method)));
  177. $default_http_method = $this->getHTTPMethod($webdriver_command);
  178. if ($http_method === $default_http_method) {
  179. throw new Exception(sprintf(
  180. '%s is the default http method for %s. Please just call %s().',
  181. $http_method,
  182. $webdriver_command,
  183. $webdriver_command));
  184. }
  185. $methods = $this->methods();
  186. if (!in_array($http_method, $methods[$webdriver_command])) {
  187. throw new Exception(sprintf(
  188. '%s is not an available http method for the command %s.',
  189. $http_method,
  190. $webdriver_command));
  191. }
  192. } else {
  193. $webdriver_command = $name;
  194. $http_method = $this->getHTTPMethod($webdriver_command);
  195. }
  196. $results = $this->curl(
  197. $http_method,
  198. '/' . $webdriver_command,
  199. array_shift($arguments));
  200. return $results['value'];
  201. }
  202. private function getHTTPMethod($webdriver_command) {
  203. if (!array_key_exists($webdriver_command, $this->methods())) {
  204. throw new Exception(sprintf(
  205. '%s is not a valid webdriver command.',
  206. $webdriver_command));
  207. }
  208. $methods = $this->methods();
  209. $http_methods = (array) $methods[$webdriver_command];
  210. return array_shift($http_methods);
  211. }
  212. }