Reputation: 341
I am creating a UI test automation framework using POM design pattern. After reading SeleniumHQ page for Page Objects, I am contemplating what all methods should I create inside a Page Object.
Let's take a simple example of login page object consisting of username, password textboxes and submit button. SeleniumHQ link has created the below methods :
1. typeUsername(String username)
2. typePassword(String password)
3. submitLogin()
4. submitLoginExceptionFailure()
5. loginAs(String username, String password)
I am a bit perplexed while looking at these methods. Why should I create first 3 methods(typeUsername, typePassword,submitLogin), when I already am creating a loginAs method. Any thoughts around it ?
SeleniumHQ Link - https://github.com/SeleniumHQ/selenium/wiki/PageObjects
Pasting the code PageObject code for LoginPage :
public class LoginPage {
private final WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
// Check that we're on the right page.
if (!"Login".equals(driver.getTitle())) {
// Alternatively, we could navigate to the login page, perhaps logging out first
throw new IllegalStateException("This is not the login page");
}
}
// The login page contains several HTML elements that will be represented as WebElements.
// The locators for these elements should only be defined once.
By usernameLocator = By.id("username");
By passwordLocator = By.id("passwd");
By loginButtonLocator = By.id("login");
// The login page allows the user to type their username into the username field
public LoginPage typeUsername(String username) {
// This is the only place that "knows" how to enter a username
driver.findElement(usernameLocator).sendKeys(username);
// Return the current page object as this action doesn't navigate to a page represented by another PageObject
return this;
}
// The login page allows the user to type their password into the password field
public LoginPage typePassword(String password) {
// This is the only place that "knows" how to enter a password
driver.findElement(passwordLocator).sendKeys(password);
// Return the current page object as this action doesn't navigate to a page represented by another PageObject
return this;
}
// The login page allows the user to submit the login form
public HomePage submitLogin() {
// This is the only place that submits the login form and expects the destination to be the home page.
// A seperate method should be created for the instance of clicking login whilst expecting a login failure.
driver.findElement(loginButtonLocator).submit();
// Return a new page object representing the destination. Should the login page ever
// go somewhere else (for example, a legal disclaimer) then changing the method signature
// for this method will mean that all tests that rely on this behaviour won't compile.
return new HomePage(driver);
}
// The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
public LoginPage submitLoginExpectingFailure() {
// This is the only place that submits the login form and expects the destination to be the login page due to login failure.
driver.findElement(loginButtonLocator).submit();
// Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials
// expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
return new LoginPage(driver);
}
// Conceptually, the login page offers the user the service of being able to "log into"
// the application using a user name and password.
public HomePage loginAs(String username, String password) {
// The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
typeUsername(username);
typePassword(password);
return submitLogin();
}
}
Upvotes: 2
Views: 2829
Reputation: 8414
Finely chopping your code into more methods allows for greater atomization. Nothing stops you from grouping the typeUsername()
, typePassword()
and submitLogin()
into login()
method.
The upside of doing so is knowing more precisely that your login failed at, say, typing password as opposed to "somewhere on the login page".
Upvotes: 0
Reputation: 446
You might want to check if typing the username only and then clicking the submit button shows a correct error message, or only the password, etc.
I usually look at the page and try to summarize what "actions" the user can do on that page, every action becomes a method. The different actions might be on different "levels". e.g. on a blog website, the user can enter the blog-title and the blog content, that are two actions the user can do, but looking from an other abstraction layer the user wants to "create" a post. So that function might again call other functions.
Basically its like any other programming, you have multiple abstraction layers, that is why you have Page Objects in the first place.
And just use iterative development, create a function that does what you want to test and if you find yourself reusing the same code (or identifier) in other functions, separate those out in a new function
Upvotes: 2