Reputation: 601
I am having difficulty understanding and utilizing dependency injection in my situation. I want to use Pico-container (https://cucumber.io/blog/2015/07/08/polymorphic-step-definitions).
This is my situation...I currently have one step definition class that contains all my selenium, and which is getting way too big:
public class StepDefinitions{
public static WebDriver driver; // a driver is returned here from a static Driver Factory Class
LoginPage loginPage = new LoginPage(driver); //Page Object Model(s)
@Before("setup")
@After //screen snapshot
@After("destroy")
@Given //many methods with this tag
@When //many methods with this tag
@Then //many methods with this tag
}
Now I want to potentially have one class that contains my driver, POMs, and Hooks:
public static WebDriver driver; //driver is returned from a static Driver Factory Class
LoginPage loginPage = new LoginPage(driver); //Page Object Model(s)
@Before("setup")
@After
@After("destroy")
Another class that contains my @Given
, one class that contains my @When
, and one class that contains my @Then
I then need to connect everything up right, so all classes can utilize the driver, hooks, and POMs. Cucumber does not support inheritance, so interfaces or Dependency Injection (Pico Container) is the way to go. I do not know how to do this, and I have studied online, I just cannot wrap my poor brain around it all.
Upvotes: 3
Views: 23997
Reputation: 4323
You might be interested in my blog post where I use Pico Container to share state between two different Cucumber-JVM step classes, http://www.thinkcode.se/blog/2017/04/01/sharing-state-between-steps-in-cucumberjvm-using-picocontainer
Upvotes: 7
Reputation: 1804
You may not be able to implement inheritance but you can use constructors in step definitions class to pass on driver object reference from one class to another.
public class Step_Def_Base {
public static webDriverCreator test;
@Before
public void printScenario(Scenario scenario) {
test = new webDriverCreator(this.getClass().getSimpleName());
String className = this.getClass().getCanonicalName();
System.out.println("********************************************************");
System.out.println("Scenario: " + scenario.getName());
System.out.println("********************************************************");
}
@After
public void screenShotAndConsoleLog(Scenario result) {
test.takescreenshot.takeScreenShotOnException(result);
if (!(result.getStatus().contains("pass"))) {
throw new RuntimeException(result.getName() + " got failed");
}
test.closeBrowserSession();
}
}
public class StepDefs_AltoroMutualLoginPage {
private Step_Def_Base contextStep;
private webDriverCreator test;
public StepDefs_AltoroMutualLoginPage(Step_Def_Base contextStep) {
// TODO Auto-generated constructor stub
this.contextStep = contextStep; // <-- This is where pico-containers starts working
test = contextStep.test; // <-- Linking your driver object reference from the point where it is instantiated , i.e the base foundation class
}
@Given("^I am on test fire login page \"([^\"]*)\"$")
public void alotoroMutualLoginPage(String url) {
test.launchApplication(url);
test.altoroMutual.launchLoginLink();
test.altoroMutual.verifyUserIsOnLoginPage();
}
Now you can get creative , and organize your page objects accordingly. I aggregated and instantiated all my page object classes inside the wrapper class that is returning the web driver object. You can see in the code, I am accessing altoroMutual
pageObject class from test
object.
Make sure you are using maven to manage all dev-dependencies . Following dependencies shall add pico container in your project.
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.picocontainer</groupId>
<artifactId>picocontainer</artifactId>
<version>2.14.3</version>
</dependency>
Upvotes: 4