0

I trying to incorporate pico-container DI into my framework so I can use the @Before and @After tags across multiple step definitions. Please see the error below. Any advice would be great.

You're not allowed to extend classes that define Step Definitions or hooks. class steps.hotelBookingFormPage extends class resources.hooks

import io.cucumber.java.en.Given;
import org.openqa.selenium.internal.ShutdownHooks;
import resources.hooks;

public class hotelBookingFormPage extends hooks {

    public hooks base;
    hotelBookingFormPage (hooks base) {
        base = hooks.startBrowser();
    }

    @Given("I navigate to the hotel booking form page")
    public void iNavigateToTheHotelBookingFormPage() {
        base.driver.get("http://hotel-test.equalexperts.io/");
    }
Shafiq Ahmed Khan
  • 179
  • 1
  • 4
  • 14
  • Why are you trying to extend a class that holds hook methods? What is the final goal? – Alexey R. Nov 08 '21 at 12:18
  • I would like to have all my hooks in a separate class so I can use them across other step def files. However when I do that I get the following error: ```Before All/After All failed java.lang.NoClassDefFoundError: org/picocontainer/MutablePicoContainer``` I have pico-container jar added to my dependencies but still get the above error – Shafiq Ahmed Khan Nov 08 '21 at 13:16

2 Answers2

1

io.cucumber.java.InvalidMethodException: You're not allowed to extend classes that define Step Definitions or hooks.

Cucumber creates a new instance of all classes defining StepDefinition before each scenario. It then invokes StepDefinition methods on one of those instances whenever it needs to run a step. If I declare a method test in a class and extended to StepDefinition extended to class then two instances will be created and test method will be available on both instances, and cucumber would not be able to decide what instance to invoke the method on. Incase of inheriting to class(which is having hook methods) then you can use composition.

Current way:

class hotelBookingFormPage extends hooks{
 public hooks base;
    hotelBookingFormPage (hooks base) {
        base = hooks.startBrowser();
    }
}

Updated way:

class hotelBookingFormPage{
    hotelBookingFormPage () {
        hooks base = new hooks();
        base.startBrowser();
    }
}
Nandan A
  • 2,702
  • 1
  • 12
  • 23
1

I believe you are trying to use hooks in wrong way. Hooks are not the classes but the annotated methods within any class under your glued path. You should not call them directly.

Where a hook is defined has no impact on what scenarios or steps it is run for.

(c) Cucumber documentation

All the hooks are called each time your scenario/step finishes. If you need to have more flexible control over than you need to use conditional hooks

Alexey R.
  • 8,057
  • 2
  • 11
  • 27