WebDriverCurlService.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <?php
  2. namespace Drupal\FunctionalJavascriptTests;
  3. use WebDriver\Service\CurlService;
  4. use WebDriver\Exception\CurlExec;
  5. use WebDriver\Exception as WebDriverException;
  6. /**
  7. * Provides a curl service to interact with Selenium driver.
  8. *
  9. * Extends WebDriver\Service\CurlService to solve problem with race conditions,
  10. * when multiple processes requests.
  11. */
  12. class WebDriverCurlService extends CurlService {
  13. /**
  14. * {@inheritdoc}
  15. */
  16. public function execute($requestMethod, $url, $parameters = NULL, $extraOptions = []) {
  17. $extraOptions += [
  18. CURLOPT_FAILONERROR => TRUE,
  19. ];
  20. $retries = 0;
  21. while ($retries < 10) {
  22. try {
  23. $customHeaders = [
  24. 'Content-Type: application/json;charset=UTF-8',
  25. 'Accept: application/json;charset=UTF-8',
  26. ];
  27. $curl = curl_init($url);
  28. curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  29. switch ($requestMethod) {
  30. case 'GET':
  31. break;
  32. case 'POST':
  33. if ($parameters && is_array($parameters)) {
  34. curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($parameters));
  35. }
  36. else {
  37. $customHeaders[] = 'Content-Length: 0';
  38. }
  39. // Suppress "Expect: 100-continue" header automatically added by
  40. // cURL that causes a 1 second delay if the remote server does not
  41. // support Expect.
  42. $customHeaders[] = 'Expect:';
  43. curl_setopt($curl, CURLOPT_POST, TRUE);
  44. break;
  45. case 'DELETE':
  46. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  47. break;
  48. case 'PUT':
  49. if ($parameters && is_array($parameters)) {
  50. curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($parameters));
  51. }
  52. else {
  53. $customHeaders[] = 'Content-Length: 0';
  54. }
  55. // Suppress "Expect: 100-continue" header automatically added by
  56. // cURL that causes a 1 second delay if the remote server does not
  57. // support Expect.
  58. $customHeaders[] = 'Expect:';
  59. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
  60. break;
  61. }
  62. foreach ($extraOptions as $option => $value) {
  63. curl_setopt($curl, $option, $value);
  64. }
  65. curl_setopt($curl, CURLOPT_HTTPHEADER, $customHeaders);
  66. $rawResult = trim(curl_exec($curl));
  67. $info = curl_getinfo($curl);
  68. $info['request_method'] = $requestMethod;
  69. if (array_key_exists(CURLOPT_FAILONERROR, $extraOptions) && $extraOptions[CURLOPT_FAILONERROR] && CURLE_GOT_NOTHING !== ($errno = curl_errno($curl)) && $error = curl_error($curl)) {
  70. curl_close($curl);
  71. throw WebDriverException::factory(WebDriverException::CURL_EXEC, sprintf("Curl error thrown for http %s to %s%s\n\n%s", $requestMethod, $url, $parameters && is_array($parameters) ? ' with params: ' . json_encode($parameters) : '', $error));
  72. }
  73. curl_close($curl);
  74. $result = json_decode($rawResult, TRUE);
  75. if (isset($result['status']) && $result['status'] === WebDriverException::STALE_ELEMENT_REFERENCE) {
  76. usleep(100000);
  77. $retries++;
  78. continue;
  79. }
  80. return [$rawResult, $info];
  81. }
  82. catch (CurlExec $exception) {
  83. $retries++;
  84. }
  85. }
  86. throw WebDriverException::factory(WebDriverException::CURL_EXEC, sprintf("Curl error thrown for http %s to %s%s\n\n%s", $requestMethod, $url, $parameters && is_array($parameters) ? ' with params: ' . json_encode($parameters) : '', $error));
  87. }
  88. }