-
-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement possibility to overwrite the step status for cucumber messages/json #1106
Comments
Native support for soft errors has been proposed before. I agree with Cucumber's maintainers, that the use cases for this are questionable and I remain hesistant in adding complexity to support it. Furthermore, I don't want to see any further drift between the user experience in cucumber-js and the processor. Thus, I am closing this issue. |
As an alternative, you can store soft errors yourself and post-process the messages, as shown below. Feature: soft errors
Scenario: soft errors
Given a step with soft error
And a normal step const { BeforeStep, AfterStep, Given } = require("@badeball/cypress-cucumber-preprocessor");
BeforeStep(function () {
delete this.softError;
});
AfterStep(function ({ testStepId }) {
if (this.softError) {
cy.task("store-soft-error", {
testStepId,
message: this.softError.message
});
}
});
Given("a step with soft error", function () {
this.softError = new Error("some error");
});
Given("a normal step", () => {}); const fs = require("fs/promises");
const { defineConfig } = require("cypress");
const createBundler = require("@bahmutov/cypress-esbuild-preprocessor");
const {
addCucumberPreprocessorPlugin,
afterRunHandler,
} = require("@badeball/cypress-cucumber-preprocessor");
const {
createEsbuildPlugin,
} = require("@badeball/cypress-cucumber-preprocessor/esbuild");
async function setupNodeEvents(on, config) {
// This is required for the preprocessor to be able to generate JSON reports after each run, and more,
await addCucumberPreprocessorPlugin(on, config, {
omitAfterRunHandler: true,
});
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
);
const softErrors = [];
on("task", {
"store-soft-error": (softError) => {
softErrors.push(softError);
return true;
},
});
on("after:run", async () => {
await afterRunHandler(config);
if (!config.isTextTerminal) {
return true;
}
const messagesPath = "cucumber-messages.ndjson";
const messages = (await fs.readFile(messagesPath))
.toString()
.trim()
.split("\n")
.map(JSON.parse);
for (const message of messages) {
if (message.testStepFinished) {
const matchingSoftError = softErrors.find(
(softError) =>
softError.testStepId === message.testStepFinished.testStepId
);
if (matchingSoftError) {
const { testStepResult } = message.testStepFinished;
testStepResult.status = "FAILED";
testStepResult.message = matchingSoftError.message;
}
}
}
await fs.writeFile(messagesPath, messages.map(JSON.stringify).join("\n"));
return true;
});
// Make sure to return the config object as it might have been modified by the plugin.
return config;
}
module.exports = defineConfig({
e2e: {
specPattern: "**/*.feature",
setupNodeEvents,
},
}); |
@badeball thank you a lot for providing this code sample!!! Especially the way how to store globally softErrors as you showed is wonderful |
@badeball it works as a way to modify the I'm using multiple cucumber html reporter which relies on the Any thoughts how to bypass that behaviour and be able to regenerate the |
@badeball I figured it out, thanks again. Without your code sample, I wouldn't pull it off The code should be placed above |
Current behavior
Basically, currently there's no way (at least known to me) how to overwrite the result status of the step on the scope of the cucumber message/jsonlogs.
Let's imagine there are some huge scenarios with a lot of steps in itself. Some of the assertion steps just check whether element contains expected text and these steps are in the middle of the scenario.
The problem is when the middle step fails, then next steps are skipped and runner gets to the next scenario.
Here's an idea to catch all errors from custom assertion methods (there's no way for doing that with cypress native commands like "should" or "and") like I mentioned about checking the text value of element, and push it to the array storing these errors. Following that, the runner will continue execution and my steps will be marked as passed.
On the end of scenario I would like to map all these errors from array with their corresponding steps to mark those as failed. Thus, in the html report my scenario will have several failed steps instead of just one with the rest to be skipped.
But if error happens in cypress command or any other uncatchable error, it will follow the usual behaviour when the scenario is immediately terminated and step is marked as failed. So not always it will be that runner executes all listed steps of the scenario (only those that I intend to catch).
Desired behavior
A way to mark steps where failures were caught to the "failed" status on the cucumber messages/json logs level thus my report will accurately represent the scenario execution result
Test code to reproduce
Here's just an example of how I would catch it inside my custom assertion method. Pay attention to the try/catch block in the bottom
`
`
Versions
Checklist
cypress-cucumber-preprocessor@4.3.1
(package name has changed and it is no longer the most recent version, see #689).The text was updated successfully, but these errors were encountered: