You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

@cucumber/cucumber

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 8.7.0 to 10.2.1

lib/api/test_helpers.d.ts

2

lib/api/console_logger.d.ts
/// <reference types="node" />
import { Writable } from 'stream';
import { Writable } from 'node:stream';
import { ILogger } from '../logger';

@@ -4,0 +4,0 @@ export declare class ConsoleLogger implements ILogger {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleLogger = void 0;
const console_1 = require("console");
const node_console_1 = require("node:console");
class ConsoleLogger {
stream;
debugEnabled;
console;
constructor(stream, debugEnabled) {
this.stream = stream;
this.debugEnabled = debugEnabled;
this.console = new console_1.Console(this.stream);
this.console = new node_console_1.Console(this.stream);
}

@@ -11,0 +14,0 @@ debug(...content) {

/// <reference types="node" />
import { IConfiguration } from '../configuration';
import { ILogger } from '../logger';
import { IRunConfiguration } from './types';
export declare function convertConfiguration(flatConfiguration: IConfiguration, env: NodeJS.ProcessEnv): Promise<IRunConfiguration>;
export declare function convertConfiguration(logger: ILogger, flatConfiguration: IConfiguration, env: NodeJS.ProcessEnv): Promise<IRunConfiguration>;

@@ -5,3 +5,3 @@ "use strict";

const configuration_1 = require("../configuration");
async function convertConfiguration(flatConfiguration, env) {
async function convertConfiguration(logger, flatConfiguration, env) {
return {

@@ -30,11 +30,11 @@ sources: {

},
formats: convertFormats(flatConfiguration, env),
formats: convertFormats(logger, flatConfiguration, env),
};
}
exports.convertConfiguration = convertConfiguration;
function convertFormats(flatConfiguration, env) {
var _a, _b;
const splitFormats = flatConfiguration.format.map((item) => configuration_1.OptionSplitter.split(item));
function convertFormats(logger, flatConfiguration, env) {
const splitFormats = flatConfiguration.format.map((item) => Array.isArray(item) ? item : (0, configuration_1.splitFormatDescriptor)(logger, item));
return {
stdout: (_b = (_a = [...splitFormats].reverse().find(([, target]) => !target)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : 'progress',
stdout: [...splitFormats].reverse().find(([, target]) => !target)?.[0] ??
'progress',
files: splitFormats

@@ -41,0 +41,0 @@ .filter(([, target]) => !!target)

@@ -0,2 +1,7 @@

import { ILogger } from '../logger';
import { IRunEnvironment } from './types';
export declare function mergeEnvironment(provided: IRunEnvironment): Required<IRunEnvironment>;
type EnvironmentWithLogger = Required<IRunEnvironment> & {
logger: ILogger;
};
export declare function mergeEnvironment(provided: IRunEnvironment): EnvironmentWithLogger;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeEnvironment = void 0;
const console_logger_1 = require("./console_logger");
function mergeEnvironment(provided) {
return Object.assign({}, {
const fullEnvironment = Object.assign({}, {
cwd: process.cwd(),

@@ -12,4 +13,8 @@ stdout: process.stdout,

}, provided);
return {
...fullEnvironment,
logger: new console_logger_1.ConsoleLogger(fullEnvironment.stderr, fullEnvironment.debug),
};
}
exports.mergeEnvironment = mergeEnvironment;
//# sourceMappingURL=environment.js.map
/// <reference types="node" />
/// <reference types="node" />
import { EventEmitter } from 'node:events';
import { IFormatterStream } from '../formatter';
import { EventEmitter } from 'events';
import { EventDataCollector } from '../formatter/helpers';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
import { ILogger } from '../logger';
import { IRunOptionsFormats } from './types';
import { ILogger } from '../logger';
export declare function initializeFormatters({ env, cwd, stdout, logger, onStreamError, eventBroadcaster, eventDataCollector, configuration, supportCodeLibrary, }: {

@@ -19,3 +19,3 @@ env: NodeJS.ProcessEnv;

configuration: IRunOptionsFormats;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}): Promise<() => Promise<void>>;

@@ -7,6 +7,7 @@ "use strict";

exports.initializeFormatters = void 0;
const util_1 = require("util");
const node_util_1 = require("node:util");
const node_path_1 = __importDefault(require("node:path"));
const fs_1 = __importDefault(require("mz/fs"));
const mkdirp_1 = require("mkdirp");
const builder_1 = __importDefault(require("../formatter/builder"));
const fs_1 = __importDefault(require("mz/fs"));
const path_1 = __importDefault(require("path"));
async function initializeFormatters({ env, cwd, stdout, logger, onStreamError, eventBroadcaster, eventDataCollector, configuration, supportCodeLibrary, }) {

@@ -28,3 +29,3 @@ async function initializeFormatter(stream, target, type) {

? async () => await Promise.resolve()
: (0, util_1.promisify)(stream.end.bind(stream)),
: (0, node_util_1.promisify)(stream.end.bind(stream)),
supportCodeLibrary,

@@ -40,8 +41,19 @@ };

formatters.push(await initializeFormatter(stdout, 'stdout', configuration.stdout));
for (const [target, type] of Object.entries(configuration.files)) {
const stream = fs_1.default.createWriteStream(null, {
fd: await fs_1.default.open(path_1.default.resolve(cwd, target), 'w'),
});
formatters.push(await initializeFormatter(stream, target, type));
}
const streamPromises = [];
Object.entries(configuration.files).forEach(([target, type]) => {
streamPromises.push((async (target, type) => {
const absoluteTarget = node_path_1.default.resolve(cwd, target);
try {
await (0, mkdirp_1.mkdirp)(node_path_1.default.dirname(absoluteTarget));
}
catch (error) {
logger.warn('Failed to ensure directory for formatter target exists');
}
const stream = fs_1.default.createWriteStream(null, {
fd: await fs_1.default.open(absoluteTarget, 'w'),
});
formatters.push(await initializeFormatter(stream, target, type));
})(target, type));
});
await Promise.all(streamPromises);
return async function () {

@@ -48,0 +60,0 @@ await Promise.all(formatters.map(async (f) => await f.finished()));

@@ -1,21 +0,13 @@

import { Envelope, GherkinDocument, IdGenerator, Location, ParseError, Pickle } from '@cucumber/messages';
import { Envelope, IdGenerator, ParseError } from '@cucumber/messages';
import { IFilterablePickle } from '../filter';
import { ISourcesCoordinates } from './types';
import { ILogger } from '../logger';
interface PickleWithDocument {
gherkinDocument: GherkinDocument;
location: Location;
pickle: Pickle;
}
export declare function getFilteredPicklesAndErrors({ newId, cwd, logger, unexpandedFeaturePaths, featurePaths, coordinates, onEnvelope, }: {
export declare function getPicklesAndErrors({ newId, cwd, sourcePaths, coordinates, onEnvelope, }: {
newId: IdGenerator.NewId;
cwd: string;
logger: ILogger;
unexpandedFeaturePaths: string[];
featurePaths: string[];
sourcePaths: string[];
coordinates: ISourcesCoordinates;
onEnvelope?: (envelope: Envelope) => void;
}): Promise<{
filteredPickles: PickleWithDocument[];
filterablePickles: readonly IFilterablePickle[];
parseErrors: ParseError[];
}>;
export {};
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFilteredPicklesAndErrors = void 0;
exports.getPicklesAndErrors = void 0;
const gherkin_streams_1 = require("@cucumber/gherkin-streams");
const gherkin_utils_1 = require("@cucumber/gherkin-utils");
const pickle_filter_1 = __importDefault(require("../pickle_filter"));
const helpers_1 = require("../cli/helpers");
async function getFilteredPicklesAndErrors({ newId, cwd, logger, unexpandedFeaturePaths, featurePaths, coordinates, onEnvelope, }) {
async function getPicklesAndErrors({ newId, cwd, sourcePaths, coordinates, onEnvelope, }) {
const gherkinQuery = new gherkin_utils_1.Query();
const parseErrors = [];
await gherkinFromPaths(featurePaths, {
await gherkinFromPaths(sourcePaths, {
newId,

@@ -23,22 +18,8 @@ relativeTo: cwd,

}
onEnvelope === null || onEnvelope === void 0 ? void 0 : onEnvelope(envelope);
onEnvelope?.(envelope);
});
const pickleFilter = new pickle_filter_1.default({
cwd,
featurePaths: unexpandedFeaturePaths,
names: coordinates.names,
tagExpression: coordinates.tagExpression,
});
const filteredPickles = gherkinQuery
.getPickles()
.filter((pickle) => {
const filterablePickles = gherkinQuery.getPickles().map((pickle) => {
const gherkinDocument = gherkinQuery
.getGherkinDocuments()
.find((doc) => doc.uri === pickle.uri);
return pickleFilter.matches({ gherkinDocument, pickle });
})
.map((pickle) => {
const gherkinDocument = gherkinQuery
.getGherkinDocuments()
.find((doc) => doc.uri === pickle.uri);
const location = gherkinQuery.getLocation(pickle.astNodeIds[pickle.astNodeIds.length - 1]);

@@ -51,9 +32,8 @@ return {

});
(0, helpers_1.orderPickles)(filteredPickles, coordinates.order, logger);
return {
filteredPickles,
filterablePickles,
parseErrors,
};
}
exports.getFilteredPicklesAndErrors = getFilteredPicklesAndErrors;
exports.getPicklesAndErrors = getPicklesAndErrors;
async function gherkinFromPaths(paths, options, onEnvelope) {

@@ -60,0 +40,0 @@ return new Promise((resolve, reject) => {

/**
* Cucumber for JavaScript
* JavaScript API for running and extending Cucumber
*
* @remarks These docs cover the API used for running Cucumber programmatically. The entry point is `@cucumber/cucumber/api`.
* @packageDocumentation
* @module api
* @remarks
* These docs cover the API used for running Cucumber programmatically. The entry point is `@cucumber/cucumber/api`.
*/
export { IConfiguration } from '../configuration';
export { IPickleOrder } from '../filter';
export { IPublishConfig } from '../publish';
export * from './load_configuration';

@@ -9,0 +13,0 @@ export * from './load_sources';

"use strict";
/**
* Cucumber for JavaScript
* JavaScript API for running and extending Cucumber
*
* @remarks These docs cover the API used for running Cucumber programmatically. The entry point is `@cucumber/cucumber/api`.
* @packageDocumentation
* @module api
* @remarks
* These docs cover the API used for running Cucumber programmatically. The entry point is `@cucumber/cucumber/api`.
*/

@@ -8,0 +10,0 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

import { IRunEnvironment, IResolvedConfiguration, ILoadConfigurationOptions } from './types';
/**
* Load user-authored configuration to be used in a test run.
* Load user-authored configuration to be used in a test run
*
* @public
* @param options - Coordinates required to find configuration.
* @param environment - Project environment.
* @param options - Coordinates required to find configuration
* @param environment - Project environment
*/
export declare function loadConfiguration(options?: ILoadConfigurationOptions, environment?: IRunEnvironment): Promise<IResolvedConfiguration>;

@@ -9,18 +9,18 @@ "use strict";

const environment_1 = require("./environment");
const console_logger_1 = require("./console_logger");
/**
* Load user-authored configuration to be used in a test run.
* Load user-authored configuration to be used in a test run
*
* @public
* @param options - Coordinates required to find configuration.
* @param environment - Project environment.
* @param options - Coordinates required to find configuration
* @param environment - Project environment
*/
async function loadConfiguration(options = {}, environment = {}) {
var _a;
const { cwd, stderr, env, debug } = (0, environment_1.mergeEnvironment)(environment);
const logger = new console_logger_1.ConsoleLogger(stderr, debug);
const configFile = (_a = options.file) !== null && _a !== void 0 ? _a : (0, locate_file_1.locateFile)(cwd);
const { cwd, env, logger } = (0, environment_1.mergeEnvironment)(environment);
const configFile = options.file ?? (0, locate_file_1.locateFile)(cwd);
if (configFile) {
logger.debug(`Configuration will be loaded from "${configFile}"`);
}
else if (configFile === false) {
logger.debug('Skipping configuration file resolution');
}
else {

@@ -34,4 +34,4 @@ logger.debug('No configuration file found');

logger.debug('Resolved configuration:', original);
(0, validate_configuration_1.validateConfiguration)(original);
const runnable = await (0, convert_configuration_1.convertConfiguration)(original, env);
(0, validate_configuration_1.validateConfiguration)(original, logger);
const runnable = await (0, convert_configuration_1.convertConfiguration)(logger, original, env);
return {

@@ -38,0 +38,0 @@ useConfiguration: original,

import { ILoadSourcesResult, IRunEnvironment, ISourcesCoordinates } from './types';
/**
* Load and parse features, produce a filtered and ordered test plan and/or parse errors.
* Load and parse features, produce a filtered and ordered test plan and/or
* parse errors
*
* @public
* @param coordinates - Coordinates required to find features
* @param environment - Project environment.
* @param coordinates - Coordinates required to find and process features
* @param environment - Project environment
*/
export declare function loadSources(coordinates: ISourcesCoordinates, environment?: IRunEnvironment): Promise<ILoadSourcesResult>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadSources = void 0;
const paths_1 = require("./paths");
const messages_1 = require("@cucumber/messages");
const paths_1 = require("../paths");
const environment_1 = require("./environment");
const gherkin_1 = require("./gherkin");
const console_logger_1 = require("./console_logger");
const plugins_1 = require("./plugins");
/**
* Load and parse features, produce a filtered and ordered test plan and/or parse errors.
* Load and parse features, produce a filtered and ordered test plan and/or
* parse errors
*
* @public
* @param coordinates - Coordinates required to find features
* @param environment - Project environment.
* @param coordinates - Coordinates required to find and process features
* @param environment - Project environment
*/
async function loadSources(coordinates, environment = {}) {
const { cwd, stderr, debug } = (0, environment_1.mergeEnvironment)(environment);
const logger = new console_logger_1.ConsoleLogger(stderr, debug);
const mergedEnvironment = (0, environment_1.mergeEnvironment)(environment);
const { cwd, logger } = mergedEnvironment;
const newId = messages_1.IdGenerator.uuid();
const { unexpandedFeaturePaths, featurePaths } = await (0, paths_1.resolvePaths)(logger, cwd, coordinates);
if (featurePaths.length === 0) {
const pluginManager = await (0, plugins_1.initializeForLoadSources)(logger, coordinates, mergedEnvironment);
const resolvedPaths = await (0, paths_1.resolvePaths)(logger, cwd, coordinates);
pluginManager.emit('paths:resolve', resolvedPaths);
const { sourcePaths } = resolvedPaths;
if (sourcePaths.length === 0) {
return {

@@ -27,11 +31,12 @@ plan: [],

}
const { filteredPickles, parseErrors } = await (0, gherkin_1.getFilteredPicklesAndErrors)({
const { filterablePickles, parseErrors } = await (0, gherkin_1.getPicklesAndErrors)({
newId,
cwd,
logger,
unexpandedFeaturePaths,
featurePaths,
sourcePaths,
coordinates,
onEnvelope: (envelope) => pluginManager.emit('message', envelope),
});
const plan = filteredPickles.map(({ location, pickle }) => ({
const filteredPickles = await pluginManager.transform('pickles:filter', filterablePickles);
const orderedPickles = await pluginManager.transform('pickles:order', filteredPickles);
const plan = orderedPickles.map(({ location, pickle }) => ({
name: pickle.name,

@@ -48,2 +53,3 @@ uri: pickle.uri,

});
await pluginManager.cleanup();
return {

@@ -50,0 +56,0 @@ plan,

@@ -1,10 +0,9 @@

import { ILoadSupportOptions, IRunEnvironment } from './types';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { ILoadSupportOptions, IRunEnvironment, ISupportCodeLibrary } from './types';
/**
* Load support code for use in test runs.
* Load support code for use in test runs
*
* @public
* @param options - Subset of `IRunnableConfiguration` required to find the support code.
* @param environment - Project environment.
* @param options - Options required to find the support code
* @param environment - Project environment
*/
export declare function loadSupport(options: ILoadSupportOptions, environment?: IRunEnvironment): Promise<ISupportCodeLibrary>;

@@ -5,19 +5,22 @@ "use strict";

const messages_1 = require("@cucumber/messages");
const paths_1 = require("./paths");
const paths_1 = require("../paths");
const support_1 = require("./support");
const environment_1 = require("./environment");
const console_logger_1 = require("./console_logger");
const plugins_1 = require("./plugins");
/**
* Load support code for use in test runs.
* Load support code for use in test runs
*
* @public
* @param options - Subset of `IRunnableConfiguration` required to find the support code.
* @param environment - Project environment.
* @param options - Options required to find the support code
* @param environment - Project environment
*/
async function loadSupport(options, environment = {}) {
const { cwd, stderr, debug } = (0, environment_1.mergeEnvironment)(environment);
const logger = new console_logger_1.ConsoleLogger(stderr, debug);
const mergedEnvironment = (0, environment_1.mergeEnvironment)(environment);
const { cwd, logger } = mergedEnvironment;
const newId = messages_1.IdGenerator.uuid();
const { requirePaths, importPaths } = await (0, paths_1.resolvePaths)(logger, cwd, options.sources, options.support);
return await (0, support_1.getSupportCodeLibrary)({
const pluginManager = await (0, plugins_1.initializeForLoadSupport)();
const resolvedPaths = await (0, paths_1.resolvePaths)(logger, cwd, options.sources, options.support);
pluginManager.emit('paths:resolve', resolvedPaths);
const { requirePaths, importPaths } = resolvedPaths;
const supportCodeLibrary = await (0, support_1.getSupportCodeLibrary)({
cwd,

@@ -29,4 +32,6 @@ newId,

});
await pluginManager.cleanup();
return supportCodeLibrary;
}
exports.loadSupport = loadSupport;
//# sourceMappingURL=load_support.js.map
import { PluginManager } from '../plugin';
import { IRunEnvironment, IRunOptions } from './types';
import { ILogger } from '../logger';
export declare function initializePlugins(logger: ILogger, configuration: IRunOptions, environment: IRunEnvironment): Promise<PluginManager>;
import { IRunConfiguration, IRunEnvironment, ISourcesCoordinates } from './types';
export declare function initializeForLoadSources(logger: ILogger, coordinates: ISourcesCoordinates, environment: Required<IRunEnvironment>): Promise<PluginManager>;
export declare function initializeForLoadSupport(): Promise<PluginManager>;
export declare function initializeForRunCucumber(logger: ILogger, configuration: IRunConfiguration, environment: Required<IRunEnvironment>): Promise<PluginManager>;

@@ -6,15 +6,26 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.initializePlugins = void 0;
exports.initializeForRunCucumber = exports.initializeForLoadSupport = exports.initializeForLoadSources = void 0;
const plugin_1 = require("../plugin");
const publish_1 = __importDefault(require("../publish"));
const INTERNAL_PLUGINS = {
publish: publish_1.default,
};
async function initializePlugins(logger, configuration, environment) {
const filter_1 = __importDefault(require("../filter"));
async function initializeForLoadSources(logger, coordinates, environment) {
// eventually we'll load plugin packages here
const pluginManager = new plugin_1.PluginManager(Object.values(INTERNAL_PLUGINS));
await pluginManager.init(logger, configuration, environment);
const pluginManager = new plugin_1.PluginManager();
await pluginManager.init('loadSources', filter_1.default, coordinates, logger, environment);
return pluginManager;
}
exports.initializePlugins = initializePlugins;
exports.initializeForLoadSources = initializeForLoadSources;
async function initializeForLoadSupport() {
// eventually we'll load plugin packages here
return new plugin_1.PluginManager();
}
exports.initializeForLoadSupport = initializeForLoadSupport;
async function initializeForRunCucumber(logger, configuration, environment) {
// eventually we'll load plugin packages here
const pluginManager = new plugin_1.PluginManager();
await pluginManager.init('runCucumber', publish_1.default, configuration.formats.publish, logger, environment);
await pluginManager.init('runCucumber', filter_1.default, configuration.sources, logger, environment);
return pluginManager;
}
exports.initializeForRunCucumber = initializeForRunCucumber;
//# sourceMappingURL=plugins.js.map
import { Envelope } from '@cucumber/messages';
import { IRunOptions, IRunEnvironment, IRunResult } from './types';
/**
* Execute a Cucumber test run.
* Execute a Cucumber test run and return the overall result
*
* @public
* @param configuration - Configuration loaded from `loadConfiguration`.
* @param environment - Project environment.
* @param onMessage - Callback fired each time Cucumber emits a message.
* @param options - Options for the run, obtainable via {@link loadConfiguration}
* @param environment - Project environment
* @param onMessage - Callback fired each time Cucumber emits a message
*/
export declare function runCucumber(configuration: IRunOptions, environment?: IRunEnvironment, onMessage?: (message: Envelope) => void): Promise<IRunResult>;
export declare function runCucumber(options: IRunOptions, environment?: IRunEnvironment, onMessage?: (message: Envelope) => void): Promise<IRunResult>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runCucumber = void 0;
const node_events_1 = require("node:events");
const messages_1 = require("@cucumber/messages");
const events_1 = require("events");
const helpers_1 = require("../formatter/helpers");
const helpers_2 = require("../cli/helpers");
const paths_1 = require("./paths");
const paths_1 = require("../paths");
const runtime_1 = require("./runtime");

@@ -15,21 +15,26 @@ const formatters_1 = require("./formatters");

const plugins_1 = require("./plugins");
const console_logger_1 = require("./console_logger");
/**
* Execute a Cucumber test run.
* Execute a Cucumber test run and return the overall result
*
* @public
* @param configuration - Configuration loaded from `loadConfiguration`.
* @param environment - Project environment.
* @param onMessage - Callback fired each time Cucumber emits a message.
* @param options - Options for the run, obtainable via {@link loadConfiguration}
* @param environment - Project environment
* @param onMessage - Callback fired each time Cucumber emits a message
*/
async function runCucumber(configuration, environment = {}, onMessage) {
const { cwd, stdout, stderr, env, debug } = (0, environment_1.mergeEnvironment)(environment);
const logger = new console_logger_1.ConsoleLogger(stderr, debug);
async function runCucumber(options, environment = {}, onMessage) {
const mergedEnvironment = (0, environment_1.mergeEnvironment)(environment);
const { cwd, stdout, stderr, env, logger } = mergedEnvironment;
const newId = messages_1.IdGenerator.uuid();
const supportCoordinates = 'World' in configuration.support
? configuration.support.originalCoordinates
: configuration.support;
const { unexpandedFeaturePaths, featurePaths, requirePaths, importPaths } = await (0, paths_1.resolvePaths)(logger, cwd, configuration.sources, supportCoordinates);
const supportCodeLibrary = 'World' in configuration.support
? configuration.support
const supportCoordinates = 'originalCoordinates' in options.support
? options.support.originalCoordinates
: options.support;
const pluginManager = await (0, plugins_1.initializeForRunCucumber)(logger, {
...options,
support: supportCoordinates,
}, mergedEnvironment);
const resolvedPaths = await (0, paths_1.resolvePaths)(logger, cwd, options.sources, supportCoordinates);
pluginManager.emit('paths:resolve', resolvedPaths);
const { sourcePaths, requirePaths, importPaths } = resolvedPaths;
const supportCodeLibrary = 'originalCoordinates' in options.support
? options.support
: await (0, support_1.getSupportCodeLibrary)({

@@ -42,8 +47,7 @@ cwd,

});
const plugins = await (0, plugins_1.initializePlugins)(logger, configuration, environment);
const eventBroadcaster = new events_1.EventEmitter();
const eventBroadcaster = new node_events_1.EventEmitter();
if (onMessage) {
eventBroadcaster.on('envelope', onMessage);
}
eventBroadcaster.on('envelope', (value) => plugins.emit('message', value));
eventBroadcaster.on('envelope', (value) => pluginManager.emit('message', value));
const eventDataCollector = new helpers_1.EventDataCollector(eventBroadcaster);

@@ -60,3 +64,3 @@ let formatterStreamError = false;

eventDataCollector,
configuration: configuration.formats,
configuration: options.formats,
supportCodeLibrary,

@@ -67,13 +71,13 @@ });

let parseErrors = [];
if (featurePaths.length > 0) {
const gherkinResult = await (0, gherkin_1.getFilteredPicklesAndErrors)({
if (sourcePaths.length > 0) {
const gherkinResult = await (0, gherkin_1.getPicklesAndErrors)({
newId,
cwd,
logger,
unexpandedFeaturePaths,
featurePaths,
coordinates: configuration.sources,
sourcePaths,
coordinates: options.sources,
onEnvelope: (envelope) => eventBroadcaster.emit('envelope', envelope),
});
pickleIds = gherkinResult.filteredPickles.map(({ pickle }) => pickle.id);
const filteredPickles = await pluginManager.transform('pickles:filter', gherkinResult.filterablePickles);
const orderedPickles = await pluginManager.transform('pickles:order', filteredPickles);
pickleIds = orderedPickles.map(({ pickle }) => pickle.id);
parseErrors = gherkinResult.parseErrors;

@@ -86,3 +90,3 @@ }

await cleanupFormatters();
await plugins.cleanup();
await pluginManager.cleanup();
return {

@@ -109,7 +113,7 @@ success: false,

importPaths,
options: configuration.runtime,
options: options.runtime,
});
const success = await runtime.start();
await cleanupFormatters();
await plugins.cleanup();
await pluginManager.cleanup();
return {

@@ -116,0 +120,0 @@ success: success && !formatterStreamError,

/// <reference types="node" />
import { EventEmitter } from 'node:events';
import { IdGenerator } from '@cucumber/messages';
import { IRuntime } from '../runtime';
import { EventEmitter } from 'events';
import { EventDataCollector } from '../formatter/helpers';
import { IdGenerator } from '@cucumber/messages';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
import { ILogger } from '../logger';
import { IRunOptionsRuntime } from './types';
import { ILogger } from '../logger';
export declare function makeRuntime({ cwd, logger, eventBroadcaster, eventDataCollector, pickleIds, newId, supportCodeLibrary, requireModules, requirePaths, importPaths, options: { parallel, ...options }, }: {

@@ -16,3 +16,3 @@ cwd: string;

pickleIds: string[];
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
requireModules: string[];

@@ -19,0 +19,0 @@ requirePaths: string[];

import { IdGenerator } from '@cucumber/messages';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
export declare function getSupportCodeLibrary({ cwd, newId, requireModules, requirePaths, importPaths, }: {

@@ -9,2 +9,2 @@ cwd: string;

importPaths: string[];
}): Promise<ISupportCodeLibrary>;
}): Promise<SupportCodeLibrary>;

@@ -7,12 +7,15 @@ "use strict";

exports.getSupportCodeLibrary = void 0;
const node_url_1 = require("node:url");
const support_code_library_builder_1 = __importDefault(require("../support_code_library_builder"));
const url_1 = require("url");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { importer } = require('../importer');
const try_require_1 = __importDefault(require("../try_require"));
async function getSupportCodeLibrary({ cwd, newId, requireModules, requirePaths, importPaths, }) {
support_code_library_builder_1.default.reset(cwd, newId);
requireModules.map((module) => require(module));
requirePaths.map((path) => require(path));
support_code_library_builder_1.default.reset(cwd, newId, {
requireModules,
requirePaths,
importPaths,
});
requireModules.map((module) => (0, try_require_1.default)(module));
requirePaths.map((path) => (0, try_require_1.default)(path));
for (const path of importPaths) {
await importer((0, url_1.pathToFileURL)(path));
await import((0, node_url_1.pathToFileURL)(path).toString());
}

@@ -19,0 +22,0 @@ return support_code_library_builder_1.default.finalize();

/// <reference types="node" />
/// <reference types="node" />
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { FormatOptions, IPublishConfig } from '../formatter';
import { PickleOrder } from '../models/pickle_order';
import { IRuntimeOptions } from '../runtime';
import { Writable } from 'node:stream';
import { JsonObject } from 'type-fest';
import { IPublishConfig } from '../publish';
import { IConfiguration } from '../configuration';
import { Writable } from 'stream';
import { IPickleOrder } from '../filter';
/**
* Options for {@link loadConfiguration}
* @public

@@ -14,11 +14,15 @@ */

/**
* Path to load configuration file from (defaults to `cucumber.(js|cjs|mjs|json)` if omitted).
* Path to load configuration file from, or `false` to skip
* @default `cucumber.(json|yaml|yml|js|cjs|mjs)`
*/
file?: string;
file?: string | false;
/**
* Zero or more profile names from which to source configuration (if omitted or empty, the `default` profile will be used).
* Zero or more profile names from which to source configuration in the file
* @remarks
* If omitted or empty, the `default` profile will be used.
*/
profiles?: string[];
/**
* Ad-hoc configuration options to be applied over the top of whatever is loaded from the configuration file/profiles.
* Ad-hoc configuration options to be merged over the top of whatever is
* loaded from the configuration file/profiles
*/

@@ -28,2 +32,3 @@ provided?: Partial<IConfiguration>;

/**
* Response from {@link loadConfiguration}
* @public

@@ -33,7 +38,8 @@ */

/**
* The final flat configuration object resolved from the configuration file/profiles plus any extra provided.
* The final flat configuration object resolved from the configuration
* file/profiles plus any extra provided
*/
useConfiguration: IConfiguration;
/**
* The format that can be passed into `runCucumber`.
* The format that can be passed into {@link runCucumber}
*/

@@ -43,15 +49,38 @@ runConfiguration: IRunConfiguration;

/**
* Options relating to sources (i.e. feature files) - where to load them from,
* how to interpret, filter and order them
* @public
*/
export interface ISourcesCoordinates {
/**
* Default Gherkin dialect
* @remarks
* Used if no dialect is specified in the feature file itself.
*/
defaultDialect: string;
/**
* Paths and/or glob expressions to feature files
*/
paths: string[];
/**
* Regular expressions of which scenario names should match one of to be run
*/
names: string[];
/**
* Tag expression to filter which scenarios should be run
*/
tagExpression: string;
order: PickleOrder;
/**
* Run in the order defined, or in a random order
*/
order: IPickleOrder;
}
/**
* A pickle that has been successfully compiled from a source
* @public
*/
export interface IPlannedPickle {
/**
* Name of the pickle (after parameter resolution)
*/
name: string;

@@ -65,2 +94,3 @@ uri: string;

/**
* An error encountered when parsing a source
* @public

@@ -74,23 +104,53 @@ */

};
/**
* Error message explaining what went wrong with the parse
*/
message: string;
}
/**
* Response from {@link loadSources}
* @public
*/
export interface ILoadSourcesResult {
/**
* Pickles that have been successfully compiled, in the order they would be
* run in
*/
plan: IPlannedPickle[];
/**
* Any errors encountered when parsing sources
*/
errors: ISourcesError[];
}
/**
* Options relating to user code (aka support code) - where to load it from and
* how to preprocess it
* @public
*/
export interface ISupportCodeCoordinates {
/**
* Names of transpilation modules to load, via `require()`
*/
requireModules: string[];
/**
* Paths and/or glob expressions of user code to load, via `require()`
*/
requirePaths: string[];
/**
* Paths and/or glob expressions of user code to load, via `import()`
*/
importPaths: string[];
}
/**
* Options for {@link loadSupport}
* @public
* @remarks
* A subset of {@link IRunConfiguration}
*/
export interface ILoadSupportOptions {
/**
* @remarks
* This is needed because the default support path locations are derived from
* feature file locations.
*/
sources: ISourcesCoordinates;

@@ -100,17 +160,74 @@ support: ISupportCodeCoordinates;

/**
* Options relating to behaviour when actually running tests
* @public
*/
export interface IRunOptionsRuntime extends IRuntimeOptions {
export interface IRunOptionsRuntime {
/**
* Perform a dry run, where a test run is prepared but nothing is executed
*/
dryRun: boolean;
/**
* Stop running tests when a test fails
*/
failFast: boolean;
/**
* Filter out stack frames from Cucumber's code when formatting stack traces
*/
filterStacktraces: boolean;
/**
* Run tests in parallel with the given number of worker processes
*/
parallel: number;
/**
* Retry failing tests up to the given number of times
*/
retry: number;
/**
* Tag expression to filter which scenarios can be retried
*/
retryTagFilter: string;
/**
* Fail the test run if there are pending steps
*/
strict: boolean;
/**
* Parameters to be passed to the World
* @remarks
* The value must be a JSON-serializable object.
*/
worldParameters: JsonObject;
}
/**
* Options relating to formatters - which ones to use, where to write their
* output, how they should behave
* @public
*/
export interface IRunOptionsFormats {
/**
* Name/path of the formatter to use for `stdout` output
*/
stdout: string;
/**
* Zero or more mappings of file output path (key) to name/path of the
* formatter to use (value)
* @example
* \{
* "./reports/cucumber.html": "html",
* "./reports/custom.txt": "./custom-formatter.js"
* \}
*/
files: Record<string, string>;
/**
* Options for report publication, or `false` to disable publication
*/
publish: IPublishConfig | false;
options: FormatOptions;
/**
* Options to be provided to formatters
* @remarks
* The value must be a JSON-serializable object.
*/
options: JsonObject;
}
/**
* Structured configuration object suitable for passing to {@link runCucumber}
* @public

@@ -125,8 +242,30 @@ */

/**
* A collection of user-defined code and setup ("support code") that can be
* used for a test run
* @public
* @remarks
* This is mostly a marker interface. The actual instance is a complex object
* that you shouldn't interact with directly, but some functions return and/or
* accept it as a means of optimising a test workflow.
*/
export declare type ISupportCodeCoordinatesOrLibrary = ISupportCodeCoordinates | ISupportCodeLibrary;
export interface ISupportCodeLibrary {
readonly originalCoordinates: ISupportCodeCoordinates;
}
/**
* Either an actual {@link ISupportCodeLibrary | support code library}, or the
* {@link ISupportCodeCoordinates | coordinates} required to create and
* populate one
* @public
* @remarks
* This alias exists because {@link runCucumber} will accept an existing
* support code library in its options and thus avoid trying to load it again,
* improving performance and avoiding cache issues for use cases where multiple
* test runs happen within the same process. Note this is only useful in serial
* mode, as parallel workers will each load the support code themselves anyway.
*/
export type ISupportCodeCoordinatesOrLibrary = ISupportCodeCoordinates | ISupportCodeLibrary;
/**
* Options for {@link runCucumber}
* @public
*/
export interface IRunOptions {

@@ -139,4 +278,3 @@ sources: ISourcesCoordinates;

/**
* Contextual data about the project environment.
*
* Contextual data about the project environment
* @public

@@ -146,19 +284,25 @@ */

/**
* Working directory for the project (defaults to `process.cwd()` if omitted).
* Working directory for the project
* @default process.cwd()
*/
cwd?: string;
/**
* Writable stream where the test run's main output is written (defaults to `process.stdout` if omitted).
* Writable stream where the test run's main formatter output is written
* @default process.stdout
*/
stdout?: Writable;
/**
* Writable stream where the test run's warning/error output is written (defaults to `process.stderr` if omitted).
* Writable stream where the test run's warning/error output is written
* @default process.stderr
*/
stderr?: Writable;
/**
* Environment variables (defaults to `process.env` if omitted).
* Environment variables
* @default process.env
*/
env?: NodeJS.ProcessEnv;
/**
* Whether debug logging is enabled.
* Whether debug logging should be emitted to {@link IRunEnvironment.stderr}
* @default false
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/debugging.md}
*/

@@ -168,4 +312,3 @@ debug?: boolean;

/**
* Result of a Cucumber test run.
*
* Response from {@link runCucumber}
* @public

@@ -175,9 +318,14 @@ */

/**
* Whether the test run was overall successful i.e. no failed scenarios. The exact meaning can vary based on the `strict` configuration option.
* Whether the test run was overall successful
* @remarks
* The exact meaning can vary based on the `strict` configuration option.
*/
success: boolean;
/**
* The support code library that was used in the test run; can be reused in subsequent `runCucumber` calls.
* The support code library that was used in the test run
* @remarks
* This can be reused in subsequent {@link runCucumber} calls,
* see {@link ISupportCodeCoordinatesOrLibrary}
*/
support: ISupportCodeLibrary;
}
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { EventEmitter } from 'events';
import { EventEmitter } from 'node:events';
import { Readable } from 'node:stream';
import { IdGenerator } from '@cucumber/messages';
import { EventDataCollector } from '../formatter/helpers';
import PickleFilter from '../pickle_filter';
import { EventDataCollector } from '../formatter/helpers';
import { Readable } from 'stream';
import { IdGenerator } from '@cucumber/messages';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { PickleOrder } from '../models/pickle_order';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
import { ILogger } from '../logger';
import { IPickleOrder } from '../filter';
interface IParseGherkinMessageStreamRequest {

@@ -30,9 +30,9 @@ cwd?: string;

export declare function parseGherkinMessageStream({ eventBroadcaster, eventDataCollector, gherkinMessageStream, order, pickleFilter, }: IParseGherkinMessageStreamRequest): Promise<string[]>;
export declare function orderPickles<T = string>(pickleIds: T[], order: PickleOrder, logger: ILogger): void;
export declare function orderPickles<T = string>(pickleIds: T[], order: IPickleOrder, logger: ILogger): void;
export declare function emitMetaMessage(eventBroadcaster: EventEmitter, env: NodeJS.ProcessEnv): Promise<void>;
export declare function emitSupportCodeMessages({ eventBroadcaster, supportCodeLibrary, newId, }: {
eventBroadcaster: EventEmitter;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
newId: IdGenerator.NewId;
}): void;
export {};

@@ -30,9 +30,7 @@ "use strict";

exports.emitSupportCodeMessages = exports.emitMetaMessage = exports.orderPickles = exports.parseGherkinMessageStream = void 0;
const node_os_1 = __importDefault(require("node:os"));
const knuth_shuffle_seeded_1 = __importDefault(require("knuth-shuffle-seeded"));
const value_checker_1 = require("../value_checker");
const configuration_1 = require("../configuration");
const os_1 = __importDefault(require("os"));
const messages = __importStar(require("@cucumber/messages"));
const ci_environment_1 = __importDefault(require("@cucumber/ci-environment"));
const support_code_library_builder_1 = require("../support_code_library_builder");
const value_checker_1 = require("../value_checker");
const version_1 = require("../version");

@@ -72,3 +70,3 @@ /**

function orderPickles(pickleIds, order, logger) {
const [type, seed] = configuration_1.OptionSplitter.split(order);
const [type, seed] = splitOrder(order);
switch (type) {

@@ -92,2 +90,8 @@ case 'defined':

exports.orderPickles = orderPickles;
function splitOrder(order) {
if (!order.includes(':')) {
return [order, ''];
}
return order.split(':');
}
async function emitMetaMessage(eventBroadcaster, env) {

@@ -101,7 +105,7 @@ const meta = {

cpu: {
name: os_1.default.arch(),
name: node_os_1.default.arch(),
},
os: {
name: os_1.default.platform(),
version: os_1.default.release(),
name: node_os_1.default.platform(),
version: node_os_1.default.release(),
},

@@ -119,8 +123,15 @@ runtime: {

exports.emitMetaMessage = emitMetaMessage;
const makeSourceReference = (source) => ({
uri: source.uri,
location: {
line: source.line,
},
});
function emitParameterTypes(supportCodeLibrary, eventBroadcaster, newId) {
for (const parameterType of supportCodeLibrary.parameterTypeRegistry
.parameterTypes) {
if (support_code_library_builder_1.builtinParameterTypes.includes(parameterType.name)) {
if (parameterType.builtin) {
continue;
}
const source = supportCodeLibrary.parameterTypeRegistry.lookupSource(parameterType);
const envelope = {

@@ -133,2 +144,3 @@ parameterType: {

useForSnippets: parameterType.useForSnippets,
sourceReference: makeSourceReference(source),
},

@@ -158,8 +170,3 @@ };

},
sourceReference: {
uri: stepDefinition.uri,
location: {
line: stepDefinition.line,
},
},
sourceReference: makeSourceReference(stepDefinition),
},

@@ -180,8 +187,3 @@ };

tagExpression: testCaseHookDefinition.tagExpression,
sourceReference: {
uri: testCaseHookDefinition.uri,
location: {
line: testCaseHookDefinition.line,
},
},
sourceReference: makeSourceReference(testCaseHookDefinition),
},

@@ -200,8 +202,3 @@ };

id: testRunHookDefinition.id,
sourceReference: {
uri: testRunHookDefinition.uri,
location: {
line: testRunHookDefinition.line,
},
},
sourceReference: makeSourceReference(testRunHookDefinition),
},

@@ -208,0 +205,0 @@ };

/// <reference types="node" />
import { IFormatterStream } from '../formatter';
export interface ICliRunResult {
shouldAdvertisePublish: boolean;
shouldExitImmediately: boolean;

@@ -6,0 +5,0 @@ success: boolean;

@@ -6,2 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const debug_1 = __importDefault(require("debug"));
const configuration_1 = require("../configuration");

@@ -11,4 +12,8 @@ const api_1 = require("../api");

const install_validator_1 = require("./install_validator");
const debug_1 = __importDefault(require("debug"));
class Cli {
argv;
cwd;
stdout;
stderr;
env;
constructor({ argv, cwd, stdout, stderr = process.stderr, env, }) {

@@ -22,3 +27,6 @@ this.argv = argv;

async run() {
await (0, install_validator_1.validateInstall)();
const debugEnabled = debug_1.default.enabled('cucumber');
if (debugEnabled) {
await (0, install_validator_1.validateInstall)();
}
const { options, configuration: argvConfiguration } = configuration_1.ArgvParser.parse(this.argv);

@@ -28,3 +36,2 @@ if (options.i18nLanguages) {

return {
shouldAdvertisePublish: false,
shouldExitImmediately: true,

@@ -37,3 +44,2 @@ success: true,

return {
shouldAdvertisePublish: false,
shouldExitImmediately: true,

@@ -48,3 +54,3 @@ success: true,

env: this.env,
debug: debug_1.default.enabled('cucumber'),
debug: debugEnabled,
};

@@ -58,5 +64,2 @@ const { useConfiguration: configuration, runConfiguration } = await (0, api_1.loadConfiguration)({

return {
shouldAdvertisePublish: !runConfiguration.formats.publish &&
!configuration.publishQuiet &&
!(0, configuration_1.isTruthyString)(this.env.CUCUMBER_PUBLISH_QUIET),
shouldExitImmediately: configuration.forceExit,

@@ -63,0 +66,0 @@ success,

@@ -13,3 +13,3 @@ "use strict";

It looks like you're running Cucumber from a global installation.
This won't work - you need to have Cucumber installed as a local dependency in your project.
If so, you'll likely see issues - you need to have Cucumber installed as a local dependency in your project.
See https://github.com/cucumber/cucumber-js/blob/main/docs/installation.md#invalid-installations

@@ -16,0 +16,0 @@ `);

@@ -9,6 +9,4 @@ "use strict";

* but other code abstracts those to remain composable and testable. */
const validate_node_engine_version_1 = require("./validate_node_engine_version");
const _1 = __importDefault(require("./"));
const verror_1 = __importDefault(require("verror"));
const publish_banner_1 = __importDefault(require("./publish_banner"));
const validate_node_engine_version_1 = require("./validate_node_engine_version");
function logErrorMessageAndExit(message) {

@@ -18,5 +16,2 @@ console.error(message);

}
function displayPublishAdvertisementBanner() {
console.error(publish_banner_1.default);
}
async function run() {

@@ -39,7 +34,4 @@ (0, validate_node_engine_version_1.validateNodeEngineVersion)(process.version, (error) => {

catch (error) {
logErrorMessageAndExit(verror_1.default.fullStack(error));
logErrorMessageAndExit(error);
}
if (result.shouldAdvertisePublish) {
displayPublishAdvertisementBanner();
}
const exitCode = result.success ? 0 : 1;

@@ -46,0 +38,0 @@ if (result.shouldExitImmediately) {

@@ -1,2 +0,2 @@

declare type PackageJSON = {
type PackageJSON = {
engines: {

@@ -3,0 +3,0 @@ node: string;

@@ -7,7 +7,7 @@ "use strict";

exports.validateNodeEngineVersion = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const semver_1 = __importDefault(require("semver"));
const readActualPackageJSON = () => JSON.parse(fs_1.default
.readFileSync(path_1.default.resolve(__dirname, '..', '..', 'package.json'))
const readActualPackageJSON = () => JSON.parse(node_fs_1.default
.readFileSync(node_path_1.default.resolve(__dirname, '..', '..', 'package.json'))
.toString());

@@ -14,0 +14,0 @@ function validateNodeEngineVersion(currentVersion, onError, onWarning, readPackageJSON = readActualPackageJSON) {

@@ -34,3 +34,7 @@ "use strict";

failFast: yup.boolean(),
format: yup.array().of(yup.string()),
format: yup
.array()
.of(yup.lazy((val) => Array.isArray(val)
? yup.array().of(yup.string()).min(1).max(2)
: yup.string())),
formatOptions: yup.object(),

@@ -40,3 +44,3 @@ import: yup.array().of(yup.string()),

name: yup.array().of(yup.string()),
order: yup.string().oneOf(['defined', 'random']),
order: yup.string().matches(/^random:.*|random|defined$/),
paths: yup.array().of(yup.string()),

@@ -43,0 +47,0 @@ parallel: yup.number().integer().min(0),

@@ -0,3 +1,3 @@

import { ILogger } from '../logger';
import { IConfiguration } from './types';
import { ILogger } from '../logger';
export declare function fromFile(logger: ILogger, cwd: string, file: string, profiles?: string[]): Promise<Partial<IConfiguration>>;

@@ -7,12 +7,14 @@ "use strict";

exports.fromFile = void 0;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const node_util_1 = require("node:util");
const node_url_1 = require("node:url");
const string_argv_1 = __importDefault(require("string-argv"));
const path_1 = __importDefault(require("path"));
const url_1 = require("url");
const yaml_1 = __importDefault(require("yaml"));
const read_pkg_up_1 = __importDefault(require("read-pkg-up"));
const merge_configurations_1 = require("./merge_configurations");
const argv_parser_1 = __importDefault(require("./argv_parser"));
const check_schema_1 = require("./check_schema");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { importer } = require('../importer');
async function fromFile(logger, cwd, file, profiles = []) {
const definitions = await loadFile(cwd, file);
const definitions = await loadFile(logger, cwd, file);
if (!definitions.default) {

@@ -35,17 +37,45 @@ logger.debug('No default profile defined in configuration file');

exports.fromFile = fromFile;
async function loadFile(cwd, file) {
const filePath = path_1.default.join(cwd, file);
async function loadFile(logger, cwd, file) {
const filePath = node_path_1.default.join(cwd, file);
const extension = node_path_1.default.extname(filePath);
let definitions;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
definitions = require(filePath);
switch (extension) {
case '.json':
definitions = JSON.parse(await (0, node_util_1.promisify)(node_fs_1.default.readFile)(filePath, { encoding: 'utf-8' }));
break;
case '.yaml':
case '.yml':
definitions = yaml_1.default.parse(await (0, node_util_1.promisify)(node_fs_1.default.readFile)(filePath, { encoding: 'utf-8' }));
break;
case '.cjs':
logger.debug(`Loading configuration file "${file}" as CommonJS based on extension`);
// eslint-disable-next-line @typescript-eslint/no-var-requires
definitions = require(filePath);
break;
case '.mjs':
logger.debug(`Loading configuration file "${file}" as ESM based on extension`);
definitions = await import((0, node_url_1.pathToFileURL)(filePath).toString());
break;
case '.js':
{
const parentPackage = await readPackageJson(filePath);
if (!parentPackage) {
logger.debug(`Loading configuration file "${file}" as CommonJS based on absence of a parent package`);
// eslint-disable-next-line @typescript-eslint/no-var-requires
definitions = require(filePath);
}
else if (parentPackage.type === 'module') {
logger.debug(`Loading configuration file "${file}" as ESM based on "${parentPackage.name}" package type`);
definitions = await import((0, node_url_1.pathToFileURL)(filePath).toString());
}
else {
logger.debug(`Loading configuration file "${file}" as CommonJS based on "${parentPackage.name}" package type`);
// eslint-disable-next-line @typescript-eslint/no-var-requires
definitions = require(filePath);
}
}
break;
default:
throw new Error(`Unsupported configuration file extension "${extension}"`);
}
catch (error) {
if (error.code === 'ERR_REQUIRE_ESM') {
definitions = await importer((0, url_1.pathToFileURL)(filePath));
}
else {
throw error;
}
}
if (typeof definitions !== 'object') {

@@ -56,2 +86,6 @@ throw new Error(`Configuration file ${filePath} does not export an object`);

}
async function readPackageJson(filePath) {
const parentPackage = await (0, read_pkg_up_1.default)({ cwd: node_path_1.default.dirname(filePath) });
return parentPackage?.packageJson;
}
function extractConfiguration(logger, name, definition) {

@@ -58,0 +92,0 @@ if (typeof definition === 'string') {

@@ -6,3 +6,3 @@ export { default as ArgvParser } from './argv_parser';

export * from './merge_configurations';
export * from './option_splitter';
export * from './split_format_descriptor';
export * from './types';

@@ -27,4 +27,4 @@ "use strict";

__exportStar(require("./merge_configurations"), exports);
__exportStar(require("./option_splitter"), exports);
__exportStar(require("./split_format_descriptor"), exports);
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map

@@ -7,4 +7,4 @@ "use strict";

exports.locateFile = void 0;
const node_path_1 = __importDefault(require("node:path"));
const fs_1 = __importDefault(require("mz/fs"));
const path_1 = __importDefault(require("path"));
const DEFAULT_FILENAMES = [

@@ -15,7 +15,9 @@ 'cucumber.js',

'cucumber.json',
'cucumber.yaml',
'cucumber.yml',
];
function locateFile(cwd) {
return DEFAULT_FILENAMES.find((filename) => fs_1.default.existsSync(path_1.default.join(cwd, filename)));
return DEFAULT_FILENAMES.find((filename) => fs_1.default.existsSync(node_path_1.default.join(cwd, filename)));
}
exports.locateFile = locateFile;
//# sourceMappingURL=locate_file.js.map

@@ -1,25 +0,147 @@

import { FormatOptions } from '../formatter';
import { PickleOrder } from '../models/pickle_order';
import { JsonObject } from 'type-fest';
import { IPickleOrder } from '../filter';
/**
* User-defined configuration
*
* @public
*/
export interface IConfiguration {
/**
* Paths to where your feature files are
* @default []
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#finding-your-features}
*/
paths: string[];
/**
* Show the full backtrace for errors
* @default false
*/
backtrace: boolean;
/**
* Perform a dry run, where a test run is prepared but nothing is executed
* @default false
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/dry_run.md}
*/
dryRun: boolean;
/**
* Explicitly call `process.exit()` after the test run
* @default false
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#exiting}
* @remarks
* This option is only used by the CLI.
*/
forceExit: boolean;
/**
* Stop running tests when a test fails
* @default false
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/fail_fast.md}
*/
failFast: boolean;
format: string[];
formatOptions: FormatOptions;
/**
* Name/path and (optionally) output file path of each formatter to use
*
* @example
* [
* "\@cucumber/pretty-formatter",
* ["html", "./reports/cucumber.html"],
* ["./custom-formatter.js", "./reports/custom.txt"]
* ]
* @default []
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/formatters.md}
* @remarks
* Each item has one or two values. The first (required) identifies the
* formatter to be used. The second (optional) specifies where the output
* should be written.
*/
format: Array<string | [string, string?]>;
/**
* Options to be provided to formatters
* @default \{\}
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/formatters.md#options}
* @remarks
* The value must be a JSON-serializable object.
*/
formatOptions: JsonObject;
/**
* Paths to where your support code is
* @default []
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#finding-your-code}
*/
import: string[];
/**
* Default language for your feature files
* @default "en"
*/
language: string;
/**
* Regular expressions of which scenario names should match one of to be run
* @default []
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/filtering.md#names}
*/
name: string[];
order: PickleOrder;
paths: string[];
/**
* Run in the order defined, or in a random order
* @default "defined"
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/filtering.md#order}
*/
order: IPickleOrder;
/**
* Run tests in parallel with the given number of worker processes
* @default 0
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/parallel.md}
*/
parallel: number;
/**
* Publish a report of your test run to https://reports.cucumber.io/
* @default false
*/
publish: boolean;
/**
* @deprecated no longer needed
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md}
*/
publishQuiet: boolean;
/**
* Paths to where your support code is, for CommonJS
* @default []
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#finding-your-code}
*/
require: string[];
/**
* Names of transpilation modules to load, via `require()`
* @default []
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/transpiling.md}
*/
requireModule: string[];
/**
* Retry failing tests up to the given number of times
* @default 0
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/retry.md}
*/
retry: number;
/**
* Tag expression to filter which scenarios can be retried
* @default ""
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/retry.md}
*/
retryTagFilter: string;
/**
* Fail the test run if there are pending steps
* @default true
*/
strict: boolean;
/**
* Tag expression to filter which scenarios should be run
* @default ""
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/filtering.md#tags}
*/
tags: string;
worldParameters: any;
/**
* Parameters to be passed to your World
* @default \{\}
* @see {@link https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/world.md}
* @remarks
* The value must be a JSON-serializable object.
*/
worldParameters: JsonObject;
}

@@ -0,2 +1,3 @@

import { ILogger } from '../logger';
import { IConfiguration } from './types';
export declare function validateConfiguration(configuration: IConfiguration): void;
export declare function validateConfiguration(configuration: IConfiguration, logger: ILogger): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateConfiguration = void 0;
function validateConfiguration(configuration) {
function validateConfiguration(configuration, logger) {
if (configuration.publishQuiet) {
logger.warn('`publishQuiet` option is no longer needed, you can remove it from your configuration; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
}
if (configuration.requireModule.length && !configuration.require.length) {
logger.warn('Use of `require-module` option normally means you should specify your support code paths with `require`; see https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#finding-your-code');
}
if (configuration.retryTagFilter && !configuration.retry) {

@@ -6,0 +12,0 @@ throw new Error('a positive `retry` count must be specified when setting `retryTagFilter`');

@@ -5,9 +5,9 @@ /// <reference types="node" />

/// <reference types="node" />
import { EventEmitter } from 'node:events';
import { Writable as WritableStream } from 'node:stream';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
import { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax';
import EventDataCollector from './helpers/event_data_collector';
import StepDefinitionSnippetBuilder from './step_definition_snippet_builder';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import Formatter, { FormatOptions, IFormatterCleanupFn, IFormatterLogFn } from '.';
import { EventEmitter } from 'events';
import EventDataCollector from './helpers/event_data_collector';
import { Writable as WritableStream } from 'stream';
import { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax';
interface IGetStepDefinitionSnippetBuilderOptions {

@@ -17,3 +17,3 @@ cwd: string;

snippetSyntax?: string;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}

@@ -29,3 +29,3 @@ export interface IBuildOptions {

cleanup: IFormatterCleanupFn;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}

@@ -32,0 +32,0 @@ declare const FormatterBuilder: {

@@ -6,12 +6,10 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const get_color_fns_1 = __importDefault(require("./get_color_fns"));
const javascript_snippet_syntax_1 = __importDefault(require("./step_definition_snippet_builder/javascript_snippet_syntax"));
const path_1 = __importDefault(require("path"));
const step_definition_snippet_builder_1 = __importDefault(require("./step_definition_snippet_builder"));
const node_path_1 = __importDefault(require("node:path"));
const node_url_1 = require("node:url");
const value_checker_1 = require("../value_checker");
const snippet_syntax_1 = require("./step_definition_snippet_builder/snippet_syntax");
const url_1 = require("url");
const step_definition_snippet_builder_1 = __importDefault(require("./step_definition_snippet_builder"));
const javascript_snippet_syntax_1 = __importDefault(require("./step_definition_snippet_builder/javascript_snippet_syntax"));
const get_color_fns_1 = __importDefault(require("./get_color_fns"));
const formatters_1 = __importDefault(require("./helpers/formatters"));
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { importer } = require('../importer');
const FormatterBuilder = {

@@ -53,10 +51,10 @@ async build(type, options) {

async loadCustomClass(type, descriptor, cwd) {
let normalised = descriptor;
let normalized = descriptor;
if (descriptor.startsWith('.')) {
normalised = (0, url_1.pathToFileURL)(path_1.default.resolve(cwd, descriptor));
normalized = (0, node_url_1.pathToFileURL)(node_path_1.default.resolve(cwd, descriptor));
}
else if (descriptor.startsWith('file://')) {
normalised = new URL(descriptor);
normalized = new URL(descriptor);
}
let CustomClass = await FormatterBuilder.loadFile(normalised);
let CustomClass = await FormatterBuilder.loadFile(normalized);
CustomClass = FormatterBuilder.resolveConstructor(CustomClass);

@@ -71,18 +69,3 @@ if ((0, value_checker_1.doesHaveValue)(CustomClass)) {

async loadFile(urlOrName) {
let result;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
result = require(typeof urlOrName === 'string'
? urlOrName
: (0, url_1.fileURLToPath)(urlOrName));
}
catch (error) {
if (error.code === 'ERR_REQUIRE_ESM') {
result = await importer(urlOrName);
}
else {
throw error;
}
}
return result;
return await import(urlOrName.toString());
},

@@ -100,2 +83,6 @@ resolveConstructor(ImportedCode) {

}
else if (typeof ImportedCode.default === 'object' &&
typeof ImportedCode.default.default === 'function') {
return ImportedCode.default.default;
}
return null;

@@ -102,0 +89,0 @@ },

/// <reference types="node" />
/// <reference types="node" />
import { Writable } from 'node:stream';
import { TestStepResultStatus } from '@cucumber/messages';
import { Writable } from 'stream';
export declare type IColorFn = (text: string) => string;
export type IColorFn = (text: string) => string;
export interface IColorFns {

@@ -7,0 +7,0 @@ forStatus: (status: TestStepResultStatus) => IColorFn;

/// <reference types="node" />
import { EventEmitter } from 'node:events';
import * as messages from '@cucumber/messages';
import { EventEmitter } from 'events';
export interface ITestCaseAttempt {

@@ -5,0 +5,0 @@ attempt: number;

@@ -29,8 +29,8 @@ "use strict";

class EventDataCollector {
gherkinDocumentMap = {};
pickleMap = {};
testCaseMap = {};
testCaseAttemptDataMap = {};
undefinedParameterTypes = [];
constructor(eventBroadcaster) {
this.gherkinDocumentMap = {};
this.pickleMap = {};
this.testCaseMap = {};
this.testCaseAttemptDataMap = {};
this.undefinedParameterTypes = [];
eventBroadcaster.on('envelope', this.parseEnvelope.bind(this));

@@ -37,0 +37,0 @@ }

@@ -16,2 +16,3 @@ "use strict";

const html_formatter_1 = __importDefault(require("../html_formatter"));
const junit_formatter_1 = __importDefault(require("../junit_formatter"));
const Formatters = {

@@ -30,2 +31,3 @@ getFormatters() {

'usage-json': usage_json_formatter_1.default,
junit: junit_formatter_1.default,
};

@@ -32,0 +34,0 @@ },

import * as messages from '@cucumber/messages';
import { IColorFns } from '../get_color_fns';
import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder';
import { ISupportCodeLibrary } from '../../support_code_library_builder/types';
import { SupportCodeLibrary } from '../../support_code_library_builder/types';
import { ITestCaseAttempt } from './event_data_collector';

@@ -14,3 +14,3 @@ export declare function isFailure(result: messages.TestStepResult, willBeRetried?: boolean): boolean;

testCaseAttempt: ITestCaseAttempt;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
printAttachments?: boolean;

@@ -17,0 +17,0 @@ }

@@ -7,3 +7,3 @@ "use strict";

exports.formatLocation = void 0;
const path_1 = __importDefault(require("path"));
const node_path_1 = __importDefault(require("node:path"));
const value_checker_1 = require("../../value_checker");

@@ -13,3 +13,3 @@ function formatLocation(obj, cwd) {

if ((0, value_checker_1.doesHaveValue)(cwd)) {
uri = path_1.default.relative(cwd, uri);
uri = node_path_1.default.relative(cwd, uri);
}

@@ -16,0 +16,0 @@ return `${uri}:${obj.line.toString()}`;

@@ -0,4 +1,4 @@

import * as messages from '@cucumber/messages';
import { IColorFns } from '../get_color_fns';
import { ITestCaseAttempt } from './event_data_collector';
import * as messages from '@cucumber/messages';
export interface IFormatSummaryRequest {

@@ -5,0 +5,0 @@ colorFns: IColorFns;

@@ -25,9 +25,6 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatSummary = void 0;
const duration_1 = __importDefault(require("duration"));
const messages = __importStar(require("@cucumber/messages"));
const luxon_1 = require("luxon");
const value_checker_1 = require("../../value_checker");

@@ -93,6 +90,9 @@ const STATUS_REPORT_ORDER = [

const end = new Date(messages.TimeConversion.durationToMilliseconds(durationMsg));
const duration = new duration_1.default(start, end);
// Use spaces in toString method for readability and to avoid %Ls which is a format
return duration.toString('%Ms m %S . %L s').replace(/ /g, '');
const duration = luxon_1.Interval.fromDateTimes(start, end).toDuration([
'minutes',
'seconds',
'milliseconds',
]);
return duration.toFormat("m'm'ss.SSS's'");
}
//# sourceMappingURL=summary_helpers.js.map
import { IColorFns } from '../get_color_fns';
import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder';
import { SupportCodeLibrary } from '../../support_code_library_builder/types';
import { ITestCaseAttempt } from './event_data_collector';
import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder';
import { ISupportCodeLibrary } from '../../support_code_library_builder/types';
export interface IFormatTestCaseAttemptRequest {

@@ -9,5 +9,5 @@ colorFns: IColorFns;

snippetBuilder: StepDefinitionSnippetBuilder;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
printAttachments?: boolean;
}
export declare function formatTestCaseAttempt({ colorFns, snippetBuilder, supportCodeLibrary, testCaseAttempt, printAttachments, }: IFormatTestCaseAttemptRequest): string;

@@ -33,6 +33,6 @@ "use strict";

const figures_1 = __importDefault(require("figures"));
const value_checker_1 = require("../../value_checker");
const location_helpers_1 = require("./location_helpers");
const test_case_attempt_parser_1 = require("./test_case_attempt_parser");
const step_argument_formatter_1 = require("./step_argument_formatter");
const value_checker_1 = require("../../value_checker");
const CHARACTERS = new Map([

@@ -75,4 +75,10 @@ [messages.TestStepResultStatus.AMBIGUOUS, figures_1.default.cross],

if ((0, value_checker_1.valueOrDefault)(printAttachments, true)) {
attachments.forEach(({ body, mediaType }) => {
const message = mediaType === 'text/plain' ? `: ${body}` : '';
attachments.forEach(({ body, mediaType, fileName }) => {
let message = '';
if (mediaType === 'text/plain') {
message = `: ${body}`;
}
else if (fileName) {
message = `: ${fileName}`;
}
text += (0, indent_string_1.default)(`Attachment (${mediaType})${message}\n`, 4);

@@ -79,0 +85,0 @@ });

import * as messages from '@cucumber/messages';
import { ITestCaseAttempt } from './event_data_collector';
import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder';
import { ISupportCodeLibrary } from '../../support_code_library_builder/types';
import { SupportCodeLibrary } from '../../support_code_library_builder/types';
import { ILineAndUri } from '../../types';
import { ITestCaseAttempt } from './event_data_collector';
export interface IParsedTestStep {

@@ -30,4 +30,4 @@ actionLocation?: ILineAndUri;

snippetBuilder: StepDefinitionSnippetBuilder;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}
export declare function parseTestCaseAttempt({ testCaseAttempt, snippetBuilder, supportCodeLibrary, }: IParseTestCaseAttemptRequest): IParsedTestCaseAttempt;

@@ -27,8 +27,8 @@ "use strict";

exports.parseTestCaseAttempt = void 0;
const messages = __importStar(require("@cucumber/messages"));
const messages_1 = require("@cucumber/messages");
const value_checker_1 = require("../../value_checker");
const keyword_type_1 = require("./keyword_type");
const gherkin_document_parser_1 = require("./gherkin_document_parser");
const pickle_parser_1 = require("./pickle_parser");
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../../value_checker");
const messages_1 = require("@cucumber/messages");
function parseStep({ isBeforeHook, gherkinStepMap, keyword, keywordType, pickleStep, pickleUri, snippetBuilder, supportCodeLibrary, testStep, testStepResult, testStepAttachments, }) {

@@ -35,0 +35,0 @@ const out = {

@@ -27,5 +27,5 @@ "use strict";

exports.getUsage = void 0;
const messages = __importStar(require("@cucumber/messages"));
const pickle_parser_1 = require("../pickle_parser");
const gherkin_document_parser_1 = require("../gherkin_document_parser");
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../../../value_checker");

@@ -32,0 +32,0 @@ function buildEmptyMapping(stepDefinitions) {

import Formatter, { IFormatterOptions } from '.';
export default class HtmlFormatter extends Formatter {
private readonly _finished;
private readonly _htmlStream;
static readonly documentation: string;

@@ -5,0 +5,0 @@ constructor(options: IFormatterOptions);

@@ -6,25 +6,23 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const _1 = __importDefault(require("."));
const node_stream_1 = require("node:stream");
const node_util_1 = require("node:util");
const resolve_pkg_1 = __importDefault(require("resolve-pkg"));
const html_formatter_1 = __importDefault(require("@cucumber/html-formatter"));
const value_checker_1 = require("../value_checker");
const stream_1 = require("stream");
const util_1 = require("util");
const _1 = __importDefault(require("."));
class HtmlFormatter extends _1.default {
_htmlStream;
static documentation = 'Outputs HTML report';
constructor(options) {
super(options);
const cucumberHtmlStream = new html_formatter_1.default((0, resolve_pkg_1.default)('@cucumber/html-formatter', { cwd: __dirname }) +
this._htmlStream = new html_formatter_1.default((0, resolve_pkg_1.default)('@cucumber/html-formatter', { cwd: __dirname }) +
'/dist/main.css', (0, resolve_pkg_1.default)('@cucumber/html-formatter', { cwd: __dirname }) +
'/dist/main.js');
options.eventBroadcaster.on('envelope', (envelope) => {
cucumberHtmlStream.write(envelope);
if ((0, value_checker_1.doesHaveValue)(envelope.testRunFinished)) {
cucumberHtmlStream.end();
}
this._htmlStream.write(envelope);
});
cucumberHtmlStream.on('data', (chunk) => this.log(chunk));
this._finished = (0, util_1.promisify)(stream_1.finished)(cucumberHtmlStream);
this._htmlStream.on('data', (chunk) => this.log(chunk));
}
async finished() {
await this._finished;
this._htmlStream.end();
await (0, node_util_1.promisify)(node_stream_1.finished)(this._htmlStream);
await super.finished();

@@ -34,3 +32,2 @@ }

exports.default = HtmlFormatter;
HtmlFormatter.documentation = 'Outputs HTML report';
//# sourceMappingURL=html_formatter.js.map
/// <reference types="node" />
/// <reference types="node" />
import { Writable } from 'node:stream';
import { EventEmitter } from 'node:events';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
import { IColorFns } from './get_color_fns';
import { EventDataCollector } from './helpers';
import StepDefinitionSnippetBuilder from './step_definition_snippet_builder';
import { Writable } from 'stream';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { EventEmitter } from 'events';
import { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax';

@@ -21,9 +21,5 @@ export interface FormatRerunOptions {

}
export interface IPublishConfig {
url: string;
token: string;
}
export declare type IFormatterStream = Writable;
export declare type IFormatterLogFn = (buffer: string | Uint8Array) => void;
export declare type IFormatterCleanupFn = () => Promise<any>;
export type IFormatterStream = Writable;
export type IFormatterLogFn = (buffer: string | Uint8Array) => void;
export type IFormatterCleanupFn = () => Promise<any>;
export interface IFormatterOptions {

@@ -39,3 +35,3 @@ colorFns: IColorFns;

cleanup: IFormatterCleanupFn;
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}

@@ -49,3 +45,3 @@ export default class Formatter {

protected stream: Writable;
protected supportCodeLibrary: ISupportCodeLibrary;
protected supportCodeLibrary: SupportCodeLibrary;
protected printAttachments: boolean;

@@ -52,0 +48,0 @@ private readonly cleanup;

@@ -5,2 +5,12 @@ "use strict";

class Formatter {
colorFns;
cwd;
eventDataCollector;
log;
snippetBuilder;
stream;
supportCodeLibrary;
printAttachments;
cleanup;
static documentation;
constructor(options) {

@@ -7,0 +17,0 @@ this.colorFns = options.colorFns;

@@ -0,3 +1,3 @@

import * as messages from '@cucumber/messages';
import Formatter, { IFormatterOptions } from './';
import * as messages from '@cucumber/messages';
export interface IJsonFeature {

@@ -4,0 +4,0 @@ description: string;

@@ -29,12 +29,13 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const _1 = __importDefault(require("./"));
const helpers_1 = require("./helpers");
const messages = __importStar(require("@cucumber/messages"));
const gherkin_document_parser_1 = require("./helpers/gherkin_document_parser");
const value_checker_1 = require("../value_checker");
const step_arguments_1 = require("../step_arguments");
const helpers_1 = require("./helpers");
const gherkin_document_parser_1 = require("./helpers/gherkin_document_parser");
const duration_helpers_1 = require("./helpers/duration_helpers");
const _1 = __importDefault(require("./"));
const { getGherkinStepMap, getGherkinScenarioMap } = helpers_1.GherkinDocumentParser;
const { getScenarioDescription, getPickleStepMap, getStepKeyword } = helpers_1.PickleParser;
class JsonFormatter extends _1.default {
static documentation = 'Prints the feature as JSON. The JSON format is in maintenance mode. Please consider using the message formatter with the standalone json-formatter (https://github.com/cucumber/json-formatter).';
constructor(options) {

@@ -148,3 +149,3 @@ super(options);

keyword: gherkinScenarioMap[pickle.astNodeIds[0]].keyword,
line: gherkinScenarioLocationMap[pickle.astNodeIds[0]].line,
line: gherkinScenarioLocationMap[pickle.astNodeIds[pickle.astNodeIds.length - 1]].line,
name: pickle.name,

@@ -196,5 +197,8 @@ steps,

}
if ((testStepAttachments === null || testStepAttachments === void 0 ? void 0 : testStepAttachments.length) > 0) {
if (testStepAttachments?.length > 0) {
data.embeddings = testStepAttachments.map((attachment) => ({
data: attachment.body,
data: attachment.contentEncoding ===
messages.AttachmentContentEncoding.IDENTITY
? Buffer.from(attachment.body).toString('base64')
: attachment.body,
mime_type: attachment.mediaType,

@@ -216,3 +220,2 @@ }));

getScenarioTag(tagData, feature, scenario) {
var _a;
const byAstNodeId = (tag) => tag.id === tagData.astNodeId;

@@ -228,3 +231,3 @@ const flatten = (acc, val) => acc.concat(val);

name: tagData.name,
line: (_a = tag === null || tag === void 0 ? void 0 : tag.location) === null || _a === void 0 ? void 0 : _a.line,
line: tag?.location?.line,
};

@@ -234,3 +237,2 @@ }

exports.default = JsonFormatter;
JsonFormatter.documentation = 'Prints the feature as JSON. The JSON format is in maintenance mode. Please consider using the message formatter with the standalone json-formatter (https://github.com/cucumber/cucumber/tree/master/json-formatter).';
//# sourceMappingURL=json_formatter.js.map

@@ -8,2 +8,3 @@ "use strict";

class MessageFormatter extends _1.default {
static documentation = 'Outputs protobuf messages';
constructor(options) {

@@ -15,3 +16,2 @@ super(options);

exports.default = MessageFormatter;
MessageFormatter.documentation = 'Outputs protobuf messages';
//# sourceMappingURL=message_formatter.js.map

@@ -1,4 +0,4 @@

import Formatter, { IFormatterOptions } from './';
import ProgressBar from 'progress';
import * as messages from '@cucumber/messages';
import Formatter, { IFormatterOptions } from './';
export default class ProgressBarFormatter extends Formatter {

@@ -5,0 +5,0 @@ private numberOfSteps;

@@ -6,10 +6,15 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const helpers_1 = require("./helpers");
const _1 = __importDefault(require("./"));
const progress_1 = __importDefault(require("progress"));
const value_checker_1 = require("../value_checker");
const time_1 = require("../time");
const issue_helpers_1 = require("./helpers/issue_helpers");
const time_1 = require("../time");
const helpers_1 = require("./helpers");
const _1 = __importDefault(require("./"));
// Inspired by https://github.com/thekompanee/fuubar and https://github.com/martinciu/fuubar-cucumber
class ProgressBarFormatter extends _1.default {
numberOfSteps;
testRunStarted;
issueCount;
progressBar;
static documentation = 'Similar to the Progress Formatter, but provides a real-time updating progress bar based on the total number of steps to be executed in the test run';
constructor(options) {

@@ -99,3 +104,2 @@ super(options);

exports.default = ProgressBarFormatter;
ProgressBarFormatter.documentation = 'Similar to the Progress Formatter, but provides a real-time updating progress bar based on the total number of steps to be executed in the test run';
//# sourceMappingURL=progress_bar_formatter.js.map

@@ -0,4 +1,4 @@

import * as messages from '@cucumber/messages';
import SummaryFormatter from './summary_formatter';
import { IFormatterOptions } from './index';
import * as messages from '@cucumber/messages';
import ITestStepFinished = messages.TestStepFinished;

@@ -5,0 +5,0 @@ export default class ProgressFormatter extends SummaryFormatter {

@@ -29,5 +29,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../value_checker");
const summary_formatter_1 = __importDefault(require("./summary_formatter"));
const value_checker_1 = require("../value_checker");
const messages = __importStar(require("@cucumber/messages"));
const STATUS_CHARACTER_MAPPING = new Map([

@@ -42,2 +42,3 @@ [messages.TestStepResultStatus.AMBIGUOUS, 'A'],

class ProgressFormatter extends summary_formatter_1.default {
static documentation = 'Prints one character per scenario.';
constructor(options) {

@@ -60,3 +61,2 @@ options.eventBroadcaster.on('envelope', (envelope) => {

exports.default = ProgressFormatter;
ProgressFormatter.documentation = 'Prints one character per scenario.';
//# sourceMappingURL=progress_formatter.js.map
import Formatter, { IFormatterOptions } from './';
interface UriToLinesMap {
[uri: string]: number[];
}
export default class RerunFormatter extends Formatter {
private readonly separator;
protected readonly separator: string;
static readonly documentation: string;
constructor(options: IFormatterOptions);
getFailureMap(): UriToLinesMap;
formatFailedTestCases(): string;
logFailedTestCases(): void;
}
export {};

@@ -29,8 +29,13 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../value_checker");
const gherkin_document_parser_1 = require("./helpers/gherkin_document_parser");
const _1 = __importDefault(require("./"));
const gherkin_document_parser_1 = require("./helpers/gherkin_document_parser");
const value_checker_1 = require("../value_checker");
const messages = __importStar(require("@cucumber/messages"));
const DEFAULT_SEPARATOR = '\n';
function isFailedAttempt(worstTestStepResult) {
return worstTestStepResult.status !== messages.TestStepResultStatus.PASSED;
}
class RerunFormatter extends _1.default {
separator;
static documentation = 'Prints failing files with line numbers.';
constructor(options) {

@@ -46,8 +51,8 @@ super(options);

}
logFailedTestCases() {
getFailureMap() {
const mapping = {};
this.eventDataCollector
.getTestCaseAttempts()
.forEach(({ gherkinDocument, pickle, worstTestStepResult }) => {
if (worstTestStepResult.status !== messages.TestStepResultStatus.PASSED) {
.forEach(({ gherkinDocument, pickle, worstTestStepResult, willBeRetried }) => {
if (isFailedAttempt(worstTestStepResult) && !willBeRetried) {
const relativeUri = pickle.uri;

@@ -61,3 +66,7 @@ const line = (0, gherkin_document_parser_1.getGherkinScenarioLocationMap)(gherkinDocument)[pickle.astNodeIds[pickle.astNodeIds.length - 1]].line;

});
const text = Object.keys(mapping)
return mapping;
}
formatFailedTestCases() {
const mapping = this.getFailureMap();
return Object.keys(mapping)
.map((uri) => {

@@ -68,7 +77,9 @@ const lines = mapping[uri];

.join(this.separator);
this.log(text);
}
logFailedTestCases() {
const failedTestCases = this.formatFailedTestCases();
this.log(failedTestCases);
}
}
exports.default = RerunFormatter;
RerunFormatter.documentation = 'Prints failing files with line numbers.';
//# sourceMappingURL=rerun_formatter.js.map

@@ -29,7 +29,8 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../value_checker");
const helpers_1 = require("./helpers");
const _1 = __importDefault(require("./"));
const helpers_1 = require("./helpers");
const value_checker_1 = require("../value_checker");
const messages = __importStar(require("@cucumber/messages"));
class SnippetsFormatter extends _1.default {
static documentation = "The Snippets Formatter doesn't output anything regarding the test run; it just prints snippets to implement any undefined steps";
constructor(options) {

@@ -61,3 +62,2 @@ super(options);

exports.default = SnippetsFormatter;
SnippetsFormatter.documentation = "The Snippets Formatter doesn't output anything regarding the test run; it just prints snippets to implement any undefined steps";
//# sourceMappingURL=snippets_formatter.js.map

@@ -0,5 +1,5 @@

import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions';
import * as messages from '@cucumber/messages';
import { KeywordType } from '../helpers';
import { ISnippetSnytax } from './snippet_syntax';
import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions';
import * as messages from '@cucumber/messages';
export interface INewStepDefinitionSnippetBuilderOptions {

@@ -6,0 +6,0 @@ snippetSyntax: ISnippetSnytax;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const cucumber_expressions_1 = require("@cucumber/cucumber-expressions");
const helpers_1 = require("../helpers");
const step_arguments_1 = require("../../step_arguments");
const cucumber_expressions_1 = require("@cucumber/cucumber-expressions");
const value_checker_1 = require("../../value_checker");
class StepDefinitionSnippetBuilder {
snippetSyntax;
cucumberExpressionGenerator;
constructor({ snippetSyntax, parameterTypeRegistry, }) {

@@ -9,0 +11,0 @@ this.snippetSyntax = snippetSyntax;

@@ -6,2 +6,3 @@ "use strict";

class JavaScriptSnippetSyntax {
snippetInterface;
constructor(snippetInterface) {

@@ -15,5 +16,2 @@ this.snippetInterface = snippetInterface;

}
else if (this.snippetInterface === snippet_syntax_1.SnippetInterface.Generator) {
functionKeyword += '*';
}
let implementation;

@@ -20,0 +18,0 @@ if (this.snippetInterface === snippet_syntax_1.SnippetInterface.Callback) {

@@ -5,3 +5,2 @@ import { GeneratedExpression } from '@cucumber/cucumber-expressions';

Callback = "callback",
Generator = "generator",
Promise = "promise",

@@ -8,0 +7,0 @@ Synchronous = "synchronous"

@@ -8,3 +8,2 @@ "use strict";

SnippetInterface["Callback"] = "callback";
SnippetInterface["Generator"] = "generator";
SnippetInterface["Promise"] = "promise";

@@ -11,0 +10,0 @@ SnippetInterface["Synchronous"] = "synchronous";

@@ -1,4 +0,4 @@

import Formatter, { IFormatterOptions } from './';
import * as messages from '@cucumber/messages';
import { ITestCaseAttempt } from './helpers/event_data_collector';
import Formatter, { IFormatterOptions } from './';
interface ILogIssuesRequest {

@@ -5,0 +5,0 @@ issues: ITestCaseAttempt[];

@@ -6,8 +6,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const value_checker_1 = require("../value_checker");
const time_1 = require("../time");
const helpers_1 = require("./helpers");
const issue_helpers_1 = require("./helpers/issue_helpers");
const _1 = __importDefault(require("./"));
const value_checker_1 = require("../value_checker");
const issue_helpers_1 = require("./helpers/issue_helpers");
const time_1 = require("../time");
class SummaryFormatter extends _1.default {
static documentation = 'Summary output of feature and scenarios';
constructor(options) {

@@ -68,3 +69,2 @@ super(options);

exports.default = SummaryFormatter;
SummaryFormatter.documentation = 'Summary output of feature and scenarios';
//# sourceMappingURL=summary_formatter.js.map

@@ -29,8 +29,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const cli_table3_1 = __importDefault(require("cli-table3"));
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../value_checker");
const helpers_1 = require("./helpers");
const _1 = __importDefault(require("./"));
const cli_table3_1 = __importDefault(require("cli-table3"));
const value_checker_1 = require("../value_checker");
const messages = __importStar(require("@cucumber/messages"));
class UsageFormatter extends _1.default {
static documentation = 'Prints where step definitions are used. The slowest step definitions (with duration) are listed first. If --dry-run is used the duration is not shown, and step definitions are sorted by filename instead.';
constructor(options) {

@@ -98,3 +99,2 @@ super(options);

exports.default = UsageFormatter;
UsageFormatter.documentation = 'Prints where step definitions are used. The slowest step definitions (with duration) are listed first. If --dry-run is used the duration is not shown, and step definitions are sorted by filename instead.';
//# sourceMappingURL=usage_formatter.js.map

@@ -6,6 +6,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const value_checker_1 = require("../value_checker");
const helpers_1 = require("./helpers");
const _1 = __importDefault(require("./"));
const value_checker_1 = require("../value_checker");
class UsageJsonFormatter extends _1.default {
static documentation = 'Does what the Usage Formatter does, but outputs JSON, which can be output to a file and then consumed by other tools.';
constructor(options) {

@@ -34,3 +35,2 @@ super(options);

exports.default = UsageJsonFormatter;
UsageJsonFormatter.documentation = 'Does what the Usage Formatter does, but outputs JSON, which can be output to a file and then consumed by other tools.';
//# sourceMappingURL=usage_json_formatter.js.map

@@ -0,1 +1,10 @@

/**
* User code functions and helpers
*
* @packageDocumentation
* @module (root)
* @remarks
* These docs cover the functions and helpers for user code registration and test setup. The entry point is `@cucumber/cucumber`.
*/
import * as messages from '@cucumber/messages';
import { default as _Cli } from './cli';

@@ -7,7 +16,6 @@ import * as cliHelpers from './cli/helpers';

import { default as _Runtime } from './runtime';
import * as messages from '@cucumber/messages';
export declare const version: string;
export { default as supportCodeLibraryBuilder } from './support_code_library_builder';
export { default as DataTable } from './models/data_table';
export { default as TestCaseHookDefinition } from './models/test_case_hook_definition';
export { version } from './version';
export { default as Formatter, IFormatterOptions } from './formatter';

@@ -24,7 +32,8 @@ export { default as FormatterBuilder } from './formatter/builder';

export declare const After: (<WorldType = import("./support_code_library_builder/world").IWorld<any>>(code: import("./support_code_library_builder/types").TestCaseHookFunction<WorldType>) => void) & (<WorldType_1 = import("./support_code_library_builder/world").IWorld<any>>(tags: string, code: import("./support_code_library_builder/types").TestCaseHookFunction<WorldType_1>) => void) & (<WorldType_2 = import("./support_code_library_builder/world").IWorld<any>>(options: import("./support_code_library_builder/types").IDefineTestCaseHookOptions, code: import("./support_code_library_builder/types").TestCaseHookFunction<WorldType_2>) => void);
export declare const AfterAll: ((code: Function) => void) & ((options: import("./support_code_library_builder/types").IDefineTestRunHookOptions, code: Function) => void);
export declare const AfterAll: ((code: import("./support_code_library_builder/types").TestRunHookFunction) => void) & ((options: import("./support_code_library_builder/types").IDefineTestRunHookOptions, code: import("./support_code_library_builder/types").TestRunHookFunction) => void);
export declare const AfterStep: (<WorldType = import("./support_code_library_builder/world").IWorld<any>>(code: import("./support_code_library_builder/types").TestStepHookFunction<WorldType>) => void) & (<WorldType_1 = import("./support_code_library_builder/world").IWorld<any>>(tags: string, code: import("./support_code_library_builder/types").TestStepHookFunction<WorldType_1>) => void) & (<WorldType_2 = import("./support_code_library_builder/world").IWorld<any>>(options: import("./support_code_library_builder/types").IDefineTestStepHookOptions, code: import("./support_code_library_builder/types").TestStepHookFunction<WorldType_2>) => void);
export declare const Before: (<WorldType = import("./support_code_library_builder/world").IWorld<any>>(code: import("./support_code_library_builder/types").TestCaseHookFunction<WorldType>) => void) & (<WorldType_1 = import("./support_code_library_builder/world").IWorld<any>>(tags: string, code: import("./support_code_library_builder/types").TestCaseHookFunction<WorldType_1>) => void) & (<WorldType_2 = import("./support_code_library_builder/world").IWorld<any>>(options: import("./support_code_library_builder/types").IDefineTestCaseHookOptions, code: import("./support_code_library_builder/types").TestCaseHookFunction<WorldType_2>) => void);
export declare const BeforeAll: ((code: Function) => void) & ((options: import("./support_code_library_builder/types").IDefineTestRunHookOptions, code: Function) => void);
export declare const BeforeAll: ((code: import("./support_code_library_builder/types").TestRunHookFunction) => void) & ((options: import("./support_code_library_builder/types").IDefineTestRunHookOptions, code: import("./support_code_library_builder/types").TestRunHookFunction) => void);
export declare const BeforeStep: (<WorldType = import("./support_code_library_builder/world").IWorld<any>>(code: import("./support_code_library_builder/types").TestStepHookFunction<WorldType>) => void) & (<WorldType_1 = import("./support_code_library_builder/world").IWorld<any>>(tags: string, code: import("./support_code_library_builder/types").TestStepHookFunction<WorldType_1>) => void) & (<WorldType_2 = import("./support_code_library_builder/world").IWorld<any>>(options: import("./support_code_library_builder/types").IDefineTestStepHookOptions, code: import("./support_code_library_builder/types").TestStepHookFunction<WorldType_2>) => void);
export declare const defineStep: import("./support_code_library_builder/types").IDefineStep;
export declare const defineParameterType: (options: import("./support_code_library_builder/types").IParameterTypeDefinition<any>) => void;

@@ -44,21 +53,17 @@ export declare const Given: import("./support_code_library_builder/types").IDefineStep;

/**
* @deprecated use `runCucumber` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
export declare const Cli: typeof _Cli;
/**
* @deprecated use `Given`, `When` or `Then` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
export declare const defineStep: import("./support_code_library_builder/types").IDefineStep;
/**
* @deprecated use `loadSources` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
*/
export declare const parseGherkinMessageStream: typeof cliHelpers.parseGherkinMessageStream;
/**
* @deprecated use `loadSources` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
export declare const PickleFilter: typeof _PickleFilter;
/**
* @deprecated use `loadSources` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
export declare const Runtime: typeof _Runtime;
export { INewRuntimeOptions, IRuntimeOptions } from './runtime';
"use strict";
/**
* User code functions and helpers
*
* @packageDocumentation
* @module (root)
* @remarks
* These docs cover the functions and helpers for user code registration and test setup. The entry point is `@cucumber/cucumber`.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

@@ -29,3 +37,5 @@ if (k2 === undefined) k2 = k;

Object.defineProperty(exports, "__esModule", { value: true });
exports.Runtime = exports.PickleFilter = exports.parseGherkinMessageStream = exports.defineStep = exports.Cli = exports.wrapPromiseWithTimeout = exports.Status = exports.parallelCanAssignHelpers = exports.World = exports.When = exports.Then = exports.setParallelCanAssign = exports.setWorldConstructor = exports.setDefinitionFunctionWrapper = exports.setDefaultTimeout = exports.Given = exports.defineParameterType = exports.BeforeStep = exports.BeforeAll = exports.Before = exports.AfterStep = exports.AfterAll = exports.After = exports.formatterHelpers = exports.UsageJsonFormatter = exports.UsageFormatter = exports.SummaryFormatter = exports.SnippetsFormatter = exports.RerunFormatter = exports.ProgressFormatter = exports.JsonFormatter = exports.FormatterBuilder = exports.Formatter = exports.version = exports.TestCaseHookDefinition = exports.DataTable = exports.supportCodeLibraryBuilder = void 0;
exports.Runtime = exports.PickleFilter = exports.parseGherkinMessageStream = exports.Cli = exports.wrapPromiseWithTimeout = exports.Status = exports.parallelCanAssignHelpers = exports.World = exports.When = exports.Then = exports.setParallelCanAssign = exports.setWorldConstructor = exports.setDefinitionFunctionWrapper = exports.setDefaultTimeout = exports.Given = exports.defineParameterType = exports.defineStep = exports.BeforeStep = exports.BeforeAll = exports.Before = exports.AfterStep = exports.AfterAll = exports.After = exports.formatterHelpers = exports.UsageJsonFormatter = exports.UsageFormatter = exports.SummaryFormatter = exports.SnippetsFormatter = exports.RerunFormatter = exports.ProgressFormatter = exports.JsonFormatter = exports.FormatterBuilder = exports.Formatter = exports.TestCaseHookDefinition = exports.DataTable = exports.supportCodeLibraryBuilder = exports.version = void 0;
const node_util_1 = require("node:util");
const messages = __importStar(require("@cucumber/messages"));
const cli_1 = __importDefault(require("./cli"));

@@ -40,4 +50,5 @@ const cliHelpers = __importStar(require("./cli/helpers"));

const support_code_library_builder_1 = __importDefault(require("./support_code_library_builder"));
const messages = __importStar(require("@cucumber/messages"));
const util_1 = require("util");
const version_1 = require("./version");
// type version as string to avoid tripping api-extractor every release
exports.version = version_1.version;
// Top level

@@ -50,4 +61,2 @@ var support_code_library_builder_2 = require("./support_code_library_builder");

Object.defineProperty(exports, "TestCaseHookDefinition", { enumerable: true, get: function () { return __importDefault(test_case_hook_definition_1).default; } });
var version_1 = require("./version");
Object.defineProperty(exports, "version", { enumerable: true, get: function () { return version_1.version; } });
// Formatters

@@ -80,2 +89,3 @@ var formatter_1 = require("./formatter");

exports.BeforeStep = methods.BeforeStep;
exports.defineStep = methods.defineStep;
exports.defineParameterType = methods.defineParameterType;

@@ -97,21 +107,17 @@ exports.Given = methods.Given;

/**
* @deprecated use `runCucumber` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
exports.Cli = (0, util_1.deprecate)(cli_1.default, '`Cli` is deprecated, use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
exports.Cli = (0, node_util_1.deprecate)(cli_1.default, '`Cli` is deprecated, use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
/**
* @deprecated use `Given`, `When` or `Then` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
exports.defineStep = (0, util_1.deprecate)(methods.defineStep, '`defineStep` is deprecated, use `Given`, `When` or `Then` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
exports.parseGherkinMessageStream = (0, node_util_1.deprecate)(cliHelpers.parseGherkinMessageStream, '`parseGherkinMessageStream` is deprecated, use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
/**
* @deprecated use `loadSources` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
exports.parseGherkinMessageStream = (0, util_1.deprecate)(cliHelpers.parseGherkinMessageStream, '`parseGherkinMessageStream` is deprecated, use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
exports.PickleFilter = (0, node_util_1.deprecate)(pickle_filter_1.default, '`PickleFilter` is deprecated, use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
/**
* @deprecated use `loadSources` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
* @deprecated use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md
*/
exports.PickleFilter = (0, util_1.deprecate)(pickle_filter_1.default, '`PickleFilter` is deprecated, use `loadSources` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
/**
* @deprecated use `loadSources` instead; see <https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md>
*/
exports.Runtime = (0, util_1.deprecate)(runtime_1.default, '`Runtime` is deprecated, use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
exports.Runtime = (0, node_util_1.deprecate)(runtime_1.default, '`Runtime` is deprecated, use `runCucumber` instead; see https://github.com/cucumber/cucumber-js/blob/main/docs/deprecations.md');
//# sourceMappingURL=index.js.map

@@ -5,3 +5,3 @@ import * as messages from '@cucumber/messages';

constructor(sourceTable: messages.PickleTable | string[][]);
hashes(): any[];
hashes(): Record<string, string>[];
raw(): string[][];

@@ -8,0 +8,0 @@ rows(): string[][];

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class DataTable {
rawTable;
constructor(sourceTable) {

@@ -5,0 +6,0 @@ if (sourceTable instanceof Array) {

import * as messages from '@cucumber/messages';
import { Expression } from '@cucumber/cucumber-expressions';
import { ITestCaseHookParameter } from '../support_code_library_builder/types';
import { Expression } from '@cucumber/cucumber-expressions';
import { GherkinStepKeyword } from './gherkin_step_keyword';

@@ -5,0 +5,0 @@ export interface IGetInvocationDataRequest {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Definition {
code;
id;
line;
options;
unwrappedCode;
uri;
constructor({ code, id, line, options, unwrappedCode, uri, }) {

@@ -5,0 +11,0 @@ this.code = code;

@@ -1,1 +0,1 @@

export declare type GherkinStepKeyword = 'Unknown' | 'Given' | 'When' | 'Then';
export type GherkinStepKeyword = 'Unknown' | 'Given' | 'When' | 'Then';

@@ -0,3 +1,3 @@

import { Expression } from '@cucumber/cucumber-expressions';
import Definition, { IDefinition, IGetInvocationDataRequest, IGetInvocationDataResponse, IStepDefinitionParameters } from './definition';
import { Expression } from '@cucumber/cucumber-expressions';
import { GherkinStepKeyword } from './gherkin_step_keyword';

@@ -4,0 +4,0 @@ export default class StepDefinition extends Definition implements IDefinition {

@@ -6,7 +6,10 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const step_arguments_1 = require("../step_arguments");
const value_checker_1 = require("../value_checker");
const data_table_1 = __importDefault(require("./data_table"));
const definition_1 = __importDefault(require("./definition"));
const step_arguments_1 = require("../step_arguments");
const value_checker_1 = require("../value_checker");
class StepDefinition extends definition_1.default {
keyword;
pattern;
expression;
constructor(data) {

@@ -13,0 +16,0 @@ super(data);

@@ -0,3 +1,3 @@

import * as messages from '@cucumber/messages';
import Definition, { IDefinition, IDefinitionParameters, IGetInvocationDataRequest, IGetInvocationDataResponse, IHookDefinitionOptions } from './definition';
import * as messages from '@cucumber/messages';
export default class TestCaseHookDefinition extends Definition implements IDefinition {

@@ -4,0 +4,0 @@ readonly name: string;

@@ -9,2 +9,5 @@ "use strict";

class TestCaseHookDefinition extends definition_1.default {
name;
tagExpression;
pickleTagFilter;
constructor(data) {

@@ -11,0 +14,0 @@ super(data);

@@ -0,3 +1,3 @@

import * as messages from '@cucumber/messages';
import Definition, { IDefinition, IGetInvocationDataResponse, IGetInvocationDataRequest, IDefinitionParameters, IHookDefinitionOptions } from './definition';
import * as messages from '@cucumber/messages';
export default class TestStepHookDefinition extends Definition implements IDefinition {

@@ -4,0 +4,0 @@ readonly tagExpression: string;

@@ -9,2 +9,4 @@ "use strict";

class TestStepHookDefinition extends definition_1.default {
tagExpression;
pickleTagFilter;
constructor(data) {

@@ -11,0 +13,0 @@ super(data);

@@ -7,3 +7,3 @@ "use strict";

exports.PickleTagFilter = exports.PickleNameFilter = exports.PickleLineFilter = void 0;
const path_1 = __importDefault(require("path"));
const node_path_1 = __importDefault(require("node:path"));
const tag_expressions_1 = __importDefault(require("@cucumber/tag-expressions"));

@@ -14,2 +14,5 @@ const gherkin_document_parser_1 = require("./formatter/helpers/gherkin_document_parser");

class PickleFilter {
lineFilter;
nameFilter;
tagFilter;
constructor({ cwd, featurePaths, names, tagExpression, }) {

@@ -28,2 +31,3 @@ this.lineFilter = new PickleLineFilter(cwd, featurePaths);

class PickleLineFilter {
featureUriToLinesMapping;
constructor(cwd, featurePaths = []) {

@@ -41,7 +45,7 @@ this.featureUriToLinesMapping = this.getFeatureUriToLinesMapping({

let uri = match[1];
if (path_1.default.isAbsolute(uri)) {
uri = path_1.default.relative(cwd, uri);
if (node_path_1.default.isAbsolute(uri)) {
uri = node_path_1.default.relative(cwd, uri);
}
else {
uri = path_1.default.normalize(uri);
uri = node_path_1.default.normalize(uri);
}

@@ -65,3 +69,3 @@ const linesExpression = match[2];

matchesAnyLine({ gherkinDocument, pickle }) {
const uri = path_1.default.normalize(pickle.uri);
const uri = node_path_1.default.normalize(pickle.uri);
const linesToMatch = this.featureUriToLinesMapping[uri];

@@ -79,2 +83,3 @@ if ((0, value_checker_1.doesHaveValue)(linesToMatch)) {

class PickleNameFilter {
names;
constructor(names = []) {

@@ -92,2 +97,3 @@ this.names = names;

class PickleTagFilter {
tagExpressionNode; // cucumber-tag-expressions does not export interface
constructor(tagExpression) {

@@ -94,0 +100,0 @@ if ((0, value_checker_1.doesHaveValue)(tagExpression) && tagExpression !== '') {

@@ -1,13 +0,12 @@

import { Plugin, PluginEvents } from './types';
import { IRunEnvironment, IRunOptions } from '../api';
import { IRunEnvironment } from '../api';
import { ILogger } from '../logger';
import { InternalPlugin, CoordinatorPluginEventValues, CoordinatorPluginEventKey, CoordinatorPluginTransformEventKey, Operation } from './types';
export declare class PluginManager {
private pluginFns;
private handlers;
private cleanupFns;
constructor(pluginFns: Plugin[]);
private register;
init(logger: ILogger, configuration: IRunOptions, environment: IRunEnvironment): Promise<void>;
emit<K extends keyof PluginEvents>(event: K, value: PluginEvents[K]): void;
init<OptionsType>(operation: Operation, plugin: InternalPlugin<OptionsType>, options: OptionsType, logger: ILogger, environment: Required<IRunEnvironment>): Promise<void>;
emit<K extends CoordinatorPluginEventKey>(event: K, value: CoordinatorPluginEventValues[K]): void;
transform<K extends CoordinatorPluginTransformEventKey>(event: K, value: CoordinatorPluginEventValues[K]): Promise<CoordinatorPluginEventValues[K]>;
cleanup(): Promise<void>;
}

@@ -5,21 +5,22 @@ "use strict";

class PluginManager {
constructor(pluginFns) {
this.pluginFns = pluginFns;
this.handlers = { message: [] };
this.cleanupFns = [];
}
handlers = {
message: [],
'paths:resolve': [],
'pickles:filter': [],
'pickles:order': [],
};
cleanupFns = [];
async register(event, handler) {
this.handlers[event].push(handler);
}
async init(logger, configuration, environment) {
for (const pluginFn of this.pluginFns) {
const cleanupFn = await pluginFn({
on: this.register.bind(this),
logger,
configuration,
environment,
});
if (cleanupFn) {
this.cleanupFns.push(cleanupFn);
}
async init(operation, plugin, options, logger, environment) {
const cleanupFn = await plugin.coordinator({
operation,
on: this.register.bind(this),
options,
logger,
environment,
});
if (typeof cleanupFn === 'function') {
this.cleanupFns.push(cleanupFn);
}

@@ -30,2 +31,12 @@ }

}
async transform(event, value) {
let transformed = value;
for (const handler of this.handlers[event]) {
const returned = await handler(transformed);
if (typeof returned !== 'undefined') {
transformed = returned;
}
}
return transformed;
}
async cleanup() {

@@ -32,0 +43,0 @@ for (const cleanupFn of this.cleanupFns) {

@@ -1,14 +0,38 @@

import { IRunEnvironment, IRunOptions } from '../api';
import { Envelope } from '@cucumber/messages';
import { ArrayValues, Promisable } from 'type-fest';
import { IRunEnvironment } from '../api';
import { ILogger } from '../logger';
export interface PluginEvents {
message: Envelope;
}
export interface PluginContext {
on: <K extends keyof PluginEvents>(event: K, handler: (value: PluginEvents[K]) => void) => void;
import { IFilterablePickle } from '../filter';
import { IResolvedPaths } from '../paths';
import { coordinatorTransformKeys, coordinatorVoidKeys } from './events';
export type Operation = 'loadSources' | 'loadSupport' | 'runCucumber';
export type CoordinatorPluginVoidEventKey = ArrayValues<typeof coordinatorVoidKeys>;
export type CoordinatorPluginTransformEventKey = ArrayValues<typeof coordinatorTransformKeys>;
export type CoordinatorPluginEventKey = CoordinatorPluginVoidEventKey | CoordinatorPluginTransformEventKey;
export type CoordinatorPluginEventValues = {
message: Readonly<Envelope>;
'paths:resolve': Readonly<IResolvedPaths>;
'pickles:filter': Readonly<Array<IFilterablePickle>>;
'pickles:order': Readonly<Array<IFilterablePickle>>;
};
export type CoordinatorPluginEventHandler<K extends CoordinatorPluginEventKey> = (value: CoordinatorPluginEventValues[K]) => K extends CoordinatorPluginTransformEventKey ? Promisable<CoordinatorPluginEventValues[K]> : void;
export interface CoordinatorPluginContext<OptionsType> {
operation: Operation;
on: <EventKey extends CoordinatorPluginEventKey>(event: EventKey, handler: CoordinatorPluginEventHandler<EventKey>) => void;
options: OptionsType;
logger: ILogger;
configuration: IRunOptions;
environment: IRunEnvironment;
environment: Required<IRunEnvironment>;
}
export declare type PluginCleanup = () => any | void | Promise<any | void>;
export declare type Plugin = (context: PluginContext) => Promise<PluginCleanup | void>;
export type CoordinatorPluginFunction<OptionsType> = (context: CoordinatorPluginContext<OptionsType>) => Promisable<PluginCleanup | void>;
export type PluginCleanup = () => Promisable<void>;
/**
* A plugin to implement Cucumber built-in functionality.
*
* Uses the same events and mechanisms as user-authored plugins, but is free to require configuration and context from
* inside of Cucumber as its `options`, whereas user-authored plugins will be limited to `pluginOptions` from the
* project configuration.
*/
export interface InternalPlugin<OptionsType = any> {
type: 'plugin';
coordinator: CoordinatorPluginFunction<OptionsType>;
}
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { Transform } from 'stream';
import http from 'http';
declare type HttpMethod = 'GET' | 'POST' | 'PUT';
import { Transform } from 'node:stream';
import http from 'node:http';
type HttpMethod = 'GET' | 'POST' | 'PUT';
/**

@@ -8,0 +8,0 @@ * This Writable writes data to a HTTP/HTTPS URL.

@@ -6,7 +6,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = require("stream");
const node_stream_1 = require("node:stream");
const node_fs_1 = __importDefault(require("node:fs"));
const node_http_1 = __importDefault(require("node:http"));
const node_https_1 = __importDefault(require("node:https"));
const tmp_1 = __importDefault(require("tmp"));
const fs_1 = __importDefault(require("fs"));
const http_1 = __importDefault(require("http"));
const https_1 = __importDefault(require("https"));
const value_checker_1 = require("../value_checker");

@@ -23,3 +23,8 @@ /**

*/
class HttpStream extends stream_1.Transform {
class HttpStream extends node_stream_1.Transform {
url;
method;
headers;
tempFilePath;
tempFile;
constructor(url, method, headers) {

@@ -39,3 +44,3 @@ super({

this.tempFilePath = name;
this.tempFile = fs_1.default.createWriteStream(name, { fd });
this.tempFile = node_fs_1.default.createWriteStream(name, { fd });
this.tempFile.write(chunk, encoding, callback);

@@ -86,7 +91,7 @@ });

sendHttpRequest(url, method, headers, callback) {
const httpx = (0, value_checker_1.doesHaveValue)(url.match(/^https:/)) ? https_1.default : http_1.default;
const httpx = (0, value_checker_1.doesHaveValue)(url.match(/^https:/)) ? node_https_1.default : node_http_1.default;
const additionalHttpHeaders = {};
const upload = method === 'PUT' || method === 'POST';
if (upload) {
additionalHttpHeaders['Content-Length'] = fs_1.default.statSync(this.tempFilePath).size;
additionalHttpHeaders['Content-Length'] = node_fs_1.default.statSync(this.tempFilePath).size;
}

@@ -104,3 +109,3 @@ const allHeaders = { ...headers, ...additionalHttpHeaders };

if (upload) {
(0, stream_1.pipeline)(fs_1.default.createReadStream(this.tempFilePath), req, (err) => {
(0, node_stream_1.pipeline)(node_fs_1.default.createReadStream(this.tempFilePath), req, (err) => {
if ((0, value_checker_1.doesHaveValue)(err)) {

@@ -107,0 +112,0 @@ this.emit('error', err);

import { publishPlugin } from './publish_plugin';
export default publishPlugin;
export * from './types';
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
const publish_plugin_1 = require("./publish_plugin");
exports.default = publish_plugin_1.publishPlugin;
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map

@@ -1,2 +0,3 @@

import { Plugin } from '../plugin';
export declare const publishPlugin: Plugin;
import { InternalPlugin } from '../plugin';
import { IPublishConfig } from './types';
export declare const publishPlugin: InternalPlugin<IPublishConfig | false>;

@@ -7,31 +7,36 @@ "use strict";

exports.publishPlugin = void 0;
const http_stream_1 = __importDefault(require("./http_stream"));
const stream_1 = require("stream");
const node_stream_1 = require("node:stream");
const supports_color_1 = require("supports-color");
const has_ansi_1 = __importDefault(require("has-ansi"));
const strip_ansi_1 = __importDefault(require("strip-ansi"));
const http_stream_1 = __importDefault(require("./http_stream"));
const DEFAULT_CUCUMBER_PUBLISH_URL = 'https://messages.cucumber.io/api/reports';
const publishPlugin = async ({ on, logger, configuration, environment, }) => {
if (!configuration.formats.publish) {
return undefined;
}
const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = configuration.formats.publish;
const headers = {};
if (token !== undefined) {
headers.Authorization = `Bearer ${token}`;
}
const stream = new http_stream_1.default(url, 'GET', headers);
const readerStream = new stream_1.Writable({
objectMode: true,
write: function (responseBody, encoding, writeCallback) {
environment.stderr.write(sanitisePublishOutput(responseBody, environment.stderr) + '\n');
writeCallback();
},
});
stream.pipe(readerStream);
stream.on('error', (error) => logger.error(error.message));
on('message', (value) => stream.write(JSON.stringify(value) + '\n'));
return () => stream.end();
exports.publishPlugin = {
type: 'plugin',
coordinator: async ({ on, logger, options, environment }) => {
if (!options) {
return undefined;
}
const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = options;
const headers = {};
if (token !== undefined) {
headers.Authorization = `Bearer ${token}`;
}
const stream = new http_stream_1.default(url, 'GET', headers);
const readerStream = new node_stream_1.Writable({
objectMode: true,
write: function (responseBody, encoding, writeCallback) {
environment.stderr.write(sanitisePublishOutput(responseBody, environment.stderr) + '\n');
writeCallback();
},
});
stream.pipe(readerStream);
stream.on('error', (error) => logger.error(error.message));
on('message', (value) => stream.write(JSON.stringify(value) + '\n'));
return () => new Promise((resolve) => {
stream.on('finish', () => resolve());
stream.end();
});
},
};
exports.publishPlugin = publishPlugin;
/*

@@ -38,0 +43,0 @@ This is because the Cucumber Reports service returns a pre-formatted console message

/// <reference types="node" />
import { EventEmitter } from 'events';
import { EventEmitter } from 'node:events';
import * as messages from '@cucumber/messages';
import { IdGenerator } from '@cucumber/messages';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
export declare type IAssembledTestCases = Record<string, messages.TestCase>;

@@ -11,4 +11,4 @@ export interface IAssembleTestCasesOptions {

pickles: messages.Pickle[];
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}
export declare function assembleTestCases({ eventBroadcaster, newId, pickles, supportCodeLibrary, }: IAssembleTestCasesOptions): Promise<IAssembledTestCases>;
/// <reference types="node" />
/// <reference types="node" />
import { Readable } from 'stream';
import { Readable } from 'node:stream';
import * as messages from '@cucumber/messages';

@@ -12,6 +12,15 @@ export interface IAttachmentMedia {

media: IAttachmentMedia;
fileName?: string;
}
export declare type IAttachFunction = (attachment: IAttachment) => void;
export declare type ICreateAttachment = (data: Buffer | Readable | string, mediaType?: string, callback?: () => void) => void | Promise<void>;
export declare type ICreateLog = (text: string) => void | Promise<void>;
export type IAttachFunction = (attachment: IAttachment) => void;
export interface ICreateAttachmentOptions {
mediaType: string;
fileName?: string;
}
export type ICreateStringAttachment = (data: string, mediaTypeOrOptions?: string | ICreateAttachmentOptions) => void;
export type ICreateBufferAttachment = (data: Buffer, mediaTypeOrOptions: string | ICreateAttachmentOptions) => void;
export type ICreateStreamAttachment = (data: Readable, mediaTypeOrOptions: string | ICreateAttachmentOptions) => Promise<void>;
export type ICreateStreamAttachmentWithCallback = (data: Readable, mediaTypeOrOptions: string | ICreateAttachmentOptions, callback: () => void) => void;
export type ICreateAttachment = ICreateStringAttachment & ICreateBufferAttachment & ICreateStreamAttachment & ICreateStreamAttachmentWithCallback;
export type ICreateLog = (text: string) => void;
export default class AttachmentManager {

@@ -21,6 +30,6 @@ private readonly onAttachment;

log(text: string): void | Promise<void>;
create(data: Buffer | Readable | string, mediaType?: string, callback?: () => void): void | Promise<void>;
createBufferAttachment(data: Buffer, mediaType: string): void;
createStreamAttachment(data: Readable, mediaType: string, callback: () => void): void | Promise<void>;
createStringAttachment(data: string, media: IAttachmentMedia): void;
create(data: Buffer | Readable | string, mediaTypeOrOptions?: string | ICreateAttachmentOptions, callback?: () => void): void | Promise<void>;
createBufferAttachment(data: Buffer, mediaType: string, fileName?: string): void;
createStreamAttachment(data: Readable, mediaType: string, fileName?: string, callback?: () => void): void | Promise<void>;
createStringAttachment(data: string, media: IAttachmentMedia, fileName?: string): void;
}

@@ -33,2 +33,3 @@ "use strict";

class AttachmentManager {
onAttachment;
constructor(onAttachment) {

@@ -40,24 +41,25 @@ this.onAttachment = onAttachment;

}
create(data, mediaType, callback) {
create(data, mediaTypeOrOptions, callback) {
const options = normaliseOptions(mediaTypeOrOptions);
if (Buffer.isBuffer(data)) {
if ((0, value_checker_1.doesNotHaveValue)(mediaType)) {
if ((0, value_checker_1.doesNotHaveValue)(options.mediaType)) {
throw Error('Buffer attachments must specify a media type');
}
this.createBufferAttachment(data, mediaType);
this.createBufferAttachment(data, options.mediaType, options.fileName);
}
else if (is_stream_1.default.readable(data)) {
if ((0, value_checker_1.doesNotHaveValue)(mediaType)) {
if ((0, value_checker_1.doesNotHaveValue)(options.mediaType)) {
throw Error('Stream attachments must specify a media type');
}
return this.createStreamAttachment(data, mediaType, callback);
return this.createStreamAttachment(data, options.mediaType, options.fileName, callback);
}
else if (typeof data === 'string') {
if ((0, value_checker_1.doesNotHaveValue)(mediaType)) {
mediaType = 'text/plain';
if ((0, value_checker_1.doesNotHaveValue)(options.mediaType)) {
options.mediaType = 'text/plain';
}
if (mediaType.startsWith('base64:')) {
if (options.mediaType.startsWith('base64:')) {
this.createStringAttachment(data, {
encoding: messages.AttachmentContentEncoding.BASE64,
contentType: mediaType.replace('base64:', ''),
});
contentType: options.mediaType.replace('base64:', ''),
}, options.fileName);
}

@@ -67,4 +69,4 @@ else {

encoding: messages.AttachmentContentEncoding.IDENTITY,
contentType: mediaType,
});
contentType: options.mediaType,
}, options.fileName);
}

@@ -76,9 +78,9 @@ }

}
createBufferAttachment(data, mediaType) {
createBufferAttachment(data, mediaType, fileName) {
this.createStringAttachment(data.toString('base64'), {
encoding: messages.AttachmentContentEncoding.BASE64,
contentType: mediaType,
});
}, fileName);
}
createStreamAttachment(data, mediaType, callback) {
createStreamAttachment(data, mediaType, fileName, callback) {
const promise = new Promise((resolve, reject) => {

@@ -90,3 +92,3 @@ const buffers = [];

data.on('end', () => {
this.createBufferAttachment(Buffer.concat(buffers), mediaType);
this.createBufferAttachment(Buffer.concat(buffers), mediaType, fileName);
resolve();

@@ -103,7 +105,22 @@ });

}
createStringAttachment(data, media) {
this.onAttachment({ data, media });
createStringAttachment(data, media, fileName) {
this.onAttachment({
data,
media,
...(fileName ? { fileName } : {}),
});
}
}
exports.default = AttachmentManager;
function normaliseOptions(mediaTypeOrOptions) {
if (!mediaTypeOrOptions) {
return {};
}
if (typeof mediaTypeOrOptions === 'string') {
return {
mediaType: mediaTypeOrOptions,
};
}
return mediaTypeOrOptions;
}
//# sourceMappingURL=index.js.map

@@ -0,3 +1,3 @@

import * as messages from '@cucumber/messages';
import StepDefinition from '../models/step_definition';
import * as messages from '@cucumber/messages';
import { IRuntimeOptions } from '.';

@@ -4,0 +4,0 @@ export declare function getAmbiguousStepException(stepDefinitions: StepDefinition[]): string;

@@ -30,7 +30,7 @@ "use strict";

exports.shouldCauseFailure = exports.retriesForPickle = exports.getAmbiguousStepException = void 0;
const location_helpers_1 = require("../formatter/helpers/location_helpers");
const cli_table3_1 = __importDefault(require("cli-table3"));
const indent_string_1 = __importDefault(require("indent-string"));
const messages = __importStar(require("@cucumber/messages"));
const location_helpers_1 = require("../formatter/helpers/location_helpers");
const pickle_filter_1 = require("../pickle_filter");
const messages = __importStar(require("@cucumber/messages"));
function getAmbiguousStepException(stepDefinitions) {

@@ -37,0 +37,0 @@ const table = new cli_table3_1.default({

/// <reference types="node" />
import { EventEmitter } from 'node:events';
import * as messages from '@cucumber/messages';
import { IdGenerator } from '@cucumber/messages';
import { EventEmitter } from 'events';
import { JsonObject } from 'type-fest';
import { EventDataCollector } from '../formatter/helpers';
import { ISupportCodeLibrary } from '../support_code_library_builder/types';
import { SupportCodeLibrary } from '../support_code_library_builder/types';
export interface IRuntime {

@@ -16,3 +17,3 @@ start: () => Promise<boolean>;

pickleIds: string[];
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
}

@@ -26,3 +27,3 @@ export interface IRuntimeOptions {

strict: boolean;
worldParameters: any;
worldParameters: JsonObject;
}

@@ -36,3 +37,2 @@ export default class Runtime implements IRuntime {

private readonly pickleIds;
private readonly stackTraceFilter;
private readonly supportCodeLibrary;

@@ -39,0 +39,0 @@ private success;

@@ -6,3 +6,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const stack_trace_filter_1 = __importDefault(require("../stack_trace_filter"));
const assemble_test_cases_1 = require("./assemble_test_cases");

@@ -14,13 +13,21 @@ const helpers_1 = require("./helpers");

class Runtime {
eventBroadcaster;
eventDataCollector;
stopwatch;
newId;
options;
pickleIds;
supportCodeLibrary;
success;
runTestRunHooks;
constructor({ eventBroadcaster, eventDataCollector, newId, options, pickleIds, supportCodeLibrary, }) {
this.eventBroadcaster = eventBroadcaster;
this.eventDataCollector = eventDataCollector;
this.stopwatch = new stopwatch_1.RealTestRunStopwatch();
this.stopwatch = (0, stopwatch_1.create)();
this.newId = newId;
this.options = options;
this.pickleIds = pickleIds;
this.stackTraceFilter = new stack_trace_filter_1.default();
this.supportCodeLibrary = supportCodeLibrary;
this.success = true;
this.runTestRunHooks = (0, run_test_run_hooks_1.makeRunTestRunHooks)(this.options.dryRun, this.supportCodeLibrary.defaultTimeout, (name, location) => `${name} hook errored, process exiting: ${location}`);
this.runTestRunHooks = (0, run_test_run_hooks_1.makeRunTestRunHooks)(this.options.dryRun, this.supportCodeLibrary.defaultTimeout, this.options.worldParameters, (name, location) => `${name} hook errored, process exiting: ${location}`);
}

@@ -40,2 +47,3 @@ async runTestCase(pickleId, testCase) {

skip,
filterStackTraces: this.options.filterStacktraces,
supportCodeLibrary: this.supportCodeLibrary,

@@ -50,5 +58,2 @@ worldParameters: this.options.worldParameters,

async start() {
if (this.options.filterStacktraces) {
this.stackTraceFilter.filter();
}
const testRunStarted = {

@@ -80,5 +85,2 @@ testRunStarted: {

this.eventBroadcaster.emit('envelope', testRunFinished);
if (this.options.filterStacktraces) {
this.stackTraceFilter.unfilter();
}
return this.success;

@@ -85,0 +87,0 @@ }

@@ -24,3 +24,3 @@ import * as messages from '@cucumber/messages';

skip: boolean;
elapsed: number;
elapsed: messages.Duration;
pickle: messages.Pickle;

@@ -27,0 +27,0 @@ testCase: messages.TestCase;

/// <reference types="node" />
/// <reference types="node" />
import { ChildProcess } from 'child_process';
import { ChildProcess } from 'node:child_process';
import { EventEmitter } from 'node:events';
import * as messages from '@cucumber/messages';
import { EventEmitter } from 'events';
import { IdGenerator } from '@cucumber/messages';
import { EventDataCollector } from '../../formatter/helpers';
import { IRuntime, IRuntimeOptions } from '..';
import { ISupportCodeLibrary } from '../../support_code_library_builder/types';
import { SupportCodeLibrary } from '../../support_code_library_builder/types';
import { ILogger } from '../../logger';
import { ICoordinatorReport } from './command_types';
import { IdGenerator } from '@cucumber/messages';
import { ILogger } from '../../logger';
export interface INewCoordinatorOptions {

@@ -20,3 +20,3 @@ cwd: string;

pickleIds: string[];
supportCodeLibrary: ISupportCodeLibrary;
supportCodeLibrary: SupportCodeLibrary;
requireModules: string[];

@@ -23,0 +23,0 @@ requirePaths: string[];

@@ -29,11 +29,30 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const child_process_1 = require("child_process");
const path_1 = __importDefault(require("path"));
const node_child_process_1 = require("node:child_process");
const node_path_1 = __importDefault(require("node:path"));
const messages = __importStar(require("@cucumber/messages"));
const helpers_1 = require("../helpers");
const messages = __importStar(require("@cucumber/messages"));
const value_checker_1 = require("../../value_checker");
const stopwatch_1 = require("../stopwatch");
const assemble_test_cases_1 = require("../assemble_test_cases");
const runWorkerPath = path_1.default.resolve(__dirname, 'run_worker.js');
const runWorkerPath = node_path_1.default.resolve(__dirname, 'run_worker.js');
class Coordinator {
cwd;
eventBroadcaster;
eventDataCollector;
stopwatch;
onFinish;
options;
newId;
pickleIds;
assembledTestCases;
inProgressPickles;
workers;
supportCodeLibrary;
requireModules;
requirePaths;
importPaths;
numberOfWorkers;
logger;
success;
idleInterventions;
constructor({ cwd, logger, eventBroadcaster, eventDataCollector, pickleIds, options, newId, supportCodeLibrary, requireModules, requirePaths, importPaths, numberOfWorkers, }) {

@@ -44,3 +63,3 @@ this.cwd = cwd;

this.eventDataCollector = eventDataCollector;
this.stopwatch = new stopwatch_1.RealTestRunStopwatch();
this.stopwatch = (0, stopwatch_1.create)();
this.options = options;

@@ -90,3 +109,3 @@ this.newId = newId;

startWorker(id, total) {
const workerProcess = (0, child_process_1.fork)(runWorkerPath, [], {
const workerProcess = (0, node_child_process_1.fork)(runWorkerPath, [], {
cwd: this.cwd,

@@ -214,3 +233,3 @@ env: {

skip,
elapsed: this.stopwatch.duration().nanos(),
elapsed: this.stopwatch.duration(),
pickle,

@@ -217,0 +236,0 @@ testCase,

@@ -6,9 +6,8 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const value_checker_1 = require("../../value_checker");
const worker_1 = __importDefault(require("./worker"));
const verror_1 = __importDefault(require("verror"));
const value_checker_1 = require("../../value_checker");
function run() {
const exit = (exitCode, error, message) => {
if ((0, value_checker_1.doesHaveValue)(error)) {
console.error(verror_1.default.fullStack(new verror_1.default(error, message))); // eslint-disable-line no-console
console.error(new Error(message, { cause: error })); // eslint-disable-line no-console
}

@@ -15,0 +14,0 @@ process.exit(exitCode);

import { ICoordinatorReport, IWorkerCommand, IWorkerCommandInitialize, IWorkerCommandRun } from './command_types';
declare type IExitFunction = (exitCode: number, error?: Error, message?: string) => void;
declare type IMessageSender = (command: ICoordinatorReport) => void;
type IExitFunction = (exitCode: number, error?: Error, message?: string) => void;
type IMessageSender = (command: ICoordinatorReport) => void;
export default class Worker {

@@ -12,3 +12,2 @@ private readonly cwd;

private readonly sendMessage;
private readonly stackTraceFilter;
private supportCodeLibrary;

@@ -15,0 +14,0 @@ private worldParameters;

@@ -6,7 +6,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const node_events_1 = require("node:events");
const node_url_1 = require("node:url");
const messages_1 = require("@cucumber/messages");
const durations_1 = require("durations");
const events_1 = require("events");
const url_1 = require("url");
const stack_trace_filter_1 = __importDefault(require("../../stack_trace_filter"));
const support_code_library_builder_1 = __importDefault(require("../../support_code_library_builder"));

@@ -17,6 +15,15 @@ const value_checker_1 = require("../../value_checker");

const test_case_runner_1 = __importDefault(require("../test_case_runner"));
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { importer } = require('../../importer');
const try_require_1 = __importDefault(require("../../try_require"));
const { uuid } = messages_1.IdGenerator;
class Worker {
cwd;
exit;
id;
eventBroadcaster;
filterStacktraces;
newId;
sendMessage;
supportCodeLibrary;
worldParameters;
runTestRunHooks;
constructor({ cwd, exit, id, sendMessage, }) {

@@ -28,16 +35,21 @@ this.id = id;

this.sendMessage = sendMessage;
this.eventBroadcaster = new events_1.EventEmitter();
this.stackTraceFilter = new stack_trace_filter_1.default();
this.eventBroadcaster = new node_events_1.EventEmitter();
this.eventBroadcaster.on('envelope', (envelope) => {
this.sendMessage({
jsonEnvelope: JSON.stringify(envelope),
});
// assign `workerId` property only for the `testCaseStarted` message
if (envelope.testCaseStarted) {
envelope.testCaseStarted.workerId = this.id;
}
this.sendMessage({ jsonEnvelope: JSON.stringify(envelope) });
});
}
async initialize({ filterStacktraces, requireModules, requirePaths, importPaths, supportCodeIds, options, }) {
support_code_library_builder_1.default.reset(this.cwd, this.newId);
requireModules.map((module) => require(module));
requirePaths.map((module) => require(module));
support_code_library_builder_1.default.reset(this.cwd, this.newId, {
requireModules,
requirePaths,
importPaths,
});
requireModules.map((module) => (0, try_require_1.default)(module));
requirePaths.map((module) => (0, try_require_1.default)(module));
for (const path of importPaths) {
await importer((0, url_1.pathToFileURL)(path));
await import((0, node_url_1.pathToFileURL)(path).toString());
}

@@ -47,6 +59,3 @@ this.supportCodeLibrary = support_code_library_builder_1.default.finalize(supportCodeIds);

this.filterStacktraces = filterStacktraces;
if (this.filterStacktraces) {
this.stackTraceFilter.filter();
}
this.runTestRunHooks = (0, run_test_run_hooks_1.makeRunTestRunHooks)(options.dryRun, this.supportCodeLibrary.defaultTimeout, (name, location) => `${name} hook errored on worker ${this.id}, process exiting: ${location}`);
this.runTestRunHooks = (0, run_test_run_hooks_1.makeRunTestRunHooks)(options.dryRun, this.supportCodeLibrary.defaultTimeout, this.worldParameters, (name, location) => `${name} hook errored on worker ${this.id}, process exiting: ${location}`);
await this.runTestRunHooks(this.supportCodeLibrary.beforeTestRunHookDefinitions, 'a BeforeAll');

@@ -57,5 +66,2 @@ this.sendMessage({ ready: true });

await this.runTestRunHooks(this.supportCodeLibrary.afterTestRunHookDefinitions, 'an AfterAll');
if (this.filterStacktraces) {
this.stackTraceFilter.unfilter();
}
this.exit(0);

@@ -75,4 +81,3 @@ }

async runTestCase({ gherkinDocument, pickle, testCase, elapsed, retries, skip, }) {
const stopwatch = new stopwatch_1.RealTestRunStopwatch();
stopwatch.from((0, durations_1.duration)(elapsed));
const stopwatch = (0, stopwatch_1.create)(elapsed);
const testCaseRunner = new test_case_runner_1.default({

@@ -87,2 +92,3 @@ eventBroadcaster: this.eventBroadcaster,

skip,
filterStackTraces: this.filterStacktraces,
supportCodeLibrary: this.supportCodeLibrary,

@@ -89,0 +95,0 @@ worldParameters: this.worldParameters,

@@ -0,3 +1,4 @@

import { JsonObject } from 'type-fest';
import TestRunHookDefinition from '../models/test_run_hook_definition';
export declare type RunsTestRunHooks = (definitions: TestRunHookDefinition[], name: string) => Promise<void>;
export declare const makeRunTestRunHooks: (dryRun: boolean, defaultTimeout: number, errorMessage: (name: string, location: string) => string) => RunsTestRunHooks;
export type RunsTestRunHooks = (definitions: TestRunHookDefinition[], name: string) => Promise<void>;
export declare const makeRunTestRunHooks: (dryRun: boolean, defaultTimeout: number, worldParameters: JsonObject, errorMessage: (name: string, location: string) => string) => RunsTestRunHooks;

@@ -8,6 +8,5 @@ "use strict";

const user_code_runner_1 = __importDefault(require("../user_code_runner"));
const verror_1 = __importDefault(require("verror"));
const helpers_1 = require("../formatter/helpers");
const value_checker_1 = require("../value_checker");
const makeRunTestRunHooks = (dryRun, defaultTimeout, errorMessage) => dryRun
const makeRunTestRunHooks = (dryRun, defaultTimeout, worldParameters, errorMessage) => dryRun
? async () => { }

@@ -19,3 +18,3 @@ : async (definitions, name) => {

fn: hookDefinition.code,
thisArg: null,
thisArg: { parameters: worldParameters },
timeoutInMilliseconds: (0, value_checker_1.valueOrDefault)(hookDefinition.options.timeout, defaultTimeout),

@@ -25,3 +24,3 @@ });

const location = (0, helpers_1.formatLocation)(hookDefinition);
throw new verror_1.default(error, errorMessage(name, location));
throw new Error(errorMessage(name, location), { cause: error });
}

@@ -28,0 +27,0 @@ }

@@ -6,2 +6,3 @@ import * as messages from '@cucumber/messages';

defaultTimeout: number;
filterStackTraces: boolean;
hookParameter: ITestCaseHookParameter;

@@ -12,3 +13,3 @@ step: messages.PickleStep;

}
export declare function run({ defaultTimeout, hookParameter, step, stepDefinition, world, }: IRunOptions): Promise<messages.TestStepResult>;
export declare function run({ defaultTimeout, filterStackTraces, hookParameter, step, stepDefinition, world, }: IRunOptions): Promise<messages.TestStepResult>;
declare const _default: {

@@ -15,0 +16,0 @@ run: typeof run;

@@ -30,10 +30,9 @@ "use strict";

exports.run = void 0;
const time_1 = __importDefault(require("../time"));
const messages = __importStar(require("@cucumber/messages"));
const user_code_runner_1 = __importDefault(require("../user_code_runner"));
const messages = __importStar(require("@cucumber/messages"));
const assertion_error_formatter_1 = require("assertion-error-formatter");
const value_checker_1 = require("../value_checker");
const { beginTiming, endTiming } = time_1.default;
async function run({ defaultTimeout, hookParameter, step, stepDefinition, world, }) {
beginTiming();
const stopwatch_1 = require("./stopwatch");
const format_error_1 = require("./format_error");
async function run({ defaultTimeout, filterStackTraces, hookParameter, step, stepDefinition, world, }) {
const stopwatch = (0, stopwatch_1.create)().start();
let error, result, invocationData;

@@ -66,5 +65,5 @@ try {

}
const duration = messages.TimeConversion.millisecondsToDuration(endTiming());
const duration = stopwatch.stop().duration();
let status;
let message;
let details = {};
if (result === 'skipped') {

@@ -77,3 +76,3 @@ status = messages.TestStepResultStatus.SKIPPED;

else if ((0, value_checker_1.doesHaveValue)(error)) {
message = (0, assertion_error_formatter_1.format)(error);
details = (0, format_error_1.formatError)(error, filterStackTraces);
status = messages.TestStepResultStatus.FAILED;

@@ -87,3 +86,3 @@ }

status,
message,
...details,
};

@@ -90,0 +89,0 @@ }

@@ -1,28 +0,12 @@

import * as messages from '@cucumber/messages';
import { Duration } from 'durations';
export interface ITestRunStopwatch {
from: (duration: Duration) => ITestRunStopwatch;
start: () => ITestRunStopwatch;
stop: () => ITestRunStopwatch;
import { Duration, Timestamp } from '@cucumber/messages';
/**
* A utility for timing test run operations and returning duration and
* timestamp objects in messages-compatible formats
*/
export interface IStopwatch {
start: () => IStopwatch;
stop: () => IStopwatch;
duration: () => Duration;
timestamp: () => messages.Timestamp;
timestamp: () => Timestamp;
}
export declare class RealTestRunStopwatch implements ITestRunStopwatch {
private readonly stopwatch;
private base;
from(duration: Duration): ITestRunStopwatch;
start(): ITestRunStopwatch;
stop(): ITestRunStopwatch;
duration(): Duration;
timestamp(): messages.Timestamp;
}
export declare class PredictableTestRunStopwatch implements ITestRunStopwatch {
private count;
private base;
from(duration: Duration): ITestRunStopwatch;
start(): ITestRunStopwatch;
stop(): ITestRunStopwatch;
duration(): Duration;
timestamp(): messages.Timestamp;
private convertToTimestamp;
}
export declare const create: (base?: Duration) => IStopwatch;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PredictableTestRunStopwatch = exports.RealTestRunStopwatch = void 0;
const messages = __importStar(require("@cucumber/messages"));
const durations_1 = require("durations");
class RealTestRunStopwatch {
constructor() {
this.stopwatch = (0, durations_1.stopwatch)();
this.base = null;
exports.create = void 0;
const messages_1 = require("@cucumber/messages");
const time_1 = __importDefault(require("../time"));
class StopwatchImpl {
base;
started;
constructor(base = { seconds: 0, nanos: 0 }) {
this.base = base;
}
from(duration) {
this.base = duration;
return this;
}
start() {
this.stopwatch.start();
this.started = time_1.default.performance.now();
return this;
}
stop() {
this.stopwatch.stop();
this.base = this.duration();
this.started = undefined;
return this;
}
duration() {
const current = this.stopwatch.duration();
if (this.base !== null) {
return (0, durations_1.duration)(this.base.nanos() + current.nanos());
if (typeof this.started !== 'number') {
return this.base;
}
return current;
return messages_1.TimeConversion.addDurations(this.base, messages_1.TimeConversion.millisecondsToDuration(time_1.default.performance.now() - this.started));
}
timestamp() {
return messages.TimeConversion.millisecondsSinceEpochToTimestamp(Date.now());
return messages_1.TimeConversion.millisecondsSinceEpochToTimestamp(time_1.default.Date.now());
}
}
exports.RealTestRunStopwatch = RealTestRunStopwatch;
class PredictableTestRunStopwatch {
constructor() {
this.count = 0;
this.base = null;
}
from(duration) {
this.base = duration;
return this;
}
start() {
return this;
}
stop() {
return this;
}
duration() {
const current = (0, durations_1.duration)(this.count * 1000000);
if (this.base !== null) {
return (0, durations_1.duration)(this.base.nanos() + current.nanos());
}
return current;
}
timestamp() {
const fakeTimestamp = this.convertToTimestamp(this.duration());
this.count++;
return fakeTimestamp;
}
// TODO: Remove. It's impossible to convert timestamps to durations and vice-versa
convertToTimestamp(duration) {
const seconds = Math.floor(duration.seconds());
const nanos = Math.floor((duration.seconds() - seconds) * 1000000000);
return {
seconds,
nanos,
};
}
}
exports.PredictableTestRunStopwatch = PredictableTestRunStopwatch;
const create = (base) => new StopwatchImpl(base);
exports.create = create;
//# sourceMappingURL=stopwatch.js.map
/// <reference types="node" />
import { EventEmitter } from 'node:events';
import * as messages from '@cucumber/messages';
import { IdGenerator } from '@cucumber/messages';
import { EventEmitter } from 'events';
import { ISupportCodeLibrary, ITestCaseHookParameter } from '../support_code_library_builder/types';
import { JsonObject } from 'type-fest';
import { SupportCodeLibrary, ITestCaseHookParameter } from '../support_code_library_builder/types';
import TestCaseHookDefinition from '../models/test_case_hook_definition';
import TestStepHookDefinition from '../models/test_step_hook_definition';
import { IDefinition } from '../models/definition';
import { ITestRunStopwatch } from './stopwatch';
import { IStopwatch } from './stopwatch';
export interface INewTestCaseRunnerOptions {
eventBroadcaster: EventEmitter;
stopwatch: ITestRunStopwatch;
stopwatch: IStopwatch;
gherkinDocument: messages.GherkinDocument;

@@ -19,4 +20,5 @@ newId: IdGenerator.NewId;

skip: boolean;
supportCodeLibrary: ISupportCodeLibrary;
worldParameters: any;
filterStackTraces: boolean;
supportCodeLibrary: SupportCodeLibrary;
worldParameters: JsonObject;
}

@@ -35,2 +37,3 @@ export default class TestCaseRunner {

private readonly skip;
private readonly filterStackTraces;
private readonly supportCodeLibrary;

@@ -40,3 +43,3 @@ private testStepResults;

private readonly worldParameters;
constructor({ eventBroadcaster, stopwatch, gherkinDocument, newId, pickle, testCase, retries, skip, supportCodeLibrary, worldParameters, }: INewTestCaseRunnerOptions);
constructor({ eventBroadcaster, stopwatch, gherkinDocument, newId, pickle, testCase, retries, skip, filterStackTraces, supportCodeLibrary, worldParameters, }: INewTestCaseRunnerOptions);
resetTestProgressData(): void;

@@ -51,2 +54,3 @@ getBeforeStepHookDefinitions(): TestStepHookDefinition[];

run(): Promise<messages.TestStepResultStatus>;
runAttempt(attempt: number, moreAttemptsRemaining: boolean): Promise<boolean>;
runHook(hookDefinition: TestCaseHookDefinition, hookParameter: ITestCaseHookParameter, isBeforeHook: boolean): Promise<messages.TestStepResult>;

@@ -53,0 +57,0 @@ runStepHooks(stepHooks: TestStepHookDefinition[], pickleStep: messages.PickleStep, stepResult?: messages.TestStepResult): Promise<messages.TestStepResult[]>;

@@ -29,11 +29,27 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const helpers_1 = require("./helpers");
const attachment_manager_1 = __importDefault(require("./attachment_manager"));
const step_runner_1 = __importDefault(require("./step_runner"));
const messages = __importStar(require("@cucumber/messages"));
const messages_1 = require("@cucumber/messages");
const value_checker_1 = require("../value_checker");
const step_runner_1 = __importDefault(require("./step_runner"));
const attachment_manager_1 = __importDefault(require("./attachment_manager"));
const helpers_1 = require("./helpers");
class TestCaseRunner {
constructor({ eventBroadcaster, stopwatch, gherkinDocument, newId, pickle, testCase, retries = 0, skip, supportCodeLibrary, worldParameters, }) {
this.attachmentManager = new attachment_manager_1.default(({ data, media }) => {
attachmentManager;
currentTestCaseStartedId;
currentTestStepId;
eventBroadcaster;
stopwatch;
gherkinDocument;
newId;
pickle;
testCase;
maxAttempts;
skip;
filterStackTraces;
supportCodeLibrary;
testStepResults;
world;
worldParameters;
constructor({ eventBroadcaster, stopwatch, gherkinDocument, newId, pickle, testCase, retries = 0, skip, filterStackTraces, supportCodeLibrary, worldParameters, }) {
this.attachmentManager = new attachment_manager_1.default(({ data, media, fileName }) => {
if ((0, value_checker_1.doesNotHaveValue)(this.currentTestStepId)) {

@@ -47,2 +63,3 @@ throw new Error('Cannot attach when a step/hook is not running. Ensure your step/hook waits for the attach to finish.');

mediaType: media.contentType,
fileName,
testCaseStartedId: this.currentTestCaseStartedId,

@@ -62,2 +79,3 @@ testStepId: this.currentTestStepId,

this.skip = skip;
this.filterStackTraces = filterStackTraces;
this.supportCodeLibrary = supportCodeLibrary;

@@ -71,3 +89,3 @@ this.worldParameters = worldParameters;

log: this.attachmentManager.log.bind(this.attachmentManager),
parameters: this.worldParameters,
parameters: structuredClone(this.worldParameters),
});

@@ -99,2 +117,3 @@ this.testStepResults = [];

defaultTimeout: this.supportCodeLibrary.defaultTimeout,
filterStackTraces: this.filterStackTraces,
hookParameter,

@@ -138,48 +157,3 @@ step,

const moreAttemptsRemaining = attempt + 1 < this.maxAttempts;
this.currentTestCaseStartedId = this.newId();
const testCaseStarted = {
testCaseStarted: {
attempt,
testCaseId: this.testCase.id,
id: this.currentTestCaseStartedId,
timestamp: this.stopwatch.timestamp(),
},
};
this.eventBroadcaster.emit('envelope', testCaseStarted);
// used to determine whether a hook is a Before or After
let didWeRunStepsYet = false;
for (const testStep of this.testCase.testSteps) {
await this.aroundTestStep(testStep.id, async () => {
if ((0, value_checker_1.doesHaveValue)(testStep.hookId)) {
const hookParameter = {
gherkinDocument: this.gherkinDocument,
pickle: this.pickle,
testCaseStartedId: this.currentTestCaseStartedId,
};
if (didWeRunStepsYet) {
hookParameter.result = this.getWorstStepResult();
hookParameter.willBeRetried =
this.getWorstStepResult().status ===
messages.TestStepResultStatus.FAILED && moreAttemptsRemaining;
}
return await this.runHook(findHookDefinition(testStep.hookId, this.supportCodeLibrary), hookParameter, !didWeRunStepsYet);
}
else {
const pickleStep = this.pickle.steps.find((pickleStep) => pickleStep.id === testStep.pickleStepId);
const testStepResult = await this.runStep(pickleStep, testStep);
didWeRunStepsYet = true;
return testStepResult;
}
});
}
const willBeRetried = this.getWorstStepResult().status ===
messages.TestStepResultStatus.FAILED && moreAttemptsRemaining;
const testCaseFinished = {
testCaseFinished: {
testCaseStartedId: this.currentTestCaseStartedId,
timestamp: this.stopwatch.timestamp(),
willBeRetried,
},
};
this.eventBroadcaster.emit('envelope', testCaseFinished);
const willBeRetried = await this.runAttempt(attempt, moreAttemptsRemaining);
if (!willBeRetried) {

@@ -192,2 +166,51 @@ break;

}
async runAttempt(attempt, moreAttemptsRemaining) {
this.currentTestCaseStartedId = this.newId();
const testCaseStarted = {
testCaseStarted: {
attempt,
testCaseId: this.testCase.id,
id: this.currentTestCaseStartedId,
timestamp: this.stopwatch.timestamp(),
},
};
this.eventBroadcaster.emit('envelope', testCaseStarted);
// used to determine whether a hook is a Before or After
let didWeRunStepsYet = false;
for (const testStep of this.testCase.testSteps) {
await this.aroundTestStep(testStep.id, async () => {
if ((0, value_checker_1.doesHaveValue)(testStep.hookId)) {
const hookParameter = {
gherkinDocument: this.gherkinDocument,
pickle: this.pickle,
testCaseStartedId: this.currentTestCaseStartedId,
};
if (didWeRunStepsYet) {
hookParameter.result = this.getWorstStepResult();
hookParameter.willBeRetried =
this.getWorstStepResult().status ===
messages.TestStepResultStatus.FAILED && moreAttemptsRemaining;
}
return await this.runHook(findHookDefinition(testStep.hookId, this.supportCodeLibrary), hookParameter, !didWeRunStepsYet);
}
else {
const pickleStep = this.pickle.steps.find((pickleStep) => pickleStep.id === testStep.pickleStepId);
const testStepResult = await this.runStep(pickleStep, testStep);
didWeRunStepsYet = true;
return testStepResult;
}
});
}
const willBeRetried = this.getWorstStepResult().status ===
messages.TestStepResultStatus.FAILED && moreAttemptsRemaining;
const testCaseFinished = {
testCaseFinished: {
testCaseStartedId: this.currentTestCaseStartedId,
timestamp: this.stopwatch.timestamp(),
willBeRetried,
},
};
this.eventBroadcaster.emit('envelope', testCaseFinished);
return willBeRetried;
}
async runHook(hookDefinition, hookParameter, isBeforeHook) {

@@ -194,0 +217,0 @@ if (this.shouldSkipHook(isBeforeHook)) {

@@ -7,3 +7,3 @@ "use strict";

exports.parseStepArgument = void 0;
const util_1 = __importDefault(require("util"));
const node_util_1 = __importDefault(require("node:util"));
const value_checker_1 = require("./value_checker");

@@ -17,5 +17,5 @@ function parseStepArgument(arg, mapping) {

}
throw new Error(`Unknown step argument: ${util_1.default.inspect(arg)}`);
throw new Error(`Unknown step argument: ${node_util_1.default.inspect(arg)}`);
}
exports.parseStepArgument = parseStepArgument;
//# sourceMappingURL=step_arguments.js.map

@@ -1,3 +0,3 @@

import { isFileNameInCucumber } from '../stack_trace_filter';
import { isFileNameInCucumber } from '../filter_stack_trace';
import { ILineAndUri } from '../types';
export declare function getDefinitionLineAndUri(cwd: string, isExcluded?: typeof isFileNameInCucumber): ILineAndUri;

@@ -7,12 +7,11 @@ "use strict";

exports.getDefinitionLineAndUri = void 0;
const path_1 = __importDefault(require("path"));
const source_map_support_1 = require("@cspotcode/source-map-support");
const stack_chain_1 = __importDefault(require("stack-chain"));
const stack_trace_filter_1 = require("../stack_trace_filter");
const node_path_1 = __importDefault(require("node:path"));
const error_stack_parser_1 = __importDefault(require("error-stack-parser"));
const filter_stack_trace_1 = require("../filter_stack_trace");
const value_checker_1 = require("../value_checker");
function getDefinitionLineAndUri(cwd, isExcluded = stack_trace_filter_1.isFileNameInCucumber) {
function getDefinitionLineAndUri(cwd, isExcluded = filter_stack_trace_1.isFileNameInCucumber) {
let line;
let uri;
const stackframes = stack_chain_1.default.callSite().map(source_map_support_1.wrapCallSite);
const stackframe = stackframes.find((frame) => frame.getFileName() !== __filename && !isExcluded(frame.getFileName()));
const stackframes = error_stack_parser_1.default.parse(new Error());
const stackframe = stackframes.find((frame) => frame.fileName !== __filename && !isExcluded(frame.fileName));
if (stackframe != null) {

@@ -22,3 +21,3 @@ line = stackframe.getLineNumber();

if ((0, value_checker_1.doesHaveValue)(uri)) {
uri = path_1.default.relative(cwd, uri);
uri = node_path_1.default.relative(cwd, uri);
}

@@ -25,0 +24,0 @@ }

@@ -7,5 +7,5 @@ import { IdGenerator } from '@cucumber/messages';

import StepDefinition from '../models/step_definition';
import { IDefineSupportCodeMethods, IDefineTestCaseHookOptions, IDefineTestStepHookOptions, IDefineTestRunHookOptions, IParameterTypeDefinition, ISupportCodeLibrary, TestCaseHookFunction, TestStepHookFunction, ISupportCodeCoordinates, IDefineStep } from './types';
import { ICanonicalSupportCodeIds } from '../runtime/parallel/command_types';
import { GherkinStepKeyword } from '../models/gherkin_step_keyword';
import { IDefineSupportCodeMethods, IDefineTestCaseHookOptions, IDefineTestStepHookOptions, IDefineTestRunHookOptions, IParameterTypeDefinition, SupportCodeLibrary, TestCaseHookFunction, TestStepHookFunction, ISupportCodeCoordinates, IDefineStep } from './types';
interface IStepDefinitionConfig {

@@ -37,3 +37,2 @@ code: any;

}
export declare const builtinParameterTypes: string[];
export declare class SupportCodeLibraryBuilder {

@@ -73,3 +72,3 @@ readonly methods: IDefineSupportCodeMethods;

};
finalize(canonicalIds?: ICanonicalSupportCodeIds): ISupportCodeLibrary;
finalize(canonicalIds?: ICanonicalSupportCodeIds): SupportCodeLibrary;
reset(cwd: string, newId: IdGenerator.NewId, originalCoordinates?: ISupportCodeCoordinates): void;

@@ -76,0 +75,0 @@ }

@@ -6,5 +6,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.SupportCodeLibraryBuilder = exports.builtinParameterTypes = void 0;
const build_parameter_type_1 = require("./build_parameter_type");
const get_definition_line_and_uri_1 = require("./get_definition_line_and_uri");
exports.SupportCodeLibraryBuilder = void 0;
const util_arity_1 = __importDefault(require("util-arity"));
const cucumber_expressions_1 = require("@cucumber/cucumber-expressions");
const test_case_hook_definition_1 = __importDefault(require("../models/test_case_hook_definition"));

@@ -15,21 +15,25 @@ const test_step_hook_definition_1 = __importDefault(require("../models/test_step_hook_definition"));

const helpers_1 = require("../formatter/helpers");
const value_checker_1 = require("../value_checker");
const validate_arguments_1 = __importDefault(require("./validate_arguments"));
const util_arity_1 = __importDefault(require("util-arity"));
const cucumber_expressions_1 = require("@cucumber/cucumber-expressions");
const value_checker_1 = require("../value_checker");
const world_1 = __importDefault(require("./world"));
exports.builtinParameterTypes = [
'bigdecimal',
'biginteger',
'byte',
'double',
'float',
'int',
'long',
'short',
'string',
'word',
'',
];
const get_definition_line_and_uri_1 = require("./get_definition_line_and_uri");
const build_parameter_type_1 = require("./build_parameter_type");
const sourced_parameter_type_registry_1 = require("./sourced_parameter_type_registry");
class SupportCodeLibraryBuilder {
methods;
originalCoordinates;
afterTestCaseHookDefinitionConfigs;
afterTestRunHookDefinitionConfigs;
afterTestStepHookDefinitionConfigs;
beforeTestCaseHookDefinitionConfigs;
beforeTestRunHookDefinitionConfigs;
beforeTestStepHookDefinitionConfigs;
cwd;
defaultTimeout;
definitionFunctionWrapper;
newId;
parameterTypeRegistry;
stepDefinitionConfigs;
World;
parallelCanAssign;
constructor() {

@@ -85,3 +89,4 @@ const methods = {

const parameterType = (0, build_parameter_type_1.buildParameterType)(options);
this.parameterTypeRegistry.defineParameterType(parameterType);
const source = (0, get_definition_line_and_uri_1.getDefinitionLineAndUri)(this.cwd);
this.parameterTypeRegistry.defineSourcedParameterType(parameterType, source);
}

@@ -277,9 +282,9 @@ defineStep(keyword, getCollection) {

finalize(canonicalIds) {
const stepDefinitionsResult = this.buildStepDefinitions(canonicalIds === null || canonicalIds === void 0 ? void 0 : canonicalIds.stepDefinitionIds);
const stepDefinitionsResult = this.buildStepDefinitions(canonicalIds?.stepDefinitionIds);
return {
originalCoordinates: this.originalCoordinates,
afterTestCaseHookDefinitions: this.buildTestCaseHookDefinitions(this.afterTestCaseHookDefinitionConfigs, canonicalIds === null || canonicalIds === void 0 ? void 0 : canonicalIds.afterTestCaseHookDefinitionIds),
afterTestCaseHookDefinitions: this.buildTestCaseHookDefinitions(this.afterTestCaseHookDefinitionConfigs, canonicalIds?.afterTestCaseHookDefinitionIds),
afterTestRunHookDefinitions: this.buildTestRunHookDefinitions(this.afterTestRunHookDefinitionConfigs),
afterTestStepHookDefinitions: this.buildTestStepHookDefinitions(this.afterTestStepHookDefinitionConfigs),
beforeTestCaseHookDefinitions: this.buildTestCaseHookDefinitions(this.beforeTestCaseHookDefinitionConfigs, canonicalIds === null || canonicalIds === void 0 ? void 0 : canonicalIds.beforeTestCaseHookDefinitionIds),
beforeTestCaseHookDefinitions: this.buildTestCaseHookDefinitions(this.beforeTestCaseHookDefinitionConfigs, canonicalIds?.beforeTestCaseHookDefinitionIds),
beforeTestRunHookDefinitions: this.buildTestRunHookDefinitions(this.beforeTestRunHookDefinitionConfigs),

@@ -311,3 +316,3 @@ beforeTestStepHookDefinitions: this.buildTestStepHookDefinitions(this.beforeTestStepHookDefinitionConfigs),

this.defaultTimeout = 5000;
this.parameterTypeRegistry = new cucumber_expressions_1.ParameterTypeRegistry();
this.parameterTypeRegistry = new sourced_parameter_type_registry_1.SourcedParameterTypeRegistry();
this.stepDefinitionConfigs = [];

@@ -314,0 +319,0 @@ this.parallelCanAssign = () => true;

import * as messages from '@cucumber/messages';
import { JsonObject } from 'type-fest';
import TestCaseHookDefinition from '../models/test_case_hook_definition';

@@ -6,6 +7,6 @@ import TestStepHookDefinition from '../models/test_step_hook_definition';

import StepDefinition from '../models/step_definition';
import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions';
import { IWorld } from './world';
export declare type DefineStepPattern = string | RegExp;
export declare type ParallelAssignmentValidator = (pickle: messages.Pickle, runningPickles: messages.Pickle[]) => boolean;
import { SourcedParameterTypeRegistry } from './sourced_parameter_type_registry';
export type DefineStepPattern = string | RegExp;
export type ParallelAssignmentValidator = (pickle: messages.Pickle, runningPickles: messages.Pickle[]) => boolean;
export interface ITestCaseHookParameter {

@@ -26,5 +27,8 @@ gherkinDocument: messages.GherkinDocument;

}
export declare type TestCaseHookFunction<WorldType> = (this: WorldType, arg: ITestCaseHookParameter) => any | Promise<any>;
export declare type TestStepHookFunction<WorldType> = (this: WorldType, arg: ITestStepHookParameter) => any | Promise<any>;
export declare type TestStepFunction<WorldType> = (this: WorldType, ...args: any[]) => any | Promise<any>;
export type TestRunHookFunction = (this: {
parameters: JsonObject;
}) => any | Promise<any>;
export type TestCaseHookFunction<WorldType> = (this: WorldType, arg: ITestCaseHookParameter) => any | Promise<any>;
export type TestStepHookFunction<WorldType> = (this: WorldType, arg: ITestStepHookParameter) => any | Promise<any>;
export type TestStepFunction<WorldType> = (this: WorldType, ...args: any[]) => any | Promise<any>;
export interface IDefineStepOptions {

@@ -53,3 +57,3 @@ timeout?: number;

}
export declare type IDefineStep = (<WorldType = IWorld>(pattern: DefineStepPattern, code: TestStepFunction<WorldType>) => void) & (<WorldType = IWorld>(pattern: DefineStepPattern, options: IDefineStepOptions, code: TestStepFunction<WorldType>) => void);
export type IDefineStep = (<WorldType = IWorld>(pattern: DefineStepPattern, code: TestStepFunction<WorldType>) => void) & (<WorldType = IWorld>(pattern: DefineStepPattern, options: IDefineStepOptions, code: TestStepFunction<WorldType>) => void);
export interface IDefineSupportCodeMethods {

@@ -64,6 +68,6 @@ defineParameterType: (options: IParameterTypeDefinition<any>) => void;

AfterStep: (<WorldType = IWorld>(code: TestStepHookFunction<WorldType>) => void) & (<WorldType = IWorld>(tags: string, code: TestStepHookFunction<WorldType>) => void) & (<WorldType = IWorld>(options: IDefineTestStepHookOptions, code: TestStepHookFunction<WorldType>) => void);
AfterAll: ((code: Function) => void) & ((options: IDefineTestRunHookOptions, code: Function) => void);
AfterAll: ((code: TestRunHookFunction) => void) & ((options: IDefineTestRunHookOptions, code: TestRunHookFunction) => void);
Before: (<WorldType = IWorld>(code: TestCaseHookFunction<WorldType>) => void) & (<WorldType = IWorld>(tags: string, code: TestCaseHookFunction<WorldType>) => void) & (<WorldType = IWorld>(options: IDefineTestCaseHookOptions, code: TestCaseHookFunction<WorldType>) => void);
BeforeStep: (<WorldType = IWorld>(code: TestStepHookFunction<WorldType>) => void) & (<WorldType = IWorld>(tags: string, code: TestStepHookFunction<WorldType>) => void) & (<WorldType = IWorld>(options: IDefineTestStepHookOptions, code: TestStepHookFunction<WorldType>) => void);
BeforeAll: ((code: Function) => void) & ((options: IDefineTestRunHookOptions, code: Function) => void);
BeforeAll: ((code: TestRunHookFunction) => void) & ((options: IDefineTestRunHookOptions, code: TestRunHookFunction) => void);
Given: IDefineStep;

@@ -78,3 +82,3 @@ Then: IDefineStep;

}
export interface ISupportCodeLibrary {
export interface SupportCodeLibrary {
readonly originalCoordinates: ISupportCodeCoordinates;

@@ -90,5 +94,5 @@ readonly afterTestCaseHookDefinitions: TestCaseHookDefinition[];

readonly undefinedParameterTypes: messages.UndefinedParameterType[];
readonly parameterTypeRegistry: ParameterTypeRegistry;
readonly parameterTypeRegistry: SourcedParameterTypeRegistry;
readonly World: any;
readonly parallelCanAssign: ParallelAssignmentValidator;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class World {
attach;
log;
parameters;
constructor({ attach, log, parameters }) {

@@ -5,0 +8,0 @@ this.attach = attach;

/// <reference types="node" />
/// <reference types="node" />
import { performance } from 'perf_hooks';
import { performance } from 'node:perf_hooks';
import * as messages from '@cucumber/messages';

@@ -15,9 +15,5 @@ interface ProtectedTimingBuiltins {

}
interface CustomTimingFunctions {
beginTiming: () => void;
endTiming: () => number;
}
declare const methods: Partial<ProtectedTimingBuiltins & CustomTimingFunctions>;
declare const methods: Partial<ProtectedTimingBuiltins>;
export declare function durationBetweenTimestamps(startedTimestamp: messages.Timestamp, finishedTimestamp: messages.Timestamp): messages.Duration;
export declare function wrapPromiseWithTimeout<T>(promise: Promise<T>, timeoutInMilliseconds: number, timeoutMessage?: string): Promise<T>;
export default methods;

@@ -27,18 +27,11 @@ "use strict";

exports.wrapPromiseWithTimeout = exports.durationBetweenTimestamps = void 0;
const perf_hooks_1 = require("perf_hooks");
const node_perf_hooks_1 = require("node:perf_hooks");
const messages = __importStar(require("@cucumber/messages"));
let previousTimestamp;
const methods = {
beginTiming() {
previousTimestamp = getTimestamp();
},
clearInterval: clearInterval.bind(global),
clearTimeout: clearTimeout.bind(global),
Date,
endTiming() {
return getTimestamp() - previousTimestamp;
},
setInterval: setInterval.bind(global),
setTimeout: setTimeout.bind(global),
performance: perf_hooks_1.performance,
performance: node_perf_hooks_1.performance,
};

@@ -49,5 +42,2 @@ if (typeof setImmediate !== 'undefined') {

}
function getTimestamp() {
return methods.performance.now();
}
function durationBetweenTimestamps(startedTimestamp, finishedTimestamp) {

@@ -54,0 +44,0 @@ const durationMillis = messages.TimeConversion.timestampToMillisecondsSinceEpoch(finishedTimestamp) -

@@ -6,5 +6,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const node_util_1 = __importDefault(require("node:util"));
const time_1 = require("./time");
const uncaught_exception_manager_1 = __importDefault(require("./uncaught_exception_manager"));
const util_1 = __importDefault(require("util"));
const value_checker_1 = require("./value_checker");

@@ -28,3 +28,3 @@ const UserCodeRunner = {

catch (e) {
const error = e instanceof Error ? e : util_1.default.format(e);
const error = e instanceof Error ? e : node_util_1.default.format(e);
return { error };

@@ -73,3 +73,3 @@ }

else if ((0, value_checker_1.doesHaveValue)(e)) {
error = util_1.default.format(e);
error = node_util_1.default.format(e);
}

@@ -76,0 +76,0 @@ else {

@@ -1,1 +0,1 @@

export declare const version = "8.7.0";
export declare const version = "10.2.1";

@@ -5,3 +5,3 @@ "use strict";

// Generated by genversion.
exports.version = '8.7.0';
exports.version = '10.2.1';
//# sourceMappingURL=version.js.map

@@ -11,3 +11,3 @@ {

],
"version": "8.7.0",
"version": "10.2.1",
"homepage": "https://github.com/cucumber/cucumber-js",

@@ -28,2 +28,3 @@ "author": "Julien Biezemans <jb@jbpros.com>",

"Aslak Hellesøy <aslak.hellesoy@gmail.com>",
"Auke van Leeuwen (https://github.com/aukevanleeuwen)",
"Aurélien Reeves <aurelien.reeves@smartbear.com>",

@@ -51,2 +52,3 @@ "basemmerink <bas.emmerink@gmail.com>",

"Dmytro Shpakovskyi <Marketionist@users.noreply.github.com>",
"Douglas Eggleton (https://github.com/douglaseggleton)",
"Eddie Loeffen <eddieloeffen@gmail.com>",

@@ -70,3 +72,5 @@ "efokschaner <eddyaod@gmail.com>",

"Jan-Eric Duden <jeduden@gmail.com>",
"Jaryk (https://github.com/Ugzuzg)",
"Jayson Smith <github@nes.33mail.com>",
"Jeff Tian (https://github.com/Jeff-Tian)",
"Jesse Harlin <harlinjesse@gmail.com>",

@@ -89,2 +93,3 @@ "João Guilherme Farias Duda <jgfd@cin.ufpe.br>",

"Julien Biezemans <jb@jbpros.com>",
"Julien Gonzalez (https://github.com/customcommander)",
"Karine Pires <karine.pires@alterway.fr>",

@@ -96,2 +101,3 @@ "Kārlis Amoliņš <karlis.amolins.5@gmail.com>",

"Kim, Jang-hwan <janghwan@gmail.com>",
"Konstantin Epishev <konstantin@epishev.me>",
"kostya.misura <kostya.misura@gmail.com>",

@@ -102,2 +108,3 @@ "Krispin Schulz <krispin.schulz@blackbridge.com>",

"Leonardo <mondloslp@gmail.com>",
"Long Nguyen (https://github.com/zcmgyu)",
"lopesc <lopesc@users.noreply.github.com>",

@@ -119,7 +126,10 @@ "Lucas Cimon <lucas.cimon@gmail.com>",

"Mateusz Derks <mateusz.derks@schibsted.pl>",
"Matt Travi (https://github.com/travi)",
"Matteo Collina <matteo.collina@gmail.com>",
"Maxim Koretskiy <mr.green.tv@gmail.com>",
"mgonnet <gonnet.matias@gmail.com>",
"Michael Lloyd Morris (https://github.com/michael-lloyd-morris)",
"Michael Zedeler <michael@zedeler.dk>",
"Miika Hänninen <miika.hanninen@gmail.com>",
"Mona Ghassemi (https://github.com/BlueMona)",
"nebehr <thorgeir@tut.by>",

@@ -130,2 +140,3 @@ "Nico Jansen <jansennico@gmail.com>",

"Noah Davis <noahd1@yahoo.com>",
"Oliver Odo (https://github.com/olivierodo)",
"Oliver Rogers <oli.rogers@gmail.com>",

@@ -140,6 +151,8 @@ "Olivier Melcher <olivier.melcher@gmail.com>",

"Renier Morales <renier@morales-rodriguez.net>",
"Ricardo Albuquerque (https://github.com/ricalbuquerque)",
"Rick Lee-Morlang <rick@lee-morlang.com>",
"RolandArgos <roland.ormrod@argos.co.uk>",
"Ronald Chen (https://github.com/Pyrolistical)",
"Sam Saccone <sam@samx.it>",
"Scott Deakin <scott.deakin@kantar.com>",
"Scott Deakin (https://github.com/GeekyDeaks)",
"seantdg <sm.davis@gmx.com>",

@@ -202,18 +215,17 @@ "Seb Rose <seb@claysnow.co.uk>",

"engines": {
"node": "12 || 14 || >=16"
"node": "18 || >=20"
},
"enginesTested": {
"node": "12 || 14 || 16 || 17 || 18"
"node": "18 || 20 || 21"
},
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@cucumber/ci-environment": "9.1.0",
"@cucumber/cucumber-expressions": "16.0.0",
"@cucumber/gherkin": "24.0.0",
"@cucumber/ci-environment": "10.0.0",
"@cucumber/cucumber-expressions": "17.0.1",
"@cucumber/gherkin": "27.0.0",
"@cucumber/gherkin-streams": "5.0.1",
"@cucumber/gherkin-utils": "8.0.0",
"@cucumber/html-formatter": "20.1.0",
"@cucumber/gherkin-utils": "8.0.5",
"@cucumber/html-formatter": "21.2.0",
"@cucumber/message-streams": "4.0.1",
"@cucumber/messages": "19.1.4",
"@cucumber/tag-expressions": "4.1.0",
"@cucumber/messages": "24.0.1",
"@cucumber/tag-expressions": "6.0.0",
"assertion-error-formatter": "^3.0.0",

@@ -223,8 +235,7 @@ "capital-case": "^1.0.4",

"cli-table3": "0.6.3",
"commander": "^9.0.0",
"commander": "^10.0.0",
"debug": "^4.3.4",
"duration": "^0.2.2",
"durations": "^3.4.2",
"error-stack-parser": "^2.1.4",
"figures": "^3.2.0",
"glob": "^7.1.6",
"glob": "^10.3.10",
"has-ansi": "^4.0.1",

@@ -237,70 +248,76 @@ "indent-string": "^4.0.0",

"lodash.mergewith": "^4.6.2",
"luxon": "3.2.1",
"mkdirp": "^2.1.5",
"mz": "^2.7.0",
"progress": "^2.0.3",
"read-pkg-up": "^7.0.1",
"resolve-pkg": "^2.0.0",
"semver": "7.3.7",
"stack-chain": "^2.0.0",
"string-argv": "^0.3.1",
"semver": "7.5.3",
"string-argv": "0.3.1",
"strip-ansi": "6.0.1",
"supports-color": "^8.1.1",
"tmp": "^0.2.1",
"type-fest": "^4.8.3",
"util-arity": "^1.1.0",
"verror": "^1.10.0",
"yup": "^0.32.11"
"xmlbuilder": "^15.1.1",
"yaml": "^2.2.2",
"yup": "1.2.0"
},
"devDependencies": {
"@cucumber/compatibility-kit": "11.0.1",
"@cucumber/query": "12.0.0",
"@microsoft/api-documenter": "7.19.1",
"@microsoft/api-extractor": "7.32.0",
"@sinonjs/fake-timers": "9.1.2",
"@types/chai": "4.3.3",
"@cucumber/compatibility-kit": "14.1.0",
"@cucumber/query": "12.0.1",
"@microsoft/api-extractor": "7.39.0",
"@sinonjs/fake-timers": "10.0.2",
"@types/chai": "4.3.4",
"@types/chai-xml": "^0.3.2",
"@types/debug": "4.1.7",
"@types/dirty-chai": "2.0.2",
"@types/express": "4.17.13",
"@types/express": "4.17.15",
"@types/fs-extra": "9.0.13",
"@types/glob": "7.2.0",
"@types/glob": "8.1.0",
"@types/has-ansi": "5.0.0",
"@types/lodash.merge": "4.6.7",
"@types/lodash.mergewith": "4.6.7",
"@types/mocha": "10.0.0",
"@types/mustache": "4.2.1",
"@types/luxon": "3.2.0",
"@types/mocha": "10.0.1",
"@types/mustache": "4.2.2",
"@types/mz": "2.7.4",
"@types/node": "16.11.62",
"@types/node": "20.8.3",
"@types/progress": "2.0.5",
"@types/semver": "7.3.12",
"@types/sinon-chai": "3.2.8",
"@types/semver": "7.5.0",
"@types/sinon-chai": "3.2.9",
"@types/sinonjs__fake-timers": "8.1.2",
"@types/stream-buffers": "3.0.4",
"@types/tmp": "0.2.3",
"@types/verror": "1.10.6",
"@typescript-eslint/eslint-plugin": "5.38.1",
"@typescript-eslint/parser": "5.38.1",
"chai": "4.3.6",
"@typescript-eslint/eslint-plugin": "6.7.4",
"@typescript-eslint/parser": "6.7.4",
"chai": "4.3.7",
"chai-exclude": "2.1.0",
"chai-xml": "^0.4.1",
"coffeescript": "2.7.0",
"dependency-lint": "7.1.0",
"dirty-chai": "2.0.1",
"eslint": "8.24.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-import": "2.26.0",
"eslint": "8.51.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-standard": "4.1.0",
"express": "4.18.1",
"eslint-plugin-standard": "5.0.0",
"eslint-plugin-unicorn": "^48.0.1",
"express": "4.18.2",
"fs-extra": "10.1.0",
"genversion": "3.1.1",
"mocha": "10.0.0",
"mocha": "10.2.0",
"mustache": "4.2.0",
"nyc": "15.1.0",
"prettier": "2.7.1",
"prettier": "3.0.3",
"reindent-template-literals": "1.1.0",
"shx": "0.3.4",
"sinon": "14.0.0",
"sinon": "15.0.1",
"sinon-chai": "3.7.0",
"stream-buffers": "3.0.2",
"stream-to-string": "1.2.0",
"ts-node": "10.9.1",
"tsd": "0.24.1",
"typescript": "4.8.4"
"tsd": "0.25.0",
"typedoc": "^0.25.4",
"typedoc-plugin-extras": "^3.0.0",
"typescript": "4.9.4"
},

@@ -311,11 +328,17 @@ "overrides": {

"scripts": {
"build-local": "genversion --es6 src/version.ts && tsc --build tsconfig.node.json && shx cp src/importer.js lib/ && shx cp src/wrapper.mjs lib/ && shx cp src/api/wrapper.mjs lib/api/",
"build-local": "genversion --es6 src/version.ts && tsc --build tsconfig.node.json && shx cp src/wrapper.mjs lib/ && shx cp src/api/wrapper.mjs lib/api/",
"cck-test": "mocha 'compatibility/**/*_spec.ts'",
"docs:ci": "api-extractor run --verbose",
"docs:local": "api-extractor run --verbose --local && api-documenter markdown --input-folder ./tmp/api-extractor --output-folder ./docs/api",
"exports-generate-docs": "typedoc",
"exports-test": "api-extractor run --config exports/api/api-extractor.json --verbose && api-extractor run --config exports/root/api-extractor.json --verbose",
"exports-update": "api-extractor run --config exports/api/api-extractor.json --verbose --local && api-extractor run --config exports/root/api-extractor.json --verbose --local",
"feature-test": "node bin/cucumber.js",
"lint-autofix": "eslint --fix \"{compatibility,example,features,scripts,src,test}/**/*.ts\"",
"lint-code-autofix": "eslint --fix \"{compatibility,example,features,scripts,src,test}/**/*.ts\"",
"lint-code": "eslint \"{compatibility,example,features,scripts,src,test}/**/*.ts\"",
"lint-dependencies": "dependency-lint",
"lint": "npm run lint-code && npm run lint-dependencies",
"lint-format-autofix": "prettier --write .",
"lint-format": "prettier --check .",
"lint": "npm run lint-code && npm run lint-format && npm run lint-dependencies",
"preexports-generate-docs": "npm run build-local",
"preexports-test": "npm run build-local",
"preexports-update": "npm run build-local",
"prelint-autofix": "npm run build-local",

@@ -328,4 +351,4 @@ "prelint-code": "npm run build-local",

"pretypes-test": "npm run build-local",
"test-coverage": "nyc --silent mocha 'src/**/*_spec.ts' 'compatibility/**/*_spec.ts' && nyc --silent --no-clean node bin/cucumber.js && nyc report --reporter=lcov",
"test": "npm run lint && npm run types-test && npm run unit-test && npm run cck-test && npm run feature-test",
"test-coverage": "nyc --silent mocha 'src/**/*_spec.ts' 'compatibility/**/*_spec.ts' && nyc --silent --no-clean node bin/cucumber.js --tags \"not @source-mapping\" && nyc report --reporter=lcov",
"test": "npm run lint && npm run exports-test && npm run types-test && npm run unit-test && npm run cck-test && npm run feature-test",
"types-test": "tsd",

@@ -332,0 +355,0 @@ "unit-test": "mocha 'src/**/*_spec.ts'",

@@ -12,10 +12,8 @@ <h1 align="center">

[![npm](https://img.shields.io/npm/v/@cucumber/cucumber.svg)](https://www.npmjs.com/package/@cucumber/cucumber)
[![build](https://github.com/cucumber/cucumber-js/workflows/Build/badge.svg)](https://github.com/cucumber/cucumber-js/actions)
[![coverage](https://coveralls.io/repos/github/cucumber/cucumber-js/badge.svg?branch=master)](https://coveralls.io/github/cucumber/cucumber-js?branch=master)
[![build](https://github.com/cucumber/cucumber-js/actions/workflows/build.yaml/badge.svg)](https://github.com/cucumber/cucumber-js/actions)
[![coverage](https://coveralls.io/repos/github/cucumber/cucumber-js/badge.svg?branch=main)](https://coveralls.io/github/cucumber/cucumber-js?branch=master)
[![backers](https://opencollective.com/cucumber/backers/badge.svg)](https://opencollective.com/cucumber)
[![sponsors](https://opencollective.com/cucumber/sponsors/badge.svg)](https://opencollective.com/cucumber)
[![pull requests](https://oselvar.com/api/badge?label=pull%20requests&csvUrl=https%3A%2F%2Fraw.githubusercontent.com%2Fcucumber%2Foselvar-github-metrics%2Fmain%2Fdata%2Fcucumber%2Fcucumber-js%2FpullRequests.csv)](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-js)
[![issues](https://oselvar.com/api/badge?label=issues&csvUrl=https%3A%2F%2Fraw.githubusercontent.com%2Fcucumber%2Foselvar-github-metrics%2Fmain%2Fdata%2Fcucumber%2Fcucumber-js%2Fissues.csv)](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-js)
[Cucumber](https://cucumber.io) is a tool for running automated tests written in plain language. Because they're
[Cucumber](https://github.com/cucumber) is a tool for running automated tests written in plain language. Because they're
written in plain language, they can be read by anyone on your team. Because they can be

@@ -41,2 +39,5 @@ read by anyone, you can use them to help improve communication, collaboration and trust on

First, write your main code in `src/index.js`:
```js

@@ -48,5 +49,9 @@ class Greeter {

}
module.exports = {
Greeter
}
```
First, write your feature in `features/greeting.feature`:
Then, write your feature in `features/greeting.feature`:

@@ -87,3 +92,3 @@ ```gherkin

If you learn best by example, we have [a repo with several example projects](https://github.com/cucumber-examples/cucumber-js-examples), that might help you get going.
If you learn best by example, we have [a repo with several example projects](https://github.com/cucumber/cucumber-js-examples), that might help you get going.

@@ -116,2 +121,3 @@ ## Documentation

* [Retrying flaky scenarios](./docs/retry.md)
* [JavaScript API for running programmatically](./docs/javascript_api.md)
* [Snippets for undefined steps](./docs/snippets.md)

@@ -118,0 +124,0 @@ * [Transpiling (from TypeScript etc)](./docs/transpiling.md)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc