New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

nightwatch

Package Overview
Dependencies
Maintainers
1
Versions
360
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nightwatch - npm Package Compare versions

Comparing version 0.6.15 to 0.7.0

bin/chromedriver-2.15

2

bin/nightwatch.json

@@ -10,2 +10,3 @@ {

"disable_colors": false,
"test_workers" : false,

@@ -53,2 +54,3 @@ "selenium" : {

"enabled" : false,
"on_failure" : true,
"path" : ""

@@ -55,0 +57,0 @@ },

2

CONTRIBUTING.md

@@ -9,3 +9,3 @@ # Contributing to Nightwatch

1. Please do not ask for support or questions in the __Issues__ list. The [mailing list](https://groups.google.com/forum/#!forum/nightwatchjs) is a much better place for discussions and it helps keeping things separate
2. Search for a similar issue here: https://github.com/beatfactor/nightwatch/search?type=Issues and add your scenario there and anything else which you think will help with fixing it
2. Search for a similar issue here: https://github.com/nightwatchjs/nightwatch/search?type=Issues and add your scenario there and anything else which you think will help with fixing it
3. Please do not repport issues you have with Selenium or the individual browser drivers that cannot or should not be solved in Nightwatch

@@ -12,0 +12,0 @@ 4. When submitting a new issue please include a sample test (for complex scenarios) which would reproduce the problem you're experiencing. The test should be against a public url

@@ -0,1 +1,2 @@

/* jshint expr: true */
module.exports = {

@@ -5,12 +6,24 @@ tags: ['google'],

client
.page.google().goToGoogle()
.assert.title('Google')
.assert.visible('input[name="q"]')
.setValue('input[type=text]', 'nightwatch')
.waitForElementVisible('button[name=btnG]', 1000)
.click('button[name=btnG]')
.pause(1000)
.assert.containsText('#main', 'Night Watch')
.end();
.url('http://google.no')
.pause(1000);
client.expect.element('body').to.be.present.before(1000);
client.expect.element('#lst-ib').to.have.css('display');
client.expect.element('body').to.have.attribute('class').which.contains('vasq');
client.expect.element('body').to.have.attribute('class').which.matches(/vasq$/);
client.expect.element('body').to.have.attribute('class').before(1000);
client.expect.element('#lst-ib').to.be.enabled;
client.expect.element('#hplogo').text.to.match(/Norge/).before(1000);
client.setValue('#lst-ib', 'Norway').pause(500);
client.expect.element('#lst-ib').to.have.value.equal('Norway');
client.expect.element('#lst-ib').to.be.an('input');
client.expect.element('#lst-ib').to.be.not.selected;
client.expect.element('#lst-ib').to.be.visible;
client.end();
}
};

@@ -22,8 +22,2 @@ var nightwatch = require('./lib/index.js');

},
tests: [
'tests/*.js',
'tests/extra/**/*.js',
'tests/src/**/*.js',
'tests/sampletests/**/*.js'
],
gruntfile: {

@@ -30,0 +24,0 @@ src: 'Gruntfile.js'

@@ -312,3 +312,2 @@ var util = require('util');

function addElementCommand(protocolAction, extraArgs) {
var self = this;
extraArgs = extraArgs || 0;

@@ -332,41 +331,41 @@ var expectedArgs = 3 + extraArgs;

var using = args.shift(), value = args.shift();
var using = args.shift();
var value = args.shift();
var callback = args.pop();
function CommandAction() {
events.EventEmitter.call(this);
return new CommandAction(using, value, protocolAction, args, callback);
};
}
var $this = this;
function CommandAction(using, value, protocolAction, args, callback) {
events.EventEmitter.call(this);
var el = Protocol.element(using, value, function(result) {
if (result.status !== 0) {
callback.call(client.api, result);
var errorMessage = 'Unable to locate element: "' + value + '" using: ' + using;
client.results.errors++;
client.errors.push(errorMessage);
console.log(Logger.colors.red('ERROR:'), errorMessage);
$this.emit('complete', el, $this);
} else {
result = result.value.ELEMENT;
var $this = this;
var el = Protocol.element(using, value, function(result) {
if (result.status !== 0) {
callback.call(client.api, result);
var errorMessage = 'Unable to locate element: "' + value + '" using: ' + using;
client.results.errors++;
client.errors.push(errorMessage);
console.log(Logger.colors.red('ERROR:'), errorMessage);
$this.emit('complete', el, $this);
} else {
result = result.value.ELEMENT;
args.push(function(r) {
callback.call(client.api, r);
});
args.push(function(r) {
callback.call(client.api, r);
});
args.unshift(result);
args.unshift(result);
var c = Protocol[protocolAction].apply(Protocol, args).once('complete', function() {
$this.emit('complete', c, $this);
});
}
var c = Protocol[protocolAction].apply(Protocol, args).once('complete', function() {
$this.emit('complete', c, $this);
});
}
});
}
util.inherits(CommandAction, events.EventEmitter);
util.inherits(CommandAction, events.EventEmitter);
return new CommandAction();
};
}
for (var commandName in elementCommands) {
Object.keys(elementCommands).forEach(function(commandName) {
var args = elementCommands[commandName];

@@ -378,3 +377,3 @@ if (!Array.isArray(args)) {

returnValue[commandName] = addElementCommand.apply(client.api, args);
}
});

@@ -381,0 +380,0 @@ // alias

@@ -0,1 +1,4 @@

var elementByRecursion = require('./element-commands/_elementByRecursion.js');
var elementsByRecursion = require('./element-commands/_elementsByRecursion.js');
module.exports = function(Nightwatch) {

@@ -138,2 +141,18 @@

Actions.element = function(using, value, callback) {
if (using == 'recursion') {
return new elementByRecursion(Nightwatch).command(value, callback);
}
return element(using, value, callback);
};
/*!
* element protocol action
*
* @param {string} using
* @param {string} value
* @param {function} callback
* @private
*/
function element(using, value, callback) {
var strategies = ['class name', 'css selector', 'id', 'name', 'link text',

@@ -153,2 +172,29 @@ 'partial link text', 'tag name', 'xpath'];

}, callback);
}
/**
* Search for an element on the page, starting from the identified element. The located element will be returned as a WebElement JSON object.
*
* @link /session/:sessionId/element/:id/element
* @param {string} id ID of the element to route the command to.
* @param {string} using The locator strategy to use.
* @param {string} value The search target.
* @param {function} [callback] Optional callback function to be called when the command finishes.
* @api protocol
*/
Actions.elementIdElement = function(id, using, value, callback) {
var strategies = ['class name', 'css selector', 'id', 'name', 'link text',
'partial link text', 'tag name', 'xpath'];
using = using.toLocaleLowerCase();
if (strategies.indexOf(using) === -1) {
throw new Error('Provided locating strategy is not supported: ' +
using + '. It must be one of the following:\n' +
strategies.join(', '));
}
return postRequest('/element/' + id + '/element', {
using: using,
value: value
}, callback);
};

@@ -167,6 +213,22 @@

Actions.elements = function(using, value, callback) {
if (using == 'recursion') {
return new elementsByRecursion(Nightwatch).command(value, callback);
}
return elements(using, value, callback);
};
/*!
* elements protocol action
*
* @param {string} using
* @param {string} value
* @param {function} callback
* @private
*/
function elements(using, value, callback) {
var check = /class name|css selector|id|name|link text|partial link text|tag name|xpath/gi;
if (!check.test(using)) {
throw new Error('Please provide any of the following using strings as the first parameter: ' +
'class name, css selector, id, name, link text, partial link text, tag name or xpath');
'class name, css selector, id, name, link text, partial link text, tag name, or xpath. Given: ' + using);
}

@@ -178,2 +240,29 @@

}, callback);
}
/**
* Search for multiple elements on the page, starting from the identified element. The located element will be returned as a WebElement JSON objects.
*
* @link /session/:sessionId/element/:id/elements
* @param {string} id ID of the element to route the command to.
* @param {string} using The locator strategy to use.
* @param {string} value The search target.
* @param {function} [callback] Optional callback function to be called when the command finishes.
* @api protocol
*/
Actions.elementIdElements = function(id, using, value, callback) {
var strategies = ['class name', 'css selector', 'id', 'name', 'link text',
'partial link text', 'tag name', 'xpath'];
using = using.toLocaleLowerCase();
if (strategies.indexOf(using) === -1) {
throw new Error('Provided locating strategy is not supported: ' +
using + '. It must be one of the following:\n' +
strategies.join(', '));
}
return postRequest('/element/' + id + '/elements', {
using: using,
value: value
}, callback);
};

