Skip to content

Enable ScenarioContext functions for data driven tests #1503

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
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
13 changes: 9 additions & 4 deletions lib/data/context.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
const isGenerator = require('../utils').isGenerator;
const DataTable = require('./table');
const DataScenarioConfig = require('./dataScenarioConfig');

module.exports = function (context) {
context.Data = function (dataTable) {
const data = detectDataType(dataTable);
return {
Scenario(title, opts, fn) {
const scenarios = [];
if (typeof opts === 'function' && !fn) {
fn = opts;
opts = {};
Expand All @@ -16,13 +18,15 @@ module.exports = function (context) {
if (dataRow.skip) {
context.xScenario(dataTitle);
} else {
context.Scenario(dataTitle, opts, fn)
.inject({ current: dataRow.data });
scenarios.push(context.Scenario(dataTitle, opts, fn)
.inject({ current: dataRow.data }));
}
});
return new DataScenarioConfig(scenarios);
},
only: {
Scenario(title, opts, fn) {
const scenarios = [];
if (typeof opts === 'function' && !fn) {
fn = opts;
opts = {};
Expand All @@ -33,10 +37,11 @@ module.exports = function (context) {
if (dataRow.skip) {
context.xScenario(dataTitle);
} else {
context.Scenario.only(dataTitle, opts, fn)
.inject({ current: dataRow.data });
scenarios.push(context.Scenario.only(dataTitle, opts, fn)
.inject({ current: dataRow.data }));
}
});
return new DataScenarioConfig(scenarios);
},
},
};
Expand Down
66 changes: 66 additions & 0 deletions lib/data/dataScenarioConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
class DataScenarioConfig {
constructor(scenarios) {
this.scenarios = scenarios;
}

/**
* Declares that test throws error.
* Can pass an Error object or regex matching expected message.
*
* @param {*} err
*/
throws(err) {
this.scenarios.forEach(scenario => scenario.throws(err));
return this;
}

/**
* Declares that test should fail.
* If test passes - throws an error.
* Can pass an Error object or regex matching expected message.
*
*/
fails() {
this.scenarios.forEach(scenario => scenario.fails());
return this;
}

/**
* Retry this test for x times
*
* @param {*} retries
*/
retry(retries) {
this.scenarios.forEach(scenario => scenario.retry(retries));
return this;
}

/**
* Set timeout for this test
* @param {*} timeout
*/
timeout(timeout) {
this.scenarios.forEach(scenario => scenario.timeout(timeout));
return this;
}

/**
* Configures a helper.
* Helper name can be omitted and values will be applied to first helper.
*/
config(helper, obj) {
this.scenarios.forEach(scenario => scenario.config(helper, obj));
return this;
}

/**
* Append a tag name to scenario title
* @param {*} tagName
*/
tag(tagName) {
this.scenarios.forEach(scenario => scenario.tag(tagName));
return this;
}
}

module.exports = DataScenarioConfig;
82 changes: 82 additions & 0 deletions test/unit/data/ui_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const Mocha = require('mocha/lib/mocha');
const makeUI = require('../../../lib/ui');
const addData = require('../../../lib/data/context');
const DataTable = require('../../../lib/data/table');
const Suite = require('mocha/lib/suite');
const should = require('chai').should();

describe('ui', () => {
let suite;
let context;
let dataTable;

beforeEach(() => {
context = {};
suite = new Suite('empty');
makeUI(suite);
suite.emit('pre-require', context, {}, new Mocha());
addData(context);

dataTable = new DataTable(['login', 'password']);
dataTable.add(['jon', 'snow']);
dataTable.xadd(['tyrion', 'lannister']);
dataTable.add(['jaime', 'lannister']);
});

describe('Data', () => {
it('can add a tag to all scenarios', () => {
dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {});

dataScenarioConfig.tag('@user');

dataScenarioConfig.scenarios.forEach((scenario) => {
scenario.test.tags.should.include('@user');
});
});

it('can add a timout to all scenarios', () => {
dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {});

dataScenarioConfig.timeout(3);

dataScenarioConfig.scenarios.forEach(scenario => should.equal(3, scenario.test._timeout));
});

it('can add retries to all scenarios', () => {
dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {});

dataScenarioConfig.retry(3);

dataScenarioConfig.scenarios.forEach(scenario => should.equal(3, scenario.test._retries));
});

it('can expect failure for all scenarios', () => {
dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {});

dataScenarioConfig.fails();

dataScenarioConfig.scenarios.forEach(scenario => should.exist(scenario.test.throws));
});

it('can expect a specific error for all scenarios', () => {
const err = new Error();

dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {});

dataScenarioConfig.throws(err);

dataScenarioConfig.scenarios.forEach(scenario => should.equal(err, scenario.test.throws));
});

it('can configure a helper for all scenarios', () => {
const helperName = 'myHelper';
const helper = {};

dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {});

dataScenarioConfig.config(helperName, helper);

dataScenarioConfig.scenarios.forEach(scenario => should.equal(helper, scenario.test.config[helperName]));
});
});
});