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