API Docs for: 0.0.6
Show:

File: lib/commands/element.js

  1. /*!
  2. *
  3. * Copyright (c) 2013 Sebastian Golasch
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. * DEALINGS IN THE SOFTWARE.
  22. *
  23. */
  24.  
  25. 'use strict';
  26.  
  27. // ext. libs
  28. var Q = require('q');
  29.  
  30. /**
  31. * Element related methods
  32. *
  33. * @module Driver
  34. * @class Element
  35. * @namespace Dalek.DriverNative.Commands
  36. */
  37.  
  38. var Element = {
  39.  
  40. /**
  41. * Checks if an element exists
  42. *
  43. * @method exists
  44. * @param {string} selector Selector expression to find the element
  45. * @param {string} hash Unique hash of that fn call
  46. * @chainable
  47. */
  48.  
  49. exists: function (selector, hash) {
  50. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  51. this.actionQueue.push(this._existsCb.bind(this, selector, hash));
  52. return this;
  53. },
  54.  
  55. /**
  56. * Sends out an event with the results of the `exists` call
  57. *
  58. * @method _existsCb
  59. * @param {string} selector Selector expression to find the element
  60. * @param {string} hash Unique hash of that fn call
  61. * @param {string} result Serialized JSON with the reuslts of the exists call
  62. * @return {object} promise Exists promise
  63. * @private
  64. */
  65.  
  66. _existsCb: function (selector, hash, result) {
  67. var deferred = Q.defer();
  68. this.events.emit('driver:message', {key: 'exists', selector: selector, hash: hash, value: (JSON.parse(result).value === -1 || JSON.parse(result).status === 7 ? 'false' : 'true')});
  69. deferred.resolve();
  70. return deferred.promise;
  71. },
  72.  
  73. /**
  74. * Checks if an element is visible
  75. *
  76. * @method visible
  77. * @param {string} selector Selector expression to find the element
  78. * @param {string} hash Unique hash of that fn call
  79. * @chainable
  80. */
  81.  
  82. visible: function (selector, hash) {
  83. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  84. this.actionQueue.push(this.webdriverClient.displayed.bind(this.webdriverClient, selector));
  85. this.actionQueue.push(this._visibleCb.bind(this, selector, hash));
  86. return this;
  87. },
  88.  
  89. /**
  90. * Sends out an event with the results of the `visible` call
  91. *
  92. * @method _visibleCb
  93. * @param {string} selector Selector expression to find the element
  94. * @param {string} hash Unique hash of that fn call
  95. * @param {string} result Serialized JSON with the reuslts of the visible call
  96. * @return {object} promise Visible promise
  97. * @private
  98. */
  99.  
  100. _visibleCb: function (selector, hash, result) {
  101. var deferred = Q.defer();
  102. this.events.emit('driver:message', {key: 'visible', selector: selector, hash: hash, value: JSON.parse(result).value});
  103. deferred.resolve();
  104. return deferred.promise;
  105. },
  106.  
  107. /**
  108. * Checks if an element has the expected text
  109. *
  110. * @method text
  111. * @param {string} selector Selector expression to find the element
  112. * @param {string} expected The expected text content
  113. * @param {string} hash Unique hash of that fn call
  114. * @chainable
  115. */
  116.  
  117. text: function (selector, expected, hash) {
  118. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  119. this.actionQueue.push(this.webdriverClient.text.bind(this.webdriverClient, selector));
  120. this.actionQueue.push(this._textCb.bind(this, selector, hash, expected));
  121. return this;
  122. },
  123.  
  124. /**
  125. * Sends out an event with the results of the `text` call
  126. *
  127. * @method _textCb
  128. * @param {string} selector Selector expression to find the element
  129. * @param {string} hash Unique hash of that fn call
  130. * @param {string} expected The expected text content
  131. * @param {string} result Serialized JSON with the reuslts of the text call
  132. * @return {object} Promise
  133. * @private
  134. */
  135.  
  136. _textCb: function (selector, hash, expected, result) {
  137. var deferred = Q.defer();
  138. this.events.emit('driver:message', {key: 'text', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value});
  139. deferred.resolve();
  140. return deferred.promise;
  141. },
  142.  
  143. /**
  144. * Checks if an element has the expected css property/value pairs
  145. *
  146. * @method css
  147. * @param {string} selector Selector expression to find the element
  148. * @param {string} property The css property to check
  149. * @param {string} expected The expected css value
  150. * @param {string} hash Unique hash of that fn call
  151. * @chainable
  152. */
  153.  
  154. css: function (selector, property, expected, hash) {
  155. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  156. this.actionQueue.push(this.webdriverClient.cssProperty.bind(this.webdriverClient, property));
  157. this.actionQueue.push(this._cssCb.bind(this, selector, property, hash, expected));
  158. return this;
  159. },
  160.  
  161. /**
  162. * Sends out an event with the results of the `css` call
  163. *
  164. * @method _cssCb
  165. * @param {string} selector Selector expression to find the element
  166. * @param {string} property The css property to check
  167. * @param {string} expected The expected css value
  168. * @param {string} hash Unique hash of that fn call
  169. * @param {string} result Serialized JSON with the reuslts of the text call
  170. * @return {object} Promise
  171. * @private
  172. */
  173. _cssCb: function (selector, property, hash, expected, result) {
  174. var deferred = Q.defer();
  175. this.events.emit('driver:message', {key: 'css', hash: hash, property: property, expected: expected, selector: selector, value: JSON.parse(result).value});
  176. deferred.resolve();
  177. return deferred.promise;
  178. },
  179.  
  180. /**
  181. * Checks th width of an element
  182. *
  183. * @method width
  184. * @param {string} selector Selector expression to find the element
  185. * @param {string} expected The expected width value
  186. * @param {string} hash Unique hash of that fn call
  187. * @chainable
  188. */
  189.  
  190. width: function (selector, expected, hash) {
  191. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  192. this.actionQueue.push(this.webdriverClient.size.bind(this.webdriverClient));
  193. this.actionQueue.push(this._widthCb.bind(this, selector, hash, expected));
  194. return this;
  195. },
  196.  
  197. /**
  198. * Sends out an event with the results of the `width` call
  199. *
  200. * @method _widthCb
  201. * @param {string} selector Selector expression to find the element
  202. * @param {string} expected The expected width value
  203. * @param {string} hash Unique hash of that fn call
  204. * @param {string} result Serialized JSON with the reuslts of the text call
  205. * @return {object} Promise
  206. * @private
  207. */
  208.  
  209. _widthCb: function (selector, hash, expected, result) {
  210. var deferred = Q.defer();
  211. this.events.emit('driver:message', {key: 'width', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value.width});
  212. deferred.resolve();
  213. return deferred.promise;
  214. },
  215.  
  216. /**
  217. * Checks th height of an element
  218. *
  219. * @method height
  220. * @param {string} selector Selector expression to find the element
  221. * @param {string} expected The expected height value
  222. * @param {string} hash Unique hash of that fn call
  223. * @chainable
  224. */
  225.  
  226. height: function (selector, expected, hash) {
  227. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  228. this.actionQueue.push(this.webdriverClient.size.bind(this.webdriverClient));
  229. this.actionQueue.push(this._heightCb.bind(this, selector, hash, expected));
  230. return this;
  231. },
  232.  
  233. /**
  234. * Sends out an event with the results of the `height` call
  235. *
  236. * @method _heightCb
  237. * @param {string} selector Selector expression to find the element
  238. * @param {string} expected The expected height value
  239. * @param {string} hash Unique hash of that fn call
  240. * @param {string} result Serialized JSON with the reuslts of the text call
  241. * @return {object} Promise
  242. * @private
  243. */
  244.  
  245. _heightCb: function (selector, hash, expected, result) {
  246. var deferred = Q.defer();
  247. this.events.emit('driver:message', {key: 'height', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value.height});
  248. deferred.resolve();
  249. return deferred.promise;
  250. },
  251.  
  252. /**
  253. * Checks if an element has an attribute with the expected value
  254. *
  255. * @method attribute
  256. * @param {string} selector Selector expression to find the element
  257. * @param {string} attribute The attribute that should be checked
  258. * @param {string} expected The expected text content
  259. * @param {string} hash Unique hash of that fn call
  260. * @chainable
  261. */
  262.  
  263. attribute: function (selector, attribute, expected, hash) {
  264. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  265. this.actionQueue.push(this.webdriverClient.getAttribute.bind(this.webdriverClient, attribute));
  266. this.actionQueue.push(this._attributeCb.bind(this, selector, hash, attribute, expected));
  267. return this;
  268. },
  269.  
  270. /**
  271. * Sends out an event with the results of the `attribute` call
  272. *
  273. * @method _attributeCb
  274. * @param {string} selector Selector expression to find the element
  275. * @param {string} hash Unique hash of that fn call
  276. * @param {string} attribute The attribute that should be checked
  277. * @param {string} expected The expected attribute content
  278. * @param {string} result Serialized JSON with the results of the attribute call
  279. * @return {object} promise Attribute promise
  280. * @private
  281. */
  282.  
  283. _attributeCb: function (selector, hash, attribute, expected, result) {
  284. var deferred = Q.defer();
  285. this.events.emit('driver:message', {key: 'attribute', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value });
  286. deferred.resolve();
  287. return deferred.promise;
  288. },
  289.  
  290. /**
  291. * Checks if an element has the expected value
  292. *
  293. * @method val
  294. * @param {string} selector Selector expression to find the element
  295. * @param {string} expected The expected content
  296. * @param {string} hash Unique hash of that fn call
  297. * @chainable
  298. */
  299.  
  300. val: function (selector, expected, hash) {
  301. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  302. this.actionQueue.push(this.webdriverClient.getAttribute.bind(this.webdriverClient, 'value'));
  303. this.actionQueue.push(this._valCb.bind(this, selector, hash, expected));
  304. return this;
  305. },
  306.  
  307. /**
  308. * Sends out an event with the results of the `val` call
  309. *
  310. * @method _valCb
  311. * @param {string} selector Selector expression to find the element
  312. * @param {string} hash Unique hash of that fn call
  313. * @param {string} expected The expected content
  314. * @param {string} result Serialized JSON with the results of the val call
  315. * @return {object} Promise
  316. * @private
  317. */
  318.  
  319. _valCb: function (selector, hash, expected, result) {
  320. var deferred = Q.defer();
  321. this.events.emit('driver:message', {key: 'val', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value });
  322. deferred.resolve();
  323. return deferred.promise;
  324. },
  325.  
  326. /**
  327. * Checks if an element is selected
  328. *
  329. * @method selected
  330. * @param {string} selector Selector expression to find the element
  331. * @param {string} expected The expected content
  332. * @param {string} hash Unique hash of that fn call
  333. * @chainable
  334. */
  335.  
  336. selected: function (selector, expected, hash) {
  337. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  338. this.actionQueue.push(this.webdriverClient.selected.bind(this.webdriverClient));
  339. this.actionQueue.push(this._selectedCb.bind(this, selector, hash, expected));
  340. return this;
  341. },
  342.  
  343. /**
  344. * Sends out an event with the results of the `selected` call
  345. *
  346. * @method _selectedCb
  347. * @param {string} selector Selector expression to find the element
  348. * @param {string} hash Unique hash of that fn call
  349. * @param {string} expected The expected content
  350. * @param {string} result Serialized JSON with the results of the selected call
  351. * @return {object} Promise
  352. * @private
  353. */
  354.  
  355. _selectedCb: function (selector, hash, expected, result) {
  356. var deferred = Q.defer();
  357. this.events.emit('driver:message', {key: 'selected', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value });
  358. deferred.resolve();
  359. return deferred.promise;
  360. },
  361.  
  362. /**
  363. * Checks if an element is enabled
  364. *
  365. * @method enabled
  366. * @param {string} selector Selector expression to find the element
  367. * @param {string} expected The expected content
  368. * @param {string} hash Unique hash of that fn call
  369. * @chainable
  370. */
  371.  
  372. enabled: function (selector, expected, hash) {
  373. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  374. this.actionQueue.push(this.webdriverClient.enabled.bind(this.webdriverClient));
  375. this.actionQueue.push(this._enabledCb.bind(this, selector, hash, expected));
  376. return this;
  377. },
  378.  
  379. /**
  380. * Sends out an event with the results of the `enabled` call
  381. *
  382. * @method _enabledCb
  383. * @param {string} selector Selector expression to find the element
  384. * @param {string} hash Unique hash of that fn call
  385. * @param {string} expected The expected content
  386. * @param {string} result Serialized JSON with the results of the selected call
  387. * @return {object} Promise
  388. * @private
  389. */
  390.  
  391. _enabledCb: function (selector, hash, expected, result) {
  392. var deferred = Q.defer();
  393. this.events.emit('driver:message', {key: 'enabled', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value });
  394. deferred.resolve();
  395. return deferred.promise;
  396. },
  397.  
  398. /**
  399. * Submits a form
  400. *
  401. * @method submit
  402. * @param {string} selector Selector expression to find the element
  403. * @param {string} hash Unique hash of that fn call
  404. * @param {string} uuid Unique hash of that fn call
  405. * @chainable
  406. */
  407.  
  408. submit: function (selector, hash, uuid) {
  409. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  410. this.actionQueue.push(this.webdriverClient.submit.bind(this.webdriverClient));
  411. this.actionQueue.push(this._submitCb.bind(this, selector, hash, uuid));
  412. return this;
  413. },
  414.  
  415. /**
  416. * Sends out an event with the results of the `submit` call
  417. *
  418. * @method _submitCb
  419. * @param {string} selector Selector expression to find the element
  420. * @param {string} hash Unique hash of that fn call
  421. * @param {string} uuid Unique hash of that fn call
  422. * @return {object} promise Click promise
  423. * @private
  424. */
  425.  
  426. _submitCb: function (selector, hash, uuid) {
  427. var deferred = Q.defer();
  428. this.events.emit('driver:message', {key: 'submit', value: selector, uuid: uuid, hash: hash});
  429. deferred.resolve();
  430. return deferred.promise;
  431. },
  432.  
  433. /**
  434. * Clicks an element
  435. *
  436. * @method click
  437. * @param {string} selector Selector expression to find the element
  438. * @param {string} hash Unique hash of that fn call
  439. * @param {string} uuid Unique hash of that fn call
  440. * @chainable
  441. */
  442.  
  443. click: function (selector, hash, uuid) {
  444. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  445. this.actionQueue.push(this.webdriverClient.click.bind(this.webdriverClient));
  446. this.actionQueue.push(this._clickCb.bind(this, selector, hash, uuid));
  447. return this;
  448. },
  449.  
  450. /**
  451. * Sends out an event with the results of the `click` call
  452. *
  453. * @method _clickCb
  454. * @param {string} selector Selector expression to find the element
  455. * @param {string} hash Unique hash of that fn call
  456. * @param {string} uuid Unique hash of that fn call
  457. * @return {object} promise Click promise
  458. * @private
  459. */
  460.  
  461. _clickCb: function (selector, hash, uuid) {
  462. var deferred = Q.defer();
  463. this.events.emit('driver:message', {key: 'click', value: selector, uuid: uuid, hash: hash});
  464. deferred.resolve();
  465. return deferred.promise;
  466. },
  467.  
  468. /**
  469. * Scrolls from an element to a location defined in pixels
  470. *
  471. * @method scroll
  472. * @param {string} selector Selector expression to find the element
  473. * @param {object} options X offset, Y offset, Speed
  474. * @param {string} hash Unique hash of that fn call
  475. * @param {string} uuid Unique hash of that fn call
  476. * @chainable
  477. */
  478.  
  479. scroll: function (selector, options, hash, uuid) {
  480. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector, options));
  481. this.actionQueue.push(this.webdriverClient.scroll.bind(this.webdriverClient));
  482. this.actionQueue.push(this._clickCb.bind(this, selector, options, hash, uuid));
  483. return this;
  484. },
  485.  
  486. /**
  487. * Sends out an event with the results of the `scroll` call
  488. *
  489. * @method _scrollCb
  490. * @param {string} selector Selector expression to find the element
  491. * @param {object} options X offset, Y offset, Speed
  492. * @param {string} hash Unique hash of that fn call
  493. * @param {string} uuid Unique hash of that fn call
  494. * @return {object} promise Scroll promise
  495. * @private
  496. */
  497.  
  498. _scrollCb: function (selector, options, hash, uuid) {
  499. var deferred = Q.defer();
  500. this.events.emit('driver:message', {key: 'scroll', value: selector, uuid: uuid, hash: hash});
  501. deferred.resolve();
  502. return deferred.promise;
  503. },
  504.  
  505. /**
  506. * Clicks an element
  507. *
  508. * @method click
  509. * @param {string} selector Selector expression to find the element
  510. * @param {string} hash Unique hash of that fn call
  511. * @chainable
  512. */
  513.  
  514. type: function (selector, keystrokes, hash) {
  515. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  516. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  517. this.actionQueue.push(this.webdriverClient.val.bind(this.webdriverClient, keystrokes));
  518. this.actionQueue.push(this._typeCb.bind(this, selector, keystrokes, hash));
  519. return this;
  520. },
  521.  
  522. /**
  523. * Sends out an event with the results of the `type` call
  524. *
  525. * @method _typeCb
  526. * @param {string} selector Selector expression to find the element
  527. * @param {string} hash Unique hash of that fn call
  528. * @return {object} promise Type promise
  529. * @private
  530. */
  531.  
  532. _typeCb: function (selector, keystrokes, hash) {
  533. var deferred = Q.defer();
  534. this.events.emit('driver:message', {key: 'type', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash});
  535. deferred.resolve();
  536. return deferred.promise;
  537. },
  538.  
  539. /**
  540. * Set a value to an Element
  541. *
  542. * @method setValue
  543. * @param {string} selector Selector expression to find the element
  544. * @param {string} hash Unique hash of that fn call
  545. * @chainable
  546. */
  547.  
  548. setValue: function (selector, keystrokes, hash) {
  549. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  550. this.actionQueue.push(this.webdriverClient.clear.bind(this.webdriverClient, selector));
  551. this.actionQueue.push(this.webdriverClient.val.bind(this.webdriverClient, keystrokes));
  552. this.actionQueue.push(this._setValueCb.bind(this, selector, keystrokes, hash));
  553. return this;
  554. },
  555.  
  556. /**
  557. * Sends out an event with the results of the `setvalue` call
  558. *
  559. * @method _setValueCb
  560. * @param {string} selector Selector expression to find the element
  561. * @param {string} keystrokes Value to set
  562. * @param {string} hash Unique hash of that fn call
  563. * @return {object} promise Type promise
  564. * @private
  565. */
  566.  
  567. _setValueCb: function (selector, keystrokes, hash) {
  568. var deferred = Q.defer();
  569. this.events.emit('driver:message', {key: 'setValue', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash});
  570. deferred.resolve();
  571. return deferred.promise;
  572. },
  573.  
  574. /**
  575. * Sends keys to an element (whether or not it is an input)
  576. *
  577. * @method sendKeys
  578. * @param {string} selector Selector expression to find the element
  579. * @param {string} hash Unique hash of that fn call
  580. * @chainable
  581. */
  582.  
  583. sendKeys: function (selector, keystrokes, hash) {
  584. this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector));
  585. this.actionQueue.push(this.webdriverClient.sendKeys.bind(this.webdriverClient, keystrokes));
  586. this.actionQueue.push(this._sendKeysCb.bind(this, selector, keystrokes, hash));
  587. return this;
  588. },
  589.  
  590. /**
  591. * Sends out an event with the results of the `sendKeys` call
  592. *
  593. * @method _sendKeysCb
  594. * @param {string} selector Selector expression to find the element
  595. * @param {string} hash Unique hash of that fn call
  596. * @return {object} promise Type promise
  597. * @private
  598. */
  599.  
  600. _sendKeysCb: function (selector, keystrokes, hash) {
  601. var deferred = Q.defer();
  602. this.events.emit('driver:message', {key: 'sendKeys', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash});
  603. deferred.resolve();
  604. return deferred.promise;
  605. },
  606.  
  607. /**
  608. * Wait for an element for a specific amount of time
  609. *
  610. * @method waitForElement
  611. * @param {string} selector Selector expression to find the element
  612. * @param {integer} timeout Time to wait in ms
  613. * @param {string} hash Unique hash of that fn call
  614. * @param {string} uuid Unique hash of that fn call
  615. * @chainable
  616. */
  617.  
  618. waitForElement: function (selector, timeout, hash, uuid) {
  619. this.actionQueue.push(this.webdriverClient.implicitWait.bind(this.webdriverClient, timeout));
  620. this.actionQueue.push(this._waitForElementCb.bind(this, selector, hash, uuid));
  621. return this;
  622. },
  623.  
  624. /**
  625. * Sends out an event with the results of the `waitForElement` call
  626. *
  627. * @method _waitForElementCb
  628. * @param {string} selector Selector expression to find the element
  629. * @param {string} hash Unique hash of that fn call
  630. * @param {string} uuid Unique hash of that fn call
  631. * @return {object} promise WaitForElement promise
  632. * @private
  633. */
  634.  
  635. _waitForElementCb: function (selector, hash, uuid) {
  636. var deferred = Q.defer();
  637. this.events.emit('driver:message', {key: 'waitForElement', selector: selector, value: selector, uuid: uuid, hash: hash});
  638. deferred.resolve();
  639. return deferred.promise;
  640. },
  641.  
  642. /**
  643. * Returns the number of elements matched by the selector
  644. *
  645. * @method getNumberOfElements
  646. * @param {string} selector Selector expression to find the elements
  647. * @param {integer} expected Expected number of matched elements
  648. * @param {string} uuid Unique hash of that fn call
  649. * @chainable
  650. */
  651.  
  652. getNumberOfElements: function (selector, expected, hash) {
  653. this.actionQueue.push(this.webdriverClient.elements.bind(this.webdriverClient, selector));
  654. this.actionQueue.push(this._getNumberOfElementsCb.bind(this, selector, hash, expected));
  655. return this;
  656. },
  657.  
  658. /**
  659. * Sends out an event with the results of the `getNumberOfElements` call
  660. *
  661. * @method _getNumberOfElementsCb
  662. * @param {string} selector Selector expression to find the element
  663. * @param {string} hash Unique hash of that fn call
  664. * @param {integer} expected Expected number of matched elements
  665. * @param {string} res Serialized JSON with the results of the getNumberOfElements call
  666. * @return {object} promise GetNumberOfElements promise
  667. * @private
  668. */
  669.  
  670. _getNumberOfElementsCb: function (selector, hash, expected, res) {
  671. var deferred = Q.defer();
  672. var result = JSON.parse(res);
  673. // check if the expression matched any element
  674. if (result.value === -1) {
  675. this.events.emit('driver:message', {key: 'numberOfElements', hash: hash, selector: selector, expected: expected, value: 0});
  676. } else {
  677. this.events.emit('driver:message', {key: 'numberOfElements', selector: selector, expected: expected, hash: hash, value: result.value.length});
  678. }
  679.  
  680. deferred.resolve();
  681. return deferred.promise;
  682. },
  683.  
  684.  
  685. /**
  686. * Returns the number of visible elements matched by the selector
  687. *
  688. * @method getNumberOfVisibleElements
  689. * @param {string} selector Selector expression to find the elements
  690. * @param {integer} expected Expected number of matched elements
  691. * @param {string} uuid Unique hash of that fn call
  692. * @chainable
  693. */
  694.  
  695. getNumberOfVisibleElements: function (selector, expected, hash) {
  696. this.actionQueue.push(this.webdriverClient.elements.bind(this.webdriverClient, selector));
  697. this.actionQueue.push(function (result) {
  698. var deferred = Q.defer();
  699. var res = JSON.parse(result);
  700. var resLength = res.value.length;
  701. var curLength = 0;
  702. var visibleElement = [];
  703.  
  704. res.value.forEach(function (element) {
  705. var fakeResponse = JSON.stringify({sessionId: res.sessionId, status: 0, value: element.ELEMENT});
  706. this.webdriverClient.options.id = element.ELEMENT;
  707. this.webdriverClient.displayed.bind(this.webdriverClient, selector)(fakeResponse).then(function (visRes) {
  708. curLength++;
  709. if (JSON.parse(visRes).value === true) {
  710. visibleElement.push(element);
  711. }
  712. if (curLength === resLength) {
  713. deferred.resolve(JSON.stringify({sessionId: res.sessionId, status: 0, value: visibleElement}));
  714. }
  715. });
  716. }.bind(this));
  717.  
  718. return deferred.promise;
  719. }.bind(this));
  720. this.actionQueue.push(this._getNumberOfVisibleElementsCb.bind(this, selector, hash, expected));
  721. return this;
  722. },
  723.  
  724. /**
  725. * Sends out an event with the results of the `getNumberOfVisibleElements` call
  726. *
  727. * @method _getNumberOfElementsCb
  728. * @param {string} selector Selector expression to find the element
  729. * @param {string} hash Unique hash of that fn call
  730. * @param {integer} expected Expected number of matched elements
  731. * @param {string} res Serialized JSON with the results of the getNumberOfVisibleElements call
  732. * @return {object} promise GetNumberOfElements promise
  733. * @private
  734. */
  735.  
  736. _getNumberOfVisibleElementsCb: function (selector, hash, expected, res) {
  737. var deferred = Q.defer();
  738. var result = JSON.parse(res);
  739.  
  740. // check if the expression matched any element
  741. if (result.value === -1) {
  742. this.events.emit('driver:message', {key: 'numberOfVisibleElements', hash: hash, selector: selector, expected: expected, value: 0});
  743. } else {
  744. this.events.emit('driver:message', {key: 'numberOfVisibleElements', selector: selector, expected: expected, hash: hash, value: result.value.length});
  745. }
  746.  
  747. deferred.resolve();
  748. return deferred.promise;
  749. }
  750.  
  751. };
  752.  
  753. /**
  754. * Mixes in element methods
  755. *
  756. * @param {Dalek.DriverNative} DalekNative Native driver base class
  757. * @return {Dalek.DriverNative} DalekNative Native driver base class
  758. */
  759.  
  760. module.exports = function (DalekNative) {
  761. // mixin methods
  762. Object.keys(Element).forEach(function (fn) {
  763. DalekNative.prototype[fn] = Element[fn];
  764. });
  765.  
  766. return DalekNative;
  767. };
  768.