I have a class Reporter. Inside the constructor I have initialized a counter. The counter is incremented inside a function addStepLog. After sometime when the same counter variable is called inside the afterEachScenarioStep function the value is being initialized to 0. Please note that @AfterStep is a cucumber annotation (using cucumber-java 4.2.5). Below is my code.
public class Reporter {
private final Object lockObject = new Object();
private int counter;
private List<String> stepLog;
public Reporter() {
stepLog = new ArrayList<>();
counter = 0;
}
public void addStepLog(String message) {
synchronized (lockObject) {
this.counter++;
stepLog.add(message);
}
System.out.println("Counter Value in addStep " + this.counter);
}
@AfterStep
public void afterEachScenarioStep(Scenario scenario) {
System.out.println("Value of Counter " + this.counter); // The value of counter is 0 here.
if (stepLog.size() > 0) {
System.out.println(counter++);
synchronized (lockObject) {
stepLog.forEach(scenario::write);
}
}
scenario.embed(screenshotArray, "image/png");
}
The size of the arryList is 0 and the counter is also reinitialized to 0. I am pretty sure cucumber is doing something funny.
I have created only one instance of Reporter from the Login class. The reporter is not being used anywhere else.
public class Login {
private JsonParser jsonParser = new JsonParser();
Reporter reporter = new Reporter();
public void launchBrowser(String device) {
reporter.addStepLog("Launched the Browser.");
reporter.addStepLog("Launched the Browser.");
driver(device).launchUrl(jsonParser.getValue(device, "url"));
}
public void clickForgotPassword(String device) {
reporter.addStepLog("This is a dummy Step");
reporter.addStepLog("This is a dummy Step2");
reporter.addStepLog("This is a dummy Step3");
reporter.addStepLog("This is a dummy Step4");
driver(device).click("account.forgetPassword");
}
Grasshopper's comment is the correct answer: cucumber-jvm
destroys and re-creates the "world" (which includes all steps and glue objects) for each feature. Therefore you are getting a new instance of Reporter
for each feature.
There are some workarounds listed here: https://automationpanda.com/2017/03/03/cucumber-jvm-global-hook-workarounds/
Static variables are the simplest workaround.