Webdriver.io - how to use beforeEach hooks in the config - node.js

I am building an app using the MEAN stack and Webdriver for testing.
At the moment I am cleaning the database between tests by using Mocha's beforeEach and afterEach hooks, e.g.:
describe('Links', function() {
// drop DB collections
beforeEach(function(done){
//create database objects
});
afterEach(function(done){
// drop DB collections
});
});
Is there a way of setting up wdio.conf.js for this to happen before and after each of my tests automatically? The config's before: and after: function() {} run as a beforeAll / afterAll rather than for each test.

Yes, see this url: http://webdriver.io/guide/testrunner/gettingstarted.html
if you launch the wdio config, will generate a file named wdio.conf.js, on this file exists functions to launch scripts after or before the tests, i show the example of the functions contains this file:
// =====
// Hooks
// =====
// Run functions before or after the test. If one of them returns with a promise, WebdriverIO
// will wait until that promise got resolved to continue.
//
// Gets executed before all workers get launched.
onPrepare: function() {
// do something
},
//
// Gets executed before test execution begins. At this point you will have access to all global
// variables like `browser`. It is the perfect place to define custom commands.
before: function() {
// do something
},
//
// Gets executed after all tests are done. You still have access to all global variables from
// the test.
after: function(failures, pid) {
// do something
},
//
// Gets executed after all workers got shut down and the process is about to exit. It is not
// possible to defer the end of the process using a promise.
onComplete: function() {
// do something
}
Is important, if you launch a script asynchronous, and you wait the callback in the moment of clean the database so you need a promise, else the next step hook will launch not waiting the previous function hook, example:
onPrepare: function() {
return new Promise(function(resolve, reject) {
sauceConnectLauncher({
username: 'the_pianist2',
accessKey: '67224e83a-1cf7440d-8c88-857c4d3cde49',
}, function (err, sauceConnectProcess) {
if (err) {
return reject(err);
}
console.log('success');
resolve();
});
});
},

Related

In node, how do you wait until a callback has been called?

I have a function which resolves by taking a callback like function(error, result) { ... } as a parameter. I'm trying to use mocha to test this function, but the problem is that the function returns asynchronously, so there's no good place for me to put the done(). If I put inside my result handler, it takes too long and mocha times out. If I put it outside, the test always passes because the handler hasn't been called yet. Here is my code. What's the best way to get around this?
lbl.createLabels is a function that takes an array of customers, and a directory, and creates a bunch of files in that directory, and then asynchronously calls the callback of type: function(error, callback).
describe('Tests', () => {
it('returns a list of customer objects', (done) => {
lbl.createLabels(customers, __dirname + "/..", (err, result) => {
err.should.equal(undefined)
result.should.be.a('array')
result[0].should.have.property('id')
result[0].should.have.property('tracking')
result[0].should.have.property('pdfPath')
const a = {prop:3}
a.prop.should.be.an('array')
done() // putting done() here results in a timeout
})
done() // putting done here results in the test exiting before the callback gets called
})
})
Mocha's documentation has an entire section describing how to test asynchronous code:
https://mochajs.org/#asynchronous-code
Testing asynchronous code with Mocha could not be simpler! Simply invoke the callback when your test is complete. By adding a callback (usually named done) to it(), Mocha will know that it should wait for this function to be called to complete the test.
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(function(err) {
if (err) done(err);
else done();
});
});
});
});

Mocha tests cases not waiting before to complete

I'm writing test cases with mocha in Nodejs and want to reset database data before running the tests. I'm using Knex as query builder for executing queries.
I wrote following logic:
describe('Activities:', function() {
before(funtion(){
activityDBOperations.deleteAll()
.then(function(){
// all records are deleted
});
});
it('it should add a record into Activities table: multiple time activity', function(done) {
activityDBOperations.addRecord(requestParams)
.then(function(data) {
expect(data.length > 0).to.equal(true);
done();
});
});
});
The problem is that test cases start executing and not waiting for deleteAll operation to finish. What I understand is since deleteAll is returning promise, the program execution move forward because of asynchronous nature of promises.
How can I make sure that test cases should run only when deleteAll has finished?
Either provide a callback to your before hook and call it in then:
before(function(done) {
activityDBOperations.deleteAll()
.then(function() {
// all records are deleted
done();
});
});
or, according to Mocha docs, just return a promise from before:
before(function() {
return activityDBOperations.deleteAll();
});
Add return statements so the Promises are actually returned.

Avoid the task completion callback called too many times?

