Creating page level step classes
Now is the time to break the ExampleSteps class into the following three classes and keep them all in steps package.
LandingPageSteps
public class LandingPageSteps extends DriverFactory {
@When("^she chooses to sign up$")
public void she_chooses_to_sign_up() throws Throwable {
new LandingPage(driver).she_chooses_to_sign_up();
}
}
SignupPageSteps
public class SignUpPageSteps extends DriverFactory {
@And("^she provides the first name as ([^\"]*)$")
public void she_provides_the_first_name_as(String firstName) throws Throwable {
new SignupPage(driver).she_provides_the_first_name_as(firstName);
}
@And("^she provides the last name as ([^\"]*)$")
public void she_provides_the_last_name_as(String lastName) throws Throwable {
new SignupPage(driver).she_provides_the_last_name_as(lastName);
}
@And("^she provides the email as ([^\"]*)$")
public void she_provides_the_email_as(String email) throws Throwable {
new SignupPage(driver).she_provides_the_email_as(email);
}
@And("^she provides the password as ([^\"]*)$")
public void she_provides_the_password_as(String password) throws Throwable {
new SignupPage(driver).she_provides_the_password_as(password);
}
@And("^she provides the confirm password again as ([^\"]*)$")
public void she_provides_the_confirm_password_again_as(String confirmPassword) throws Throwable {
new SignupPage(driver).she_provides_the_confirm_password_again_as(confirmPassword);
}
@And("^she signs-up$")
public void she_signs_up() throws Throwable {
new SignupPage(driver).she_signs_up();
}
}
HomePageSteps
public class HomePageSteps extends DriverFactory {
@Then("^she should be logged in to the application$")
public void she_should_be_logged_in_to_the_application() throws Throwable {
Assert.assertTrue(new HomePage(driver).isSignOutLinkDisplayed());
}
}
The only thing remaining in the ExampleStep class is now the piece of code that launches the website. Let's rename this class to StartingSteps.
StartingSteps
public class StartingSteps extends DriverFactory {
@Given("^the user is on landing page$")
public void setup() throws Throwable {
driver.get("http://accountsdemo.herokuapp.com");
driver.manage().window().maximize();
}
}
Now we have our step classes organized and the driver abstracted. But are we ready with everything. Will this code run.
Try it? What do we see?
The test runs and opens 2 browser instances and the test fails. Well looks like our DriverFactory is doing a little more than we asked for.
To break it down into exact java terms.
- All our step classes are now extending DriverFactory class.
- Everytime the scenario reaches to a new step class it follows inheritance, and the Driverfactory is asking it to create a new Driver every time.
- In our case, it creates one for StartingSteps and then again for LandingPageSteps.
What we need here is that even if all the step classes are extending the driver factory, they should not be creating a new driver instance every time. Rather they should be creating a single instance and reusing the same every time.
The easiest way to achieve this is to make the driver object static.
So the DriverFactory class would now look like the following
public class DriverFactory {
protected static WebDriver driver = new FirefoxDriver();
}
If you run the test now, all should hold good for now.