diff --git a/CHANGELOG.md b/CHANGELOG.md index 78e73f8f..8d708e97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## Unreleased + +- Support config file locations other than project root, fixes [#1243](https://github.com/badeball/cypress-cucumber-preprocessor/discussions/1243). + ## v21.0.0 Breaking changes: diff --git a/declarations.d.ts b/declarations.d.ts index e0ee0f65..a2867bf8 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -4,9 +4,14 @@ declare module "find-cypress-specs" { export function getSpecs( config: Cypress.ConfigOptions, type: Cypress.TestingType, + returnAbsolute?: boolean, ): string[]; - export function getSpecs(config: Cypress.PluginConfigOptions): string[]; + export function getSpecs( + config: Cypress.PluginConfigOptions, + type: Cypress.TestingType, + returnAbsolute?: boolean, + ): string[]; export function getConfig(): Cypress.ConfigOptions; } diff --git a/lib/add-cucumber-preprocessor-plugin.ts b/lib/add-cucumber-preprocessor-plugin.ts index 5b7b19b9..7d6da74a 100644 --- a/lib/add-cucumber-preprocessor-plugin.ts +++ b/lib/add-cucumber-preprocessor-plugin.ts @@ -138,46 +138,48 @@ export async function addCucumberPreprocessorPlugin( const node = parse(tags); - const testFiles = getSpecs(config).filter((testFile) => { - if (!testFile.endsWith(".feature")) { - switch (preprocessor.filterSpecsMixedMode) { - case "hide": - return false; - case "show": - return true; - case "empty-set": - return node.evaluate([]); - default: - assertNever(preprocessor.filterSpecsMixedMode); + const testFiles = getSpecs(config, "foobar" as any, true).filter( + (testFile) => { + if (!testFile.endsWith(".feature")) { + switch (preprocessor.filterSpecsMixedMode) { + case "hide": + return false; + case "show": + return true; + case "empty-set": + return node.evaluate([]); + default: + assertNever(preprocessor.filterSpecsMixedMode); + } } - } - - const content = fs.readFileSync(testFile).toString("utf-8"); - - const options = { - includeSource: false, - includeGherkinDocument: false, - includePickles: true, - newId: IdGenerator.incrementing(), - }; - - const envelopes = generateMessages( - content, - testFile, - SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN, - options, - ); - - const pickles = envelopes - .map((envelope) => envelope.pickle) - .filter(notNull); - - return pickles.some((pickle) => - node.evaluate( - pickle.tags?.map((tag) => tag.name).filter(notNull) ?? [], - ), - ); - }); + + const content = fs.readFileSync(testFile).toString("utf-8"); + + const options = { + includeSource: false, + includeGherkinDocument: false, + includePickles: true, + newId: IdGenerator.incrementing(), + }; + + const envelopes = generateMessages( + content, + testFile, + SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN, + options, + ); + + const pickles = envelopes + .map((envelope) => envelope.pickle) + .filter(notNull); + + return pickles.some((pickle) => + node.evaluate( + pickle.tags?.map((tag) => tag.name).filter(notNull) ?? [], + ), + ); + }, + ); debug(`Resolved specs ${inspect(testFiles)}`); diff --git a/lib/step-definitions.ts b/lib/step-definitions.ts index 3e7fc0ba..6d4161e5 100644 --- a/lib/step-definitions.ts +++ b/lib/step-definitions.ts @@ -56,6 +56,16 @@ export function getStepDefinitionPatterns( >, filepath: string, ): string[] { + assert( + path.isAbsolute(configuration.implicitIntegrationFolder), + `Expected an absolute path for implicit integration folder but got ${configuration.implicitIntegrationFolder}`, + ); + + assert( + path.isAbsolute(filepath), + `Expected an absolute path for spec but got ${filepath}`, + ); + const filepathReplacement = glob.escape( trimFeatureExtension( path.relative(configuration.implicitIntegrationFolder, filepath), diff --git a/lib/subpath-entrypoints/esbuild.ts b/lib/subpath-entrypoints/esbuild.ts index 88d2b53a..f7cc6538 100644 --- a/lib/subpath-entrypoints/esbuild.ts +++ b/lib/subpath-entrypoints/esbuild.ts @@ -75,8 +75,6 @@ export function createEsbuildPlugin( if (needPrettify) { debug("esbuild: prettifying sources"); - /** - */ sourceMap.sources = sourceMap.sources.map((source: string) => { return path.relative( configuration.projectRoot, @@ -95,9 +93,17 @@ export function createEsbuildPlugin( "base64", ); + /** + * Why `${"sourceMappingURL"}` you may ask. This is so esbuild doesn't crap itself upon + * errors, where it would search for source maps and find THIS code line, which is not a + * valid source map (obvously). + * + * Without this, esbuild would error with "Unexpected token z in JSON at position 0" every + * time an error occurred during build time. + */ await fs.appendFile( outfile, - `//# sourceMappingURL=data:application/json;base64,${encoded}\n`, + `//# ${"sourceMappingURL"}=data:application/json;base64,${encoded}\n`, ); }); } diff --git a/lib/template.ts b/lib/template.ts index 3dcfe76c..6064d2e4 100644 --- a/lib/template.ts +++ b/lib/template.ts @@ -71,7 +71,11 @@ export async function compile( const pickles = envelopes.map((envelope) => envelope.pickle).filter(notNull); const implicitIntegrationFolder = assertAndReturn( - ancestor(...getSpecs(configuration).map(path.dirname).map(path.normalize)), + ancestor( + ...getSpecs(configuration, "foobar" as any, true) + .map(path.dirname) + .map(path.normalize), + ), "Expected to find a common ancestor path", );