Plato on Github
Report Home
lib/commands/element.js
Maintainability
67.86
Lines of code
709
Difficulty
86.47
Estimated Errors
5.28
Function weight
By Complexity
By SLOC
/*! * * Copyright (c) 2013 Sebastian Golasch * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ 'use strict'; // ext. libs var Q = require('q'); /** * Element related methods * * @module Driver * @class Element * @namespace Dalek.DriverNative.Commands */ var Element = { /** * Checks if an element exists * * @method exists * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @chainable */ exists: function (selector, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this._existsCb.bind(this, selector, hash)); return this; }, /** * Sends out an event with the results of the `exists` call * * @method _existsCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} result Serialized JSON with the reuslts of the exists call * @return {object} promise Exists promise * @private */ _existsCb: function (selector, hash, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'exists', selector: selector, hash: hash, value: (JSON.parse(result).value === -1 || JSON.parse(result).status === 7 ? 'false' : 'true')}); deferred.resolve(); return deferred.promise; }, /** * Checks if an element is visible * * @method visible * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @chainable */ visible: function (selector, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.displayed.bind(this.webdriverClient, selector)); this.actionQueue.push(this._visibleCb.bind(this, selector, hash)); return this; }, /** * Sends out an event with the results of the `visible` call * * @method _visibleCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} result Serialized JSON with the reuslts of the visible call * @return {object} promise Visible promise * @private */ _visibleCb: function (selector, hash, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'visible', selector: selector, hash: hash, value: JSON.parse(result).value}); deferred.resolve(); return deferred.promise; }, /** * Checks if an element has the expected text * * @method text * @param {string} selector Selector expression to find the element * @param {string} expected The expected text content * @param {string} hash Unique hash of that fn call * @chainable */ text: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.text.bind(this.webdriverClient, selector)); this.actionQueue.push(this._textCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `text` call * * @method _textCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} expected The expected text content * @param {string} result Serialized JSON with the reuslts of the text call * @return {object} Promise * @private */ _textCb: function (selector, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'text', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value}); deferred.resolve(); return deferred.promise; }, /** * Checks if an element has the expected css property/value pairs * * @method css * @param {string} selector Selector expression to find the element * @param {string} property The css property to check * @param {string} expected The expected css value * @param {string} hash Unique hash of that fn call * @chainable */ css: function (selector, property, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.cssProperty.bind(this.webdriverClient, property)); this.actionQueue.push(this._cssCb.bind(this, selector, property, hash, expected)); return this; }, /** * Sends out an event with the results of the `css` call * * @method _cssCb * @param {string} selector Selector expression to find the element * @param {string} property The css property to check * @param {string} expected The expected css value * @param {string} hash Unique hash of that fn call * @param {string} result Serialized JSON with the reuslts of the text call * @return {object} Promise * @private */ _cssCb: function (selector, property, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'css', hash: hash, property: property, expected: expected, selector: selector, value: JSON.parse(result).value}); deferred.resolve(); return deferred.promise; }, /** * Checks th width of an element * * @method width * @param {string} selector Selector expression to find the element * @param {string} expected The expected width value * @param {string} hash Unique hash of that fn call * @chainable */ width: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.size.bind(this.webdriverClient)); this.actionQueue.push(this._widthCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `width` call * * @method _widthCb * @param {string} selector Selector expression to find the element * @param {string} expected The expected width value * @param {string} hash Unique hash of that fn call * @param {string} result Serialized JSON with the reuslts of the text call * @return {object} Promise * @private */ _widthCb: function (selector, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'width', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value.width}); deferred.resolve(); return deferred.promise; }, /** * Checks th height of an element * * @method height * @param {string} selector Selector expression to find the element * @param {string} expected The expected height value * @param {string} hash Unique hash of that fn call * @chainable */ height: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.size.bind(this.webdriverClient)); this.actionQueue.push(this._heightCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `height` call * * @method _heightCb * @param {string} selector Selector expression to find the element * @param {string} expected The expected height value * @param {string} hash Unique hash of that fn call * @param {string} result Serialized JSON with the reuslts of the text call * @return {object} Promise * @private */ _heightCb: function (selector, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'height', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value.height}); deferred.resolve(); return deferred.promise; }, /** * Checks if an element has an attribute with the expected value * * @method attribute * @param {string} selector Selector expression to find the element * @param {string} attribute The attribute that should be checked * @param {string} expected The expected text content * @param {string} hash Unique hash of that fn call * @chainable */ attribute: function (selector, attribute, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.getAttribute.bind(this.webdriverClient, attribute)); this.actionQueue.push(this._attributeCb.bind(this, selector, hash, attribute, expected)); return this; }, /** * Sends out an event with the results of the `attribute` call * * @method _attributeCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} attribute The attribute that should be checked * @param {string} expected The expected attribute content * @param {string} result Serialized JSON with the results of the attribute call * @return {object} promise Attribute promise * @private */ _attributeCb: function (selector, hash, attribute, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'attribute', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); deferred.resolve(); return deferred.promise; }, /** * Checks if an element has the expected value * * @method val * @param {string} selector Selector expression to find the element * @param {string} expected The expected content * @param {string} hash Unique hash of that fn call * @chainable */ val: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.getAttribute.bind(this.webdriverClient, 'value')); this.actionQueue.push(this._valCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `val` call * * @method _valCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} expected The expected content * @param {string} result Serialized JSON with the results of the val call * @return {object} Promise * @private */ _valCb: function (selector, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'val', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); deferred.resolve(); return deferred.promise; }, /** * Checks if an element is selected * * @method selected * @param {string} selector Selector expression to find the element * @param {string} expected The expected content * @param {string} hash Unique hash of that fn call * @chainable */ selected: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.selected.bind(this.webdriverClient)); this.actionQueue.push(this._selectedCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `selected` call * * @method _selectedCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} expected The expected content * @param {string} result Serialized JSON with the results of the selected call * @return {object} Promise * @private */ _selectedCb: function (selector, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'selected', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); deferred.resolve(); return deferred.promise; }, /** * Checks if an element is enabled * * @method enabled * @param {string} selector Selector expression to find the element * @param {string} expected The expected content * @param {string} hash Unique hash of that fn call * @chainable */ enabled: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.enabled.bind(this.webdriverClient)); this.actionQueue.push(this._enabledCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `enabled` call * * @method _enabledCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} expected The expected content * @param {string} result Serialized JSON with the results of the selected call * @return {object} Promise * @private */ _enabledCb: function (selector, hash, expected, result) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'enabled', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); deferred.resolve(); return deferred.promise; }, /** * Submits a form * * @method submit * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @chainable */ submit: function (selector, hash, uuid) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.submit.bind(this.webdriverClient)); this.actionQueue.push(this._submitCb.bind(this, selector, hash, uuid)); return this; }, /** * Sends out an event with the results of the `submit` call * * @method _submitCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @return {object} promise Click promise * @private */ _submitCb: function (selector, hash, uuid) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'submit', value: selector, uuid: uuid, hash: hash}); deferred.resolve(); return deferred.promise; }, /** * Clicks an element * * @method click * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @chainable */ click: function (selector, hash, uuid) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.click.bind(this.webdriverClient)); this.actionQueue.push(this._clickCb.bind(this, selector, hash, uuid)); return this; }, /** * Sends out an event with the results of the `click` call * * @method _clickCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @return {object} promise Click promise * @private */ _clickCb: function (selector, hash, uuid) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'click', value: selector, uuid: uuid, hash: hash}); deferred.resolve(); return deferred.promise; }, /** * Scrolls from an element to a location defined in pixels * * @method scroll * @param {string} selector Selector expression to find the element * @param {object} options X offset, Y offset, Speed * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @chainable */ scroll: function (selector, options, hash, uuid) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector, options)); this.actionQueue.push(this.webdriverClient.scroll.bind(this.webdriverClient)); this.actionQueue.push(this._clickCb.bind(this, selector, options, hash, uuid)); return this; }, /** * Sends out an event with the results of the `scroll` call * * @method _scrollCb * @param {string} selector Selector expression to find the element * @param {object} options X offset, Y offset, Speed * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @return {object} promise Scroll promise * @private */ _scrollCb: function (selector, options, hash, uuid) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'scroll', value: selector, uuid: uuid, hash: hash}); deferred.resolve(); return deferred.promise; }, /** * Clicks an element * * @method click * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @chainable */ type: function (selector, keystrokes, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.val.bind(this.webdriverClient, keystrokes)); this.actionQueue.push(this._typeCb.bind(this, selector, keystrokes, hash)); return this; }, /** * Sends out an event with the results of the `type` call * * @method _typeCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @return {object} promise Type promise * @private */ _typeCb: function (selector, keystrokes, hash) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'type', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash}); deferred.resolve(); return deferred.promise; }, /** * Sends keys to an element (whether or not it is an input) * * @method sendKeys * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @chainable */ sendKeys: function (selector, keystrokes, hash) { this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); this.actionQueue.push(this.webdriverClient.sendKeys.bind(this.webdriverClient, keystrokes)); this.actionQueue.push(this._sendKeysCb.bind(this, selector, keystrokes, hash)); return this; }, /** * Sends out an event with the results of the `sendKeys` call * * @method _sendKeysCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @return {object} promise Type promise * @private */ _sendKeysCb: function (selector, keystrokes, hash) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'sendKeys', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash}); deferred.resolve(); return deferred.promise; }, /** * Wait for an element for a specific amount of time * * @method waitForElement * @param {string} selector Selector expression to find the element * @param {integer} timeout Time to wait in ms * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @chainable */ waitForElement: function (selector, timeout, hash, uuid) { this.actionQueue.push(this.webdriverClient.implicitWait.bind(this.webdriverClient, timeout)); this.actionQueue.push(this._waitForElementCb.bind(this, selector, hash, uuid)); return this; }, /** * Sends out an event with the results of the `waitForElement` call * * @method _waitForElementCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {string} uuid Unique hash of that fn call * @return {object} promise WaitForElement promise * @private */ _waitForElementCb: function (selector, hash, uuid) { var deferred = Q.defer(); this.events.emit('driver:message', {key: 'waitForElement', selector: selector, uuid: uuid, hash: hash}); deferred.resolve(); return deferred.promise; }, /** * Returns the number of elements matched by the selector * * @method getNumberOfElements * @param {string} selector Selector expression to find the elements * @param {integer} expected Expected number of matched elements * @param {string} uuid Unique hash of that fn call * @chainable */ getNumberOfElements: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.elements.bind(this.webdriverClient, selector)); this.actionQueue.push(this._getNumberOfElementsCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `getNumberOfElements` call * * @method _getNumberOfElementsCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {integer} expected Expected number of matched elements * @param {string} res Serialized JSON with the results of the getNumberOfElements call * @return {object} promise GetNumberOfElements promise * @private */ _getNumberOfElementsCb: function (selector, hash, expected, res) { var deferred = Q.defer(); var result = JSON.parse(res); // check if the expression matched any element if (result.value === -1) { this.events.emit('driver:message', {key: 'numberOfElements', hash: hash, selector: selector, expected: expected, value: 0}); } else { this.events.emit('driver:message', {key: 'numberOfElements', selector: selector, expected: expected, hash: hash, value: result.value.length}); } deferred.resolve(); return deferred.promise; }, /** * Returns the number of visible elements matched by the selector * * @method getNumberOfVisibleElements * @param {string} selector Selector expression to find the elements * @param {integer} expected Expected number of matched elements * @param {string} uuid Unique hash of that fn call * @chainable */ getNumberOfVisibleElements: function (selector, expected, hash) { this.actionQueue.push(this.webdriverClient.elements.bind(this.webdriverClient, selector)); this.actionQueue.push(function (result) { var deferred = Q.defer(); var res = JSON.parse(result); var resLength = res.value.length; var curLength = 0; var visibleElement = []; res.value.forEach(function (element) { var fakeResponse = JSON.stringify({sessionId: res.sessionId, status: 0, value: element.ELEMENT}); this.webdriverClient.options.id = element.ELEMENT; this.webdriverClient.displayed.bind(this.webdriverClient, selector)(fakeResponse).then(function (visRes) { curLength++; if (JSON.parse(visRes).value === true) { visibleElement.push(element); } if (curLength === resLength) { deferred.resolve(JSON.stringify({sessionId: res.sessionId, status: 0, value: visibleElement})); } }); }.bind(this)); return deferred.promise; }.bind(this)); this.actionQueue.push(this._getNumberOfVisibleElementsCb.bind(this, selector, hash, expected)); return this; }, /** * Sends out an event with the results of the `getNumberOfVisibleElements` call * * @method _getNumberOfElementsCb * @param {string} selector Selector expression to find the element * @param {string} hash Unique hash of that fn call * @param {integer} expected Expected number of matched elements * @param {string} res Serialized JSON with the results of the getNumberOfVisibleElements call * @return {object} promise GetNumberOfElements promise * @private */ _getNumberOfVisibleElementsCb: function (selector, hash, expected, res) { var deferred = Q.defer(); var result = JSON.parse(res); // check if the expression matched any element if (result.value === -1) { this.events.emit('driver:message', {key: 'numberOfVisibleElements', hash: hash, selector: selector, expected: expected, value: 0}); } else { this.events.emit('driver:message', {key: 'numberOfVisibleElements', selector: selector, expected: expected, hash: hash, value: result.value.length}); } deferred.resolve(); return deferred.promise; } }; /** * Mixes in element methods * * @param {Dalek.DriverNative} DalekNative Native driver base class * @return {Dalek.DriverNative} DalekNative Native driver base class */ module.exports = function (DalekNative) { // mixin methods Object.keys(Element).forEach(function (fn) { DalekNative.prototype[fn] = Element[fn]; }); return DalekNative; };