124 lines
3.1 KiB
JavaScript

const glob = require("glob");
const path = require("path");
const fs = require("fs");
const { Parser } = require("gherkin");
const log = require("debug")("cypress:cucumber");
const jsStringEscape = require("js-string-escape");
const { getStepDefinitionsPaths } = require("./getStepDefinitionsPaths");
const { cucumberTemplate } = require("./cucumberTemplate");
const { getCucumberJsonConfig } = require("./getCucumberJsonConfig");
const {
isNonGlobalStepDefinitionsMode,
} = require("./isNonGlobalStepDefinitionsMode");
const createCucumber = (
specs,
globalToRequire,
nonGlobalToRequire,
cucumberJson
) =>
`
${cucumberTemplate}
window.cucumberJson = ${JSON.stringify(cucumberJson)};
var moduleCache = arguments[5];
function clearFromCache(moduleId, instance){
if(isWebpack()){
delete require.cache[moduleId];
} else {
clearFromCacheBrowserify(instance);
}
}
function isWebpack(){
return !!require.cache
}
// Stolen from https://github.com/browserify/browserify/issues/1444
function clearFromCacheBrowserify(instance) {
for(const key in moduleCache)
{
if(moduleCache[key].exports == instance)
{
delete moduleCache[key];
return;
}
}
throw new Error("could not clear instance from browserify module cache");
}
${globalToRequire.join("\n")}
${specs
.map(
({ spec, filePath, name }) => `
describe(\`${name}\`, function() {
window.currentFeatureName = \`${name}\`
${
nonGlobalToRequire &&
nonGlobalToRequire
.find((fileSteps) => fileSteps[filePath])
[filePath].join("\n")
}
createTestsFromFeature('${path.basename(filePath)}', '${jsStringEscape(
spec
)}');
})
`
)
.join("\n")}
`;
// eslint-disable-next-line func-names
module.exports = function (_, filePath = this.resourcePath) {
log("compiling", filePath);
const features = glob.sync(`${path.dirname(filePath)}/**/*.feature`);
let globalStepDefinitionsToRequire = [];
let nonGlobalStepDefinitionsToRequire;
if (isNonGlobalStepDefinitionsMode()) {
nonGlobalStepDefinitionsToRequire = features.map((featurePath) => ({
[featurePath]: getStepDefinitionsPaths(featurePath).map(
(sdPath) =>
`clearFromCache(require.resolve && require.resolve('${sdPath}'), require('${sdPath}'))`
),
}));
} else {
globalStepDefinitionsToRequire = [
...new Set(
features.reduce(
(requires) =>
requires.concat(
getStepDefinitionsPaths(filePath).map(
(sdPath) => `require('${sdPath}')`
)
),
[]
)
),
];
}
const specs = features
.map((featurePath) => ({
spec: fs.readFileSync(featurePath).toString(),
filePath: featurePath,
}))
.map((feature) => ({
...feature,
name: new Parser().parse(feature.spec.toString()).feature.name,
}));
return createCucumber(
specs,
globalStepDefinitionsToRequire,
nonGlobalStepDefinitionsToRequire,
getCucumberJsonConfig()
);
};