Cucumber 7 Get the step name in the BeforeStep hook TestStepStarted Event in Cucumber

Overview

I have different cucumber scenarios and I want to log the test step in BeforeStep in cucumber.

Create a Listener using the TestStepStarted

import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EventHandler;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.PickleStepTestStep;
import io.cucumber.plugin.event.TestStepStarted;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class ITestStepStarted implements ConcurrentEventListener {
    private static final Logger LOGGER = LogManager.getLogger(ITestStepStarted.class);
    public EventHandler<TestStepStarted> handler = this::logTestStepName;

    @Override
    public void setEventPublisher(EventPublisher eventPublisher) {
        eventPublisher.registerHandlerFor(TestStepStarted.class, handler);
    }

    private void logTestStepName(TestStepStarted testStepStarted) {
        if(testStepStarted.getTestStep() != null && testStepStarted.getTestStep() instanceof PickleStepTestStep) {
            PickleStepTestStep testStep = (PickleStepTestStep) testStepStarted.getTestStep();
            LOGGER.info("Step Text: {}", testStep.getStep().getText());
        }
    }
}

The given code represents a class named ITestStepStarted that implements the ConcurrentEventListener interface. Here are the key points about this class:

  1. The class has a static logger named LOGGER from the LogManager class, which is used for logging purposes.
  2. The class defines an event handler named handler of type EventHandler<TestStepStarted>. The handler is initialized with a method reference this::logTestStepName, which means the logTestStepName the method will be invoked when an event of the type TestStepStarted occurs.
  3. The class overrides the setEventPublisher method from the ConcurrentEventListener interface. Inside this method, it registers the handler for events of the type TestStepStarted with the eventPublisher.
  4. The logTestStepName method is a private method that takes an TestStepStarted object as a parameter. It checks if the TestStep object inside testStepStarted is not null and is an instance of PickleStepTestStep. If so, it casts the TestStep to PickleStepTestStep and performs some operations.
  5. Inside the logTestStepName method, the text of the step is retrieved using testStep.getStep().getText(). It is then logged using the logger, providing information about the step text.

In summary, the class ITestCaseStarted implements an event listener interface, registers an event handler for a specific event type, and captures and logs information about test steps, specifically when they are of type PickleStepTestStep.

How to use this listener

Add the listener class in your runner file as mentioned below:

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "src/test/resources/features",
        glue = "com.cucumber.framework.definitions",
        plugin = {"io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm",
                "com.cucumber.framework.listeners.ITestStepStarted"}
)
public class TestRunner {

}

Output after execution

[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: given step
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - given step
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: when step
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - when step
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: Then step
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - Then step
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: given step two
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - given step two
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: when step two
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - when step two
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: Then step two
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - when step two

Conclusion

Note: If you will try to store the step text in a variable and try to do it in BeforeStep then it will not lead to a proper result. The Hook Will be called before this listener So you will get null value for the step text.

Leave a Comment