cucumber
Version:
The official JavaScript implementation of Cucumber.
1,685 lines (1,373 loc) • 2.85 MB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Cucumber = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
function Cucumber(featureSource, supportCodeInitializer, options) {
var configuration = Cucumber.VolatileConfiguration(featureSource, supportCodeInitializer, options);
var runtime = Cucumber.Runtime(configuration);
return runtime;
}
Cucumber.Api = require('./cucumber/api');
Cucumber.Ast = require('./cucumber/ast');
Cucumber.Cli = require('./cucumber/cli');
Cucumber.Debug = require('./cucumber/debug'); // Untested namespace
Cucumber.Listener = require('./cucumber/listener');
Cucumber.Parser = require('./cucumber/parser');
Cucumber.Runtime = require('./cucumber/runtime');
Cucumber.SupportCode = require('./cucumber/support_code');
Cucumber.TagGroupParser = require('./cucumber/tag_group_parser');
Cucumber.Type = require('./cucumber/type');
Cucumber.Util = require('./cucumber/util');
Cucumber.VolatileConfiguration = require('./cucumber/volatile_configuration');
Cucumber.VERSION = '0.6.0';
module.exports = Cucumber;
},{"./cucumber/api":2,"./cucumber/ast":4,"./cucumber/cli":23,"./cucumber/debug":24,"./cucumber/listener":27,"./cucumber/parser":35,"./cucumber/runtime":36,"./cucumber/support_code":47,"./cucumber/tag_group_parser":55,"./cucumber/type":56,"./cucumber/util":60,"./cucumber/volatile_configuration":66}],2:[function(require,module,exports){
var Api = {};
Api.Scenario = require('./api/scenario');
module.exports = Api;
},{"./api/scenario":3}],3:[function(require,module,exports){
(function (Buffer){
function Scenario(astTreeWalker, astScenario) {
function isStream(value) {
return value && typeof value === 'object' && typeof value.pipe === 'function';
}
var self = {
getKeyword: function getKeyword() { return astScenario.getKeyword(); },
getName: function getName() { return astScenario.getName(); },
getDescription: function getDescription() { return astScenario.getDescription(); },
getUri: function getUri() { return astScenario.getUri(); },
getLine: function getLine() { return astScenario.getLine(); },
getTags: function getTags() { return astScenario.getTags(); },
isSuccessful: function isSuccessful() { return astTreeWalker.isScenarioSuccessful(); },
isFailed: function isFailed() { return astTreeWalker.isScenarioFailed(); },
isPending: function isPending() { return astTreeWalker.isScenarioPending(); },
isUndefined: function isUndefined() { return astTreeWalker.isScenarioUndefined(); },
isSkipped: function isSkipped() { return astTreeWalker.isScenarioSkipped(); },
getException: function getException() { return astTreeWalker.getFailureException(); },
getAttachments: function getAttachments() { return astTreeWalker.getAttachments(); },
attach: function attach(data, mimeType, callback) {
if (isStream(data)) {
if (!mimeType)
throw Error(Scenario.ATTACH_MISSING_MIME_TYPE_ARGUMENT);
if (!callback)
throw Error(Scenario.ATTACH_MISSING_CALLBACK_ARGUMENT_FOR_STREAM_READABLE);
var buffers = [];
data.on('data', function (chunk) {
buffers.push(chunk);
});
data.on('end', function () {
astTreeWalker.attach(Buffer.concat(buffers).toString(), mimeType);
callback();
});
}
else if (Buffer && Buffer.isBuffer(data)) {
if (!mimeType)
throw Error(Scenario.ATTACH_MISSING_MIME_TYPE_ARGUMENT);
astTreeWalker.attach(data.toString(), mimeType);
if (callback) {
callback();
}
}
else {
if (!mimeType) {
mimeType = Scenario.DEFAULT_TEXT_MIME_TYPE;
}
astTreeWalker.attach(data.toString(), mimeType);
}
}
};
return self;
}
Scenario.DEFAULT_TEXT_MIME_TYPE = 'text/plain';
Scenario.ATTACH_MISSING_MIME_TYPE_ARGUMENT = 'Cucumber.Api.Scenario.attach() expects a mimeType';
Scenario.ATTACH_MISSING_CALLBACK_ARGUMENT_FOR_STREAM_READABLE = 'Cucumber.Api.Scenario.attach() expects a callback when data is a stream.Readable';
module.exports = Scenario;
}).call(this,require("buffer").Buffer)
},{"buffer":69}],4:[function(require,module,exports){
var Ast = {};
Ast.Assembler = require('./ast/assembler');
Ast.Background = require('./ast/background');
Ast.DataTable = require('./ast/data_table');
Ast.DocString = require('./ast/doc_string');
Ast.Feature = require('./ast/feature');
Ast.Features = require('./ast/features');
Ast.Filter = require('./ast/filter');
Ast.Scenario = require('./ast/scenario');
Ast.ScenarioOutline = require('./ast/scenario_outline');
Ast.OutlineStep = require('./ast/outline_step');
Ast.Examples = require('./ast/examples');
Ast.Step = require('./ast/step');
Ast.HookStep = require('./ast/hook_step');
Ast.Tag = require('./ast/tag');
module.exports = Ast;
},{"./ast/assembler":5,"./ast/background":6,"./ast/data_table":7,"./ast/doc_string":9,"./ast/examples":10,"./ast/feature":11,"./ast/features":12,"./ast/filter":13,"./ast/hook_step":17,"./ast/outline_step":18,"./ast/scenario":19,"./ast/scenario_outline":20,"./ast/step":21,"./ast/tag":22}],5:[function(require,module,exports){
function Assembler(features, filter) {
var currentFeature, currentFeatureElement, currentStep, suggestedFeature;
var stashedTags = [];
var self = {
setCurrentFeature: function setCurrentFeature(feature) {
currentFeature = feature;
self.setCurrentFeatureElement(undefined);
},
getCurrentFeature: function getCurrentFeature() {
return currentFeature;
},
setCurrentFeatureElement: function setCurrentFeatureElement(featureElement) {
currentFeatureElement = featureElement;
self.setCurrentStep(undefined);
},
getCurrentFeatureElement: function getCurrentFeatureElement() {
return currentFeatureElement;
},
setCurrentStep: function setCurrentStep(step) {
currentStep = step;
},
getCurrentStep: function getCurrentStep() {
return currentStep;
},
stashTag: function stashTag(tag) {
stashedTags.push(tag);
},
revealTags: function revealTags() {
var revealedTags = stashedTags;
stashedTags = [];
return revealedTags;
},
applyCurrentFeatureTagsToElement: function applyCurrentFeatureTagsToElement(element) {
var currentFeature = self.getCurrentFeature();
var featureTags = currentFeature.getTags();
element.addInheritedTags(featureTags);
},
applyStashedTagsToElement: function applyStashedTagsToElement(element) {
var revealedTags = self.revealTags();
element.addTags(revealedTags);
},
insertBackground: function insertBackground(background) {
self.setCurrentFeatureElement(background);
var currentFeature = self.getCurrentFeature();
currentFeature.setBackground(background);
},
insertDataTableRow: function insertDataTableRow(dataTableRow) {
var currentStep = self.getCurrentStep();
currentStep.attachDataTableRow(dataTableRow);
},
insertDocString: function insertDocString(docString) {
var currentStep = self.getCurrentStep();
currentStep.attachDocString(docString);
},
insertFeature: function insertFeature(feature) {
self.tryEnrollingSuggestedFeature();
self.applyStashedTagsToElement(feature);
self.setCurrentFeature(feature);
self.suggestFeature(feature);
},
insertScenario: function insertScenario(scenario) {
self.applyCurrentFeatureTagsToElement(scenario);
self.applyStashedTagsToElement(scenario);
self.setCurrentFeatureElement(scenario);
if (filter.isElementEnrolled(scenario)) {
var currentFeature = self.getCurrentFeature();
currentFeature.addFeatureElement(scenario);
}
},
insertExamples: function insertExamples(examples) {
var currentFeatureElement = self.getCurrentFeatureElement();
if (!currentFeatureElement.isScenarioOutline())
throw new Error('Examples are allowed inside scenario outlines only');
currentFeatureElement.addExamples(examples);
self.setCurrentStep(examples);
},
insertStep: function insertStep(step) {
self.setCurrentStep(step);
var currentFeatureElement = self.getCurrentFeatureElement();
currentFeatureElement.addStep(step);
},
insertTag: function insertTag(tag) {
self.stashTag(tag);
},
finish: function finish() {
self.getCurrentFeature().convertScenarioOutlinesToScenarios();
self.tryEnrollingSuggestedFeature();
},
suggestFeature: function suggestFeature(feature) {
suggestedFeature = feature;
},
isSuggestedFeatureEnrollable: function isSuggestedFeatureEnrollable() {
var enrollable = suggestedFeature && (suggestedFeature.hasFeatureElements() || filter.isElementEnrolled(suggestedFeature));
return enrollable;
},
tryEnrollingSuggestedFeature: function tryEnrollingSuggestedFeature() {
if (self.isSuggestedFeatureEnrollable())
self.enrollSuggestedFeature();
},
enrollSuggestedFeature: function enrollSuggestedFeature() {
features.addFeature(suggestedFeature);
suggestedFeature = null;
}
};
return self;
}
module.exports = Assembler;
},{}],6:[function(require,module,exports){
function Background(keyword, name, description, uri, line) {
var Cucumber = require('../../cucumber');
var steps = Cucumber.Type.Collection();
var self = {
getKeyword: function getKeyword() {
return keyword;
},
getName: function getName() {
return name;
},
getDescription: function getDescription() {
return description;
},
getUri: function getUri() {
return uri;
},
getLine: function getLine() {
return line;
},
addStep: function addStep(step) {
var lastStep = self.getLastStep();
step.setPreviousStep(lastStep);
steps.add(step);
},
getLastStep: function getLastStep() {
return steps.getLast();
},
getSteps: function getSteps() {
return steps;
}
};
return self;
}
module.exports = Background;
},{"../../cucumber":1}],7:[function(require,module,exports){
function DataTable() {
var Cucumber = require('../../cucumber');
var _ = require('underscore');
var rowsCollection = Cucumber.Type.Collection();
var self = {
attachRow: function attachRow(row) {
rowsCollection.add(row);
},
getContents: function getContents() {
return self;
},
getRows: function getRows() {
var newRows = Cucumber.Type.Collection();
rowsCollection.syncForEach(function (row) {
newRows.add(row);
});
return newRows;
},
rows: function rows() {
var rawRows = [];
rowsCollection.syncForEach(function (row, index) {
if (index > 0) {
rawRows.push(row.raw());
}
});
return rawRows;
},
rowsHash: function rowsHash() {
var rows = self.raw();
var everyRowHasTwoColumns = rows.every(function (row) {
return row.length === 2;
});
if (!everyRowHasTwoColumns) {
throw new Error('rowsHash was called on a data table with more than two columns');
}
return _.object(rows);
},
raw: function raw() {
var rawRows = [];
rowsCollection.syncForEach(function (row) {
rawRows.push(row.raw());
});
return rawRows;
},
hashes: function hashes() {
var raw = self.raw();
var hashDataTable = Cucumber.Type.HashDataTable(raw);
var rawHashDataTable = hashDataTable.raw();
return rawHashDataTable;
}
};
return self;
}
DataTable.Row = require('./data_table/row');
module.exports = DataTable;
},{"../../cucumber":1,"./data_table/row":8,"underscore":262}],8:[function(require,module,exports){
function Row(cells, uri, line) {
var self = {
raw: function raw() {
return [].concat(cells);
},
getLine: function getLine() {
return line;
}
};
return self;
}
module.exports = Row;
},{}],9:[function(require,module,exports){
function DocString(contentType, contents, uri, line) {
var self = {
getContents: function getContents() {
return contents;
},
getContentType: function getContentType() {
return contentType;
},
getUri: function getUri() {
return uri;
},
getLine: function getLine() {
return line;
}
};
return self;
}
module.exports = DocString;
},{}],10:[function(require,module,exports){
function Examples(keyword, name, description, line) {
var Cucumber = require('../../cucumber');
var dataTable;
var self = {
getKeyword: function getKeyword() {
return keyword;
},
getName: function getName() {
return name;
},
getDescription: function getDescription() {
return description;
},
getLine: function getLine() {
return line;
},
getDataTable: function getDataTable() {
return dataTable;
},
hasDataTable: function hasDataTable() {
return !!dataTable;
},
attachDataTable: function attachDataTable(_dataTable) {
dataTable = _dataTable;
},
attachDataTableRow: function attachDataTableRow(row) {
self.ensureDataTableIsAttached();
var dataTable = self.getDataTable();
dataTable.attachRow(row);
},
ensureDataTableIsAttached: function ensureDataTableIsAttached() {
var dataTable = self.getDataTable();
if (!dataTable) {
dataTable = Cucumber.Ast.DataTable();
self.attachDataTable(dataTable);
}
}
};
return self;
}
module.exports = Examples;
},{"../../cucumber":1}],11:[function(require,module,exports){
function Feature(keyword, name, description, uri, line) {
var Cucumber = require('../../cucumber');
var background;
var featureElements = Cucumber.Type.Collection();
var tags = [];
var self = {
getKeyword: function getKeyword() {
return keyword;
},
getName: function getName() {
return name;
},
getDescription: function getDescription() {
return description;
},
getUri: function getUri() {
return uri;
},
getLine: function getLine() {
return line;
},
setBackground: function setBackground(newBackground) {
background = newBackground;
},
getBackground: function getBackground() {
return background;
},
hasBackground: function hasBackground() {
return (typeof(background) !== 'undefined');
},
addFeatureElement: function addFeatureElement(featureElement) {
var background = self.getBackground();
featureElement.setBackground(background);
featureElements.add(featureElement);
},
insertFeatureElement: function insertFeatureElement(index, featureElement) {
var background = self.getBackground();
featureElement.setBackground(background);
featureElements.insert(index, featureElement);
},
convertScenarioOutlinesToScenarios: function convertScenarioOutlinesToScenarios() {
featureElements.syncForEach(function (featureElement) {
if (featureElement.isScenarioOutline()) {
self.convertScenarioOutlineToScenarios(featureElement);
}
});
},
convertScenarioOutlineToScenarios: function convertScenarioOutlineToScenarios(scenarioOutline) {
var scenarios = scenarioOutline.buildScenarios();
var scenarioOutlineIndex = featureElements.indexOf(scenarioOutline);
featureElements.removeAtIndex(scenarioOutlineIndex);
var scenarioOutlineTags = scenarioOutline.getTags();
scenarios.syncForEach(function (scenario, index) {
scenario.addTags(scenarioOutlineTags);
self.insertFeatureElement(scenarioOutlineIndex + index, scenario);
});
},
getFeatureElements: function getFeatureElements() {
return featureElements;
},
getLastFeatureElement: function getLastFeatureElement() {
return featureElements.getLast();
},
hasFeatureElements: function hasFeatureElements() {
return featureElements.length() > 0;
},
addTags: function setTags(newTags) {
tags = tags.concat(newTags);
},
getTags: function getTags() {
return tags;
},
acceptVisitor: function acceptVisitor(visitor, callback) {
self.instructVisitorToVisitBackground(visitor, function () {
self.instructVisitorToVisitScenarios(visitor, callback);
});
},
instructVisitorToVisitBackground: function instructVisitorToVisitBackground(visitor, callback) {
if (self.hasBackground()) {
var background = self.getBackground();
visitor.visitBackground(background, callback);
} else {
callback();
}
},
instructVisitorToVisitScenarios: function instructVisitorToVisitScenarios(visitor, callback) {
featureElements.forEach(function (scenario, iterate) {
visitor.visitScenario(scenario, iterate);
}, callback);
}
};
return self;
}
module.exports = Feature;
},{"../../cucumber":1}],12:[function(require,module,exports){
function Features() {
var Cucumber = require('../../cucumber');
var features = Cucumber.Type.Collection();
var self = {
addFeature: function addFeature(feature) {
features.add(feature);
},
getFeatures: function getFeatures() {
return features;
},
getLastFeature: function getLastFeature() {
return features.getLast();
},
acceptVisitor: function acceptVisitor(visitor, callback) {
features.forEach(function (feature, iterate) {
visitor.visitFeature(feature, iterate);
}, callback);
}
};
return self;
}
module.exports = Features;
},{"../../cucumber":1}],13:[function(require,module,exports){
var _ = require('underscore');
function Filter(rules) {
var self = {
isElementEnrolled: function isElementEnrolled(element) {
var enrolled = _.all(rules, function (rule) {
return rule.isSatisfiedByElement(element);
});
return enrolled;
}
};
return self;
}
Filter.AnyOfTagsRule = require('./filter/any_of_tags_rule');
Filter.ElementMatchingTagSpec = require('./filter/element_matching_tag_spec');
Filter.ScenarioAtLineRule = require('./filter/scenario_at_line_rule');
module.exports = Filter;
},{"./filter/any_of_tags_rule":14,"./filter/element_matching_tag_spec":15,"./filter/scenario_at_line_rule":16,"underscore":262}],14:[function(require,module,exports){
var _ = require('underscore');
function AnyOfTagsRule(tags) {
var Cucumber = require('../../../cucumber');
var self = {
isSatisfiedByElement: function isSatisfiedByElement(element) {
var satisfied = _.any(tags, function (tag) {
var spec = Cucumber.Ast.Filter.ElementMatchingTagSpec(tag);
return spec.isMatching(element);
});
return satisfied;
}
};
return self;
}
module.exports = AnyOfTagsRule;
},{"../../../cucumber":1,"underscore":262}],15:[function(require,module,exports){
var _ = require('underscore');
function ElementMatchingTagSpec(tagName) {
var self = {
isMatching: function isMatching(element) {
var elementTags = element.getTags();
var matching;
if (self.isExpectingTag())
matching = _.any(elementTags, self.isTagSatisfying);
else
matching = _.all(elementTags, self.isTagSatisfying);
return matching;
},
isTagSatisfying: function isTagSatisfying(tag) {
var checkedTagName = tag.getName();
var satisfying;
if (self.isExpectingTag())
satisfying = checkedTagName === tagName;
else {
var negatedCheckedTagName = ElementMatchingTagSpec.NEGATION_CHARACTER + checkedTagName;
satisfying = negatedCheckedTagName !== tagName;
}
return satisfying;
},
isExpectingTag: function isExpectingTag() {
var expectingTag = tagName[0] !== ElementMatchingTagSpec.NEGATION_CHARACTER;
return expectingTag;
}
};
return self;
}
ElementMatchingTagSpec.NEGATION_CHARACTER = '~';
module.exports = ElementMatchingTagSpec;
},{"underscore":262}],16:[function(require,module,exports){
function ScenarioAtLineRule(suppliedPaths) {
var Cucumber = require('../../../cucumber');
var fs = require('fs');
var _ = require('underscore');
var mapping = {};
suppliedPaths.forEach(function(path){
var matches = Cucumber.Cli.ArgumentParser.FEATURE_FILENAME_AND_LINENUM_REGEXP.exec(path);
var specifiedLineNum = matches && matches[2];
if (specifiedLineNum) {
var realPath = fs.realpathSync(matches[1]);
if (!mapping[realPath]) {
mapping[realPath] = [];
}
mapping[realPath].push(parseInt(specifiedLineNum));
}
});
var self = {
isSatisfiedByElement: function isSatisfiedByElement(element) {
if (element.getUri && element.getLine) {
var lines = mapping[element.getUri()];
if (lines) {
return _.contains(lines, element.getLine());
}
return true;
}
return true;
}
};
return self;
}
module.exports = ScenarioAtLineRule;
},{"../../../cucumber":1,"fs":67,"underscore":262}],17:[function(require,module,exports){
function HookStep(keyword) {
var Cucumber = require('../../cucumber');
var self = Cucumber.Ast.Step(keyword, HookStep.NAME, HookStep.UNDEFINED_URI, HookStep.UNDEFINED_LINE);
var hook;
self.isHidden = function isHidden() {
return true;
};
self.hasUri = function hasUri() {
return false;
};
self.setHook = function setHook(newHook) {
hook = newHook;
};
self.getStepDefinition = function getStepDefinition() {
return hook;
};
return self;
}
HookStep.NAME = undefined;
HookStep.UNDEFINED_URI = undefined;
HookStep.UNDEFINED_LINE = undefined;
module.exports = HookStep;
},{"../../cucumber":1}],18:[function(require,module,exports){
function OutlineStep(keyword, name, uri, line) {
var Cucumber = require('../../cucumber');
var self = Cucumber.Ast.Step(keyword, name, uri, line);
self.setOriginalStep = function setOriginalStep(originalStep) {
self.originalStep = originalStep;
};
self.getOriginalStep = function getOriginalStep() {
return self.originalStep;
};
self.isOutlineStep = function isOutlineStep() {
return true;
};
return self;
}
module.exports = OutlineStep;
},{"../../cucumber":1}],19:[function(require,module,exports){
function Scenario(keyword, name, description, uri, line) {
var Cucumber = require('../../cucumber');
var background;
var steps = Cucumber.Type.Collection();
var inheritedTags = [];
var tags = [];
var self = {
isScenarioOutline: function isScenarioOutline() {
return false;
},
setBackground: function setBackground(newBackground) {
background = newBackground;
},
getKeyword: function getKeyword() {
return keyword;
},
getName: function getName() {
return name;
},
getDescription: function getDescription() {
return description;
},
getUri: function getUri() {
return uri;
},
getLine: function getLine() {
return line;
},
getBackground: function getBackground() {
return background;
},
addStep: function addStep(step) {
var lastStep = self.getLastStep();
step.setPreviousStep(lastStep);
steps.add(step);
},
getLastStep: function getLastStep() {
return steps.getLast();
},
setSteps: function setSteps(newSteps) {
steps = newSteps;
},
getSteps: function getSteps() {
return steps;
},
addTags: function addTags(newTags) {
tags = tags.concat(newTags);
},
addInheritedTags: function addInheritedTags(newTags) {
inheritedTags = tags.concat(newTags);
},
getTags: function getTags() {
return tags.concat(inheritedTags);
},
getOwnTags: function getOwnTags() {
return tags;
},
acceptVisitor: function acceptVisitor(visitor, callback) {
self.instructVisitorToVisitBackgroundSteps(visitor, function () {
self.instructVisitorToVisitScenarioSteps(visitor, callback);
});
},
instructVisitorToVisitBackgroundSteps: function instructVisitorToVisitBackgroundSteps(visitor, callback) {
var background = self.getBackground();
if (typeof(background) !== 'undefined') {
var steps = background.getSteps();
self.instructVisitorToVisitSteps(visitor, steps, callback);
} else {
callback();
}
},
instructVisitorToVisitScenarioSteps: function instructVisitorToVisitScenarioSteps(visitor, callback) {
self.instructVisitorToVisitSteps(visitor, steps, callback);
},
instructVisitorToVisitSteps: function instructVisitorToVisitSteps(visitor, steps, callback) {
steps.forEach(function (step, iterate) {
visitor.visitStep(step, iterate);
}, callback);
}
};
return self;
}
module.exports = Scenario;
},{"../../cucumber":1}],20:[function(require,module,exports){
function ScenarioOutline(keyword, name, description, uri, line) {
var Cucumber = require('../../cucumber');
var self = Cucumber.Ast.Scenario(keyword, name, description, uri, line);
var examplesCollection = Cucumber.Type.Collection();
self.isScenarioOutline = function () {
return true;
};
self.addExamples = function (examples) {
examplesCollection.add(examples);
};
function buildScenario(example) {
var newName = self.applyExampleRowToScenarioName(example, name);
var newSteps = self.applyExampleRowToSteps(example, self.getSteps());
var subScenario = Cucumber.Ast.Scenario(keyword, newName, description, uri, line);
subScenario.setSteps(newSteps);
return subScenario;
}
self.buildScenarios = function () {
var scenarios = Cucumber.Type.Collection();
examplesCollection.syncForEach(function (examples) {
var exampleHashes = examples.getDataTable().hashes();
exampleHashes.forEach(function (exampleHash) {
scenarios.add(buildScenario(exampleHash));
});
});
return scenarios;
};
self.getExamples = function () {
return examplesCollection;
};
function iterateExampleValues(example, callback) {
for (var hashKey in example) {
if (Object.prototype.hasOwnProperty.call(example, hashKey)) {
var findText = new RegExp('<' + hashKey + '>', 'g');
var exampleData = example[hashKey];
callback(findText, exampleData);
}
}
}
self.applyExampleRowToScenarioName = function (example, name) {
iterateExampleValues(example, function(findText, exampleData) {
name = name.replace(findText, exampleData);
});
return name;
};
self.applyExampleRowToSteps = function (example, steps) {
return steps.syncMap(function (step) {
var name = step.getName();
var table = Cucumber.Ast.DataTable();
var rows = [];
var hasDocString = step.hasDocString();
var hasDataTable = step.hasDataTable();
var oldDocString = hasDocString ? step.getDocString() : null;
var docString = hasDocString ? oldDocString.getContents() : null;
if (hasDataTable) {
step.getDataTable().getRows().syncForEach(function (row) {
var newRow = {
line: row.getLine(),
cells: JSON.stringify(row.raw())
};
rows.push(newRow);
});
}
iterateExampleValues(example, function (findText, exampleData) {
name = name.replace(findText, exampleData);
if (hasDataTable) {
/* jshint -W083 */
rows = rows.map(function (row) {
return {
line: row.line,
cells: row.cells.replace(findText, exampleData)
};
});
/* jshint +W083 */
}
if (hasDocString) {
docString = docString.replace(findText, exampleData);
}
});
var newStep = Cucumber.Ast.OutlineStep(step.getKeyword(), name, uri, step.getLine());
newStep.setOriginalStep(Cucumber.Ast.Step(step.getKeyword(), step.getName(), step.getUri(), step.getLine()));
if (hasDataTable) {
rows.forEach(function (row) {
table.attachRow(Cucumber.Ast.DataTable.Row(JSON.parse(row.cells), row.line));
});
newStep.attachDataTable(table);
}
if (hasDocString) {
newStep.attachDocString(Cucumber.Ast.DocString(oldDocString.getContentType(), docString, oldDocString.getLine()));
}
return newStep;
});
};
self.acceptVisitor = function (visitor, callback) {
callback();
};
return self;
}
module.exports = ScenarioOutline;
},{"../../cucumber":1}],21:[function(require,module,exports){
function Step(keyword, name, uri, line) {
var Cucumber = require('../../cucumber');
var docString, dataTable, previousStep;
var self = {
setPreviousStep: function setPreviousStep(newPreviousStep) {
previousStep = newPreviousStep;
},
isHidden: function isHidden() {
return false;
},
isOutlineStep: function isOutlineStep() {
return false;
},
getKeyword: function getKeyword() {
return keyword;
},
getName: function getName() {
return name;
},
hasUri: function hasUri() {
return true;
},
getUri: function getUri() {
return uri;
},
getLine: function getLine() {
return line;
},
getPreviousStep: function getPreviousStep() {
return previousStep;
},
hasPreviousStep: function hasPreviousStep() {
return !!previousStep;
},
getAttachment: function getAttachment() {
var attachment;
if (self.hasDocString()) {
attachment = self.getDocString();
} else if (self.hasDataTable()) {
attachment = self.getDataTable();
}
return attachment;
},
getAttachmentContents: function getAttachmentContents() {
var attachment = self.getAttachment();
var attachmentContents;
if (attachment)
attachmentContents = attachment.getContents();
return attachmentContents;
},
getDocString: function getDocString() { return docString; },
getDataTable: function getDataTable() { return dataTable; },
hasAttachment: function hasAttachment() {
return self.hasDocString() || self.hasDataTable();
},
hasDocString: function hasDocString() {
return !!docString;
},
hasDataTable: function hasDataTable() {
return !!dataTable;
},
attachDocString: function attachDocString(_docString) { docString = _docString; },
attachDataTable: function attachDataTable(_dataTable) { dataTable = _dataTable; },
attachDataTableRow: function attachDataTableRow(row) {
self.ensureDataTableIsAttached();
var dataTable = self.getDataTable();
dataTable.attachRow(row);
},
ensureDataTableIsAttached: function ensureDataTableIsAttached() {
var dataTable = self.getDataTable();
if (!dataTable) {
dataTable = Cucumber.Ast.DataTable();
self.attachDataTable(dataTable);
}
},
isOutcomeStep: function isOutcomeStep() {
return self.hasOutcomeStepKeyword() || self.isRepeatingOutcomeStep();
},
isEventStep: function isEventStep() {
return self.hasEventStepKeyword() || self.isRepeatingEventStep();
},
hasOutcomeStepKeyword: function hasOutcomeStepKeyword() {
return keyword === Step.OUTCOME_STEP_KEYWORD;
},
hasEventStepKeyword: function hasEventStepKeyword() {
return keyword === Step.EVENT_STEP_KEYWORD;
},
isRepeatingOutcomeStep: function isRepeatingOutcomeStep() {
return self.hasRepeatStepKeyword() && self.isPrecededByOutcomeStep();
},
isRepeatingEventStep: function isRepeatingEventStep() {
return self.hasRepeatStepKeyword() && self.isPrecededByEventStep();
},
hasRepeatStepKeyword: function hasRepeatStepKeyword() {
return keyword === Step.AND_STEP_KEYWORD || keyword === Step.BUT_STEP_KEYWORD || keyword === Step.STAR_STEP_KEYWORD;
},
isPrecededByOutcomeStep: function isPrecededByOutcomeStep() {
var result = false;
if (self.hasPreviousStep()) {
var previousStep = self.getPreviousStep();
result = previousStep.isOutcomeStep();
}
return result;
},
isPrecededByEventStep: function isPrecededByEventStep() {
var result = false;
if (self.hasPreviousStep()) {
var previousStep = self.getPreviousStep();
result = previousStep.isEventStep();
}
return result;
},
acceptVisitor: function acceptVisitor(visitor, callback) {
self.execute(visitor, function (stepResult) {
visitor.visitStepResult(stepResult, callback);
});
},
getStepDefinition: function getStepDefinition(visitor) {
return visitor.lookupStepDefinitionByName(name);
},
execute: function execute(visitor, callback) {
var stepDefinition = self.getStepDefinition(visitor);
var world = visitor.getWorld();
var scenario = visitor.getScenario();
var domain = visitor.getDomain();
stepDefinition.invoke(self, world, scenario, domain, callback);
}
};
return self;
}
Step.EVENT_STEP_KEYWORD = 'When ';
Step.OUTCOME_STEP_KEYWORD = 'Then ';
Step.AND_STEP_KEYWORD = 'And ';
Step.BUT_STEP_KEYWORD = 'But ';
Step.STAR_STEP_KEYWORD = '* ';
module.exports = Step;
},{"../../cucumber":1}],22:[function(require,module,exports){
function Tag(name, uri, line) {
var self = {
getName: function getName() {
return name;
},
getUri: function getUri() {
return uri;
},
getLine: function getLine() {
return line;
}
};
return self;
}
module.exports = Tag;
},{}],23:[function(require,module,exports){
},{}],24:[function(require,module,exports){
(function (process){
var Debug = {
TODO: function TODO(description) {
return function () { throw(new Error('IMPLEMENT ME: ' + description)); };
},
warn: function warn(string, caption, level) {
if (Debug.isMessageLeveltoBeDisplayed(level))
process.stdout.write(Debug.warningString(string, caption));
},
notice: function notice(string, caption, level) {
if (Debug.isMessageLeveltoBeDisplayed(level))
process.stdout.write(Debug.noticeString(string, caption));
},
warningString: function warningString(string, caption) {
caption = caption || 'debug-warning';
return '\x1B[30;43m' + caption + ':\x1B[0m[33m' + string + '\x1B[0m';
},
noticeString: function noticeString(string, caption) {
caption = caption || 'debug-notice';
return '\x1B[30;46m' + caption + ':\x1B[0m \x1B[36m' + string + '\x1B[0m';
},
prefix: function prefix() {
return ;
},
isMessageLeveltoBeDisplayed: function isMessageLeveltoBeDisplayed(level) {
if (process.env) {
level = level || 3; // default level
return (level <= process.env.DEBUG_LEVEL);
} else {
return false;
}
}
};
Debug.SimpleAstListener = require('./debug/simple_ast_listener');
module.exports = Debug;
}).call(this,require('_process'))
},{"./debug/simple_ast_listener":25,"_process":79}],25:[function(require,module,exports){
function SimpleAstListener(options) {
var logs = '';
var failed = false;
var beforeEachScenarioCallbacks = [];
var currentStep;
if (!options)
options = {};
function log(message, indentation) {
if (indentation)
message = indent(message, indentation);
logs = logs + message + '\n';
if (options.logToConsole)
console.log(message);
if (typeof(options.logToFunction) === 'function')
options.logToFunction (message);
}
function indent(text, indentation) {
var indented;
text.split('\n').forEach(function (line) {
var prefix = new Array(indentation + 1).join(' ');
line = prefix + line;
indented = (typeof(indented) === 'undefined' ? line : indented + '\n' + line);
});
return indented;
}
var self = {
hear: function hear(event, callback) {
switch(event.getName()) {
case 'BeforeFeature':
self.hearBeforeFeature(event.getPayloadItem('feature'), callback);
break;
case 'BeforeScenario':
self.hearBeforeScenario(event.getPayloadItem('scenario'), callback);
break;
case 'BeforeStep':
self.hearBeforeStep(event.getPayloadItem('step'), callback);
break;
case 'StepResult':
self.hearStepResult(event.getPayloadItem('stepResult'), callback);
break;
default:
callback();
}
},
hearBeforeFeature: function hearBeforeFeature(feature, callback) {
log('Feature: ' + feature.getName());
var description = feature.getDescription();
if (description !== '')
log(description, 1);
callback();
},
hearBeforeScenario: function hearBeforeScenario(scenario, callback) {
beforeEachScenarioCallbacks.forEach(function (func) {
func();
});
log('');
log(scenario.getKeyword() + ': ' + scenario.getName(), 1);
callback();
},
hearBeforeStep: function hearBeforeStep(step, callback) {
currentStep = step;
callback();
},
hearStepResult: function hearStepResult(stepResult, callback) {
log(currentStep.getKeyword() + (currentStep.getName() || ''), 2);
if (currentStep.hasDocString()) {
log('"""', 3);
log(currentStep.getDocString().getContents(), 3);
log('"""', 3);
}
callback();
},
getLogs: function getLogs() {
return logs;
},
featuresPassed: function featuresPassed() {
return !failed;
},
beforeEachScenarioDo: function beforeEachScenarioDo(func) {
beforeEachScenarioCallbacks.push(func);
}
};
return self;
}
module.exports = SimpleAstListener;
},{}],26:[function(require,module,exports){
var gherkin = require('gherkin');
/**
* Small wrapper around Gherkin that strips BOM and loads the correct lexer based
* on the language header.
*/
function GherkinLexer(content, gherkinListener) {
// Strip BOM
content = content.replace(/^\ufeff/g, '');
var language = 'en';
var lines = content.split('\n');
var len = lines.length;
for (var i = 0; i < len; i++) {
var line = lines[i];
if(!/^\s*#/.exec(line)) break;
var languageMatch = /^\s*#\s*language:\s*([a-zA-Z-_]+)\s*$/m.exec(line);
language = languageMatch === null ? 'en' : languageMatch[1].toLowerCase();
}
language = language.replace('-', '_');
var Lexer = gherkin.Lexer(language);
var lexer = new Lexer(gherkinListener);
this.scan = function () {
lexer.scan(content);
};
}
module.exports = GherkinLexer;
},{"gherkin":132}],27:[function(require,module,exports){
function Listener() {
var self = {
hear: function hear(event, callback) {
if (self.hasHandlerForEvent(event)) {
var handler = self.getHandlerForEvent(event);
handler(event, callback);
} else {
callback();
}
},
hasHandlerForEvent: function hasHandlerForEvent(event) {
var handlerName = self.buildHandlerNameForEvent(event);
return self[handlerName] !== undefined;
},
buildHandlerNameForEvent: function buildHandlerNameForEvent(event) {
return self.buildHandlerName(event.getName());
},
getHandlerForEvent: function getHandlerForEvent(event) {
var eventHandlerName = self.buildHandlerNameForEvent(event);
return self[eventHandlerName];
},
buildHandlerName: function buildHandler(shortName) {
return Listener.EVENT_HANDLER_NAME_PREFIX + shortName + Listener.EVENT_HANDLER_NAME_SUFFIX;
},
setHandlerForEvent: function setHandlerForEvent(shortname, handler) {
var eventName = self.buildHandlerName(shortname);
self[eventName] = handler;
}
};
return self;
}
Listener.EVENT_HANDLER_NAME_PREFIX = 'handle';
Listener.EVENT_HANDLER_NAME_SUFFIX = 'Event';
Listener.Events = require('./listener/events');
Listener.Formatter = require('./listener/formatter');
Listener.PrettyFormatter = require('./listener/pretty_formatter');
Listener.ProgressFormatter = require('./listener/progress_formatter');
Listener.JsonFormatter = require('./listener/json_formatter');
Listener.StatsJournal = require('./listener/stats_journal');
Listener.SummaryFormatter = require('./listener/summary_formatter');
module.exports = Listener;
},{"./listener/events":28,"./listener/formatter":29,"./listener/json_formatter":30,"./listener/pretty_formatter":31,"./listener/progress_formatter":32,"./listener/stats_journal":33,"./listener/summary_formatter":34}],28:[function(require,module,exports){
exports.BeforeFeatures = 'BeforeFeatures';
exports.BeforeFeature = 'BeforeFeature';
exports.Background = 'Background';
exports.BeforeScenario = 'BeforeScenario';
exports.BeforeStep = 'BeforeStep';
exports.StepResult = 'StepResult';
exports.AfterStep = 'AfterStep';
exports.AfterScenario = 'AfterScenario';
exports.AfterFeature = 'AfterFeature';
exports.AfterFeatures = 'AfterFeatures';
},{}],29:[function(require,module,exports){
(function (process){
function Formatter(options) {
var Cucumber = require('../../cucumber');
if (!options)
options = {};
if (options.logToConsole === undefined)
options.logToConsole = true;
var logs = '';
var self = Cucumber.Listener();
self.log = function log(string) {
logs += string;
if (options.logToConsole)
process.stdout.write(string);
if (typeof(options.logToFunction) === 'function')
options.logToFunction(string);
};
self.getLogs = function getLogs() {
return logs;
};
return self;
}
module.exports = Formatter;
}).call(this,require('_process'))
},{"../../cucumber":1,"_process":79}],30:[function(require,module,exports){
/* jshint -W106 */
function JsonFormatter(options) {
var Cucumber = require('../../cucumber');
var GherkinJsonFormatter = require('gherkin/lib/gherkin/formatter/json_formatter');
var currentFeatureId = 'undefined';
var self = Cucumber.Listener.Formatter(options);
var formatterIo = {
write: function (string) {
self.log(string);
}
};
var gherkinJsonFormatter = new GherkinJsonFormatter(formatterIo);
var parentFeatureTags;
self.getGherkinFormatter = function getGherkinFormatter() {
return gherkinJsonFormatter;
};
self.formatStep = function formatStep(step) {
var stepProperties = {
name: step.getName(),
line: step.getLine(),
keyword: step.getKeyword()
};
if (step.isHidden()) {
stepProperties.hidden = true;
}
if (step.hasDocString()) {
var docString = step.getDocString();
stepProperties.doc_string = {
value: docString.getContents(),
line: docString.getLine(),
content_type: docString.getContentType()
};
}
if (step.hasDataTable()) {
var tableContents = step.getDataTable().getContents();
var raw = tableContents.raw();
var tableProperties = [];
raw.forEach(function (rawRow) {
var row = {line: undefined, cells: rawRow};
tableProperties.push(row);
});
stepProperties.rows = tableProperties;
}
gherkinJsonFormatter.step(stepProperties);
};
self.formatTags = function formatTags(tags, parentTags) {
var tagsProperties = [];
tags.forEach(function (tag) {
var isParentTag = false;
if (parentTags) {
parentTags.forEach(function (parentTag) {
if ((tag.getName() === parentTag.getName()) && (tag.getLine() === parentTag.getLine())) {
isParentTag = true;
}
});
}
if (!isParentTag) {
tagsProperties.push({name: tag.getName(), line: tag.getLine()});
}
});
return tagsProperties;
};
self.handleBeforeFeatureEvent = function handleBeforeFeatureEvent(event, callback) {
var feature = event.getPayloadItem('feature');
currentFeatureId = feature.getName().replace(/ /g, '-'); // FIXME: wrong abstraction level, this should be encapsulated "somewhere"
var featureProperties = {
id: currentFeatureId,
name: feature.getName(),
description: feature.getDescription(),
line: feature.getLine(),
keyword: feature.getKeyword()
};
var tags = feature.getTags();
if (tags.length > 0) {
featureProperties.tags = self.formatTags(tags, []);
}
gherkinJsonFormatter.uri(feature.getUri());
gherkinJsonFormatter.feature(featureProperties);
parentFeatureTags = tags;
callback();
};
self.handleBackgroundEvent = function handleBackgroundEvent(event, callback) {
var background = event.getPayloadItem('background');
gherkinJsonFormatter.background({
name: background.getName(),
keyword: 'Background',
description: background.getDescription(),
type: 'background',
line: background.getLine()
});
var steps = background.getSteps();
steps.forEach(function (value) { self.formatStep(value); });
callback();
};
self.handleBeforeScenarioEvent = function handleBeforeScenarioEvent(event, callback) {
var scenario = event.getPayloadItem('scenario');
var id = currentFeatureId + ';' + scenario.getName().replace(/ /g, '-').toLowerCase();
var scenarioProperties = {name: scenario.getName(), id: id, line: scenario.getLine(), keyword: 'Scenario', description: scenario.getDescription(), type: 'scenario'};
var tags = scenario.getTags();
if (tags.length > 0) {
var formattedTags = self.formatTags(tags, parentFeatureTags);
if (formattedTags.length > 0) {
scenarioProperties.tags = formattedTags;
}
}
gherkinJsonFormatter.scenario(scenarioProperties);
callback();
};
self.handleStepResultEvent = function handleStepResultEvent(event, callback) {
var stepResult = event.getPayloadItem('stepResult');
var step = stepResult.getStep();
self.formatStep(step);
var stepOutput = {};
var resultStatus;
var attachments;
if (stepResult.isSuccessful()) {
resultStatus = 'passed';
if (stepResult.hasAttachments()) {
attachments = stepResult.getAttachments();
}
stepOutput.duration = stepResult.getDuration();
}
else if (stepResult.isPending()) {
resultStatus = 'pending';
stepOutput.error_message = undefined;
}
else if (stepResult.isSkipped()) {
resultStatus = 'skipped';
}
else if (stepResult.isUndefined()) {
resultStatus = 'undefined';
}
else {
resultStatus = 'failed';
var failureMessage = stepResult.getFailureException();
if (failureMessage) {
stepOutput.error_message = (failureMessage.stack || failureMessage);
}
if (stepResult.hasAttachments()) {
attachments = stepResult.getAttachments();
}
stepOutput.duration = stepResult.getDuration();
}
stepOutput.status = resultStatus;
gherkinJsonFormatter.result(stepOutput);
gherkinJsonFormatter.match({location: undefined});
if (attachments) {
attachments.syncForEach(function (attachment) {
gherkinJsonFormatter.embedding(attachment.getMimeType(), attachment.getData());
});
}
callback();
};
self.handleAfterFeaturesEvent = function handleAfterFeaturesEvent(event, callback) {
gherkinJsonFormatter.eof();
gherkinJsonFormatter.done();
callback();
};
return self;
}
module.exports = JsonFormatter;
},{"../../cucumber":1,"gherkin/lib/gherkin/formatter/json_formatter":133}],31:[function(require,module,exports){
(function (process){
function PrettyFormatter(options) {
var Cucumber = require('../../cucumber');
var path = require('path');
var colors = Cucumber.Util.Colors;
var self = Cucumber.Listener.Formatter(options);
var summaryFormatter = Cucumber.Listener.SummaryFormatter({
coffeeScriptSnippets: options.coffeeScriptSnippets,
snippets: options.snippets,
logToConsole: false
});
var currentMaxStepLength = 0;
var parentHear = self.hear;
self.hear = function hear(event, callback) {
summaryFormatter.hear(event, function () {
parentHear(event, callback);
});
};
self.handleBeforeFeatureEvent = function handleBeforeFeatureEv