Selenium Design Patterns
Selenium - Page Object Design Pattern
Within your web app’s UI there are areas that your tests interact with. A Page Object simply models these as objects within the test code. This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place. In other wards one of the challenges of writing test automation is keeping your [selectors] (classes, id’s, or xpath’ etc.) up to date with the latest version of your code. The next challenge is to keep the code you write nice and DRY (Don’t Repeat Yourself). The page object pattern helps us accomplish this in one solution. Instead of including our selectors in our step definitions in cucumber, we instead place them in a class file where we can manage all these selectors and methods together. Your test file should only call the test methods.
You can also place reusable functions or logic inside of these pages and call them from your step files. The page object serves as a layer of abstraction between tests and code. When a test fails, it fails on an individual step. That step may call a selector that is no longer valid, but that selector may be used by many other steps. By having a single source of truth of what the selector is supposed to be, fixing one selector on the page object could repair a number of failing tests that were affected by the same selector.
For detailed example please refer to the selenium dev documentation
Selenium - Page Factory Pattern
Page Factory’ is one way of implementing the ‘Page Object Model’. Page Factory is a way to initialize the web elements you want to interact with within the page object when you create an instance of it. Page Factory in Selenium is an inbuilt Page Object Model framework concept for Selenium WebDriver but it is very optimized. It is used for initialization of Page objects or to instantiate the Page object itself. It is also used to initialize Page class elements without using “FindElement/s.”
Here as well, we follow the concept of separation of Page Object Repository and Test Methods. Additionally, with the help of class PageFactory in Selenium, we use annotations @FindBy to find WebElement. It is a lazy way of loading to identify WebElements only with AjaxElementLocatorFactory, when they are used in any operation. In other words, it will find it again whenever we use a Webelement. So you won’t see StaleElementExceptions with PageFactory, but you may see them by using driver.findElement in the example below.
Two elements are defined by PageFactory and FindElement respectively in the product page.
By productLocator = By.xpath("//h2[@class=product-title]/a");
@FindBy(xpath = "//h2[@class=product-title]/a)
WebElement product;
Then use PageFactory to initiate the product element.
public HomePage(WebDriver driver)
{
this.driver = driver;
PageFactory.initElements(driver, this);
}
Then use the above two elements in methods in your test class.
For more information on how to implement the selenium design pattern using JAVA please refer to author’s selenium java framework
Conclusion
- The public methods represent the services that the page offers
- Try not to expose the internals of the page
- Generally don’t make assertions
- Methods return other PageObjects
- Need not represent an entire page
- Different results for the same action are modelled as different methods
We encourage our readers to treat each other respectfully and constructively. Thank you for taking the time to read this blog post to the end. We look forward to your contributions. Let’s make something great together! What do you think? Please vote and post your comments.