Skip to content

Commit

Permalink
revise implementation and add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
tianfeng92 committed Nov 21, 2024
1 parent 195c5c6 commit aa780f4
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 25 deletions.
57 changes: 32 additions & 25 deletions src/cucumber-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { CucumberRunnerConfig } from './types';
import * as utils from './utils';
import { NodeContext } from 'sauce-testrunner-utils/lib/types';

function buildArgs(runCfg: CucumberRunnerConfig, cucumberBin: string) {
export function buildArgs(runCfg: CucumberRunnerConfig, cucumberBin: string) {
const paths: string[] = [];
runCfg.suite.options.paths.forEach((p) => {
paths.push(path.join(runCfg.projectPath, p));
Expand Down Expand Up @@ -50,32 +50,10 @@ function buildArgs(runCfg: CucumberRunnerConfig, cucumberBin: string) {
procArgs.push(tag);
});

function parseNewFormat(format: string, assetsDir: string) {
// Regex to validate and extract key and value from the new format.
// Example: "html":"file://hostname/formatter/report.html"
const match = format.match(/^"([^"]+)":"(.+)"$/);
if (!match) {
return null;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, key, value] = match;
return `"${key}":"${path.join(assetsDir, value)}"`;
}

runCfg.suite.options.format?.forEach((format) => {
const updatedFormat = normalizeFormat(format, runCfg.assetsDir);
procArgs.push('--format');

const newFormat = parseNewFormat(format, runCfg.assetsDir);
if (newFormat) {
return newFormat;
}

const opts = format.split(':');
if (opts.length === 2) {
return `"${opts[0]}":"${path.join(runCfg.assetsDir, opts[1])}"`;
}

return `"${format}"`;
procArgs.push(updatedFormat);
});

if (runCfg.suite.options.parallel) {
Expand All @@ -87,6 +65,35 @@ function buildArgs(runCfg: CucumberRunnerConfig, cucumberBin: string) {
return procArgs;
}

/**
* Normalizes a Cucumber format string by ensuring it is in the form of `"key":"value"`.
*
* @param {string} format - The input format string, which can be in various forms:
* - `"key:value"`
* - `"key":"value"`
* - `key:value`
* @param {string} assetDir - The asset directory.
* @throws {Error} If the input format is invalid (e.g., missing a colon separator).
* @returns {string} The normalized format string in the form of `"key":"value"`,
* with the asset directory prepended to relative paths.
*
* Example:
* Input: `"html:formatter/report.html"`, `"/project/assets"`
* Output: `"html":"/project/assets/formatter/report.html"`
*/
export function normalizeFormat(format: string, assetDir: string): string {
const match = format.match(/^"?([^:]+):"?([^"]+)"?$/);
if (!match) {
throw new Error(`Invalid format: ${format}`);
}

let [, key, value] = match;
key = key.replace(/^"|"$/g, '');
value = value.replace(/^"|"$/g, '');
const updatedPath = path.join(assetDir, value);
return `"${key}":"${updatedPath}"`;
}

export async function runCucumber(
nodeBin: string,
runCfg: CucumberRunnerConfig,
Expand Down
65 changes: 65 additions & 0 deletions tests/unit/src/cucumber-runner.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const { buildArgs, normalizeFormat } = require('../../../src/cucumber-runner');

describe('buildArgs', () => {
const cucumberBin = '/usr/local/bin/cucumber';

it('should build correct arguments with basic configuration', () => {
const runCfg = {
sauce: {
metadata: {},
},
projectPath: '/project',
assetsDir: '/project/assets',
suite: {
options: {
paths: ['features/test.feature'],
},
},
};

const result = buildArgs(runCfg, cucumberBin);

expect(result).toEqual([
cucumberBin,
'/project/features/test.feature',
'--force-exit',
'--require-module',
'ts-node/register',
'--format',
'@saucelabs/cucumber-reporter',
'--format-options',
'{"upload":false,"outputFile":"/project/assets/sauce-test-report.json"}',
]);
});
});

describe('normalizeFormat', () => {
const assetDir = '/project/assets';

it('should normalize formats with both quoted format type and path', () => {
expect(normalizeFormat(`"html":"formatter/report.html"`, assetDir)).toBe(
`"html":"/project/assets/formatter/report.html"`,
);
});

it('should normalize formats with only one pair of quote', () => {
expect(normalizeFormat(`"html:formatter/report.html"`, assetDir)).toBe(
`"html":"/project/assets/formatter/report.html"`,
);
});

it('should normalize formats with no quotes', () => {
expect(normalizeFormat(`html:formatter/report.html`, assetDir)).toBe(
`"html":"/project/assets/formatter/report.html"`,
);
});

it('should throw an error for invalid formats', () => {
expect(() =>
normalizeFormat(`html-formatter/report.html`, assetDir),
).toThrow('Invalid format: html-formatter/report.html');
expect(() =>
normalizeFormat(`"htmlformatter/report.html"`, assetDir),
).toThrow('Invalid format: "htmlformatter/report.html"');
});
});

0 comments on commit aa780f4

Please sign in to comment.