Hi I have the following simple nightwatch demo script which is looping when ran with multiple browser environment, but which works fine if I run the test with single browser.
Following arguments loops the test:
var argv = {
test: 'nightwatchgoogletest.js',
config: 'nightwatch.json',
reporter: 'junit',
env : 'default,chrome'
};
Following works fine:
var argv = {
test: 'nightwatchgoogletest.js',
config: 'nightwatch.json',
reporter: 'junit',
env : 'chrome' (or default or any single browser)
};
Following is my code, please let me know what am I doing wrong here.
nightwatchgoogletest.js :
module.exports = {
'Demo test Google' : function (client) {
client
.url('http://google.no')
.pause(1000);
// expect element to be present in 1000ms
client.expect.element('body').to.be.present.before(1000);
// expect element <#lst-ib> to have css property 'display'
client.expect.element('#lst-ib').to.have.css('display');
// expect element to have attribute 'class' which contains text 'vasq'
client.expect.element('body').to.have.attribute('class').which.contains('vasq');
// expect element <#lst-ib> to be an input tag
client.expect.element('#lst-ib').to.be.an('input');
// expect element <#lst-ib> to be visible
client.expect.element('#lst-ib').to.be.visible;
client.end();
}
};
And have written the following node script to call above test:
var Nightwatch = require('nightwatch');
function proceess_test() {
try {
var argv = {
test: 'nightwatchgoogletest.js',
config: 'nightwatch.json',
reporter: 'junit',
env : 'default,chrome'
};
console.log("\n>> Initiating Tests for ...",process.env.__NIGHTWATCH_ENV_KEY);
var settings = {};
var done = function() {console.log("done")};
Nightwatch.runner(argv, done, settings);
done();
} catch (error) {
console.log('Exception: ' + error.message);
}
}
proceess_test();
With the following nightwatch configuration:
http://www.jsoneditoronline.org/?id=7e8e1616d595417ceeafaccc6358b33d
But when I run the test, it going in an infinite testing loop as follows:
Related
We have protractor-cucumber framework as e2e test. Till now we use the conf file with statically mentioning the environment details inside the conf json. I would like to pass user defined arguments with the protractor_conf file something like below.
protractor protractor_conf.js -DbrowserName=chrome -DexecPlatform=(native/sauce)
and would like to fetch this argument inside the conf.js and substitute under the capabilities section. I could not get proper details on net, so any help/suggestions would be appreciated.
You can add Parameters in your conf.js file then pass the arugs from the command line.
Here is an example.
// The params object will be passed directly to the Protractor instance,
// and can be accessed from your test as browser.params. It is an arbitrary
// object and can contain anything you may need in your test.
// This can be changed via the command line as:
// --params.environment.Browser "Firefox"
params: {
environment: {
browser: 'Chrome',
execPlatform: 'sauce',
password: 'default'
}
}
Now from we can pass the arugs from command line
protractor conf.js --parameters.environment.browser= Firefox --parameters.environment.execPlatform=sauce --parameters.environment.password=password123
Next, you can also refer these parameters in your spec file.
describe('describe some test', function() {
it('describe some step', function() {
$('.password').sendKeys(browser.params.login.password);
});
});
There are multiple advantages to having a parameter setup.
If we know we are going to be using the same values in multiple spec files (i.e login email and password), parameters are great for removing unnecessary repetition.
Being able to change parameter values at runtime makes it easier to run the same tests with different data.
Increases security – Having passwords hardcoded in your spec files is not a great approach. Parameters give you the ability to keep them out and instead provide them at runtime.
You can use process api to parse the arguments in cmd line.
// protractor conf.js
var readParamsFromCli = function() {
var paramsPair = process.argv.slice(3).filter(function(it){
return it.startsWith('-D');
});
var params = {};
paramsPair.forEach(function(pair){
var parts = pair.split('=');
var name = parts[0].trim().replace('-D', '');
var value = parts[1] && parts[1].trim() || true;
params[name] = value;
});
return params;
};
var params = readParamsFromCli();
var capbilities = {
browserName: params.browserName || 'chrome',
platform: params.execPlatform
};
exports.config = {
...
capbilities: capbilities
};
Then you can run case as following:
protractor protractor_conf.js -DbrowserName=chrome -DexecPlatform=native
You could split the configuration up into multiple config files. For example protractor-chrome.conf.js:
const baseConf = require('./protractor.conf').config;
exports.config = Object.assign({
capabilities: {
browserName: 'chrome'
}
}, baseConf);
This will be similar to 2nd example but uses the config file directly.
const args = require('minimist')(process.argv.slice(2));
exports.config = {
//your config stuff
baseUrl: args.Url ? args.URL : <your default>,
capabilities: {
'browserName': 'chrome',
chromeOptions: {
args: [args.Options]
},
}
}
Then in your package.json script like this:
"e2e": "protractor protractor.conf.js --Url=http://test.com" --Options=--headless
I am attempting to re-run my gulp build when gulpfile.js changes, but I am having issues with the method all of my research has lead me to.
I have one watcher for all my less and javascript files and a configuration object that has the list of files to watch, how they are output, etc. This is a stripped-down example of what it looks like:
var $ = require('gulp-load-plugins')();
var config = {
root: rootPath,
output: {
app: 'app',
vendor: 'vendor'
}, // ...
};
gulp.task('default', ['build', 'watch']);
gulp.task('build', ['clean', 'less:app', 'less:theme', 'css:vendor', 'js:app', 'js:vendor', 'rev', 'css:copyfonts']);
gulp.task('watch', function () {
var allFiles = config.styles.appSrc
.concat(config.styles.vendorSrc)
.concat(config.scripts.appSrc)
.concat(config.scripts.vendorSrc);
$.watch(allFiles, function () {
gulp.start('default');
});
});
gulp.task('watch:gulp', function () {
var p;
gulp.watch('gulpfile.js', spawnUpdatedGulp);
spawnUpdatedGulp();
function spawnUpdatedGulp() {
if (p) {
p.kill();
}
p = spawn('gulp', ['default', '--color'], { stdio: 'inherit' });
}
});
// .. other build tasks ..
The above code shows how I tried the accepted answer to this:
How can Gulp be restarted upon each Gulpfile change?
However, it has a major issue. When I run watch:gulp, it runs the build just fine, and everything is great. The config.output.app variable is how the app specific css and js files are named, so my test case has been:
run gulp:watch, check that the css output is named according to config.output.app
change config.output.app, and perform step #1 again
save any random javascript file that it is watching, and see if it builds correctly
Step 3 is riddled with permission errors because of multiple watchers on the files, and this only gets worse the more I repeat steps 1 and 2. Visual Studio will even freeze.
I have not found a way to clean up the old watchers. I tried to manually kill them like this:
var appFileWatcher;
gulp.task('watch', function () {
var allFiles = config.styles.appSrc
.concat(config.styles.vendorSrc)
.concat(config.scripts.appSrc)
.concat(config.scripts.vendorSrc);
appFileWatcher = $.watch(allFiles, function () {
gulp.start('default');
});
});
gulp.task('watch:gulp', function () {
var p;
var gulpWatcher = $.watch('gulpfile.js', spawnUpdatedGulp);
spawnUpdatedGulp();
function spawnUpdatedGulp() {
if (p) {
p.kill();
}
if (appFileWatcher) {
appFileWatcher.unwatch();
}
gulpWatcher.unwatch();
p = spawn('gulp', ['default', '--color'], { stdio: 'inherit' });
}
});
This also does not work. I still get multiple watchers trying to perform the build when I perform my same test case.
How do I kill those watchers that stay around after the new gulp process is spawned?
I have a grunt task that runs all of my nodejs server side test files.
grunt.registerTask('serverTest', ['env:test', 'mongoose', 'mochaTest']);
While developing tests I would like to only run the test I'm currently working on. My task is setup to run a list of all test assets in the code base:
mochaTest: {
src: testAssets.tests.server,
options: {
reporter: 'spec'
}
},
I would like to specify a filter parameter at the cli to only select a specific file from testAssets.tests.server which is a big list of tests since it's defined as modules/*/tests/server/**/*.js and returns every test in the code base.
For example if I entered the following at the command line:
grunt serverTest:*fileUnderTest.js
Grunt would filter the testAssets.tests.server and only execute the files that match *fileUnderTest.js
I've read through the documentation and seen a lot of examples but can't figure out how to do this without creating a separate target and specifying the file name in the grunt file.
There's probably a more efficient means but the following code at the start of my gruntfile got the filtering working for me.
// get regex epression from CLI
var expression = grunt.option('filter');
//filter the testAssets.tests.server array
var testFiles = filtered(getGlobbedPaths(testAssets.tests.server),expression);
// test array with regex and return array of matches
var filtered = (function(arr,pattern){
var filtered = [],
i = arr.length,
re = new RegExp(pattern);
while (i--) {
if (re.test(arr[i])) {
filtered.push(arr[i]);
}
}
return filtered;
});
And then the grunt task becomes:
mochaTest: {
src: testFiles,
options: {
reporter: 'spec'
}
}
grunt.registerTask('serverTest', ['env:test', 'mongoose', 'mochaTest']);
So a command line call such as:
grunt serverTest --filter=comment.server.model.tests.js
Will run any test file matching the filter and a command like:
grunt serverTest
Will run all test files in the project
For reference my project is based on meanjs which globs all the paths to files so I run the getGlobbedPaths() function which is defined in config.js to first expand the file path array prior to filtering:
var getGlobbedPaths = function(globPatterns, excludes) {
// URL paths regex
var urlRegex = new RegExp('^(?:[a-z]+:)?\/\/', 'i');
// The output array
var output = [];
// If glob pattern is array so we use each pattern in a recursive way, otherwise we use glob
if (_.isArray(globPatterns)) {
globPatterns.forEach(function(globPattern) {
output = _.union(output, getGlobbedPaths(globPattern, excludes));
});
} else if (_.isString(globPatterns)) {
if (urlRegex.test(globPatterns)) {
output.push(globPatterns);
} else {
glob(globPatterns, {
sync: true
}, function(err, files) {
if (excludes) {
files = files.map(function(file) {
if (_.isArray(excludes)) {
for (var i in excludes) {
file = file.replace(excludes[i], '');
}
} else {
file = file.replace(excludes, '');
}
return file;
});
}
output = _.union(output, files);
});
}
}
return output;
};
I have Gulpfile with jshint configured to use jshint-stylish reporter. I need to pass option verbose to reporter in order to display warning codes. Is it possible to do it using Gulp?
Current my gulpfile.js looks like below:
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var compass = require('gulp-compass');
var path = require('path');
require('shelljs/global');
var jsFiles = ['www/js/**/*.js', '!www/js/libraries/**/*.js', 'www/spec/**/*.js', '!www/spec/lib/**/*.js'];
var sassFiles = 'www/sass/*.scss';
gulp.task('lint', function () {
return gulp
.src(jsFiles)
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));
});
gulp.task('compass', function () {
gulp.src(sassFiles)
.pipe(compass({
project: path.join(__dirname, 'www'),
css: 'css',
sass: 'sass',
image: 'img',
font: 'fonts'
})).on('error', function() {});
});
var phonegapBuild = function (platform) {
if (!which('phonegap')) {
console.log('phonegap command not found')
return 1;
}
exec('phonegap local build ' + platform);
};
gulp.task('build:android', ['lint', 'compass'], function () {
phonegapBuild('android');
});
gulp.task('build:ios', ['lint', 'compass'], function () {
phonegapBuild('ios');
});
gulp.task('watch', function() {
gulp.watch(jsFiles, ['lint']);
gulp.watch(sassFiles, ['compass']);
});
gulp.task('default', ['lint', 'compass']);
Well, this, plus the fact that the output of the stylish reporter is hardly readable on Windows due to the darkness of the blue text, so I have to keep going in an manually changing the colour after installing it, has made me do something about it. So you should hopefully have more luck with this reporter I've just written:
https://github.com/spiralx/jshint-summary
You basically use it like this;
var summary = require('jshint-summary');
// ...
.pipe(jshint.reporter(summary({
verbose: true,
reasonCol: 'cyan,bold',
codeCol: 'green'
})
and the summary function will initialise the function passed to JSHint with those settings - see the page on Github for a bit more documentation.
It's got some very basic tests, and the library's gulpfile.js uses it to show its own JSHint output :)
How about using similar technique, as you already did with phonegap?
var jshint = function (parameter) {
// todo: define paths with js files, or pass them as parameter too
exec('jshint ' + paths + ' ' + parameter);
};
Based on https://github.com/wearefractal/gulp-jshint/blob/master/index.js#L99 it appears that gulp-jshint doesn't facilitate passing more than the name to the reporter if you load it with a string. It seems a simple thing to extend though. I'll race you to a pull request. :D
Alternatively, try something like this:
var stylish = require('jshint-stylish');
// ...
.pipe(jshint.reporter(stylish(opt)));
I'm pretty sure I have the syntax wrong, but this may get you unstuck.
It's annoying, and makes any decent reporter somewhat tricky to use within the existing framework. I've come up with this hack for the Stylish reporter, it's just currently in my gulpfile.js:
function wrapStylishReporter(reporterOptions) {
var reporter = require(stylish).reporter,
reporterOptions = reporterOptions || {};
var wrapped = function(results, data, config) {
var opts = [config, reporterOptions].reduce(function(dest, src) {
if (src) {
for (var k in src) {
dest[k] = src[k];
}
}
return dest;
}, {});
reporter(results, data, opts);
};
return jshint.reporter(wrapped);
}
And then for the task definition itself:
gulp.task('lint', function() {
return gulp.src('+(bin|lib)/**/*.js')
.pipe(jshint())
.pipe(wrapStylishReporter({ verbose: true }))
.pipe(jshint.reporter('fail'));
});
Ideally reporters would either be a function that takes an options parameter and returns the reporter function, or a fairly basic class so you could have options as well as state.
I have a problem where I am trying to get the Karma runner to execute my mocha specs that are loaded using RequireJS. Unfortunately, I can't figure out why the specs won't execute even though the framework is loading. Here are the relavant bits I hope:
// karma.conf.js
// Karma configuration
// Generated on Thu Jun 13 2013 13:38:06 GMT-0500 (CDT)
// base path, that will be used to resolve files and exclude
basePath = '';
// list of files / patterns to load in the browser
files = [
MOCHA,
MOCHA_ADAPTER,
REQUIRE,
REQUIRE_ADAPTER,
// !! libs required for test framework
{pattern: 'test/lib/chai.js', included: false},
// !! put what used to be in your requirejs 'shim' config here
'app/bower_components/angular/angular.js',
'app/bower_components/angular-cookies/angular-cookies.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-scenario/angular-scenario.js',
'app/bower_components/jquery/jquery.js',
{pattern: 'app/scripts/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false},
'test/test-main.js'
];
// list of files to exclude
exclude = [
'app/scripts/main.js'
];
// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters = ['progress'];
// web server port
port = 9876;
// cli runner port
runnerPort = 9100;
// enable / disable colors in the output (reporters and logs)
colors = true;
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_INFO;
// enable / disable watching file and executing tests whenever any file changes
autoWatch = true;
browsers = ['Chrome'];
// If browser does not capture in given timeout [ms], kill it
captureTimeout = 60000;
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = false;
Then this is my test-main.js file which handles the requireJS loading
var tests = [];
for (var file in window.__karma__.files) {
if (/Spec\.js$/.test(file)) {
tests.push('../../' + file.replace(/^\/base\//, '').replace(/\.js$/, ''));
}
}
requirejs.config({
baseUrl: '/base/app/scripts/',
paths: {
chai: "../../test/lib/chai",
namespace: "vendor/namespace",
jquery: "../bower_components/jquery/jquery",
bootstrap: "vendor/bootstrap",
angular: "../bower_components/angular/angular",
angularCookies: "../bower_components/angular-cookies/angular-cookies",
angularResource: "../bower_components/angular-resource/angular-resource",
angularSanitize: "../bower_components/angular-sanitize/angular-sanitize",
applicationController: "controllers/application",
gameController: "controllers/game",
gamePresenter: "directives/game-presenter",
}
});
require(tests, function(){
window.__karma__.start();
});
This is an example of my spec that I am running:
define(['chai', 'namespace','racecar'],
function(chai, namespace, racecar) {
var assert = chai.assert,
expect = chai.expect,
should = chai.should();
// This executes correctly!
var player = new com.angular.racecar.Player();
player.should.be.an('object');
// This never gets run!
describe('Player', function () {
it('should be an object', function () {
var player = new com.angular.racecar.Player();
player.should.be.an('object');
});
});
});
Here is an example of the code I am testing:
(function() {
"use strict";
var Player;
namespace('com.angular.racecar', {
Player: Player = (function() {
function Player() {
this.car = new com.angular.racecar.Car();
return this;
}
return Player;
})()
});
}(this)
The output simply says:
INFO [Chrome 27.0 (Mac)]: Connected on socket id fc4Kj9T0ppIzp9D0kmdH
Chrome 27.0 (Mac): Executed 0 of 0 SUCCESS (0.192 secs / 0 secs)
Angular-mock is supposed to work only with Jasmine. To make it work with Mocha you need to use the modified angular-mock created by http://www.yearofmoo.com/ described in their testing article. The direct link to the file is https://github.com/yearofmoo-articles/AngularJS-Testing-Article/tree/master/test/lib/angular
To use mocha tests you need to use the unstable branch of angular JS, and in that >= v1.1.1
You can see they added mocha support here : https://github.com/angular/angular.js/blob/master/CHANGELOG.md#111-pathological-kerning-2012-11-26
Diff: https://github.com/angular/angular.js/commit/92558fe4119fb1ee793d781de1888abef181c7f6