1
0

Commands.pm 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. package Selenium::Remote::Commands;
  2. use strict;
  3. use warnings;
  4. # ABSTRACT: Implement commands for Selenium::Remote::Driver
  5. =head1 DESCRIPTION
  6. Defines all the HTTP endpoints available to execute on a selenium server.
  7. If you have either a customized Selenium Server, or want new features
  8. you should update the _cmds hash.
  9. =for Pod::Coverage *EVERYTHING*
  10. =cut
  11. use Moo;
  12. has '_cmds' => (
  13. is => 'lazy',
  14. reader => 'get_cmds',
  15. builder => sub {
  16. return {
  17. 'status' => {
  18. 'method' => 'GET',
  19. 'url' => 'status',
  20. 'no_content_success' => 0
  21. },
  22. 'newSession' => {
  23. 'method' => 'POST',
  24. 'url' => 'session',
  25. 'no_content_success' => 0
  26. },
  27. 'getSessions' => {
  28. 'method' => 'GET',
  29. 'url' => 'sessions',
  30. 'no_content_success' => 0
  31. },
  32. 'getCapabilities' => {
  33. 'method' => 'GET',
  34. 'url' => 'session/:sessionId',
  35. 'no_content_success' => 0
  36. },
  37. 'setTimeout' => {
  38. 'method' => 'POST',
  39. 'url' => 'session/:sessionId/timeouts',
  40. 'no_content_success' => 1
  41. },
  42. 'setAsyncScriptTimeout' => {
  43. 'method' => 'POST',
  44. 'url' => 'session/:sessionId/timeouts/async_script',
  45. 'no_content_success' => 1
  46. },
  47. 'setImplicitWaitTimeout' => {
  48. 'method' => 'POST',
  49. 'url' => 'session/:sessionId/timeouts/implicit_wait',
  50. 'no_content_success' => 1
  51. },
  52. 'quit' => {
  53. 'method' => 'DELETE',
  54. 'url' => 'session/:sessionId',
  55. 'no_content_success' => 1
  56. },
  57. 'getCurrentWindowHandle' => {
  58. 'method' => 'GET',
  59. 'url' => 'session/:sessionId/window_handle',
  60. 'no_content_success' => 0
  61. },
  62. 'getWindowHandles' => {
  63. 'method' => 'GET',
  64. 'url' => 'session/:sessionId/window_handles',
  65. 'no_content_success' => 0
  66. },
  67. 'getWindowSize' => {
  68. 'method' => 'GET',
  69. 'url' => 'session/:sessionId/window/:windowHandle/size',
  70. 'no_content_success' => 0
  71. },
  72. 'getWindowPosition' => {
  73. 'method' => 'GET',
  74. 'url' => 'session/:sessionId/window/:windowHandle/position',
  75. 'no_content_success' => 0
  76. },
  77. 'maximizeWindow' => {
  78. 'method' => 'POST',
  79. 'url' => 'session/:sessionId/window/:windowHandle/maximize',
  80. 'no_content_success' => 1
  81. },
  82. 'setWindowSize' => {
  83. 'method' => 'POST',
  84. 'url' => 'session/:sessionId/window/:windowHandle/size',
  85. 'no_content_success' => 1
  86. },
  87. 'setWindowPosition' => {
  88. 'method' => 'POST',
  89. 'url' => 'session/:sessionId/window/:windowHandle/position',
  90. 'no_content_success' => 1
  91. },
  92. 'getCurrentUrl' => {
  93. 'method' => 'GET',
  94. 'url' => 'session/:sessionId/url',
  95. 'no_content_success' => 0
  96. },
  97. 'get' => {
  98. 'method' => 'POST',
  99. 'url' => 'session/:sessionId/url',
  100. 'no_content_success' => 1
  101. },
  102. 'goForward' => {
  103. 'method' => 'POST',
  104. 'url' => 'session/:sessionId/forward',
  105. 'no_content_success' => 1
  106. },
  107. 'goBack' => {
  108. 'method' => 'POST',
  109. 'url' => 'session/:sessionId/back',
  110. 'no_content_success' => 1
  111. },
  112. 'refresh' => {
  113. 'method' => 'POST',
  114. 'url' => 'session/:sessionId/refresh',
  115. 'no_content_success' => 1
  116. },
  117. 'executeScript' => {
  118. 'method' => 'POST',
  119. 'url' => 'session/:sessionId/execute',
  120. 'no_content_success' => 0
  121. },
  122. 'executeAsyncScript' => {
  123. 'method' => 'POST',
  124. 'url' => 'session/:sessionId/execute_async',
  125. 'no_content_success' => 0
  126. },
  127. 'screenshot' => {
  128. 'method' => 'GET',
  129. 'url' => 'session/:sessionId/screenshot',
  130. 'no_content_success' => 0
  131. },
  132. 'availableEngines' => {
  133. 'method' => 'GET',
  134. 'url' => 'session/:sessionId/ime/available_engines',
  135. 'no_content_success' => 0
  136. },
  137. 'switchToFrame' => {
  138. 'method' => 'POST',
  139. 'url' => 'session/:sessionId/frame',
  140. 'no_content_success' => 1
  141. },
  142. 'switchToWindow' => {
  143. 'method' => 'POST',
  144. 'url' => 'session/:sessionId/window',
  145. 'no_content_success' => 1
  146. },
  147. 'getAllCookies' => {
  148. 'method' => 'GET',
  149. 'url' => 'session/:sessionId/cookie',
  150. 'no_content_success' => 0
  151. },
  152. 'addCookie' => {
  153. 'method' => 'POST',
  154. 'url' => 'session/:sessionId/cookie',
  155. 'no_content_success' => 1
  156. },
  157. 'deleteAllCookies' => {
  158. 'method' => 'DELETE',
  159. 'url' => 'session/:sessionId/cookie',
  160. 'no_content_success' => 1
  161. },
  162. 'deleteCookieNamed' => {
  163. 'method' => 'DELETE',
  164. 'url' => 'session/:sessionId/cookie/:name',
  165. 'no_content_success' => 1
  166. },
  167. 'getPageSource' => {
  168. 'method' => 'GET',
  169. 'url' => 'session/:sessionId/source',
  170. 'no_content_success' => 0
  171. },
  172. 'getTitle' => {
  173. 'method' => 'GET',
  174. 'url' => 'session/:sessionId/title',
  175. 'no_content_success' => 0
  176. },
  177. 'findElement' => {
  178. 'method' => 'POST',
  179. 'url' => 'session/:sessionId/element',
  180. 'no_content_success' => 0
  181. },
  182. 'findElements' => {
  183. 'method' => 'POST',
  184. 'url' => 'session/:sessionId/elements',
  185. 'no_content_success' => 0
  186. },
  187. 'getActiveElement' => {
  188. 'method' => 'POST',
  189. 'url' => 'session/:sessionId/element/active',
  190. 'no_content_success' => 0
  191. },
  192. 'describeElement' => {
  193. 'method' => 'GET',
  194. 'url' => 'session/:sessionId/element/:id',
  195. 'no_content_success' => 0
  196. },
  197. 'findChildElement' => {
  198. 'method' => 'POST',
  199. 'url' => 'session/:sessionId/element/:id/element',
  200. 'no_content_success' => 0
  201. },
  202. 'findChildElements' => {
  203. 'method' => 'POST',
  204. 'url' => 'session/:sessionId/element/:id/elements',
  205. 'no_content_success' => 0
  206. },
  207. 'clickElement' => {
  208. 'method' => 'POST',
  209. 'url' => 'session/:sessionId/element/:id/click',
  210. 'no_content_success' => 1
  211. },
  212. 'submitElement' => {
  213. 'method' => 'POST',
  214. 'url' => 'session/:sessionId/element/:id/submit',
  215. 'no_content_success' => 1
  216. },
  217. 'sendKeysToElement' => {
  218. 'method' => 'POST',
  219. 'url' => 'session/:sessionId/element/:id/value',
  220. 'no_content_success' => 1
  221. },
  222. 'sendKeysToActiveElement' => {
  223. 'method' => 'POST',
  224. 'url' => 'session/:sessionId/keys',
  225. 'no_content_success' => 1
  226. },
  227. 'sendModifier' => {
  228. 'method' => 'POST',
  229. 'url' => 'session/:sessionId/modifier',
  230. 'no_content_success' => 1
  231. },
  232. 'isElementSelected' => {
  233. 'method' => 'GET',
  234. 'url' => 'session/:sessionId/element/:id/selected',
  235. 'no_content_success' => 0
  236. },
  237. 'setElementSelected' => {
  238. 'method' => 'POST',
  239. 'url' => 'session/:sessionId/element/:id/selected',
  240. 'no_content_success' => 0
  241. },
  242. 'toggleElement' => {
  243. 'method' => 'POST',
  244. 'url' => 'session/:sessionId/element/:id/toggle',
  245. 'no_content_success' => 0
  246. },
  247. 'isElementEnabled' => {
  248. 'method' => 'GET',
  249. 'url' => 'session/:sessionId/element/:id/enabled',
  250. 'no_content_success' => 0
  251. },
  252. 'getElementLocation' => {
  253. 'method' => 'GET',
  254. 'url' => 'session/:sessionId/element/:id/location',
  255. 'no_content_success' => 0
  256. },
  257. 'getElementLocationInView' => {
  258. 'method' => 'GET',
  259. 'url' => 'session/:sessionId/element/:id/location_in_view',
  260. 'no_content_success' => 0
  261. },
  262. 'getElementTagName' => {
  263. 'method' => 'GET',
  264. 'url' => 'session/:sessionId/element/:id/name',
  265. 'no_content_success' => 0
  266. },
  267. 'clearElement' => {
  268. 'method' => 'POST',
  269. 'url' => 'session/:sessionId/element/:id/clear',
  270. 'no_content_success' => 1
  271. },
  272. 'getElementAttribute' => {
  273. 'method' => 'GET',
  274. 'url' => 'session/:sessionId/element/:id/attribute/:name',
  275. 'no_content_success' => 0
  276. },
  277. 'elementEquals' => {
  278. 'method' => 'GET',
  279. 'url' => 'session/:sessionId/element/:id/equals/:other',
  280. 'no_content_success' => 0
  281. },
  282. 'isElementDisplayed' => {
  283. 'method' => 'GET',
  284. 'url' => 'session/:sessionId/element/:id/displayed',
  285. 'no_content_success' => 0
  286. },
  287. 'close' => {
  288. 'method' => 'DELETE',
  289. 'url' => 'session/:sessionId/window',
  290. 'no_content_success' => 1
  291. },
  292. 'getElementSize' => {
  293. 'method' => 'GET',
  294. 'url' => 'session/:sessionId/element/:id/size',
  295. 'no_content_success' => 0
  296. },
  297. 'getElementText' => {
  298. 'method' => 'GET',
  299. 'url' => 'session/:sessionId/element/:id/text',
  300. 'no_content_success' => 0
  301. },
  302. 'getElementValueOfCssProperty' => {
  303. 'method' => 'GET',
  304. 'url' => 'session/:sessionId/element/:id/css/:propertyName',
  305. 'no_content_success' => 0
  306. },
  307. 'mouseMoveToLocation' => {
  308. 'method' => 'POST',
  309. 'url' => 'session/:sessionId/moveto',
  310. 'no_content_success' => 1
  311. },
  312. 'getAlertText' => {
  313. 'method' => 'GET',
  314. 'url' => 'session/:sessionId/alert_text',
  315. 'no_content_success' => 0
  316. },
  317. 'sendKeysToPrompt' => {
  318. 'method' => 'POST',
  319. 'url' => 'session/:sessionId/alert_text',
  320. 'no_content_success' => 1
  321. },
  322. 'acceptAlert' => {
  323. 'method' => 'POST',
  324. 'url' => 'session/:sessionId/accept_alert',
  325. 'no_content_success' => 1
  326. },
  327. 'dismissAlert' => {
  328. 'method' => 'POST',
  329. 'url' => 'session/:sessionId/dismiss_alert',
  330. 'no_content_success' => 1
  331. },
  332. 'click' => {
  333. 'method' => 'POST',
  334. 'url' => 'session/:sessionId/click',
  335. 'no_content_success' => 1
  336. },
  337. 'doubleClick' => {
  338. 'method' => 'POST',
  339. 'url' => 'session/:sessionId/doubleclick',
  340. 'no_content_success' => 1
  341. },
  342. 'buttonDown' => {
  343. 'method' => 'POST',
  344. 'url' => 'session/:sessionId/buttondown',
  345. 'no_content_success' => 1
  346. },
  347. 'buttonUp' => {
  348. 'method' => 'POST',
  349. 'url' => 'session/:sessionId/buttonup',
  350. 'no_content_success' => 1
  351. },
  352. 'generalAction' => {
  353. 'method' => 'POST',
  354. 'url' => 'session/:sessionId/actions',
  355. 'no_content_success' => 1
  356. },
  357. 'uploadFile' => {
  358. 'method' => 'POST',
  359. 'url' => 'session/:sessionId/file',
  360. 'no_content_success' => 0
  361. },
  362. 'getLocalStorageItem' => {
  363. 'method' => 'GET',
  364. 'url' => '/session/:sessionId/local_storage/key/:key',
  365. 'no_content_success' => 0
  366. },
  367. 'deleteLocalStorageItem' => {
  368. 'method' => 'DELETE',
  369. 'url' => '/session/:sessionId/local_storage/key/:key',
  370. 'no_content_success' => 1
  371. },
  372. 'cacheStatus' => {
  373. 'method' => 'GET',
  374. 'url' => 'session/:sessionId/application_cache/status',
  375. 'no_content_success' => 0
  376. },
  377. 'setGeolocation' => {
  378. 'method' => 'POST',
  379. 'url' => 'session/:sessionId/location',
  380. 'no_content_success' => 1
  381. },
  382. 'getGeolocation' => {
  383. 'method' => 'GET',
  384. 'url' => 'session/:sessionId/location',
  385. 'no_content_success' => 0
  386. },
  387. 'getLog' => {
  388. 'method' => 'POST',
  389. 'url' => 'session/:sessionId/log',
  390. 'no_content_success' => 0
  391. },
  392. 'getLogTypes' => {
  393. 'method' => 'GET',
  394. 'url' => 'session/:sessionId/log/types',
  395. 'no_content_success' => 0
  396. },
  397. 'setOrientation' => {
  398. 'method' => 'POST',
  399. 'url' => 'session/:sessionId/orientation',
  400. 'no_content_success' => 1
  401. },
  402. 'getOrientation' => {
  403. 'method' => 'GET',
  404. 'url' => 'session/:sessionId/orientation',
  405. 'no_content_success' => 0
  406. },
  407. # firefox extension
  408. 'setContext' => {
  409. 'method' => 'POST',
  410. 'url' => 'session/:sessionId/moz/context',
  411. 'no_content_success' => 1
  412. },
  413. 'getContext' => {
  414. 'method' => 'GET',
  415. 'url' => 'session/:sessionId/moz/context',
  416. 'no_content_success' => 0
  417. },
  418. # geckodriver workarounds
  419. 'executeScriptGecko' => {
  420. 'method' => 'POST',
  421. 'url' => 'session/:sessionId/execute/sync',
  422. 'no_content_success' => 0
  423. },
  424. 'executeAsyncScriptGecko' => {
  425. 'method' => 'POST',
  426. 'url' => 'session/:sessionId/execute/async',
  427. 'no_content_success' => 0
  428. },
  429. # /session/:sessionId/local_storage
  430. # /session/:sessionId/local_storage/key/:key
  431. # /session/:sessionId/local_storage/size
  432. # /session/:sessionId/session_storage
  433. # /session/:sessionId/session_storage/key/:key
  434. # /session/:sessionId/session_storage/size
  435. };
  436. }
  437. );
  438. # helper methods to manipulate the _cmds hash
  439. sub get_url {
  440. my ( $self, $command ) = @_;
  441. return $self->get_cmds->{$command}->{url};
  442. }
  443. sub get_method {
  444. my ( $self, $command ) = @_;
  445. return $self->get_cmds->{$command}->{method};
  446. }
  447. sub get_no_content_success {
  448. my ( $self, $command ) = @_;
  449. return $self->get_cmds->{$command}->{no_content_success};
  450. }
  451. # This method will replace the template & return
  452. sub get_params {
  453. my ( $self, $args ) = @_;
  454. if ( !( defined $args->{'session_id'} ) ) {
  455. return;
  456. }
  457. my $data = {};
  458. my $command = $args->{'command'};
  459. my $url = $self->get_url($command);
  460. # Do the var substitutions.
  461. $url =~ s/:sessionId/$args->{'session_id'}/;
  462. $url =~ s/:id/$args->{'id'}/;
  463. $url =~ s/:name/$args->{'name'}/;
  464. $url =~ s/:propertyName/$args->{'property_name'}/;
  465. $url =~ s/:other/$args->{'other'}/;
  466. $url =~ s/:windowHandle/$args->{'window_handle'}/;
  467. $data->{'method'} = $self->get_method($command);
  468. $data->{'no_content_success'} = $self->get_no_content_success($command);
  469. $data->{'url'} = $url;
  470. return $data;
  471. }
  472. 1;
  473. __END__