diff --git a/lib/data/context.js b/lib/data/context.js index 40a5c25b9..13c3c9897 100644 --- a/lib/data/context.js +++ b/lib/data/context.js @@ -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 = {}; @@ -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 = {}; @@ -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); }, }, }; diff --git a/lib/data/dataScenarioConfig.js b/lib/data/dataScenarioConfig.js new file mode 100644 index 000000000..2ecf335aa --- /dev/null +++ b/lib/data/dataScenarioConfig.js @@ -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; diff --git a/test/unit/data/ui_test.js b/test/unit/data/ui_test.js new file mode 100644 index 000000000..19f13f0c4 --- /dev/null +++ b/test/unit/data/ui_test.js @@ -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])); + }); + }); +});