0

Cucumber: how can you create a BaseSteps class if you can’t use inheritance with Cucumber?

Login Steps inherits the CommonSteps class:

    public class LoginSteps extends CommonSteps {

    WebDriver driver = getDriver();

    @Given("^User navigates to the \"([^\"]*)\" website$")
    public void user_navigates_to_the_website(String url) throws Throwable {
        basePage.loadUrl(url);
    }

    @And("^User entered the \"([^\"]*)\" username$")
    public void user_entered_the_username(String username) throws Throwable {
        loginPage.setUsername(username);
    }






public class CommonSteps  {
    @After
    public void close_browser_window(Scenario scenario) throws Exception {
        if (scenario.isFailed()) {
            scenario.embed(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES), "image/png");
        }
    }
}
Gbru
  • 1,065
  • 3
  • 24
  • 56
  • 1
    Possible duplicate of [Cucumber: You're not allowed to extend classes that define step definitions or hooks](http://stackoverflow.com/questions/41985002/cucumber-youre-not-allowed-to-extend-classes-that-define-step-definitions-or-h) – Roberto Pegoraro Apr 26 '17 at 19:22
  • I had the same problem and detailed how to solve it here: https://stackoverflow.com/a/71242684/2737314 – Lucas Feb 23 '22 at 20:06

2 Answers2

2

The idiomatic solution in Java, end therefore Cucumber-JVM, is use dependency injection when you want to share state between steps implemented in different classes.

Cucumber support many different dependency injection frameworks. If your project already uses one, it is very likely that your dependency framework is supported.

If you don't use a dependency injection framework, I suggest that you use PicoContainer. If you need to know how to use it, I wrote a blog post describing how to share state between steps.

Thomas Sundberg
  • 4,098
  • 3
  • 18
  • 25
1

You can use inheritance, just not with steps for the reason's cited in Roberto Pegoraro's link. I like to organize my steps into different step def files. But this leads to interoperability problems. If you use class variables to communicate between steps then those steps have to be in the same file; unless you use inheritance. I create a UiCommon class to contain the shared class variables (e.g. page file instance variables) that the steps use to communicate between themselves. Each step definition file extends UiCommon. Now it doesn't matter how I refactor the steps definitions between the various step definition files. They can still communicate.

For small projects this isn't usually an issue. But for a large project with multiple test automation engineers who need to minimize git merge conflicts it matters.

MikeJRamsey56
  • 2,779
  • 1
  • 20
  • 34
  • thanks so much for the reply, so in turn you create a class which will contain all the main methods and then every step file will contain 'Before' and 'After' tags etc which will in turn use the methods housed within the main methods class. – Gbru Apr 28 '17 at 11:07
  • **All** Before and After tags run once per scenario. So unless you want them all to run either have one each or limit them by tag. – MikeJRamsey56 Apr 28 '17 at 13:31