Session.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <?php
  2. /**
  3. * Copyright 2004-2017 Facebook. All Rights Reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. * @package WebDriver
  18. *
  19. * @author Justin Bishop <jubishop@gmail.com>
  20. * @author Anthon Pang <apang@softwaredevelopment.ca>
  21. */
  22. namespace WebDriver;
  23. /**
  24. * WebDriver\Session class
  25. *
  26. * @package WebDriver
  27. *
  28. * @method string window_handle() Retrieve the current window handle.
  29. * @method array window_handles() Retrieve the list of all window handles available to the session.
  30. * @method string url() Retrieve the URL of the current page
  31. * @method void postUrl($jsonUrl) Navigate to a new URL
  32. * @method void forward() Navigates forward in the browser history, if possible.
  33. * @method void back() Navigates backward in the browser history, if possible.
  34. * @method void refresh() Refresh the current page.
  35. * @method mixed execute($jsonScript) Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (synchronous)
  36. * @method mixed execute_async($jsonScript) Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (asynchronous)
  37. * @method string screenshot() Take a screenshot of the current page.
  38. * @method array getCookie() Retrieve all cookies visible to the current page.
  39. * @method array postCookie($jsonCookie) Set a cookie.
  40. * @method string source() Get the current page source.
  41. * @method string title() Get the current page title.
  42. * @method void keys($jsonKeys) Send a sequence of key strokes to the active element.
  43. * @method string getOrientation() Get the current browser orientation.
  44. * @method void postOrientation($jsonOrientation) Set the current browser orientation.
  45. * @method string getAlert_text() Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.
  46. * @method void postAlert_text($jsonText) Sends keystrokes to a JavaScript prompt() dialog.
  47. * @method void accept_alert() Accepts the currently displayed alert dialog.
  48. * @method void dismiss_alert() Dismisses the currently displayed alert dialog.
  49. * @method void moveto($jsonCoordinates) Move the mouse by an offset of the specified element (or current mouse cursor).
  50. * @method void click($jsonButton) Click any mouse button (at the coordinates set by the last moveto command).
  51. * @method void buttondown() Click and hold the left mouse button (at the coordinates set by the last moveto command).
  52. * @method void buttonup() Releases the mouse button previously held (where the mouse is currently at).
  53. * @method void doubleclick() Double-clicks at the current mouse coordinates (set by moveto).
  54. * @method array execute_sql($jsonQuery) Execute SQL.
  55. * @method array getLocation() Get the current geo location.
  56. * @method void postLocation($jsonCoordinates) Set the current geo location.
  57. * @method boolean getBrowser_connection() Is browser online?
  58. * @method void postBrowser_connection($jsonState) Set browser online.
  59. */
  60. final class Session extends Container
  61. {
  62. /**
  63. * @var array
  64. */
  65. private $capabilities = null;
  66. /**
  67. * {@inheritdoc}
  68. */
  69. protected function methods()
  70. {
  71. return array(
  72. 'window_handle' => array('GET'),
  73. 'window_handles' => array('GET'),
  74. 'url' => array('GET', 'POST'), // alternate for POST, use open($url)
  75. 'forward' => array('POST'),
  76. 'back' => array('POST'),
  77. 'refresh' => array('POST'),
  78. 'execute' => array('POST'),
  79. 'execute_async' => array('POST'),
  80. 'screenshot' => array('GET'),
  81. 'cookie' => array('GET', 'POST'), // for DELETE, use deleteAllCookies()
  82. 'source' => array('GET'),
  83. 'title' => array('GET'),
  84. 'keys' => array('POST'),
  85. 'orientation' => array('GET', 'POST'),
  86. 'alert_text' => array('GET', 'POST'),
  87. 'accept_alert' => array('POST'),
  88. 'dismiss_alert' => array('POST'),
  89. 'moveto' => array('POST'),
  90. 'click' => array('POST'),
  91. 'buttondown' => 'POST',
  92. 'buttonup' => array('POST'),
  93. 'doubleclick' => array('POST'),
  94. 'execute_sql' => array('POST'),
  95. 'location' => array('GET', 'POST'),
  96. 'browser_connection' => array('GET', 'POST'),
  97. // specific to Java SeleniumServer
  98. 'file' => array('POST'),
  99. );
  100. }
  101. /**
  102. * {@inheritdoc}
  103. */
  104. protected function obsoleteMethods()
  105. {
  106. return array(
  107. 'modifier' => array('POST'),
  108. 'speed' => array('GET', 'POST'),
  109. 'alert' => array('GET'),
  110. 'visible' => array('GET', 'POST'),
  111. );
  112. }
  113. /**
  114. * Open URL: /session/:sessionId/url (POST)
  115. * An alternative to $session->url($url);
  116. *
  117. * @param string $url
  118. *
  119. * @return \WebDriver\Session
  120. */
  121. public function open($url)
  122. {
  123. $this->curl('POST', '/url', array('url' => $url));
  124. return $this;
  125. }
  126. /**
  127. * Get browser capabilities: /session/:sessionId (GET)
  128. *
  129. * @return mixed
  130. */
  131. public function capabilities()
  132. {
  133. if (! isset($this->capabilities)) {
  134. $result = $this->curl('GET', '');
  135. $this->capabilities = $result['value'];
  136. }
  137. return $this->capabilities;
  138. }
  139. /**
  140. * Close session: /session/:sessionId (DELETE)
  141. *
  142. * @return mixed
  143. */
  144. public function close()
  145. {
  146. $result = $this->curl('DELETE', '');
  147. return $result['value'];
  148. }
  149. // There's a limit to our ability to exploit the dynamic nature of PHP when it
  150. // comes to the cookie methods because GET and DELETE request methods are indistinguishable
  151. // from each other: neither takes parameters.
  152. /**
  153. * Get all cookies: /session/:sessionId/cookie (GET)
  154. * Alternative to: $session->cookie();
  155. *
  156. * Note: get cookie by name not implemented in API
  157. *
  158. * @return mixed
  159. */
  160. public function getAllCookies()
  161. {
  162. $result = $this->curl('GET', '/cookie');
  163. return $result['value'];
  164. }
  165. /**
  166. * Set cookie: /session/:sessionId/cookie (POST)
  167. * Alternative to: $session->cookie($cookie_json);
  168. *
  169. * @param array $cookieJson
  170. *
  171. * @return \WebDriver\Session
  172. */
  173. public function setCookie($cookieJson)
  174. {
  175. $this->curl('POST', '/cookie', array('cookie' => $cookieJson));
  176. return $this;
  177. }
  178. /**
  179. * Delete all cookies: /session/:sessionId/cookie (DELETE)
  180. *
  181. * @return \WebDriver\Session
  182. */
  183. public function deleteAllCookies()
  184. {
  185. $this->curl('DELETE', '/cookie');
  186. return $this;
  187. }
  188. /**
  189. * Delete a cookie: /session/:sessionId/cookie/:name (DELETE)
  190. *
  191. * @param string $cookieName
  192. *
  193. * @return \WebDriver\Session
  194. */
  195. public function deleteCookie($cookieName)
  196. {
  197. $this->curl('DELETE', '/cookie/' . $cookieName);
  198. return $this;
  199. }
  200. /**
  201. * window methods: /session/:sessionId/window (POST, DELETE)
  202. * - $session->window() - close current window
  203. * - $session->window($name) - set focus
  204. * - $session->window($window_handle)->method() - chaining
  205. *
  206. * @return \WebDriver\Window|\WebDriver\Session
  207. */
  208. public function window()
  209. {
  210. // close current window
  211. if (func_num_args() === 0) {
  212. $this->curl('DELETE', '/window');
  213. return $this;
  214. }
  215. // set focus
  216. $arg = func_get_arg(0); // window handle or name attribute
  217. if (is_array($arg)) {
  218. $this->curl('POST', '/window', $arg);
  219. return $this;
  220. }
  221. // chaining
  222. return new Window($this->url . '/window', $arg);
  223. }
  224. /**
  225. * Delete window: /session/:sessionId/window (DELETE)
  226. *
  227. * @return \WebDriver\Session
  228. */
  229. public function deleteWindow()
  230. {
  231. $this->curl('DELETE', '/window');
  232. return $this;
  233. }
  234. /**
  235. * Set focus to window: /session/:sessionId/window (POST)
  236. *
  237. * @param mixed $name window handler or name attribute
  238. *
  239. * @return \WebDriver\Session
  240. */
  241. public function focusWindow($name)
  242. {
  243. $this->curl('POST', '/window', array('name' => $name));
  244. return $this;
  245. }
  246. /**
  247. * frame methods: /session/:sessionId/frame (POST)
  248. * - $session->frame($json) - change focus to another frame on the page
  249. * - $session->frame()->method() - chaining
  250. *
  251. * @return \WebDriver\Session|\WebDriver\Frame
  252. */
  253. public function frame()
  254. {
  255. if (func_num_args() === 1) {
  256. $arg = func_get_arg(0); // json
  257. $this->curl('POST', '/frame', $arg);
  258. return $this;
  259. }
  260. // chaining
  261. return new Frame($this->url . '/frame');
  262. }
  263. /**
  264. * timeouts methods: /session/:sessionId/timeouts (POST)
  265. * - $session->timeouts($json) - set timeout for an operation
  266. * - $session->timeouts()->method() - chaining
  267. *
  268. * @return \WebDriver\Session|\WebDriver\Timeouts
  269. */
  270. public function timeouts()
  271. {
  272. // set timeouts
  273. if (func_num_args() === 1) {
  274. $arg = func_get_arg(0); // json
  275. $this->curl('POST', '/timeouts', $arg);
  276. return $this;
  277. }
  278. if (func_num_args() === 2) {
  279. $arg = array(
  280. 'type' => func_get_arg(0), // 'script' or 'implicit'
  281. 'ms' => func_get_arg(1), // timeout in milliseconds
  282. );
  283. $this->curl('POST', '/timeouts', $arg);
  284. return $this;
  285. }
  286. // chaining
  287. return new Timeouts($this->url . '/timeouts');
  288. }
  289. /**
  290. * ime method chaining, e.g.,
  291. * - $session->ime()->method()
  292. *
  293. * @return \WebDriver\Ime
  294. */
  295. public function ime()
  296. {
  297. return new Ime($this->url . '/ime');
  298. }
  299. /**
  300. * Get active element (i.e., has focus): /session/:sessionId/element/active (POST)
  301. * - $session->activeElement()
  302. *
  303. * @return mixed
  304. */
  305. public function activeElement()
  306. {
  307. $result = $this->curl('POST', '/element/active');
  308. return $this->webDriverElement($result['value']);
  309. }
  310. /**
  311. * touch method chaining, e.g.,
  312. * - $session->touch()->method()
  313. *
  314. * @return \WebDriver\Touch
  315. *
  316. */
  317. public function touch()
  318. {
  319. return new Touch($this->url . '/touch');
  320. }
  321. /**
  322. * local_storage method chaining, e.g.,
  323. * - $session->local_storage()->method()
  324. *
  325. * @return \WebDriver\Storage
  326. */
  327. public function local_storage()
  328. {
  329. return Storage::factory('local', $this->url . '/local_storage');
  330. }
  331. /**
  332. * session_storage method chaining, e.g.,
  333. * - $session->session_storage()->method()
  334. *
  335. * @return \WebDriver\Storage
  336. */
  337. public function session_storage()
  338. {
  339. return Storage::factory('session', $this->url . '/session_storage');
  340. }
  341. /**
  342. * application cache chaining, e.g.,
  343. * - $session->application_cache()->status()
  344. *
  345. * @return \WebDriver\ApplicationCache
  346. */
  347. public function application_cache()
  348. {
  349. return new ApplicationCache($this->url . '/application_cache');
  350. }
  351. /**
  352. * log methods: /session/:sessionId/log (POST)
  353. * - $session->log($type) - get log for given log type
  354. * - $session->log()->method() - chaining
  355. *
  356. * @return mixed
  357. */
  358. public function log()
  359. {
  360. // get log for given log type
  361. if (func_num_args() === 1) {
  362. $arg = func_get_arg(0);
  363. if (is_string($arg)) {
  364. $arg = array(
  365. 'type' => $arg,
  366. );
  367. }
  368. $result = $this->curl('POST', '/log', $arg);
  369. return $result['value'];
  370. }
  371. // chaining
  372. return new Log($this->url . '/log');
  373. }
  374. /**
  375. * {@inheritdoc}
  376. */
  377. protected function getElementPath($elementId)
  378. {
  379. return sprintf('%s/element/%s', $this->url, $elementId);
  380. }
  381. }