Skip to content

Fix bootstrapAll and teardownAll calls from exported object #1492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions docs/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ CodeceptJS provides API to run custom code before and after the test and inject
In case you need to execute arbitrary code before or after the tests,
you can use `bootstrap` and `teardown` config. Use it to start and stop webserver, Selenium, etc.

When using the [Multiple Execution](http://codecept.io/advanced/#multiple-execution) mode , there are two additional hooks available; `bootstrapAll` and `teardownAll`. These hooks are only called once each; before all of the test suites are run (`bootstrapAll`) and after all of the test suites have finished (`teardownAll`).
When using the [Multiple Execution](http://codecept.io/advanced/#multiple-execution) mode, there are two additional hooks available; `bootstrapAll` and `teardownAll`. See [BootstrapAll & TeardownAll](#bootstrapall--teardownall) for more information.

There are different ways to define bootstrap and teardown functions:

Expand Down Expand Up @@ -113,6 +113,27 @@ exports.config = {

```

## BootstrapAll & TeardownAll

There are two additional hooks for [multiple browser execution](http://codecept.io/advanced/#multiple-execution) mode.
These hooks are only called once each; before all of the multiple runs are start (`bootstrapAll`) and after all of the multiple runs have finished (`teardownAll`).
Unlike them, the `bootstrap` and `teardown` hooks are called between and after each of multiple runs respectively.

For example, you use Firefox and Chrome browsers in multiple run.
First, `bootstrapAll` is called. Then two `bootstrap` runs: first is for Firefox and second - for Chrome.
Then tests in Chrome end, so `teardown` for Chrome runs. Same for Firefox, after tests `teardown` is executed.
Finally, `teardownAll` runs.

The `bootstrapAll` and `teardownAll` hooks are preferred to use for setting up common logic of tested project: to start application server or database, to start webdriver's grid.
The `bootstrap` and `teardown` hooks are used for setting up each testing browser: to create unique [cloud testing server](https://codecept.io/helpers/WebDriverIO#cloud-providers) connection or to create specific browser-related test data in database (like users with names with browsername in it).

Same as `bootstrap` and `teardown`, there are 3 ways to define `bootstrapAll` and `teardownAll` functions:

* JS file executed as is (synchronously).
* JS file exporting function with optional callback for async execution.
* JS file exporting an object with `bootstrapAll` and `teardownAll` methods.
* Inside JS config file

### Example: BootstrapAll & TeardownAll Inside Config

Using JavaScript-style config `codecept.conf.js`, bootstrapAll and teardownAll functions can be placed inside of it:
Expand Down Expand Up @@ -169,7 +190,44 @@ exports.config = {
}
```

**Note**: The `bootstrapAll` and `teardownAll` hooks are only called when using [Multiple Execution](http://codecept.io/advanced/#multiple-execution).
### Example: Bootstrap & Teardown Inside an Object

Examples above can be combined into one file.

Add to config (`codecept.json`):

```js
"bootstrapAll": "./presettings.js"
"teardownAll": "./presettings.js"
"bootstrap": "./presettings.js"
"teardown": "./presettings.js"
```

`presettings.js` should export object with `bootstrap` and `teardown` functions:

```js
// presettings.js
const server = require('./app_server');
const browserstackConnection = require("./browserstackConnection");
const uniqueIdentifier = generateSomeUniqueIdentifierFunction();

module.exports = {
bootstrapAll: function(done) {
server.start(done);
},
teardownAll: function(done) {
server.stop(done);
},
bootstrap: function(done) {
browserstackConnection.connect(uniqueIdentifier);
},
teardown: function(done) {
browserstackConnection.disconnect(uniqueIdentifier);
},
}
```

**Remember**: The `bootstrapAll` and `teardownAll` hooks are only called when using [Multiple Execution](http://codecept.io/advanced/#multiple-execution).

## Plugins

Expand Down
4 changes: 2 additions & 2 deletions lib/command/run-multiple.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ module.exports = function (selectedRuns, options) {
}

const done = () => event.emit(event.multiple.before, null);
runHook(config.bootstrapAll, done, 'multiple.bootstrap');
runHook(config.bootstrapAll, done, 'bootstrapAll');

if (options.config) { // update paths to config path
config.tests = path.resolve(testRoot, config.tests);
Expand Down Expand Up @@ -91,7 +91,7 @@ module.exports = function (selectedRuns, options) {
return childProcessesPromise.then(() => {
// fire hook
const done = () => event.emit(event.multiple.after, null);
runHook(config.teardownAll, done, 'multiple.teardown');
runHook(config.teardownAll, done, 'teardownAll');
});
};

Expand Down
4 changes: 4 additions & 0 deletions test/data/sandbox/bootstrapall.function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = async (done) => {
await console.log('"bootstrapAll" is called.');
done();
};
6 changes: 6 additions & 0 deletions test/data/sandbox/bootstrapall.object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
bootstrapAll: async (done) => {
await console.log('"bootstrapAll" is called.');
done();
},
};
19 changes: 19 additions & 0 deletions test/data/sandbox/codecept.bootstrapall.multiple.code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
exports.config = {
tests: './*_test.js',
timeout: 10000,
output: './output',
helpers: {
FileSystem: {},
},
include: {},
bootstrap: false,
mocha: {},
name: 'require test',
multiple: {
default: {
browsers: ['chrome', { browser: 'firefox' }],
},
},
bootstrapAll: () => console.log('"bootstrapAll" is called.'),
teardownAll: () => console.log('"teardownAll" is called.'),
};
19 changes: 19 additions & 0 deletions test/data/sandbox/codecept.bootstrapall.multiple.function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
exports.config = {
tests: './*_test.js',
timeout: 10000,
output: './output',
helpers: {
FileSystem: {},
},
include: {},
bootstrap: false,
mocha: {},
name: 'require test',
multiple: {
default: {
browsers: ['chrome', { browser: 'firefox' }],
},
},
bootstrapAll: './bootstrapall.function.js',
teardownAll: './teardownall.function.js',
};
19 changes: 19 additions & 0 deletions test/data/sandbox/codecept.bootstrapall.multiple.object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
exports.config = {
tests: './*_test.js',
timeout: 10000,
output: './output',
helpers: {
FileSystem: {},
},
include: {},
bootstrap: false,
mocha: {},
name: 'require test',
multiple: {
default: {
browsers: ['chrome', { browser: 'firefox' }],
},
},
bootstrapAll: './bootstrapall.object.js',
teardownAll: './teardownall.object.js',
};
4 changes: 4 additions & 0 deletions test/data/sandbox/teardownall.function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = async (done) => {
await console.log('"teardownAll" is called.');
done();
};
6 changes: 6 additions & 0 deletions test/data/sandbox/teardownall.object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
teardownAll: async (done) => {
await console.log('"teardownAll" is called.');
done();
},
};
34 changes: 34 additions & 0 deletions test/runner/run_multiple_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,40 @@ describe('CodeceptJS Multiple Runner', function () {
});
});

describe('bootstrapAll and teardownAll', () => {
const _codecept_run = `run-multiple --config ${codecept_dir}`;

it('should be executed from function in config', (done) => {
exec(`${runner} ${_codecept_run}/codecept.bootstrapall.multiple.code.js default`, (err, stdout, stderr) => {
stdout.should.include('CodeceptJS'); // feature
stdout.should.include('"bootstrapAll" is called.');
stdout.should.include('"teardownAll" is called.');
assert(!err);
done();
});
});

it('should be executed from function in file', (done) => {
exec(`${runner} ${_codecept_run}/codecept.bootstrapall.multiple.function.js default`, (err, stdout, stderr) => {
stdout.should.include('CodeceptJS'); // feature
stdout.should.include('"bootstrapAll" is called.');
stdout.should.include('"teardownAll" is called.');
assert(!err);
done();
});
});

it('should be executed from object in file', (done) => {
exec(`${runner} ${_codecept_run}/codecept.bootstrapall.multiple.object.js default`, (err, stdout, stderr) => {
stdout.should.include('CodeceptJS'); // feature
stdout.should.include('"bootstrapAll" is called.');
stdout.should.include('"teardownAll" is called.');
assert(!err);
done();
});
});
});

describe('with require parameter', () => {
const _codecept_run = `run-multiple --config ${codecept_dir}`;
const moduleOutput = 'Module was required 1';
Expand Down