| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- var util = require('util');
- var events = require('events');
- var Logger = require('../util/logger.js');
- var Utils = require('../util/utils.js');
- module.exports = function(client) {
- var Protocol = require('./protocol.js')(client);
- var returnValue = {};
- var elementCommands = {};
- /**
- * Simulates a click event on the given DOM element. Uses `elementIdClick` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.click("#main ul li a.first");
- * };
- * ```
- *
- * @method click
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdClick
- * @api commands
- */
- elementCommands.click = 'elementIdClick';
- /**
- * Clear a textarea or a text input element's value. Uses `elementIdValue` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.clearValue('input[type=text]');
- * };
- * ```
- *
- * @method clearValue
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdClear
- * @api commands
- */
- elementCommands.clearValue = 'elementIdClear';
- /**
- * Retrieve the value of an attribute for a given DOM element. Uses `elementIdAttribute` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.getAttribute("#main ul li a.first", "href", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value, "#home");
- * });
- * };
- * ```
- *
- * @method getAttribute
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {string} attribute The attribute name to inspect.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdAttribute
- * @returns {*} The value of the attribute
- * @api commands
- */
- elementCommands.getAttribute = ['elementIdAttribute', 1];
- /**
- * Retrieve the value of a css property for a given DOM element. Uses `elementIdCssProperty` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.getCssProperty("#main ul li a.first", "display", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value, 'inline');
- * });
- * };
- * ```
- *
- * @method getCssProperty
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {string} cssProperty The CSS property to inspect.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdCssProperty
- * @returns {*} The value of the css property
- * @api commands
- */
- elementCommands.getCssProperty = ['elementIdCssProperty', 1];
- /**
- * Determine an element's size in pixels. Uses `elementIdSize` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.getElementSize("#main ul li a.first", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value.width, 500);
- * this.assert.equal(result.value.height, 20);
- * });
- * };
- * ```
- *
- * @method getElementSize
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdSize
- * @returns {{width: number, height: number}} The width and height of the element in pixels
- * @api commands
- */
- elementCommands.getElementSize = 'elementIdSize';
- /**
- * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page.
- *
- * The element's coordinates are returned as a JSON object with x and y properties. Uses `elementIdLocation` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.getLocation("#main ul li a.first", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value.x, 200);
- * this.assert.equal(result.value.y, 200);
- * });
- * };
- * ```
- *
- * @method getLocation
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdLocation
- * @returns {x:number, y:number} The X and Y coordinates for the element on the page.
- * @api commands
- */
- elementCommands.getLocation = 'elementIdLocation';
- /**
- * Determine an element's location on the screen once it has been scrolled into view. Uses `elementIdLocationInView` protocol command.
- *
- * ```
- * this.demoTest = function (browser) {
- * browser.getLocationInView("#main ul li a.first", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value.x, 200);
- * this.assert.equal(result.value.y, 200);
- * });
- * };
- * ```
- *
- * @method getLocationInView
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdLocationInView
- * @returns {x: number, y: number} The X and Y coordinates for the element on the page.
- * @api commands
- */
- elementCommands.getLocationInView = 'elementIdLocationInView';
- /**
- * Query for an element's tag name. Uses `elementIdName` protocol command.
- *
- * ```
- * this.demoTest = function (client) {
- * client.getTagName("#main ul li .first", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value, "a");
- * });
- * };
- * ```
- *
- * @method getTagName
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdName
- * @returns {number} The element's tag name, as a lowercase string.
- * @api commands
- */
- elementCommands.getTagName = 'elementIdName';
- /**
- * Returns the visible text for the element. Uses `elementIdText` protocol command.
- *
- * ```
- * this.demoTest = function (browser) {
- * browser.getText("#main ul li a.first", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value, "nightwatchjs.org");
- * });
- * };
- * ```
- *
- * @method getText
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdText
- * @returns {string} The element's visible text.
- * @api commands
- */
- elementCommands.getText = 'elementIdText';
- /**
- * Returns a form element current value. Uses `elementIdValue` protocol command.
- *
- * ```
- * this.demoTest = function (browser) {
- * browser.getValue("form.login input[type=text]", function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value, "enter username");
- * });
- * };
- * ```
- *
- * @method getValue
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdValue
- * @returns {string} The element's value.
- * @api commands
- */
- elementCommands.getValue = 'elementIdValue';
- /**
- * Determine if an element is currently displayed. Uses `elementIdDisplayed` protocol command.
- *
- * ```
- * this.demoTest = function (browser) {
- * browser.isVisible('#main', function(result) {
- * this.assert.equal(typeof result, "object");
- * this.assert.equal(result.status, 0);
- * this.assert.equal(result.value, true);
- * });
- * };
- * ```
- *
- * @method isVisible
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdDisplayed
- * @api commands
- */
- elementCommands.isVisible = 'elementIdDisplayed';
- /**
- * Move the mouse by an offset of the specified element. Uses `moveTo` protocol command.
- *
- * ```
- * this.demoTest = function (browser) {
- * browser.moveToElement('#main', 10, 10);
- * };
- * ```
- *
- * @method moveToElement
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {number} xoffset X offset to move to, relative to the top-left corner of the element.
- * @param {number} yoffset Y offset to move to, relative to the top-left corner of the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see moveTo
- * @api commands
- */
- elementCommands.moveToElement = ['moveTo', 2];
- /**
- * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.
- *
- * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](http://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `client.Keys`.
- *
- * ```
- * // send some simple text to an input
- * this.demoTest = function (browser) {
- * browser.setValue('input[type=text]', 'nightwatch');
- * };
- * //
- * // send some text to an input and hit enter.
- * this.demoTest = function (browser) {
- * browser.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]);
- * };
- * ```
- *
- * @link /session/:sessionId/element/:id/value
- * @method setValue
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {string|array} value The text to send to the element or key strokes.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see elementIdValue
- * @api commands
- */
- elementCommands.setValue = ['elementIdValue', 1];
- /**
- * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. Uses `submit` protocol command.
- *
- * ```
- * this.demoTest = function (browser) {
- * browser.submitForm('form.login');
- * };
- * ```
- *
- * @method submitForm
- * @param {string} selector The CSS/Xpath selector used to locate the element.
- * @param {function} [callback] Optional callback function to be called when the command finishes.
- * @see submit
- * @api commands
- */
- elementCommands.submitForm = 'submit';
- function addElementCommand(protocolAction, extraArgs) {
- extraArgs = extraArgs || 0;
- var expectedArgs = 3 + extraArgs;
- return function commandActionFn() {
- var originalStackTrace = commandActionFn.stackTrace;
- var noopFn = function() {};
- var args = Array.prototype.slice.call(arguments, 0);
- if (typeof args[args.length-1] !== 'function') {
- args.push(noopFn);
- }
- var defaultUsing = client.locateStrategy || 'css selector';
- if (expectedArgs - args.length === 1) {
- args.unshift(defaultUsing);
- }
- if (args.length < expectedArgs - 1 || args.length > expectedArgs) {
- throw new Error(protocolAction + ' method expects ' + (expectedArgs - 1) + ' or ' + expectedArgs + ' arguments - ' + args.length + ' given.');
- }
- var using = args.shift();
- var value = args.shift();
- var callback = args.pop();
- return new CommandAction(using, value, protocolAction, args, callback, originalStackTrace);
- };
- }
- function CommandAction(using, value, protocolAction, args, callback, originalStackTrace) {
- events.EventEmitter.call(this);
- var $this = this;
- var el = Protocol.element(using, value, function(result) {
- if (result.status !== 0) {
- callback.call(client.api, result);
- var errorMessage = 'ERROR: Unable to locate element: "' + value + '" using: ' + using;
- var stack = originalStackTrace.split('\n');
- stack.shift();
- Utils.showStackTraceWithHeadline(errorMessage, stack);
- client.results.errors++;
- client.errors.push(errorMessage + '\n' + stack.join('\n'));
- $this.emit('complete', el, $this);
- } else {
- result = result.value.ELEMENT;
- args.push(function(r) {
- callback.call(client.api, r);
- });
- args.unshift(result);
- var c = Protocol[protocolAction].apply(Protocol, args).once('complete', function() {
- $this.emit('complete', c, $this);
- });
- }
- });
- }
- util.inherits(CommandAction, events.EventEmitter);
- Object.keys(elementCommands).forEach(function(commandName) {
- var args = elementCommands[commandName];
- if (!Array.isArray(args)) {
- args = [args];
- }
- returnValue[commandName] = addElementCommand.apply(client.api, args);
- });
- // alias
- returnValue.sendKeys = returnValue.setValue;
- return returnValue;
- };
|