Fluent Page Objects can help make code easier to write, but we have to be careful not to couple too many classes together.
Another simple tip, but I use this a lot.
Return ’this’ from your Page Object methods
e.g.
AdminLoginPage page = new AdminLoginPage(driver);
page.
enterUserName("Admin").
enterPassword("AdminPass").
doNotRememberMe().
submitForm();
In the above code I have a Page Object called AdminLoginPage
.
Modelling the page at:
And you can see that the enterUserName
, enterPassword
and doNotRememberMe
are all ‘fluent’ in the sense that they return ’this’ so I can chain them when using the Page Object.
e.g.
public AdminLoginPage enterUserName(String username){
final WebElement elem = driver.findElement(By.name("username"));
elem.clear();
elem.sendKeys(username);
return this;
}
On returning ‘other’ Page Objects
Note that this does not mean that I advocate returning ‘other’ Page Objects from a Page Object
i..e if ‘submitForm’ causes a chain of system events such that a new page is displayed in the browser then I don’t advocate returning that page as a Page Object from the ‘submitForm’ object.
If navigating to a new page was a possibility I would make ‘submitForm’ a ‘void’ object, because I treat ‘Navigation’ as a separate responsibility, managed by a separate set of Objects.
public void submitForm(){
driver.findElement(By.id("login")).click();
}
Part of the reason for this is… what if the submitForm
fails, i.e. it was the wrong username and password so we didn’t login.
Should I have submitFormSuccessfully
and submitFormIncorrectly
?
I find it easier to use Page Object methods model the page functionality, rather than the page navigation flows.
On returning child components
Note that this does not mean that I never return ‘child’ or ‘container’ Page Objects.
e.g. if this page had a Widget, that I had modelled as a separate Page Object, I am quite happy to return a ’new Widget’ Object from a method on this Page Object, because this Page Object would be acting as a container for that one.
Not an absolute rule
But not navigation.
Not for me.
At least, most of the time, because all rules are made to be broken, thereby granting us the requisite variety we need to model our applications effectively. So sometimes I may choose to navigate via Page Objects. Very often I do this for expediency, or for throw away code. I’ll very likely refactor it out later.
Full Source
The full source for this is in my Webdriver Java FAQs project:
Specifically:
If you want to learn how to use Selenium WebDriver with Java then check out our online courses. I have a full course on Page Objects and Abstraction layers.