refactor(Cypress): add nodemodules
This commit is contained in:
165
node_modules/cypress-cucumber-preprocessor/lib/cukejson/cucumberDataCollector.js
generated
vendored
Normal file
165
node_modules/cypress-cucumber-preprocessor/lib/cukejson/cucumberDataCollector.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
const { Parser } = require("gherkin");
|
||||
const statuses = require("cucumber/lib/status").default;
|
||||
|
||||
class CucumberDataCollector {
|
||||
constructor(uri, spec) {
|
||||
this.feature = new Parser().parse(spec.toString()).feature;
|
||||
this.scenarioSteps = {};
|
||||
this.runScenarios = {};
|
||||
this.runTests = {};
|
||||
this.stepResults = {};
|
||||
this.testError = null;
|
||||
this.uri = uri;
|
||||
this.spec = spec;
|
||||
|
||||
this.currentScenario = null;
|
||||
this.currentStep = 0;
|
||||
|
||||
this.timer = Date.now();
|
||||
|
||||
this.logStep = (step) => {
|
||||
Cypress.log({
|
||||
name: "step",
|
||||
displayName: step.keyword,
|
||||
message: `**${step.text}**`,
|
||||
consoleProps: () => ({ feature: this.uri, step }),
|
||||
});
|
||||
};
|
||||
|
||||
this.onStartTest = () => {};
|
||||
|
||||
this.onFinishTest = () => {
|
||||
if (this.testError) {
|
||||
this.attachErrorToFailingStep();
|
||||
}
|
||||
};
|
||||
|
||||
this.onStartScenario = (scenario, stepsToRun) => {
|
||||
this.currentScenario = scenario;
|
||||
this.currentStep = 0;
|
||||
this.stepResults = {};
|
||||
this.scenarioSteps[scenario.name] = stepsToRun;
|
||||
this.testError = null;
|
||||
|
||||
stepsToRun.forEach((step) => {
|
||||
this.stepResults[step.index] = { status: statuses.PENDING };
|
||||
});
|
||||
this.runScenarios[scenario.name] = scenario;
|
||||
};
|
||||
|
||||
this.onFinishScenario = (scenario) => {
|
||||
this.markStillPendingStepsAsSkipped(scenario);
|
||||
this.recordScenarioResult(scenario);
|
||||
};
|
||||
|
||||
this.onStartStep = (step) => {
|
||||
this.currentStep = step.index;
|
||||
this.setStepToPending(step);
|
||||
this.logStep(step);
|
||||
};
|
||||
|
||||
this.onFinishStep = (step, result) => {
|
||||
this.recordStepResult(step, result);
|
||||
};
|
||||
|
||||
this.onFail = (err) => {
|
||||
this.testError = err;
|
||||
if (
|
||||
err.message &&
|
||||
err.message.indexOf("Step implementation missing for") > -1
|
||||
) {
|
||||
this.stepResults[this.currentStep] = {
|
||||
status: statuses.UNDEFINED,
|
||||
duration: this.timeTaken(),
|
||||
};
|
||||
} else if (err.constructor.name === "Pending") {
|
||||
// cypress marks skipped mocha tests as pending
|
||||
// https://github.com/cypress-io/cypress/issues/3092
|
||||
// don't record this error and mark the step as skipped
|
||||
this.stepResults[this.currentStep] = {
|
||||
status: statuses.SKIPPED,
|
||||
duration: this.timeTaken(),
|
||||
};
|
||||
} else {
|
||||
this.stepResults[this.currentStep] = {
|
||||
status: statuses.FAILED,
|
||||
duration: this.timeTaken(),
|
||||
exception: this.testError,
|
||||
};
|
||||
}
|
||||
this.onFinishScenario(this.currentScenario);
|
||||
};
|
||||
|
||||
this.timeTaken = () => {
|
||||
const now = Date.now();
|
||||
const duration = now - this.timer;
|
||||
this.timer = now;
|
||||
return duration;
|
||||
};
|
||||
|
||||
this.formatTestCase = (scenario) => {
|
||||
const line = scenario.example
|
||||
? scenario.example.line
|
||||
: scenario.location.line;
|
||||
return {
|
||||
sourceLocation: { uri, line },
|
||||
};
|
||||
};
|
||||
|
||||
this.attachErrorToFailingStep = () => {
|
||||
Object.keys(this.runTests).forEach((test) => {
|
||||
const stepResults = this.runTests[test];
|
||||
Object.keys(stepResults).forEach((stepIdx) => {
|
||||
const stepResult = stepResults[stepIdx];
|
||||
if (stepResult.result === statuses.FAILED) {
|
||||
stepResult.exception = this.testError;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.markStillPendingStepsAsSkipped = (scenario) => {
|
||||
this.runTests[scenario.name] = Object.keys(this.stepResults).map(
|
||||
(key) => {
|
||||
const result = this.stepResults[key];
|
||||
return {
|
||||
...result,
|
||||
status:
|
||||
result.status === statuses.PENDING
|
||||
? statuses.SKIPPED
|
||||
: result.status,
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
this.recordScenarioResult = (scenario) => {
|
||||
const allSkipped = this.areAllStepsSkipped(scenario.name);
|
||||
const anyFailed = this.anyStepsHaveFailed(scenario.name);
|
||||
if (allSkipped) this.runTests[scenario.name].result = statuses.SKIPPED;
|
||||
else
|
||||
this.runTests[scenario.name].result = anyFailed
|
||||
? statuses.FAILED
|
||||
: statuses.PASSED;
|
||||
};
|
||||
|
||||
this.setStepToPending = (step) => {
|
||||
this.stepResults[step.index] = { status: statuses.PENDING };
|
||||
};
|
||||
|
||||
this.recordStepResult = (step, result) => {
|
||||
this.stepResults[step.index] = {
|
||||
status: result,
|
||||
duration: this.timeTaken(),
|
||||
};
|
||||
};
|
||||
|
||||
this.areAllStepsSkipped = (name) =>
|
||||
this.runTests[name].every((e) => e.status === statuses.SKIPPED);
|
||||
|
||||
this.anyStepsHaveFailed = (name) =>
|
||||
this.runTests[name].find((e) => e.status === statuses.FAILED) !==
|
||||
undefined;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { CucumberDataCollector };
|
160
node_modules/cypress-cucumber-preprocessor/lib/cukejson/cucumberDataCollector.test.js
generated
vendored
Normal file
160
node_modules/cypress-cucumber-preprocessor/lib/cukejson/cucumberDataCollector.test.js
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
const fs = require("fs");
|
||||
const statuses = require("cucumber/lib/status").default;
|
||||
const { CucumberDataCollector } = require("./cucumberDataCollector");
|
||||
const { generateCucumberJson } = require("./generateCucumberJson");
|
||||
|
||||
window.cucumberJson = { generate: true };
|
||||
|
||||
const assertCucumberJson = (json, expectedResults) => {
|
||||
expect(json).to.have.length(1);
|
||||
expect(json[0].keyword).to.eql("Feature");
|
||||
expect(json[0].name).to.eql("Being a plugin");
|
||||
expect(json[0].elements).to.have.length(1);
|
||||
expect(json[0].elements[0].keyword).to.eql("Scenario");
|
||||
expect(json[0].elements[0].name).to.eql("Basic example");
|
||||
expect(json[0].elements[0].steps).to.have.length(3);
|
||||
expect(json[0].elements[0].steps[0].keyword).to.equal("Given ");
|
||||
expect(json[0].elements[0].steps[0].name).to.equal(
|
||||
"a feature and a matching step definition file"
|
||||
);
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(json[0].elements[0].steps[0].result).to.be.not.null;
|
||||
expect(json[0].elements[0].steps[0].result.status).to.eql(expectedResults[0]);
|
||||
expect(json[0].elements[0].steps[1].keyword).to.equal("When ");
|
||||
expect(json[0].elements[0].steps[1].name).to.equal("I run cypress tests");
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(json[0].elements[0].steps[1].result).to.be.not.null;
|
||||
expect(json[0].elements[0].steps[1].result.status).to.eql(expectedResults[1]);
|
||||
expect(json[0].elements[0].steps[2].keyword).to.equal("Then ");
|
||||
expect(json[0].elements[0].steps[2].name).to.equal("they run properly");
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
expect(json[0].elements[0].steps[2].result).to.be.not.null;
|
||||
expect(json[0].elements[0].steps[2].result.status).to.eql(expectedResults[2]);
|
||||
};
|
||||
describe("Cucumber Data Collector", () => {
|
||||
const scenario = {
|
||||
type: "Scenario",
|
||||
tags: [],
|
||||
location: { line: 7, column: 3 },
|
||||
keyword: "Scenario",
|
||||
name: "Basic example",
|
||||
steps: [
|
||||
{
|
||||
type: "Step",
|
||||
location: { line: 8, column: 5 },
|
||||
keyword: "Given ",
|
||||
text: "a feature and a matching step definition file",
|
||||
},
|
||||
{
|
||||
type: "Step",
|
||||
location: { line: 9, column: 5 },
|
||||
keyword: "When ",
|
||||
text: "I run cypress tests",
|
||||
},
|
||||
{
|
||||
type: "Step",
|
||||
location: { line: 10, column: 5 },
|
||||
keyword: "Then ",
|
||||
text: "they run properly",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const stepsToRun = [
|
||||
{
|
||||
type: "Step",
|
||||
location: { line: 8, column: 5 },
|
||||
keyword: "Given ",
|
||||
text: "a feature and a matching step definition file",
|
||||
index: 0,
|
||||
},
|
||||
{
|
||||
type: "Step",
|
||||
location: { line: 9, column: 5 },
|
||||
keyword: "When ",
|
||||
text: "I run cypress tests",
|
||||
index: 1,
|
||||
},
|
||||
{
|
||||
type: "Step",
|
||||
location: { line: 10, column: 5 },
|
||||
keyword: "Then ",
|
||||
text: "they run properly",
|
||||
index: 2,
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
const filePath = "./cypress/integration/Plugin.feature";
|
||||
const spec = fs.readFileSync(filePath);
|
||||
this.testState = new CucumberDataCollector(filePath, spec);
|
||||
this.testState.onStartTest();
|
||||
});
|
||||
|
||||
it("runs", () => {
|
||||
this.testState.onFinishTest();
|
||||
const json = generateCucumberJson(this.testState);
|
||||
expect(json).to.have.length(0);
|
||||
});
|
||||
|
||||
it("records pending scenarios", () => {
|
||||
this.testState.onStartScenario(scenario, stepsToRun);
|
||||
this.testState.onFinishScenario(scenario);
|
||||
this.testState.onFinishTest();
|
||||
const json = generateCucumberJson(this.testState);
|
||||
assertCucumberJson(json, [
|
||||
statuses.SKIPPED,
|
||||
statuses.SKIPPED,
|
||||
statuses.SKIPPED,
|
||||
]);
|
||||
});
|
||||
it("records passed scenarios", () => {
|
||||
this.testState.onStartScenario(scenario, stepsToRun);
|
||||
this.testState.onStartStep(stepsToRun[0]);
|
||||
this.testState.onFinishStep(stepsToRun[0], statuses.PASSED);
|
||||
this.testState.onStartStep(stepsToRun[1]);
|
||||
this.testState.onFinishStep(stepsToRun[1], statuses.PASSED);
|
||||
this.testState.onStartStep(stepsToRun[2]);
|
||||
this.testState.onFinishStep(stepsToRun[2], statuses.PASSED);
|
||||
this.testState.onFinishScenario(scenario);
|
||||
this.testState.onFinishTest();
|
||||
const json = generateCucumberJson(this.testState);
|
||||
assertCucumberJson(json, [
|
||||
statuses.PASSED,
|
||||
statuses.PASSED,
|
||||
statuses.PASSED,
|
||||
]);
|
||||
});
|
||||
|
||||
it("records failed scenarios", () => {
|
||||
this.testState.onStartScenario(scenario, stepsToRun);
|
||||
this.testState.onStartStep(stepsToRun[0]);
|
||||
this.testState.onFinishStep(stepsToRun[0], statuses.PASSED);
|
||||
this.testState.onStartStep(stepsToRun[1]);
|
||||
this.testState.onFinishStep(stepsToRun[1], statuses.FAILED);
|
||||
this.testState.onFinishScenario(scenario);
|
||||
this.testState.onFinishTest();
|
||||
const json = generateCucumberJson(this.testState);
|
||||
assertCucumberJson(json, [
|
||||
statuses.PASSED,
|
||||
statuses.FAILED,
|
||||
statuses.SKIPPED,
|
||||
]);
|
||||
});
|
||||
|
||||
it("handles missing steps", () => {
|
||||
this.testState.onStartScenario(scenario, stepsToRun);
|
||||
this.testState.onStartStep(stepsToRun[0]);
|
||||
this.testState.onFinishStep(stepsToRun[0], statuses.PASSED);
|
||||
this.testState.onStartStep(stepsToRun[1]);
|
||||
this.testState.onFinishStep(stepsToRun[1], statuses.UNDEFINED);
|
||||
this.testState.onFinishScenario(scenario);
|
||||
this.testState.onFinishTest();
|
||||
const json = generateCucumberJson(this.testState);
|
||||
assertCucumberJson(json, [
|
||||
statuses.PASSED,
|
||||
statuses.UNDEFINED,
|
||||
statuses.SKIPPED,
|
||||
]);
|
||||
});
|
||||
});
|
72
node_modules/cypress-cucumber-preprocessor/lib/cukejson/generateCucumberJson.js
generated
vendored
Normal file
72
node_modules/cypress-cucumber-preprocessor/lib/cukejson/generateCucumberJson.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
const { EventEmitter } = require("events");
|
||||
const { generateEvents } = require("gherkin");
|
||||
const JsonFormatter = require("cucumber/lib/formatter/json_formatter").default;
|
||||
const formatterHelpers = require("cucumber/lib/formatter/helpers");
|
||||
|
||||
function generateCucumberJson(state) {
|
||||
let output = "";
|
||||
const logFn = (data) => {
|
||||
output += data;
|
||||
};
|
||||
|
||||
const eventBroadcaster = new EventEmitter();
|
||||
|
||||
function storePickle({ pickle, uri }) {
|
||||
eventBroadcaster.emit("pickle-accepted", { pickle, uri });
|
||||
}
|
||||
|
||||
eventBroadcaster.on("pickle", storePickle);
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new JsonFormatter({
|
||||
eventBroadcaster,
|
||||
eventDataCollector: new formatterHelpers.EventDataCollector(
|
||||
eventBroadcaster
|
||||
),
|
||||
log: logFn,
|
||||
});
|
||||
|
||||
// Start feeding the recorded test run into the JsonFormatter
|
||||
|
||||
// Feed in the static test structure
|
||||
generateEvents(state.spec.toString(), state.uri).forEach((event) => {
|
||||
eventBroadcaster.emit(event.type, event);
|
||||
});
|
||||
|
||||
// Feed in the results from the recorded scenarios and steps
|
||||
Object.keys(state.runTests).forEach((test) => {
|
||||
const scenario = state.runScenarios[test];
|
||||
const stepResults = state.runTests[test];
|
||||
const stepsToRun = state.scenarioSteps[test];
|
||||
const steps = stepsToRun.map((step) => ({
|
||||
sourceLocation: { uri: state.uri, line: step.location.line },
|
||||
}));
|
||||
eventBroadcaster.emit("test-case-prepared", {
|
||||
sourceLocation: state.formatTestCase(scenario).sourceLocation,
|
||||
steps,
|
||||
});
|
||||
stepResults.forEach((stepResult, stepIdx) => {
|
||||
eventBroadcaster.emit("test-step-prepared", {
|
||||
index: stepIdx,
|
||||
testCase: state.formatTestCase(scenario),
|
||||
});
|
||||
eventBroadcaster.emit("test-step-finished", {
|
||||
index: stepIdx,
|
||||
testCase: state.formatTestCase(scenario),
|
||||
result: stepResult,
|
||||
});
|
||||
if (stepResult.attachment) {
|
||||
eventBroadcaster.emit("test-step-attachment", stepResult.attachment);
|
||||
}
|
||||
});
|
||||
eventBroadcaster.emit("test-case-finished", {
|
||||
sourceLocation: state.formatTestCase(scenario).sourceLocation,
|
||||
result: state.runTests[scenario.name].result,
|
||||
});
|
||||
});
|
||||
eventBroadcaster.emit("test-run-finished", {});
|
||||
|
||||
return JSON.parse(output);
|
||||
}
|
||||
|
||||
module.exports = { generateCucumberJson };
|
Reference in New Issue
Block a user