refactor app directory structure and add tests

This commit is contained in:
s2
2016-11-10 16:27:26 +01:00
parent 204834ce28
commit dd88218c0e
1844 changed files with 263520 additions and 0 deletions

View File

@@ -0,0 +1,388 @@
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;
};