UNPKG

@badeball/cypress-cucumber-preprocessor

Version:

[![Build status](https://github.com/badeball/cypress-cucumber-preprocessor/actions/workflows/build.yml/badge.svg)](https://github.com/badeball/cypress-cucumber-preprocessor/actions/workflows/build.yml) [![Npm package weekly downloads](https://badgen.net/n

186 lines (185 loc) 7.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getRegistry = exports.freeRegistry = exports.assignRegistry = exports.withRegistry = exports.Registry = exports.MultipleDefinitionsError = exports.MissingDefinitionError = void 0; 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; const noopNode = { evaluate: () => true }; function parseHookArguments(options, fn, keyword, position) { return { tags: options.tags, name: options.name, node: options.tags ? (0, tag_expressions_1.default)(options.tags) : noopNode, implementation: fn, keyword, position, }; } class Registry { constructor(experimentalSourceMap) { this.experimentalSourceMap = experimentalSourceMap; this.preliminaryStepDefinitions = []; this.stepDefinitions = []; this.preliminaryHooks = []; this.hooks = []; this.stepHooks = []; this.defineStep = this.defineStep.bind(this); this.runStepDefininition = this.runStepDefininition.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 } of this .preliminaryStepDefinitions) { if (typeof description === "string") { this.stepDefinitions.push({ id: newId(), expression: new cucumber_expressions_1.CucumberExpression(description, this.parameterTypeRegistry), implementation, position, }); } else { this.stepDefinitions.push({ id: newId(), expression: new cucumber_expressions_1.RegularExpression(description, this.parameterTypeRegistry), implementation, position, }); } } for (const preliminaryHook of this.preliminaryHooks) { this.hooks.push(Object.assign({ id: newId() }, preliminaryHook)); } } 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)(this.experimentalSourceMap), }); } defineParameterType({ name, regexp, transformer, }) { this.parameterTypeRegistry.defineParameterType(new cucumber_expressions_1.ParameterType(name, regexp, null, transformer, true, false)); } defineHook(keyword, options, fn) { this.preliminaryHooks.push(parseHookArguments(options, fn, keyword, (0, source_map_1.maybeRetrievePositionFromSourceMap)(this.experimentalSourceMap))); } defineBefore(options, fn) { this.defineHook("Before", options, fn); } defineAfter(options, fn) { this.defineHook("After", options, fn); } defineStepHook(keyword, options, fn) { this.stepHooks.push(parseHookArguments(options, fn, keyword, (0, source_map_1.maybeRetrievePositionFromSourceMap)(this.experimentalSourceMap))); } defineBeforeStep(options, fn) { this.defineStepHook("BeforeStep", options, fn); } defineAfterStep(options, fn) { this.defineStepHook("AfterStep", options, fn); } getMatchingStepDefinitions(text) { return this.stepDefinitions.filter((stepDefinition) => stepDefinition.expression.match(text)); } resolveStepDefintion(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]; } } runStepDefininition(world, text, argument) { const stepDefinition = this.resolveStepDefintion(text); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const args = stepDefinition.expression .match(text) .map((match) => match.getValue(world)); if (argument) { args.push(argument); } return stepDefinition.implementation.apply(world, args); } resolveHooks(keyword, tags) { return this.hooks.filter((hook) => hook.keyword === keyword && hook.node.evaluate(tags)); } resolveBeforeHooks(tags) { return this.resolveHooks("Before", tags); } resolveAfterHooks(tags) { return this.resolveHooks("After", tags).reverse(); } runHook(world, hook, options) { return hook.implementation.call(world, options); } resolveStepHooks(keyword, tags) { return this.stepHooks.filter((hook) => hook.keyword === keyword && hook.node.evaluate(tags)); } 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); } } 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; } exports.withRegistry = withRegistry; function assignRegistry(registry) { globalThis[globalPropertyName] = registry; } exports.assignRegistry = assignRegistry; function freeRegistry() { delete globalThis[globalPropertyName]; } exports.freeRegistry = freeRegistry; function getRegistry() { return (0, assertions_1.assertAndReturn)(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)"); } exports.getRegistry = getRegistry;