@@ -297,3 +386,3 @@

/**
* Determine if an OPTION element, or an INPUT element of type checkbox or radiobutton is currently selected.
* Determine if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.
*

@@ -996,6 +1085,6 @@ * @link /session/:sessionId/element/:id/selected

Actions.dismiss_alert = Actions.dismissAlert;
/**
* Gets the text of the log type specified
* Gets the text of the log type specified
*

@@ -1023,3 +1112,3 @@ * @link /session/:sessionId/log

};
/////////////////////////////////////////////////////////////////////////////

@@ -1026,0 +1115,0 @@ // Helpers

@@ -11,2 +11,3 @@ /*!

var Assertion = require('./assertion.js');
var Page = require('../page-object/page.js');

@@ -95,14 +96,15 @@ module.exports = new (function() {

*/
function loadAssertions() {
client.api.assert = {};
function loadAssertions(parent) {
parent = parent || client.api;
parent.assert = {};
if (client.options.start_session) {
client.api.verify = {};
parent.verify = {};
}
for (var prop in assertModule) {
if (assertModule.hasOwnProperty(prop)) {
client.api.assert[prop] = (function(prop) {
parent.assert[prop] = (function(prop) {
return makeAssertion(prop, true);
})(prop);
if (client.options.start_session) {
client.api.verify[prop] = (function (prop) {
parent.verify[prop] = (function (prop) {
return makeAssertion(prop, false);

@@ -117,4 +119,4 @@ })(prop);

loadAssertionFiles(dirPath, client.api.assert, true);
loadAssertionFiles(dirPath, client.api.verify, false);
loadAssertionFiles(dirPath, parent.assert, true);
loadAssertionFiles(dirPath, parent.verify, false);
}

@@ -174,7 +176,8 @@ }

*/
function loadProtocolActions() {
function loadProtocolActions(parent) {
parent = parent || client.api;
var protocol = require('./../api/protocol.js')(client);
var actions = Object.keys(protocol);
actions.forEach(function(command) {
addCommand(command, protocol[command], client.api, client.api);
addCommand(command, protocol[command], client.api, parent);
});

@@ -184,20 +187,32 @@ }

/**
* Loads the composite commands defined by nightwatch
* Loads all the composite commands defined by nightwatch
*/
function loadClientCommands() {
// adding element specific commands
function loadAllCommands(parent) {
loadElementCommands(parent);
loadClientCommands(parent);
loadCommandFiles(client.api, parent, true);
}
/**
* Loads the element composite commands defined by nightwatch
*/
function loadElementCommands(parent) {
parent = parent || client.api;
var elementCommands = require('./../api/element-commands.js')(client);
var entries = Object.keys(elementCommands);
var entries = Object.keys(elementCommands);
entries.forEach(function(command) {
addCommand(command, elementCommands[command], client.api, client.api);
addCommand(command, elementCommands[command], client.api, parent);
});
}
// adding client specific commands
/**
* Loads all the client commands defined by nightwatch
*/
function loadClientCommands(parent) {
parent = parent || client.api;
var clientCommands = require('./../api/client-commands.js')(client);
entries = Object.keys(clientCommands);
var entries = Object.keys(clientCommands);
entries.forEach(function(command) {
addCommand(command, clientCommands[command], client.api, client.api, true);
addCommand(command, clientCommands[command], client.api, parent, true);
});
loadCommandFiles(client.api);
}

@@ -208,20 +223,25 @@

*/
function loadCommandFiles(context) {
var relativePath = './../api/commands/';
var commandFiles = fs.readdirSync(path.join(__dirname, relativePath));
var commandName;
var commandModule;
function loadCommandFiles(context, parent, shouldLoadClientCommands) {
var relativePaths = ['./../api/element-commands/'];
if (shouldLoadClientCommands) {
relativePaths.push('./../api/client-commands/');
}
for (var i = 0, len = commandFiles.length; i < len; i++) {
var ext = path.extname(commandFiles[i]);
commandName = path.basename(commandFiles[i], ext);
if (ext === '.js' && commandName.substr(0, 1) !== '_') {
commandModule = require(__dirname + relativePath + commandFiles[i]);
var m = loadCommandModule(commandModule, context);
addCommand(commandName, m.command, m.context, client.api);
relativePaths.forEach(function(relativePath) {
var commandFiles = fs.readdirSync(path.join(__dirname, relativePath));
var commandName;
var commandModule;
for (var i = 0, len = commandFiles.length; i < len; i++) {
var ext = path.extname(commandFiles[i]);
commandName = path.basename(commandFiles[i], ext);
if (ext === '.js' && commandName.substr(0, 1) !== '_') {
commandModule = require(__dirname + relativePath + commandFiles[i]);
var m = loadCommandModule(commandModule, context);
addCommand(commandName, m.command, m.context, parent);
}
}
}
});
}
/**

@@ -233,5 +253,6 @@ * Loads a command module either specified as an object with a `command` method

* @param {object} context
* @param {object} [addt_props]
* @returns {{command: function, context: *}}
*/
function loadCommandModule(module, context, addt_props) {
function loadCommandModule(module, context, addt_props, return_val) {
var m = {command: null, context: context};

@@ -326,4 +347,5 @@

*/
function loadCustomAssertions(folder) {
function loadCustomAssertions(folder, parent) {
folder = folder || custom_assertions_path;
parent = parent || client.api;
if (!custom_assertions_path) {

@@ -334,3 +356,3 @@ return;

if (Array.isArray(folder)) {
folder.forEach(function(folderName) {
folder.forEach(function(folderName, parent) {
loadCustomAssertions(folderName);

@@ -341,22 +363,61 @@ });

loadCustomAssertionFolder(folder);
loadCustomAssertionFolder(folder, parent);
}
function loadCustomAssertionFolder(folderName) {
function loadCustomAssertionFolder(folderName, parent) {
var absPath = path.resolve(folderName);
loadAssertionFiles(absPath, client.api.assert, true);
loadAssertionFiles(absPath, client.api.verify, false);
loadAssertionFiles(absPath, parent.assert, true);
loadAssertionFiles(absPath, parent.verify, false);
}
function loadExpectAssertions(parent) {
parent = parent || client.api;
var Expect = require('../api/expect.js')(client);
var assertions = Object.keys(Expect);
parent.expect = {};
assertions.forEach(function(assertion) {
parent.expect[assertion] = function() {
var args = Array.prototype.slice.call(arguments);
var command = Expect[assertion].apply(parent, args);
function F(element) {
events.EventEmitter.call(this);
this.client = client;
this.element = element;
}
util.inherits(F, events.EventEmitter);
F.prototype.command = function() {
this.element.locate(this);
return this;
};
var instance = new F(command.element);
CommandQueue.add(assertion, instance.command, instance, []);
return command.expect;
};
});
}
/**
* Loads page object files
* @param {string} [dirPath]
*/
function loadPageObjects() {
if (!page_objects_path) {
function loadPageObjects(dirPath) {
if (!page_objects_path && !dirPath) {
return;
}
client.api.page = {};
dirPath = dirPath || page_objects_path;
client.api.page = client.api.page || {};
var absPath = path.resolve(page_objects_path);
if (Array.isArray(dirPath)) {
dirPath.forEach(function(folder) {
loadPageObjects(folder);
});
return;
}
var absPath = path.resolve(dirPath);
var pageFiles = fs.readdirSync(absPath);

@@ -385,2 +446,20 @@

if (useEnhancedModel(pageFnOrObject)) {
var loadOntoPageObject = function(parent) {
if (client.options.start_session) {
loadElementCommands(parent);
loadCommandFiles(client.api, parent, false);
loadExpectAssertions(parent);
// Alias
parent.expect.section = parent.expect.element;
}
loadAssertions(parent);
loadCustomCommands(null, parent);
loadCustomAssertions(null, parent);
return parent;
};
pageFnOrObject.name = name;
return new Page(pageFnOrObject, loadOntoPageObject, context, client);
}
return new (function() {

@@ -396,2 +475,6 @@ if (typeof pageFnOrObject == 'function') {

function useEnhancedModel(pageFnOrObject) {
return typeof pageFnOrObject == 'object' && (pageFnOrObject.elements || pageFnOrObject.sections);
}
/**

@@ -454,4 +537,5 @@ *

loadProtocolActions();
loadClientCommands();
loadAllCommands();
loadPageObjects();
loadExpectAssertions();
}

@@ -458,0 +542,0 @@ loadAssertions();

@@ -231,6 +231,6 @@ var util = require('util');

stacktrace : stacktrace,
failure : failure !== '' ? failure : false
elementNotFound : failure !== '' ? failure : false
});
if (!passed && abortOnFailure && client.options.start_session) {
if (!passed && abortOnFailure && client.options.start_session && client.options.skip_testcases_on_fail) {
client.terminate();

@@ -237,0 +237,0 @@ }

@@ -107,2 +107,3 @@ /*!

this.options.start_session = this.options.start_session || (typeof this.options.start_session == 'undefined');
this.options.skip_testcases_on_fail = this.options.skip_testcases_on_fail || (typeof this.options.skip_testcases_on_fail == 'undefined');

@@ -213,5 +214,10 @@ this.api.options.log_screenshot_data = this.options.log_screenshot_data ||

if (this.options.end_session_on_fail) {
this.enqueueCommand('session', ['delete'], function(result) {
//this.enqueueCommand('session', ['delete'], function(result) {
// self.finished();
//});
this.api.end(function() {
self.finished();
});
this.queue.run();
} else {

@@ -282,2 +288,6 @@ this.finished();

this.clearResult();
};
Nightwatch.prototype.clearResult = function() {
this.errors.length = 0;

@@ -330,17 +340,3 @@ this.results.passed = 0;

if (screenshotContent && self.options.screenshots.enabled) {
var d = new Date();
var dateStamp = d.toLocaleString('en-GB', {
weekday : 'narrow',
year : 'numeric',
month : '2-digit',
day : '2-digit',
timeZoneName : 'short',
hour : '2-digit',
minute : '2-digit',
second : '2-digit',
era : 'short'
}).replace(/:/g,'').replace(/\s/g,'-').replace(/-\(.+?\)/,'');
var fileNamePath = path.resolve(path.join(self.options.screenshots.path, 'ERROR_' +
dateStamp + '.png'));
var fileNamePath = Utils.getScreenshotFileName('ERROR_', self.options.screenshots.path);
self.saveScreenshotToFile(fileNamePath, screenshotContent);

@@ -547,2 +543,1 @@ result.lastScreenshotFile = fileNamePath;

})();

@@ -146,2 +146,6 @@ /**

// $ nightwatch --retries
this.command('retries')
.description('Retries failed or errored testcases up <n> times.');
// $ nightwatch -h

@@ -162,2 +166,1 @@ // $ nightwatch --help

})();

@@ -8,2 +8,4 @@ var fs = require('fs');

var Selenium = require('../selenium.js');
var ChildProcess = require('./child-process.js');
var ErrorHandler = require('./errorhandler.js');

@@ -65,2 +67,4 @@ var SETTINGS_DEPRECTED_VAL = './settings.json';

this.argv.env = this.argv.env || 'default';
// reading the settings file

@@ -77,2 +81,4 @@ try {

}
this.settings.output = this.settings.output || typeof this.settings.output == 'undefined';
} catch (ex) {

@@ -86,6 +92,2 @@ Logger.error(ex);

isParallelMode : function() {
return process.env.__NIGHTWATCH_PARALLEL_MODE === '1';
},
/**

@@ -122,2 +124,3 @@ * Looks for pattern ${VAR_NAME} in settings

}
try {

@@ -153,32 +156,4 @@ var fullPath = path.resolve(this.settings.globals_path);

/**
*
* @param {object|null} err
* @param {object} results
* @param {function} finished
*/
globalErrorHandler : function(err, results, finished) {
finished = finished || function() {};
if (results && results.errors) {
console.log(results.errmessages.join('\n'));
}
if (err) {
Logger.enable();
if (!err.message) {
err.message = 'There was an error while running the test.';
}
this.logError(err);
finished(false);
process.exit(1);
} else {
var result = true;
if (results.failed || results.errors) {
result = false;
}
finished(result);
}
singleTestRun: function () {
return typeof this.argv.test == 'string';
},

@@ -192,4 +167,3 @@

var testsource;
if (typeof this.argv.test == 'string') {
if (this.singleTestRun()) {
testsource = (this.argv.test.indexOf(process.cwd()) === -1) ?

@@ -210,3 +184,3 @@ path.join(process.cwd(), this.argv.test) :

this.argv.testcase = null;
this.logWarning('Option --testcase used without --test is ignored.');
ErrorHandler.logWarning('Option --testcase used without --test is ignored.');
}

@@ -271,6 +245,6 @@ if (typeof this.argv.group == 'string') {

console.error('There was an error while starting the Selenium server:');
self.globalErrorHandler({
ErrorHandler.handle({
message : error_out
});
return;

@@ -319,3 +293,4 @@ }

testcase : self.argv.testcase,
end_session_on_fail : self.endSessionOnFail
end_session_on_fail : self.endSessionOnFail,
retries : self.argv.retries
}, function(err, results) {

@@ -328,6 +303,6 @@ self.stopSelenium(function() {

afterGlobal.call(globalsContext, function done() {
self.globalErrorHandler(err, results, finished);
ErrorHandler.handle(err, results, finished);
});
} catch (ex) {
self.globalErrorHandler(ex, results, finished);
ErrorHandler.handle(ex, results, finished);
}

@@ -374,2 +349,5 @@ });

return this;
} else if (this.parallelModeWorkers()) {
this.setupParallelMode(null, done);
return this;
}

@@ -382,5 +360,15 @@

setGlobalOutputOptions: function () {
this.test_settings.output = this.test_settings.output || (this.settings.output && typeof this.test_settings.output == 'undefined');
this.test_settings.silent = this.test_settings.silent || typeof this.test_settings.silent == 'undefined';
if (this.argv.verbose) {
this.test_settings.silent = false;
}
return this;
},
/**
* Sets the specific test settings for the specified environment
* @param {string} env
* @param {string} [env]
* @returns {CliRunner}

@@ -390,20 +378,15 @@ */

// picking the environment specific test settings
this.test_settings = this.settings.test_settings[env];
this.test_settings.custom_commands_path = this.settings.custom_commands_path || '';
this.test_settings.custom_assertions_path = this.settings.custom_assertions_path || '';
this.test_settings.page_objects_path = this.settings.page_objects_path || '';
this.test_settings = env && this.settings.test_settings[env] || {};
if (env) {
this.test_settings.custom_commands_path = this.settings.custom_commands_path || '';
this.test_settings.custom_assertions_path = this.settings.custom_assertions_path || '';
this.test_settings.page_objects_path = this.settings.page_objects_path || '';
this.inheritFromDefaultEnv();
this.updateTestSettings();
// read the external globals, if any
this.readExternalGlobals();
this.inheritFromDefaultEnv();
this.updateTestSettings();
this.readExternalGlobals();
}
this.test_settings.output = this.test_settings.output || this.settings.output ||
(typeof this.test_settings.output == 'undefined' && typeof this.settings.output == 'undefined');
this.setGlobalOutputOptions();
this.test_settings.silent = this.test_settings.silent || typeof this.test_settings.silent == 'undefined';
if (this.argv.verbose) {
this.test_settings.silent = false;
}
if (typeof this.argv.skipgroup == 'string') {

@@ -447,3 +430,3 @@ this.test_settings.skipgroup = this.argv.skipgroup.split(',');

// overwrite selenium settings per environment
if (this.test_settings.selenium && typeof (this.test_settings.selenium) == 'object') {
if (Utils.isObject(this.test_settings.selenium)) {
for (var prop in this.test_settings.selenium) {

@@ -487,3 +470,3 @@ this.settings.selenium[prop] = this.test_settings.selenium[prop];

var deprecationNotice = function(propertyName, newSettingName) {
self.logWarning('DEPRECATION NOTICE: Property ' + propertyName + ' is deprecated since v0.5. Please' +
ErrorHandler.logWarning('DEPRECATION NOTICE: Property ' + propertyName + ' is deprecated since v0.5. Please' +
' use the "cli_args" object on the "selenium" property to define "' + newSettingName + '". E.g.:');

@@ -521,3 +504,3 @@ var demoObj = '{\n' +

mergeCliArgs : function() {
if (this.test_settings.cli_args && typeof this.test_settings.cli_args == 'object') {
if (Utils.isObject(this.test_settings.cli_args)) {
for (var prop in this.test_settings.cli_args) {

@@ -532,2 +515,14 @@ if (this.test_settings.cli_args.hasOwnProperty(prop)) {

////////////////////////////////////////////////////////////////////////////////////
// Parallelism related
////////////////////////////////////////////////////////////////////////////////////
isParallelMode : function() {
return process.env.__NIGHTWATCH_PARALLEL_MODE === '1';
},
parallelModeWorkers: function () {
return !this.isParallelMode() && !this.singleTestRun() && (this.settings.test_workers === true ||
Utils.isObject(this.settings.test_workers) && this.settings.test_workers.enabled);
},
/**

@@ -544,6 +539,6 @@ * Enables parallel execution mode

this.startSelenium(function() {
self.startChildProcesses(envs, function(o, code) {
self.startChildProcesses(envs, function(code) {
self.stopSelenium(function() {
if (done) {
done(o, code);
done(self.childProcessOutput, code);
}

@@ -557,23 +552,5 @@ if (code) {

return this;
},
/**
* Returns an array of cli arguments to be passed to the child process,
* based on the args passed to the main process
* @returns {Array}
*/
getChildProcessArgs : function(mainModule) {
var args = [mainModule];
for (var i = 2; i < process.argv.length; i++) {
if (process.argv[i] == '-e' || process.argv[i] == '--env') {
i++;
} else {
args.push(process.argv[i]);
}
}
return args;
},
getAvailableColors : function () {

@@ -607,149 +584,123 @@ var availColors = [

startChildProcesses : function(envs, doneCallback) {
var execFile = require('child_process').execFile, child, self = this;
var mainModule = process.mainModule.filename;
doneCallback = doneCallback || function() {};
var availColors = this.getAvailableColors();
var prevIndex = 0;
var output = {};
var globalExitCode = 0;
var processStartDelay = this.settings.parallel_process_delay || 10;
var writeToSdtout = function(data, item, index) {
data = data.replace(/^\s+|\s+$/g, '');
output[item] = output[item] || [];
this.childProcessOutput = {};
ChildProcess.prevIndex = 0;
var env_output = '';
var color_pair = availColors[index%4];
if (prevIndex !== index) {
prevIndex = index;
if (self.settings.live_output) {
env_output += '\n';
}
}
var args = this.getChildProcessArgs(envs);
if (self.settings.disable_colors) {
env_output += ' ' + item + ' ';
} else {
env_output += Logger.colors[color_pair[1]](' ' + item + ' ',
Logger.colors.background[color_pair[0]]);
}
if (envs === null) {
this.startTestWorkers(availColors, args, doneCallback);
return this;
}
if (self.settings.live_output) {
env_output += ' ' + data;
} else {
env_output += '\t' + data + '\n';
}
this.startEnvChildren(envs, availColors, args, doneCallback);
},
if (self.settings.live_output) {
console.log(env_output);
startEnvChildren : function(envs, availColors, args, doneCallback) {
var self = this;
envs.forEach(function(environment, index) {
self.childProcessOutput[environment] = [];
var childArgs = args.slice();
childArgs.push('--env', environment);
var child = new ChildProcess(environment, index, self.childProcessOutput[environment], self.settings, childArgs);
child.setLabel(environment + ' environment');
self.runningProcesses[child.itemKey] = child;
self.runningProcesses[child.itemKey].run(availColors, function(output, exitCode) {
if (self.processesRunning() === 0) {
if (!self.settings.live_output) {
self.printChildProcessOutput();
}
doneCallback(exitCode);
}
});
});
},
getChildProcessArgs : function(envs) {
var childProcessArgs = [];
for (var i = 2; i < process.argv.length; i++) {
if (envs && (process.argv[i] == '-e' || process.argv[i] == '--env')) {
i++;
} else {
output[item].push(env_output);
childProcessArgs.push(process.argv[i]);
}
};
}
envs.forEach(function(item, index) {
var cliArgs = self.getChildProcessArgs(mainModule);
cliArgs.push('--env', item, '--parallel-mode');
var env = process.env;
var itemKey = self.getChildProcessEnvKey(item, index);
return childProcessArgs;
},
setTimeout(function() {
env.__NIGHTWATCH_PARALLEL_MODE = 1;
env.__NIGHTWATCH_ENV = item;
env.__NIGHTWATCH_ENV_KEY = itemKey;
startTestWorkers : function(availColors, args, doneCallback) {
var workerCount = this.getTestWorkersCount();
var source = this.getTestSource();
child = execFile(process.execPath, cliArgs, {
cwd : process.cwd(),
encoding: 'utf8',
env : env
}, function (error, stdout, stderr) {});
this.initTestSettings();
var self = this;
self.runningProcesses[itemKey] = true;
Runner.readPaths(source, this.test_settings, function(error, modulePaths) {
if (error) {
ErrorHandler.handle(error, null, doneCallback);
return;
}
console.log('Started child process for env:',
self.settings.disable_colors ? (' ' + itemKey + ' ') : (Logger.colors.yellow(' ' + itemKey + ' ', Logger.colors.background.black)), '\n');
var remaining = modulePaths.length;
Utils.processAsyncQueue(workerCount, modulePaths, function(modulePath, index, next) {
var filename = path.basename(modulePath, '.js');
child.stdout.on('data', function (data) {
writeToSdtout(data, itemKey, index);
});
self.childProcessOutput[filename] = [];
child.stderr.on('data', function (data) {
writeToSdtout(data, itemKey, index);
});
var childArgs = args.slice();
childArgs.push('--test', modulePath);
var child = new ChildProcess(filename, index, self.childProcessOutput[filename], self.settings, childArgs);
child.setLabel(Utils.getModuleKey(modulePath, self.settings.src_folders, modulePaths));
self.runningProcesses[child.itemKey] = child;
self.runningProcesses[child.itemKey].run(availColors, function (output, exitCode) {
remaining -=1;
if (remaining > 0) {
next();
} else {
if (!self.settings.live_output) {
self.printChildProcessOutput();
}
child.on('close', function(code) {
if (!self.processesRunning()) {
doneCallback(output, globalExitCode);
doneCallback(exitCode);
}
});
});
});
},
child.on('exit', function (code) {
if (code) {
globalExitCode = 2;
}
if (!self.settings.live_output) {
var child_output = output[itemKey] || '';
for (var i = 0; i < child_output.length; i++) {
process.stdout.write(child_output[i]);
}
console.log('');
}
self.runningProcesses[itemKey] = false;
});
}, index * processStartDelay);
printChildProcessOutput : function() {
var self = this;
Object.keys(this.childProcessOutput).forEach(function(environment) {
self.childProcessOutput[environment].forEach(function(output) {
process.stdout.write(output + '\n');
});
});
},
processesRunning : function() {
for (var item in this.runningProcesses) {
if (this.runningProcesses.hasOwnProperty(item) && this.runningProcesses[item]) {
return true;
}
getTestWorkersCount : function() {
var workers = 1;
if (this.settings.test_workers === true || this.settings.test_workers.workers === 'auto') {
workers = require('os').cpus().length;
} else if ('number' === typeof this.settings.test_workers.workers) {
workers = this.settings.test_workers.workers;
}
return false;
},
getChildProcessEnvKey : function(env, index) {
return env + '_' + (index+1);
return workers;
},
logWarning : function(message) {
console.warn(Logger.colors.brown(message));
},
logError : function(err) {
if (!err) {
return;
}
var util = require('util');
console.error('');
var stackTrace = err && err.stack;
if (!stackTrace) {
var data;
if (err.message) {
data = err.data;
err = err.message;
processesRunning : function() {
var running = 0;
for (var item in this.runningProcesses) {
if (this.runningProcesses.hasOwnProperty(item) && this.runningProcesses[item].processRunning) {
running += 1;
}
if (typeof err == 'string') {
process.stderr.write(Logger.colors.red(err));
if (data) {
if (typeof data == 'object' && Object.keys(data).length > 0) {
data = util.inspect(data);
}
process.stderr.write(data + '\n');
}
process.stderr.write('\n');
} else {
console.error(err);
}
return;
}
var parts = stackTrace.split('\n');
process.stderr.write(Logger.colors.red(parts.shift()) + '\n');
process.stderr.write(parts.join('\n') + '\n\n');
return running;
}

@@ -756,0 +707,0 @@ };

@@ -57,2 +57,28 @@ var util = require('util');

ClientManager.prototype.publishTestResults = function(testcase, results, errors) {
if (!this['@client'].api.currentTest) {
return this;
}
var currentTestSuite = this['@client'].api.currentTest.results;
currentTestSuite.passed += results.passed;
currentTestSuite.failed += results.failed;
currentTestSuite.errors += results.errors;
currentTestSuite.skipped += results.skipped;
currentTestSuite.tests += results.tests.length;
currentTestSuite.testcases = currentTestSuite.testcases || {};
currentTestSuite.testcases[testcase] = {
passed : results.passed,
failed : results.failed,
errors : results.errors,
skipped : results.skipped,
tests : results.tests.length,
assertions : results.tests
};
return this;
};
ClientManager.prototype.results = function(type, value) {

@@ -66,2 +92,6 @@ if (typeof value == 'undefined') {

ClientManager.prototype.clearResult = function() {
return this['@client'].clearResult();
};
ClientManager.prototype.terminated = function() {

@@ -72,3 +102,3 @@ return this['@client'].terminated;

ClientManager.prototype.print = function(startTime) {
return this['@client'].printResult.call(this['@client'], startTime);
return this['@client'].printResult(startTime);
};

@@ -75,0 +105,0 @@

@@ -92,8 +92,12 @@ var fs = require('fs');

if (this.globalResults.passed > 0 && this.globalResults.errors === 0 && this.globalResults.failed === 0) {
var allSkipped = Object.keys(modulekeys.modules).length === results.steps.length;
if ((this.globalResults.passed > 0 || allSkipped) && this.globalResults.errors === 0 && this.globalResults.failed === 0) {
if (!showSummary) {
return;
}
console.log(Logger.colors.green('OK. ' + this.globalResults.passed),
'total assertions passed. (' + Utils.formatElapsedTime(elapsedTime) + ')');
var count = this.globalResults.passed;
var message = (count > 1 ? ' total assertions' : ' assertion') + ' passed.';
console.log(Logger.colors.green('OK. ' + count) + message + ' (' + Utils.formatElapsedTime(elapsedTime) + ')');
} else {

@@ -113,3 +117,3 @@ var skipped = '';

console.log(Logger.colors.light_red('TEST FAILURE:'), errorsMsg + Logger.colors.red(this.globalResults.failed) +
' assertions failed, ' + Logger.colors.green(this.globalResults.passed) + ' passed', '(' + Utils.formatElapsedTime(elapsedTime) + ')' + skipped);
' assertions failed, ' + Logger.colors.green(this.globalResults.passed) + ' passed', '(' + Utils.formatElapsedTime(elapsedTime) + ')' + skipped);

@@ -130,5 +134,5 @@ this.printSummary();

test.assertions.forEach(function(a) {
if (a.failure !== false) {
if (a.elementNotFound !== false) {
if (this.options.start_session) {
console.log(' ' + a.message + ' - ' + a.failure);
console.log(' ' + a.message + ' - ' + a.elementNotFound);
} else {

@@ -135,0 +139,0 @@ console.log(' ' + a.stacktrace.split('\n').join('\n '));

@@ -79,5 +79,6 @@ var Walk = require('./walk.js');

results.steps.length > 1)) {
testSuite.printResult(time);
testSuite.printResult(time);
}
}).run().then(function onTestSuiteResolved(testResults) {
var testSuite = globalResults.modules[moduleKey];

@@ -88,2 +89,3 @@ testSuite.skipped = testResults.steps;

testSuite.tests = Object.keys(testSuite.completed).length + (testSuite.skipped && testSuite.skipped.length || 0);
var failures = 0;

@@ -106,21 +108,7 @@ var errors = 0;

/**
*
* @param {Array} testSource
* @param {object} opts
* @param {object} additionalOpts
* @param {function} finishCallback
*/
this.run = function runner(testSource, opts, additionalOpts, finishCallback) {
opts.parallelMode = process.env.__NIGHTWATCH_PARALLEL_MODE == '1';
if (opts.parallelMode) {
opts.currentEnv = process.env.__NIGHTWATCH_ENV_KEY;
}
opts.live_output = additionalOpts.live_output;
opts.start_session = additionalOpts.start_session;
opts.report_prefix = '';
this.readPaths = function(testSource, opts, cb) {
var modulePaths = [];
var joinedPaths = 0;
var modulesCount = 0;
globalStartTime = new Date().getTime();
finishCallback = finishCallback || function () {};
if (typeof testSource == 'string') {

@@ -141,3 +129,2 @@ testSource = [testSource];

var modulePaths = [], joinedPaths = 0, modulesCount = 0;
var errorMessage = ['No tests defined! using source folder:', fullPaths];

@@ -151,3 +138,3 @@ if (opts.tag_filter) {

if (err.code == 'ENOENT') {
finishCallback({
cb({
message : 'Cannot read source folder: ' + err.path

@@ -157,3 +144,3 @@ }, false);

}
finishCallback(err, false);
cb(err, false);
return;

@@ -170,51 +157,82 @@ }

opts.modulesNo = modulePaths && modulePaths.length || 0;
if (modulePaths.length === 0) {
finishCallback({message: errorMessage.join(' ')});
cb({message: errorMessage.join(' ')});
return;
}
(function runNextModule() {
var modulePath = modulePaths.shift();
var promise = runTestModule(modulePath, fullPaths, opts, additionalOpts, finishCallback);
if (promise === null) {
return;
}
cb(null, modulePaths, fullPaths);
}
}, opts);
};
promise.then(function(testResults) {
if (modulePaths.length) {
setTimeout(function() {
runNextModule();
}, 100);
} else {
var reporter = new Reporter(globalResults, testResults, globalStartTime, {
output_folder : additionalOpts.output_folder,
filename_prefix : opts.report_prefix,
globals : opts.globals,
reporter : additionalOpts.reporter,
start_session : opts.start_session
});
/**
*
* @param {Array} testSource
* @param {object} opts
* @param {object} additionalOpts
* @param {function} finishCallback
*/
this.run = function runner(testSource, opts, additionalOpts, finishCallback) {
opts.parallelMode = process.env.__NIGHTWATCH_PARALLEL_MODE == '1';
if (opts.parallelMode) {
opts.currentEnv = process.env.__NIGHTWATCH_ENV_KEY;
}
opts.live_output = additionalOpts.live_output;
opts.start_session = additionalOpts.start_session;
opts.report_prefix = '';
if (opts.output) {
reporter.printTotalResults(globalResults, testResults);
}
globalStartTime = new Date().getTime();
finishCallback = finishCallback || function () {};
reporter.save().then(function() {
reporter.globalReporter(opts.globals)(globalResults, function() {
finishCallback(null, globalResults);
});
}, function(err) {
console.log(Logger.colors.yellow('Output folder doesn\'t exist and cannot be created.'));
console.log(err.stack);
finishCallback(null);
});
}
}, function(err) {
finishCallback(err, globalResults);
});
})();
this.readPaths(testSource, opts, function (err, modulePaths, fullPaths) {
if (err) {
finishCallback(err, false);
return;
}
}, opts);
(function runNextModule() {
var modulePath = modulePaths.shift();
var promise = runTestModule(modulePath, fullPaths, opts, additionalOpts, finishCallback);
if (promise === null) {
return;
}
promise.then(function(testResults) {
if (modulePaths.length) {
setTimeout(function() {
runNextModule();
}, 100);
} else {
var reporter = new Reporter(globalResults, testResults, globalStartTime, {
output_folder : additionalOpts.output_folder,
filename_prefix : opts.report_prefix,
globals : opts.globals,
reporter : additionalOpts.reporter,
start_session : opts.start_session
});
if (opts.output) {
reporter.printTotalResults(globalResults, testResults);
}
reporter.save().then(function() {
reporter.globalReporter(opts.globals)(globalResults, function() {
finishCallback(null, globalResults);
});
}, function(err) {
console.log(Logger.colors.yellow('Output folder doesn\'t exist and cannot be created.'));
console.log(err.stack);
finishCallback(null);
});
}
}, function(err) {
finishCallback(err, globalResults);
});
})();
});
processListener(finishCallback);
};
})();

@@ -48,3 +48,6 @@ /**

SeleniumServer.prototype.start = function() {
process.stdout.write(Logger.colors.light_purple('Starting selenium server' + (this.settings.parallelMode ? ' in parallel mode' : '') +'... '));
if (this.settings.output) {
process.stdout.write(Logger.colors.light_purple('Starting selenium server' + (this.settings.parallelMode ? ' in parallel mode' : '') +'... '));
}
this.setCliArgs();

@@ -51,0 +54,0 @@ this.process = child_process.spawn('java', this.cliOpts);

@@ -7,5 +7,7 @@ var path = require('path');

function TestCase(suite, testFn) {
function TestCase(suite, testFn, numRetries, maxRetries) {
this.suite = suite;
this.testFn = testFn;
this.numRetries = numRetries;
this.maxRetries = maxRetries;
}

@@ -18,4 +20,9 @@

process.stdout.write('\n');
console.log((opts.parallelMode && !opts.live_output ? 'Results for: ' : 'Running: '),
Logger.colors.green(this.testFn));
if (this.numRetries > 0) {
console.log('Retrying (' + this.numRetries + '/' + this.maxRetries + '): ',
Logger.colors.red(this.testFn));
} else {
console.log((opts.parallelMode && !opts.live_output ? 'Results for: ' : 'Running: '),
Logger.colors.green(this.testFn));
}
}

@@ -22,0 +29,0 @@ return this;

@@ -33,2 +33,3 @@ var path = require('path');

this.options = opts;
this.maxRetries = addtOpts.retries;
this.suiteName = Utils.getTestSuiteName(this.module.moduleKey);

@@ -136,2 +137,4 @@ this.setupClient();

var doneFn = self.adaptDoneCallback(done, 'afterEach', deferred);
self.client.publishTestResults(self.currentTest, self.module.get().results, errors);
if (expectedArgs < 2) {

@@ -194,2 +197,6 @@ // user has only supplied the done callback argument (pre v0.6 behaviour), e.g.:

TestSuite.prototype.clearResult = function(startTime) {
return this.client.clearResult();
};
TestSuite.prototype.runTestSuiteModule = function() {

@@ -214,18 +221,5 @@ var self = this;

TestSuite.prototype.onTestCaseFinished = function(results, errors, time) {
var elapsedTime = (time/1000).toPrecision(4);
this.testResults.passed += results.passed;
this.testResults.failed += results.failed;
this.testResults.errors += results.errors;
this.testResults.skipped += results.skipped;
this.testResults.tests += results.tests.length;
this.testResults.time += time;
this.testResults.testcases[this.currentTest] = {
passed : results.passed,
failed : results.failed,
errors : results.errors,
skipped : results.skipped,
tests : results.tests.length,
time : elapsedTime
};
this.testResults.testcases[this.currentTest] = this.testResults.testcases[this.currentTest] || {};
this.testResults.testcases[this.currentTest].time = (time/1000).toPrecision(4);
this.emit('testcase:finished', results, errors, time);

@@ -247,3 +241,2 @@ };

this.setCurrentTest();
var self = this;

@@ -254,4 +247,20 @@ deffered = deffered || Q.defer();

var testCase = new TestCase(this, this.currentTest);
testCase.print().run().then(function(response) {
deffered = this.runTestCase(this.currentTest, deffered, 0);
} else {
deffered.resolve();
}
return deffered.promise;
};
TestSuite.prototype.runTestCase = function(currentTest, deffered, numRetries) {
var self = this;
var testCase = new TestCase(this, currentTest, numRetries, this.maxRetries);
testCase.print().run().then(function(response) {
if ((response.results.failed || response.results.errors) && numRetries < self.maxRetries) {
numRetries++;
self.clearResult();
self.runTestCase(currentTest, deffered, numRetries);
} else {
self.onTestCaseFinished(response.results, response.errors, response.time);

@@ -266,10 +275,8 @@

}
}, function(error) {
deffered.reject(error);
});
} else {
deffered.resolve();
}
}
}, function(error) {
deffered.reject(error);
});
return deffered.promise;
return deffered;
};

@@ -396,2 +403,2 @@

module.exports = TestSuite;
module.exports = TestSuite;

@@ -0,1 +1,2 @@

var path = require('path');
var Util = module.exports = {};

@@ -56,1 +57,102 @@

};
var formatRegExp = /%[sdj%]/g;
/**
* A smaller version of util.format that doesn't support json and
* if a placeholder is missing, it is omitted instead of appended
*
* @param f
* @returns {string}
*/
Util.format = function format(f) {
var i = 1;
var args = arguments;
var len = args.length;
return String(f).replace(formatRegExp, function(x) {
if (x === '%%') {
return '%';
}
if (i >= len) {
return x;
}
switch (x) {
case '%s':
return String(args[i++]);
case '%d':
return Number(args[i++]);
default:
return x;
}
});
};
Util.getScreenshotFileName = function(prefix, screenshots_path) {
prefix = prefix.replace(/\s/g, '-').replace(/"|'/g, '');
var d = new Date();
var dateParts = d.toString().replace(/:/g,'').split(' ');
dateParts.shift();
dateParts.pop();
var dateStamp = dateParts.join('-');
return path.resolve(path.join(screenshots_path, prefix + '_' + dateStamp + '.png'));
};
Util.isObject = function(obj) {
return (typeof obj == 'object') && (obj !== null);
};
Util.processAsyncQueue = function(concurrency, files, cb) {
var maxWorkers = Math.min(concurrency, files.length);
var queue = [];
var add = function(item) {
queue.push(item);
};
var workers = 0;
var index = 0;
var next = function() {
workers -= 1;
process();
};
for (var i = 0; i < files.length; i++) {
add(files[i]);
}
var process = function() {
while (workers < maxWorkers) {
workers += 1;
if (queue.length) {
var item = queue.shift();
cb(item, index++, next);
}
}
};
process();
};
Util.getModuleKey = function(filePath, srcFolders, fullPaths) {
var modulePathParts = filePath.split(path.sep);
var diffInFolder = '';
var folder = '';
var parentFolder = '';
var moduleName = modulePathParts.pop();
filePath = modulePathParts.join(path.sep);
if (srcFolders) {
for (var i = 0; i < srcFolders.length; i++) {
folder = path.resolve(srcFolders[i]);
if (fullPaths.length > 1) {
parentFolder = folder.split(path.sep).pop();
}
if (filePath.indexOf(folder) === 0) {
diffInFolder = filePath.substring(folder.length + 1);
break;
}
}
}
return path.join(parentFolder, diffInFolder, moduleName);
};
{
"name": "nightwatch",
"description": "A node.js bindings implementation for selenium 2.0/webdriver",
"version": "0.6.15",
"version": "0.7.0",
"author": {

@@ -13,8 +13,8 @@ "name": "Andrei Rusu",

"type": "MIT",
"url": "https://raw.github.com/beatfactor/nightwatch/master/LICENSE"
"url": "https://raw.github.com/nightwatchjs/nightwatch/master/LICENSE"
},
"bugs": "https://github.com/beatfactor/nightwatch/issues",
"bugs": "https://github.com/nightwatchjs/nightwatch/issues",
"repository": {
"type": "git",
"url": "git@github.com:beatfactor/nightwatch.git"
"url": "git@github.com:nightwatchjs/nightwatch.git"
},

@@ -26,3 +26,4 @@ "dependencies": {

"optimist": ">=0.3.5",
"q": "^1.1.2"
"q": "^1.1.2",
"chai-nightwatch": "~0.1.x"
},

@@ -29,0 +30,0 @@ "devDependencies": {

@@ -19,3 +19,3 @@ # Nightwatch

```sh
$ git clone git@github.com:beatfactor/nightwatch.git
$ git clone git@github.com:nightwatchjs/nightwatch.git
$ cd nightwatch

@@ -35,2 +35,2 @@ $ npm install

### Setup Guides
Browser specific setup and usage guides along with debugging instructions can be found on the [**Wiki**](https://github.com/beatfactor/nightwatch/wiki).
Browser specific setup and usage guides along with debugging instructions can be found on the [**Wiki**](https://github.com/nightwatchjs/nightwatch/wiki).

@@ -7,3 +7,6 @@ {

"globals_path" : "./globals.js",
"test_workers" : {
"enabled" : false
},
"output" : false,
"selenium" : {

@@ -10,0 +13,0 @@ "start_process" : false,

@@ -71,2 +71,7 @@ {

"url" : "/wd/hub/session/1352110219202/element",
"postdata" : "{\"using\":\"css selector\",\"value\":\"#signupSection\"}",
"response" : "{\"sessionId\":\"1352110219202\",\"status\":0,\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":604376696}"
},
{
"url" : "/wd/hub/session/1352110219202/element",
"postdata" : "{\"using\":\"xpath\",\"value\":\"//weblogin\"}",

@@ -76,2 +81,7 @@ "response" : "{\"sessionId\":\"1352110219202\",\"status\":0,\"value\":{\"ELEMENT\":\"0\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":604376696}"

{
"url" : "/wd/hub/session/1352110219202/element/0/element",
"postdata" : "{\"using\":\"css selector\",\"value\":\"#helpBtn\"}",
"response" : "{\"sessionId\":\"1352110219202\",\"status\":0,\"value\":{\"ELEMENT\":\"1\"},\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":604376696}"
},
{
"url" : "/wd/hub/session/1352110219202/elements",

@@ -92,2 +102,12 @@ "postdata" : "{\"using\":\"css selector\",\"value\":\"#weblogin\"}",

{
"url" : "/wd/hub/session/1352110219202/elements",
"postdata" : "{\"using\":\"css selector\",\"value\":\"#signupSection\"}",
"response" : "{\"sessionId\":\"1352110219202\",\"status\":0,\"value\":[{\"ELEMENT\":\"0\"},{\"ELEMENT\":\"1\"}],\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":604376696}"
},
{
"url" : "/wd/hub/session/1352110219202/element/0/elements",
"postdata" : "{\"using\":\"css selector\",\"value\":\"#helpBtn\"}",
"response" : "{\"sessionId\":\"1352110219202\",\"status\":0,\"value\":[{\"ELEMENT\":\"1\"}],\"class\":\"org.openqa.selenium.remote.Response\",\"hCode\":604376696}"
},
{
"url" : "/wd/hub/session/1352110219202/buttondown",

@@ -94,0 +114,0 @@ "postdata" : "{\"button\":0}",

@@ -20,9 +20,15 @@ var nightwatch = require('../index.js');

return nightwatch.client(opts).start().once('error', function() {
if (callback) {
callback();
}
process.exit();
});
return nightwatch.client(opts)
.on('selenium:session_create', function() {
if (callback) {
callback();
}
})
.once('error', function() {
if (callback) {
callback();
}
process.exit();
}).start();
}
};

@@ -32,8 +32,10 @@ try {

'src',
'src/expect',
'src/runner',
'src/protocol',
'src/http',
'src/index',
'src/assertions',
'src/commands',
'src/protocol',
'src/http',
'src/index'
'src/page-object'
], options, function(err) {

@@ -40,0 +42,0 @@ setTimeout(function() {

@@ -11,2 +11,3 @@ var MockServer = require('mockserver');

var client = this.client.api;
MockServer.addMock({

@@ -13,0 +14,0 @@ 'url' : '/wd/hub/session/1352110219202/element/0/clear',

@@ -170,2 +170,3 @@ var os = require('os');

eq(client.options.use_xpath, true);
eq(client.options.skip_testcases_on_fail, true);
eq(client.api.launchUrl, '/home');

@@ -172,0 +173,0 @@ eq(client.api.launch_url, '/home');

@@ -594,3 +594,11 @@

});
var CliRunner = require('../../../'+ BASE_PATH +'/../lib/runner/cli/clirunner.js');
mockery.registerMock('./errorhandler.js', {
handle : function(err) {
test.equals(err.message, 'Server already running.');
test.equals(runner.settings.parallelMode, true);
test.done();
}
});
var CliRunner = require('../../../'+ BASE_PATH + '/../lib/runner/cli/clirunner.js');
var runner = new CliRunner({

@@ -605,10 +613,4 @@ config : './nightwatch.json',

runner.globalErrorHandler = function(err) {
test.equals(err.message, 'Server already running.');
test.equals(runner.settings.parallelMode, true);
test.done();
};
runner.startSelenium();
}
};

@@ -1,2 +0,1 @@

var BASE_PATH = process.env.NIGHTWATCH_COV ? 'lib-cov' : 'lib';

@@ -28,4 +27,4 @@ var util = require('util');

setTimeout(function() {
this.emit('close');
this.emit('exit');
this.emit('close');
}.bind(this), 11);

@@ -41,2 +40,7 @@ };

});
mockery.registerMock('os', {
cpus : function() {
return [0, 1];
}
});

@@ -50,2 +54,3 @@ callback();

mockery.disable();
process.env.__NIGHTWATCH_PARALLEL_MODE = null;
callback();

@@ -65,3 +70,3 @@ },

test.equals(code, 0);
test.deepEqual(output, {});
test.deepEqual(output, { 'default': [], mixed: [] });
test.equals(self.allArgs.length, 2);

@@ -73,4 +78,4 @@ test.equals(self.allArgs[0][2], 'default');

test.ok('mixed_2' in runner.runningProcesses);
test.equals(runner.runningProcesses['default_1'], false);
test.equals(runner.runningProcesses['mixed_2'], false);
test.equals(runner.runningProcesses['default_1'].processRunning, false);
test.equals(runner.runningProcesses['mixed_2'].processRunning, false);
test.done();

@@ -97,4 +102,4 @@ });

test.ok('mixed_2' in runner.runningProcesses);
test.equals(runner.runningProcesses['mixed_1'], false);
test.equals(runner.runningProcesses['mixed_2'], false);
test.equals(runner.runningProcesses['mixed_1'].processRunning, false);
test.equals(runner.runningProcesses['mixed_2'].processRunning, false);
test.done();

@@ -104,3 +109,74 @@ });

test.ok(runner.parallelMode);
},
testParallelExecutionWithWorkersDefaults : function(test) {
var self = this;
var CliRunner = require('../../../' + BASE_PATH + '/../lib/runner/cli/clirunner.js');
var runner = new CliRunner({
config : './extra/parallelism.json'
});
runner.init(function() {
test.ok(runner.isParallelMode());
test.equals(self.allArgs.length, 17);
test.ok('sample_1' in runner.runningProcesses);
test.ok('sampleSingleTest_2' in runner.runningProcesses);
var child = runner.runningProcesses.sample_1;
test.deepEqual(child.env_output, []);
test.ok(child.mainModule.length > 0);
test.strictEqual(child.index, 0);
test.equal(child.startDelay, 10);
test.equal(child.environment, 'sample');
test.deepEqual(child.settings, runner.settings);
test.strictEqual(child.globalExitCode, 0);
test.equal(child.args.length, 2);
test.equal(child.args[0], '--test');
test.done();
});
test.ok(runner.settings.test_workers);
test.ok(runner.parallelModeWorkers());
},
testParallelExecutionWithWorkersAuto : function(test) {
var self = this;
var CliRunner = require('../../../' + BASE_PATH + '/../lib/runner/cli/clirunner.js');
var runner = new CliRunner({
config : './extra/parallelism-auto.json'
});
runner.init(function() {
test.ok(runner.isParallelMode());
test.equals(self.allArgs.length, 17);
test.done();
});
test.deepEqual(runner.settings.test_workers, {
enabled : true,
workers : 'auto'
});
test.ok(runner.parallelModeWorkers());
},
testParallelExecutionWithWorkersCount : function(test) {
var self = this;
var CliRunner = require('../../../' + BASE_PATH + '/../lib/runner/cli/clirunner.js');
var runner = new CliRunner({
config : './extra/parallelism-count.json'
});
runner.init(function() {
test.ok(runner.isParallelMode());
test.equals(self.allArgs.length, 17);
test.done();
});
test.deepEqual(runner.settings.test_workers, {
enabled : true,
workers : 6
});
test.ok(runner.parallelModeWorkers());
}
};

@@ -49,2 +49,22 @@

testRunRetries : function(test) {
test.expect(11);
var testsPath = path.join(process.cwd(), '/sampletests/withfailures');
this.Runner.run([testsPath], {
seleniumPort : 10195,
silent : true,
output : false,
globals : {
test : test
}
}, {
output_folder : false,
start_session : true,
retries: 1
}, function(err, results) {
test.equals(err, null);
test.done();
});
},
'test run multiple sources and same module name' : function(test) {

@@ -537,3 +557,21 @@ var srcFolders = [

});
},
testRunCurrentTestInAfterEach : function(test) {
var testsPath = path.join(process.cwd(), '/sampletests/withaftereach/sampleSingleTest.js');
this.Runner.run([testsPath], {
seleniumPort : 10195,
silent : true,
output : false,
globals : {
test : test
}
}, {
output_folder : false,
start_session : true
}, function(err, results) {
test.equals(err, null);
test.done();
});
}
};

@@ -94,7 +94,27 @@ var BASE_PATH = process.env.NIGHTWATCH_COV ? 'lib-cov' : 'lib';

test.ok(typeof client.api.page == 'object');
test.ok('SimplePage' in client.api.page);
client.api.page.SimplePage(test);
test.ok('SimplePageFn' in client.api.page);
test.ok('simplePageObj' in client.api.page);
client.api.page.SimplePageFn(test);
var simplePage = client.api.page.simplePageObj();
test.equals(typeof simplePage, 'object');
},
testAddPageObjectArrayPath : function(test) {
var client = this.client;
client.on('selenium:session_create', function(sessionId) {
test.done();
});
client.options.page_objects_path = ['./extra/pageobjects', './extra/otherPageobjects'];
Api.init(client);
Api.loadPageObjects();
test.ok(typeof client.api.page == 'object');
test.ok('simplePageObj' in client.api.page);
test.ok('otherPage' in client.api.page);
},
testAddCustomAssertion : function(test) {

@@ -101,0 +121,0 @@ var client = this.client;

@@ -23,2 +23,17 @@ var BASE_PATH = process.env.NIGHTWATCH_COV ? 'lib-cov' : 'lib';

testElementIdElement : function(test) {
var client = this.client;
var protocol = this.protocol;
this.client.on('selenium:session_create', function(sessionId) {
var command = protocol.elementIdElement('0', 'id', '#weblogin', function callback() {
test.done();
});
test.equal(command.request.method, 'POST');
test.equal(command.data, '{"using":"id","value":"#weblogin"}');
test.equal(command.request.path, '/wd/hub/session/1352110219202/element/0/element');
});
},
testElementPlural : function(test) {

@@ -38,2 +53,17 @@ var protocol = this.protocol;

testElementIdElementPlural : function(test) {
var client = this.client;
var protocol = this.protocol;
this.client.on('selenium:session_create', function(sessionId) {
var command = protocol.elementIdElements('0', 'id', '#weblogin', function callback() {
test.done();
});
test.equal(command.request.method, 'POST');
test.equal(command.data, '{"using":"id","value":"#weblogin"}');
test.equal(command.request.path, '/wd/hub/session/1352110219202/element/0/elements');
});
},
testElementActive : function(test) {

@@ -40,0 +70,0 @@ var protocol = this.protocol;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc