client-commands.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. var events = require('events');
  2. module.exports = function(client) {
  3. return {
  4. /**
  5. * Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute.
  6. *
  7. * To find out the window handle use `window_handles` protocol action
  8. *
  9. * ```
  10. * this.demoTest = function (browser) {
  11. * browser.window_handles(function(result) {
  12. * var handle = result.value[0];
  13. * browser.switchWindow(handle);
  14. * });
  15. * };
  16. * ```
  17. *
  18. * @method switchWindow
  19. * @param {string} handleOrName The server assigned window handle or the name attribute.
  20. * @param {function} [callback] Optional callback function to be called when the command finishes.
  21. * @see window
  22. * @since v0.3.0
  23. * @api commands
  24. */
  25. switchWindow : function(handleOrName, callback) {
  26. var self = this;
  27. this.window('POST', handleOrName, function(result) {
  28. if (typeof callback === 'function') {
  29. callback.call(self, result);
  30. }
  31. });
  32. return this;
  33. },
  34. /**
  35. * Resizes the current window.
  36. *
  37. * ```
  38. * this.demoTest = function (browser) {
  39. * browser.resizeWindow(1000, 800);
  40. * };
  41. * ```
  42. *
  43. * @method resizeWindow
  44. * @param {number} width The new window width.
  45. * @param {number} height The new window height.
  46. * @param {function} [callback] Optional callback function to be called when the command finishes.
  47. * @see windowSize
  48. * @since v0.3.0
  49. * @api commands
  50. */
  51. resizeWindow : function(width, height, callback) {
  52. var self = this;
  53. return this.windowSize('current', width, height, function(result) {
  54. if (typeof callback === 'function') {
  55. callback.call(self, result);
  56. }
  57. });
  58. },
  59. /**
  60. * Sets the current window position.
  61. *
  62. * ```
  63. * this.demoTest = function (browser) {
  64. * browser.setWindowPosition(0, 0);
  65. * };
  66. * ```
  67. *
  68. * @method setWindowPosition
  69. * @param {number} offsetX The new window offset x-position.
  70. * @param {number} offsetY The new window offset y-position.
  71. * @param {function} [callback] Optional callback function to be called when the command finishes.
  72. * @see windowPosition
  73. * @since v0.8.18
  74. * @api commands
  75. */
  76. setWindowPosition : function(offsetX, offsetY, callback) {
  77. var self = this;
  78. return this.windowPosition('current', offsetX, offsetY, function(result) {
  79. if (typeof callback === 'function') {
  80. callback.call(self, result);
  81. }
  82. });
  83. },
  84. /**
  85. * Maximizes the current window.
  86. *
  87. * ```
  88. * this.demoTest = function (browser) {
  89. * browser.maximizeWindow();
  90. * };
  91. * ```
  92. *
  93. * @method maximizeWindow
  94. * @param {function} [callback] Optional callback function to be called when the command finishes.
  95. * @see windowMaximize
  96. * @since v0.5.13
  97. * @api commands
  98. */
  99. maximizeWindow: function(callback) {
  100. var self = this;
  101. return this.windowMaximize('current', function(result) {
  102. if (typeof callback === 'function') {
  103. callback.call(self, result);
  104. }
  105. });
  106. },
  107. /**
  108. * Take a screenshot of the current page and saves it as the given filename.
  109. *
  110. * ```
  111. * this.demoTest = function (browser) {
  112. * browser.saveScreenshot('/path/to/fileName.png');
  113. * };
  114. * ```
  115. *
  116. * @method saveScreenshot
  117. * @param {string} fileName The complete path to the file name where the screenshot should be saved.
  118. * @param {function} [callback] Optional callback function to be called when the command finishes.
  119. * @see screenshot
  120. * @api commands
  121. */
  122. saveScreenshot : function(fileName, callback) {
  123. var self = this;
  124. return this.screenshot(client.api.options.log_screenshot_data, function(result) {
  125. client.saveScreenshotToFile(fileName, result.value, function(err) {
  126. if (typeof callback === 'function') {
  127. callback.call(self, result, err);
  128. }
  129. });
  130. });
  131. },
  132. /**
  133. * Returns the title of the current page. Uses title protocol command.
  134. *
  135. * ```
  136. * this.demoTest = function (browser) {
  137. * browser.getTitle(function(title) {
  138. * this.assert.equal(typeof title, 'string');
  139. * this.assert.equal(title, 'Nightwatch.js');
  140. * });
  141. * };
  142. * ```
  143. *
  144. * @method getTitle
  145. * @param {function} [callback] Optional callback function to be called when the command finishes.
  146. * @see title
  147. * @returns {string} The page title.
  148. * @api commands
  149. */
  150. getTitle : function(callback) {
  151. var self = this;
  152. return this.title(function(result) {
  153. callback.call(self, result.value);
  154. });
  155. },
  156. /**
  157. * Close the current window. This can be useful when you're working with multiple windows open (e.g. an OAuth login).
  158. * Uses `window` protocol command.
  159. *
  160. * ```
  161. * this.demoTest = function (client) {
  162. * client.closeWindow();
  163. * };
  164. * ```
  165. *
  166. * @method closeWindow
  167. * @param {function} [callback] Optional callback function to be called when the command finishes.
  168. * @see window
  169. * @since v0.3.0
  170. * @api commands
  171. */
  172. closeWindow : function(callback) {
  173. var self = this;
  174. return this.window('DELETE', function(result) {
  175. if (typeof callback === 'function') {
  176. callback.call(self, result);
  177. }
  178. });
  179. },
  180. /**
  181. * This command is an alias to url and also a convenience method when called without any arguments in the sense that it performs a call to .url() with passing the value of `launch_url` field from the settings file.
  182. * Uses `url` protocol command.
  183. *
  184. * ```
  185. * this.demoTest = function (client) {
  186. * client.init();
  187. * };
  188. * ```
  189. *
  190. * @method init
  191. * @param {string} [url] Url to navigate to.
  192. * @see url
  193. * @since v0.4.0
  194. * @api commands
  195. */
  196. init : function(url) {
  197. if (url) {
  198. return this.url(url);
  199. }
  200. if (!this.launchUrl) {
  201. return this;
  202. }
  203. return this.url(this.launchUrl);
  204. },
  205. /**
  206. * Convenience method that adds the specified hash (i.e. url fragment) to the current value of the `launch_url` as set in `nightwatch.json`.
  207. *
  208. * ```
  209. * this.demoTest = function (client) {
  210. * client.urlHash('#hashvalue');
  211. * // or
  212. * client.urlHash('hashvalue');
  213. * };
  214. * ```
  215. *
  216. * @method urlHash
  217. * @param {string} hash The hash to add/replace to the current url (i.e. the value set in the launch_url property in nightwatch.json).
  218. * @see url
  219. * @since v0.4.0
  220. * @api commands
  221. */
  222. urlHash : function(hash) {
  223. if (hash.charAt(0) === '#') {
  224. hash = hash.substring(1);
  225. }
  226. return this.url(this.launchUrl + '#' + hash);
  227. },
  228. /**
  229. * Retrieve all cookies visible to the current page. The cookies are returned as an array of cookie JSON object, as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).
  230. *
  231. * Uses `cookie` protocol command.
  232. *
  233. * ```
  234. * this.demoTest = function(browser) {
  235. * browser.getCookies(function callback(result) {
  236. * this.assert.equal(result.value.length, 1);
  237. * this.assert.equals(result.value[0].name, 'test_cookie');
  238. * });
  239. * }
  240. * ```
  241. *
  242. * @method getCookies
  243. * @param {function} callback The callback function which will receive the response as an argument.
  244. * @api commands
  245. * @since v0.4.0
  246. * @see cookie
  247. * @returns {Array.<object>} A list of cookies.
  248. */
  249. getCookies : function(callback) {
  250. return this.cookie('GET', callback);
  251. },
  252. /**
  253. * Retrieve a single cookie visible to the current page. The cookie is returned as a cookie JSON object, as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).
  254. *
  255. * Uses `cookie` protocol command.
  256. *
  257. * ```
  258. * this.demoTest = function(browser) {
  259. * browser.getCookie(name, function callback(result) {
  260. * this.assert.equal(result.value, '123456');
  261. * this.assert.equals(result.name, 'test_cookie');
  262. * });
  263. * }
  264. * ```
  265. *
  266. * @method getCookie
  267. * @param {string} name The cookie name.
  268. * @param {function} callback The callback function which will receive the response as an argument.
  269. * @api commands
  270. * @since v0.4.0
  271. * @see cookie
  272. * @returns {object|null} The cookie object as a selenium cookie JSON object or null if the cookie wasn't found.
  273. */
  274. getCookie : function(name, callback) {
  275. var self = this;
  276. return this.cookie('GET', function(result) {
  277. if (!result.value || result.value.length === 0) {
  278. callback.call(self, null);
  279. return;
  280. }
  281. var cookie = null;
  282. for (var i = 0; i < result.value.length; i++) {
  283. if (result.value[i].name === name) {
  284. cookie = result.value[i];
  285. break;
  286. }
  287. }
  288. callback.call(self, cookie);
  289. });
  290. },
  291. /**
  292. * Set a cookie, specified as a cookie JSON object, as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).
  293. *
  294. * Uses `cookie` protocol command.
  295. *
  296. * ```
  297. * this.demoTest = function(browser) {
  298. * browser.setCookie({
  299. * name : "test_cookie",
  300. * value : "test_value",
  301. * path : "/", (Optional)
  302. * domain : "example.org", (Optional)
  303. * secure : false, (Optional)
  304. * httpOnly : false, // (Optional)
  305. * expiry : 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC
  306. * });
  307. * }
  308. * ```
  309. *
  310. * @method setCookie
  311. * @param {object} cookie The cookie object.
  312. * @param {function} [callback] Optional callback function to be called when the command finishes.
  313. * @api commands
  314. * @since v0.4.0
  315. * @see cookie
  316. */
  317. setCookie : function(cookie, callback) {
  318. return this.cookie('POST', cookie, callback);
  319. },
  320. /**
  321. * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page.
  322. *
  323. * ```
  324. * this.demoTest = function(browser) {
  325. * browser.deleteCookie("test_cookie", function() {
  326. * // do something more in here
  327. * });
  328. * }
  329. * ```
  330. *
  331. * @method deleteCookie
  332. * @param cookieName The name of the cookie to delete.
  333. * @param {function} [callback] Optional callback function to be called when the command finishes.
  334. * @api commands
  335. * @since v0.4.0
  336. * @see cookie
  337. */
  338. deleteCookie : function(cookieName, callback) {
  339. return this.cookie('DELETE', cookieName, callback);
  340. },
  341. /**
  342. * Delete all cookies visible to the current page.
  343. *
  344. * ```
  345. * this.demoTest = function(browser) {
  346. * browser.deleteCookies(function() {
  347. * // do something more in here
  348. * });
  349. * }
  350. * ```
  351. *
  352. * @method deleteCookies
  353. * @param {function} [callback] Optional callback function to be called when the command finishes.
  354. * @api commands
  355. * @since v0.4.0
  356. * @see cookie
  357. */
  358. deleteCookies : function(callback) {
  359. return this.cookie('DELETE', callback);
  360. },
  361. /**
  362. * Utility command to load an external script into the page specified by url.
  363. *
  364. * ```
  365. * this.demoTest = function(client) {
  366. * this.injectScript('http://example.org/js/utility.js', function() {
  367. * // we're all done here.
  368. * });
  369. * };
  370. * ```
  371. *
  372. * @method injectScript
  373. * @param {string} scriptUrl The script file url
  374. * @param {string} [id] Dom element id to be set on the script tag.
  375. * @param {function} [callback] Optional callback function to be called when the command finishes.
  376. * @api commands
  377. * @since v0.4.0
  378. * @returns {HTMLScriptElement} The newly created script tag.
  379. */
  380. injectScript : function(scriptUrl, id, callback) {
  381. var args = [scriptUrl];
  382. if (arguments.length == 2 && typeof arguments[1] == 'function') {
  383. callback = arguments[1];
  384. } else if (typeof id == 'string') {
  385. args.push(id);
  386. }
  387. return this.execute(function(u,i) {/* jshint browser:true */return (function(d){var e=d.createElement('script');var m=d.getElementsByTagName('head')[0];e.src=u;if(i){e.id=i;}m.appendChild(e);return e;})(document);}, args, callback);
  388. },
  389. /**
  390. * Gets the available log types
  391. *
  392. * ```
  393. * this.demoTest = function(client) {
  394. * this.getLogTypes(function(typesArray) {
  395. *
  396. * });
  397. * };
  398. * ```
  399. *
  400. * @method getLogTypes
  401. * @param {function} [callback] Optional callback function to be called when the command finishes.
  402. * @api commands
  403. * @see logTypes
  404. */
  405. getLogTypes: function(callback) {
  406. var self = this;
  407. return this.sessionLogTypes(function(response) {
  408. if (callback) {
  409. callback.call(self, response.value);
  410. }
  411. });
  412. },
  413. /**
  414. * Gets a log from selenium
  415. *
  416. * ```
  417. * this.demoTest = function(client) {
  418. * this.getLog('browser', function(logEntriesArray) {
  419. * console.log('Log length: ' + logEntriesArray.length);
  420. * logEntriesArray.forEach(function(log) {
  421. * console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);
  422. * });
  423. * });
  424. * };
  425. * ```
  426. *
  427. * @method getLog
  428. * @param {string|function} typeString Log type to request
  429. * @param {function} [callback] Optional callback function to be called when the command finishes.
  430. * @api commands
  431. * @see log
  432. */
  433. getLog: function(typeString, callback) {
  434. var self = this;
  435. if (typeof typeString !== 'string') {
  436. if (typeof typeString === 'function') {
  437. callback = typeString;
  438. }
  439. typeString = 'browser';
  440. }
  441. return this.sessionLog(typeString, function (response) {
  442. if (callback) {
  443. callback.call(self, response.value);
  444. }
  445. });
  446. },
  447. /**
  448. * Utility command to test if the log type is available
  449. *
  450. * ```
  451. * this.demoTest = function(browser) {
  452. * browser.isLogAvailable('browser', function(isAvailable) {
  453. * // do something more in here
  454. * });
  455. * }
  456. * ```
  457. *
  458. * @method isLogAvailable
  459. * @param {string|function} typeString Type of log to test
  460. * @param {function} [callback] Optional callback function to be called when the command finishes.
  461. * @api commands
  462. * @see getLogTypes
  463. */
  464. isLogAvailable: function(typeString, callback) {
  465. var self = this;
  466. if (typeof typeString !== 'string') {
  467. if (typeof typeString === 'function') {
  468. callback = typeString;
  469. }
  470. typeString = 'browser';
  471. }
  472. return this.getLogTypes(function (types) {
  473. var isAvailable;
  474. try {
  475. isAvailable = Array.isArray(types) && types.indexOf(typeString) >= 0;
  476. } catch (err) {
  477. isAvailable = false;
  478. }
  479. if (callback) {
  480. callback.call(self, isAvailable);
  481. }
  482. });
  483. }
  484. };
  485. };