@badeball/cypress-cucumber-preprocessor
Version:
[](https://github.com/badeball/cypress-cucumber-preprocessor/actions/workflows/build.yml) [ • 10.5 kB
JavaScript
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Registry = exports.DEFAULT_HOOK_ORDER = exports.MultipleDefinitionsError = exports.MissingDefinitionError = void 0;
exports.withRegistry = withRegistry;
exports.assignRegistry = assignRegistry;
exports.freeRegistry = freeRegistry;
exports.getRegistry = getRegistry;
const cucumber_expressions_1 = require("@cucumber/cucumber-expressions");
const tag_expressions_1 = __importDefault(require("@cucumber/tag-expressions"));
const assertions_1 = require("./helpers/assertions");
const error_1 = require("./helpers/error");
const source_map_1 = require("./helpers/source-map");
class MissingDefinitionError extends error_1.CypressCucumberError {
}
exports.MissingDefinitionError = MissingDefinitionError;
class MultipleDefinitionsError extends error_1.CypressCucumberError {
}
exports.MultipleDefinitionsError = MultipleDefinitionsError;
exports.DEFAULT_HOOK_ORDER = 10000;
const noopNode = { evaluate: () => true };
let userCodeLexicalOrder = 0;
function parseMaybeTags(tags) {
return tags ? (0, tag_expressions_1.default)(tags) : noopNode;
}
class Registry {
constructor(experimentalSourceMap = true) {
this.experimentalSourceMap = experimentalSourceMap;
this.preliminaryStepDefinitions = [];
this.stepDefinitions = [];
this.preliminaryCaseHooks = [];
this.preliminaryRunHooks = [];
this.runHooks = [];
this.caseHooks = [];
this.stepHooks = [];
this.parameterTypeOrdering = new Map();
this.defineStep = this.defineStep.bind(this);
this.runStepDefinition = this.runStepDefinition.bind(this);
this.defineParameterType = this.defineParameterType.bind(this);
this.defineBefore = this.defineBefore.bind(this);
this.defineAfter = this.defineAfter.bind(this);
this.parameterTypeRegistry = new cucumber_expressions_1.ParameterTypeRegistry();
}
finalize(newId) {
for (const { description, implementation, position, lexicalOrder } of this
.preliminaryStepDefinitions) {
if (typeof description === "string") {
this.stepDefinitions.push({
id: newId(),
expression: new cucumber_expressions_1.CucumberExpression(description, this.parameterTypeRegistry),
implementation,
position,
lexicalOrder,
});
}
else {
this.stepDefinitions.push({
id: newId(),
expression: new cucumber_expressions_1.RegularExpression(description, this.parameterTypeRegistry),
implementation,
position,
lexicalOrder,
});
}
}
for (const preliminaryCaseHook of this.preliminaryCaseHooks) {
this.caseHooks.push(Object.assign({ id: newId() }, preliminaryCaseHook));
}
for (const preliminaryRunHook of this.preliminaryRunHooks) {
this.runHooks.push(Object.assign({ id: newId() }, preliminaryRunHook));
}
}
defineStep(description, implementation) {
if (typeof description !== "string" && !(description instanceof RegExp)) {
throw new Error("Unexpected argument for step definition");
}
this.preliminaryStepDefinitions.push({
description,
implementation,
position: (0, source_map_1.maybeRetrievePositionFromSourceMap)(),
lexicalOrder: userCodeLexicalOrder++,
});
}
defineParameterType({ name, regexp, transformer, }) {
const parameterType = new cucumber_expressions_1.ParameterType(name, regexp, null, transformer, true, false);
this.parameterTypeOrdering.set(parameterType, userCodeLexicalOrder++);
this.parameterTypeRegistry.defineParameterType(parameterType);
}
defineCaseHook(keyword, options, fn) {
const { order } = options, remainingOptions = __rest(options, ["order"]);
this.preliminaryCaseHooks.push(Object.assign({ node: parseMaybeTags(options.tags), implementation: fn, keyword: keyword, position: (0, source_map_1.maybeRetrievePositionFromSourceMap)(), order: order !== null && order !== void 0 ? order : exports.DEFAULT_HOOK_ORDER, lexicalOrder: userCodeLexicalOrder++ }, remainingOptions));
}
defineBefore(options, fn) {
this.defineCaseHook("Before", options, fn);
}
defineAfter(options, fn) {
this.defineCaseHook("After", options, fn);
}
defineStepHook(keyword, options, fn) {
const { order } = options, remainingOptions = __rest(options, ["order"]);
this.stepHooks.push(Object.assign({ node: parseMaybeTags(options.tags), implementation: fn, keyword: keyword, position: (0, source_map_1.maybeRetrievePositionFromSourceMap)(), order: order !== null && order !== void 0 ? order : exports.DEFAULT_HOOK_ORDER }, remainingOptions));
}
defineBeforeStep(options, fn) {
this.defineStepHook("BeforeStep", options, fn);
}
defineAfterStep(options, fn) {
this.defineStepHook("AfterStep", options, fn);
}
defineRunHook(keyword, options, fn) {
var _a;
this.preliminaryRunHooks.push({
implementation: fn,
keyword: keyword,
position: (0, source_map_1.maybeRetrievePositionFromSourceMap)(),
order: (_a = options.order) !== null && _a !== void 0 ? _a : exports.DEFAULT_HOOK_ORDER,
lexicalOrder: userCodeLexicalOrder++,
});
}
defineBeforeAll(options, fn) {
this.defineRunHook("BeforeAll", options, fn);
}
defineAfterAll(options, fn) {
this.defineRunHook("AfterAll", options, fn);
}
getMatchingStepDefinitions(text) {
return this.stepDefinitions.filter((stepDefinition) => stepDefinition.expression.match(text));
}
resolveStepDefinition(text) {
const matchingStepDefinitions = this.getMatchingStepDefinitions(text);
if (matchingStepDefinitions.length === 0) {
throw new MissingDefinitionError(`Step implementation missing for: ${text}`);
}
else if (matchingStepDefinitions.length > 1) {
throw new MultipleDefinitionsError(`Multiple matching step definitions for: ${text}\n` +
matchingStepDefinitions
.map((stepDefinition) => {
const { expression } = stepDefinition;
const stringExpression = expression instanceof cucumber_expressions_1.RegularExpression
? String(expression.regexp)
: expression.source;
if (stepDefinition.position) {
return ` ${stringExpression} - ${stepDefinition.position.source}:${stepDefinition.position.line}`;
}
else {
return ` ${stringExpression}`;
}
})
.join("\n"));
}
else {
return matchingStepDefinitions[0];
}
}
runStepDefinition(world, text, dryRun, argument) {
const stepDefinition = this.resolveStepDefinition(text);
const args = stepDefinition.expression
.match(text)
.map((match) => match.getValue(world));
if (argument) {
args.push(argument);
}
if (dryRun) {
return;
}
return stepDefinition.implementation.apply(world, args);
}
resolveCaseHooks(keyword, tags) {
return this.caseHooks
.filter((hook) => hook.keyword === keyword && hook.node.evaluate(tags))
.sort((a, b) => {
return a.order - b.order;
});
}
resolveBeforeHooks(tags) {
return this.resolveCaseHooks("Before", tags);
}
resolveAfterHooks(tags) {
return this.resolveCaseHooks("After", tags).reverse();
}
runCaseHook(world, hook, options) {
return hook.implementation.call(world, options);
}
resolveStepHooks(keyword, tags) {
return this.stepHooks
.filter((hook) => hook.keyword === keyword && hook.node.evaluate(tags))
.sort((a, b) => {
return a.order - b.order;
});
}
resolveBeforeStepHooks(tags) {
return this.resolveStepHooks("BeforeStep", tags);
}
resolveAfterStepHooks(tags) {
return this.resolveStepHooks("AfterStep", tags).reverse();
}
runStepHook(world, hook, options) {
return hook.implementation.call(world, options);
}
resolveRunHooks(keyword) {
return this.runHooks
.filter((hook) => hook.keyword === keyword)
.sort((a, b) => {
return a.order - b.order;
});
}
resolveBeforeAllHooks() {
return this.resolveRunHooks("BeforeAll");
}
resolveAfterAllHooks() {
return this.resolveRunHooks("AfterAll").reverse();
}
runRunHook(world, hook) {
return hook.implementation.call(world);
}
}
exports.Registry = Registry;
const globalPropertyName = "__cypress_cucumber_preprocessor_registry_dont_use_this";
function withRegistry(experimentalSourceMap, fn) {
const registry = new Registry(experimentalSourceMap);
assignRegistry(registry);
fn();
freeRegistry();
return registry;
}
function assignRegistry(registry) {
globalThis[globalPropertyName] = registry;
}
function freeRegistry() {
delete globalThis[globalPropertyName];
}
function getRegistry() {
return (0, assertions_1.ensure)(globalThis[globalPropertyName], "Expected to find a global registry (this usually means you are trying to define steps or hooks in support/e2e.js, which is not supported)");
}