Given the following gulp tasks I'm able to successfully start the gulp, webpack and nodemon process, but the webpack tasks are open ended, so they will continue to fire the completion handler when their watch / compile cycle is complete.
The server task depends on the client task output, so I need these operations to be synchronous, hence the done
function onBuild(done) {
return function(err, stats) {
if(err) {
gutil.log('Error', err);
if(done) {
done();
}
} else {
Object.keys(stats.compilation.assets).forEach(function(key){
gutil.log('Webpack: output ', gutil.colors.green(key));
});
gutil.log('Webpack: ', gutil.colors.blue('finished ', stats.compilation.name));
if(done) {
done();
}
}
}
}
//dev watch
gulp.task('webpack-client-watch', function(done) {
webpack(devConfig[0]).watch(100, function(err, stats) {
onBuild(done)(err, stats);
});
});
gulp.task('webpack-server-watch', function(done) {
webpack(devConfig[1]).watch(100, function(err, stats) {
onBuild(done)(err, stats);
nodemon.restart();
});
});
gulp.task('webpack-watch',function(callback) {
runSequence(
'webpack-client-watch',
'webpack-server-watch',
callback
);
});
gulp.task('nodemon', ['webpack-watch'], function() {
nodemon({
script: path.join('server/dist/index.js'),
//ignore everything
ignore: ['*'],
watch: ['foo/'],
ext: 'noop'
}).on('restart', function() {
gutil.log(gutil.colors.cyan('Restarted'));
});
});
When I change a file, the watcher does its thing and gulp complains about the callback being called yet again.
[15:00:25] Error: task completion callback called too many times
I've looked at this, but not sure if its applicable.
Why might I be getting "task completion callback called too many times" in gulp?
Basically, I just want this to work synchronously and continuously without error.
gulp nodemon
This solved it for me: Just don't call the callback parameter in your webpack-watch task. Leave it out completely.
After that, the watcher works fine and fast without complaining.
If public folder exists in your application. Please remove and re-run, after you can see this issue resolved.

Difficulty testing asynchronous function

I'm trying to learn Mocha and am having trouble dealing with asynchronous code.
I would like to create a test database, populate it with some data, and then write some tests. My issue is that I can not figure out how to require that my test database be created and populated before additional tests are run. Here's the basic structure of my code:
describe('Database', function() {
// create the DB and populate it with some test data
iniDB(dbName, function(db) {
addDataToDB(db, table, data);
});
// tests below here
});
From reading the documentation, it seems that I need to use before to ensure that my asynchronous code runs prior to my tests. To attempt this, I tried using something like this:
describe('Database', function() {
before(function(done) {
iniDB(dbName, function(db) {
addDataToDB(db, table, data);
});
done();
});
// tests below here
});
How can I tell Mocha to first create and populate my database before running subsequent tests?
Using before() is the right solution, just invoke done() when all your data has finished writing. Something like this:
before(function(done) {
iniDB(dbName, function(db) {
addDataToDB(db, table, data, function() {
done();
});
});
});

Mocha beforeEach and afterEach during testing

I have been trying to test my test server using mocha. This is the following code that I use, almost the same as one found in another similar post.
beforeEach(function(done) {
// Setup
console.log('test before function');
ws.on('open', function() {
console.log('worked...');
done();
});
ws.on('close', function() {
console.log('disconnected...');
});
});
afterEach(function(done) {
// Cleanup
if(readyState) {
console.log('disconnecting...');
ws.close();
} else {
// There will not be a connection unless you have done() in beforeEach, socket.on('connect'...)
console.log('no connection to break...');
}
done();
});
describe('WebSocket test', function() {
//assert.equal(response.result, null, 'Successful Authentification');
});
the problem is that when I execute this draft, none of the console.log that is expected to be seen is visible on the command prompt. Can you please explain to me what am I doing wrong?
Georgi is correct that you need an it call to specify a test but you don't need to have a top level describe in your file if you don't want to. You could replace your single describe with a bunch of it calls:
it("first", function () {
// Whatever test.
});
it("second", function () {
// Whatever other test.
});
This works very well if your test suite is small and composed of only one file.
If your test suite is bigger or spread among multiple files, I would very strongly suggest you put your beforeEach and afterEach together with your it inside the describe, unless you are absolutely positive that every single test in the suite needs the work done by beforeEach or afterEach. (I've written multiple test suites with Mocha and I've never had a beforeEach or afterEach that I needed to run for every single test.) Something like:
describe('WebSocket test', function() {
beforeEach(function(done) {
// ...
});
afterEach(function(done) {
// ...
});
it('response should be null', function() {
assert.equal(response.result, null, 'Successful Authentification');
});
});
If you do not put your beforeEach and afterEach inside describe like this, then let's say you have one file to test web sockets and another file to test some database operations. The tests in the file that contains the database operation tests will also have your beforeEach and afterEach executed before and after them. Putting the beforeEach and afterEach inside the describe like shown above will ensure that they are performed only for your web socket tests.
You have no tests in your example. If there are no tests to be run, then before and after hooks won't be invoked. Try adding a test like:
describe('WebSocket test', function() {
it('should run test and invoke hooks', function(done) {
assert.equal(1,1);
done();
});
});
You need to have a test-callback(eg. it) inside suite-callback(eg, describe) to execute beforeEach() and afterEach() hooks. More info https://mochajs.org/#run-cycle-overview

Resources