@@ -137,6 +137,29 @@ class HttpCommandExecutor implements WebDriverCommandExecutor
137137 DriverCommand::TOUCH_SCROLL  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/touch/scroll ' ],
138138 DriverCommand::TOUCH_UP  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/touch/up ' ],
139139 ];
140+  /** 
141+  * @var array Will be merged with $commands 
142+  */ 
143+  protected  static  $ w3cCompliantCommands
144+  DriverCommand::ACCEPT_ALERT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/alert/accept ' ],
145+  DriverCommand::ACTIONS  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/actions ' ],
146+  DriverCommand::DISMISS_ALERT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/alert/dismiss ' ],
147+  DriverCommand::EXECUTE_SCRIPT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/execute/sync ' ],
148+  DriverCommand::EXECUTE_ASYNC_SCRIPT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/execute/async ' ],
149+  DriverCommand::GET_CURRENT_WINDOW_HANDLE  => ['method '  => 'GET ' , 'url '  => '/session/:sessionId/window ' ],
150+  DriverCommand::GET_ELEMENT_LOCATION  => ['method '  => 'GET ' , 'url '  => '/session/:sessionId/element/:id/rect ' ],
151+  DriverCommand::GET_ELEMENT_PROPERTY  => [
152+  'method '  => 'GET ' ,
153+  'url '  => '/session/:sessionId/element/:id/property/:name ' ,
154+  ],
155+  DriverCommand::GET_ELEMENT_SIZE  => ['method '  => 'GET ' , 'url '  => '/session/:sessionId/element/:id/rect ' ],
156+  DriverCommand::GET_WINDOW_HANDLES  => ['method '  => 'GET ' , 'url '  => '/session/:sessionId/window/handles ' ],
157+  DriverCommand::GET_ALERT_TEXT  => ['method '  => 'GET ' , 'url '  => '/session/:sessionId/alert/text ' ],
158+  DriverCommand::IMPLICITLY_WAIT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/timeouts ' ],
159+  DriverCommand::SET_ALERT_VALUE  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/alert/text ' ],
160+  DriverCommand::SET_SCRIPT_TIMEOUT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/timeouts ' ],
161+  DriverCommand::SET_TIMEOUT  => ['method '  => 'POST ' , 'url '  => '/session/:sessionId/timeouts ' ],
162+  ];
140163 /** 
141164 * @var string 
142165 */ 
@@ -145,6 +168,10 @@ class HttpCommandExecutor implements WebDriverCommandExecutor
145168 * @var resource 
146169 */ 
147170 protected  $ curl
171+  /** 
172+  * @var bool 
173+  */ 
174+  protected  $ isW3cComplianttrue ;
148175
149176 /** 
150177 * @param string $url 
@@ -153,6 +180,8 @@ class HttpCommandExecutor implements WebDriverCommandExecutor
153180 */ 
154181 public  function  __construct ($ url$ http_proxynull , $ http_proxy_portnull )
155182 {
183+  self ::$ w3cCompliantCommandsarray_merge (self ::$ commandsself ::$ w3cCompliantCommands
184+ 
156185 $ this url  = $ url
157186 $ this curl  = curl_init ();
158187
@@ -179,6 +208,11 @@ public function __construct($url, $http_proxy = null, $http_proxy_port = null)
179208 $ this setConnectionTimeout (30000 );
180209 }
181210
211+  public  function  disableW3cCompliance ()
212+  {
213+  $ this isW3cCompliant  = false ;
214+  }
215+ 
182216 /** 
183217 * Set timeout for the connect phase 
184218 * 
@@ -226,11 +260,19 @@ public function setRequestTimeout($timeout_in_ms)
226260 */ 
227261 public  function  execute (WebDriverCommand $ command
228262 {
229-  if  (!isset (self ::$ commands$ commandgetName ()])) {
230-  throw  new  InvalidArgumentException ($ commandgetName () . ' is not a valid command. ' );
263+  $ commandName$ commandgetName ();
264+  if  (!isset (self ::$ commands$ commandName
265+  if  ($ this isW3cCompliant  && !isset (self ::$ w3cCompliantCommands$ commandName
266+  throw  new  InvalidArgumentException ($ commandgetName () . ' is not a valid command. ' );
267+  }
268+  }
269+ 
270+  if  ($ this isW3cCompliant ) {
271+  $ rawself ::$ w3cCompliantCommands$ commandgetName ()];
272+  } else  {
273+  $ rawself ::$ commands$ commandgetName ()];
231274 }
232275
233-  $ rawself ::$ commands$ commandgetName ()];
234276 $ http_method$ raw'method ' ];
235277 $ url$ raw'url ' ];
236278 $ urlstr_replace (':sessionId ' , $ commandgetSessionID (), $ url
@@ -271,8 +313,13 @@ public function execute(WebDriverCommand $command)
271313
272314 $ encoded_paramsnull ;
273315
274-  if  ($ http_method'POST '  && $ paramsis_array ($ params
275-  $ encoded_paramsjson_encode ($ params
316+  if  ($ http_method'POST ' ) {
317+  if  ($ paramsis_array ($ params
318+  $ encoded_paramsjson_encode ($ params
319+  } elseif  ($ this isW3cCompliant ) {
320+  // POST body must be valid JSON in W3C, even if empty: https://www.w3.org/TR/webdriver/#processing-model 
321+  $ encoded_params'{} ' ;
322+  }
276323 }
277324
278325 curl_setopt ($ this curl , CURLOPT_POSTFIELDS , $ encoded_params
@@ -317,12 +364,23 @@ public function execute(WebDriverCommand $command)
317364 }
318365
319366 $ sessionIdnull ;
320-  if  (is_array ($ resultsarray_key_exists ('sessionId ' , $ results
367+  if  (is_array ($ valuearray_key_exists ('sessionId ' , $ value
368+  // W3C's WebDriver 
369+  $ sessionId$ value'sessionId ' ];
370+  } elseif  (is_array ($ resultsarray_key_exists ('sessionId ' , $ results
371+  // Legacy JsonWire 
321372 $ sessionId$ results'sessionId ' ];
322373 }
323374
375+  // @see https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors 
376+  if  (isset ($ value'error ' ])) {
377+  // W3C's WebDriver 
378+  WebDriverException::throwException ($ value'error ' ], $ message$ results
379+  }
380+ 
324381 $ statusisset ($ results'status ' ]) ? $ results'status ' ] : 0 ;
325-  if  ($ status0 ) {
382+  if  ($ status0 ) {
383+  // Legacy JsonWire 
326384 WebDriverException::throwException ($ status$ message$ results
327385 }
328386
0 commit comments