Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.
Page object pattern maps UI pages to classes and related actions to methods in that class. This allows for better grouping of page actions. All the actions specific to each page will be in a single class. Page object pattern has few advantages:
This page explains page object pattern in detail.
In this blog post, I will explain about how to use page object pattern while writing Twist tests. Let us consider a test scenario in which we are searching for a product in Amazon and adding the product to shopping cart.
In Twist, each step lives in a fixture class and this can represent actions specific to that page. In the above example, we have two page classes, "On Homepage" and "On shopping cart page". Now before each step executes, we should navigate to the specific pages, so that the step can perform its task without worrying about navigating to the page.
Before Twist 13.1, your step would be something like this:
public void searchForAndAddToCart(String product) throws Exception {
String url = "http://amazon.com";
if (!browser.getCurrentUrl().equals(url)) {
browser.get(url);
}
// Implementation for search and add to cart
}
Or in your scenario, you could navigate before each step, something like this:
The trouble here is that for each step that gets added to the fixture class, the navigation has to be completed before it can perform the action. This becomes a problem when more and more actions get added to the fixture class. It can be easily solved by using "Execution hooks" which are introduced in Twist 13.1.
Twist provides global, scenario level execution hook and a fixture level hook. Fixture level hooks are local to the fixture class. In this example, we will use a fixture level hook.
public void searchForAndAddToCart(String product) throws Exception {
// Implementation for search and add to cart
}
@BeforeEachStep
public void beforeEachStep() {
String url = "http://amazon.com";
if (!browser.getCurrentUrl().equals(url)) {
browser.get(url);
}
}
"beforeEachStep()" method will be executed before every step executes in that fixture. We will navigate to the required page in this hook. With this, the step implementation doesn’t need to worry about the navigation.
Similarly, to verify items are added to shopping cart, “before hook” ensures you are on the shopping cart page before the verification code is executed.
public void verifyShoppingCartContains(String string1) throws Exception {
// Code to do the verification
}
@BeforeEachStep
public void beforeEachStep() {
String url = "https://www.amazon.com/gp/cart/view.html/";
if (!browser.getCurrentUrl().equals(url)) {
browser.get(url);
}
}
This method also improves reusability of steps across scenarios. For instance, we can use "Verify shopping cart contains product" from any scenario file without thinking about its navigation. This also simplifies the scenario, as shown below,
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.
Thoughtworks acknowledges the Traditional Owners of the land where we work and live, and their continued connection to Country. We pay our respects to Elders past and present. Aboriginal and Torres Strait Islander peoples were the world's first scientists, technologists, engineers and mathematicians. We celebrate the stories, culture and traditions of Aboriginal and Torres Strait Islander Elders of all communities who also work and live on this land.
As a company, we invite Thoughtworkers to be actively engaged in advancing reconciliation and strengthen their solidarity with the First Peoples of Australia. Since 2019, we have been working with Reconciliation Australia to formalize our commitment and take meaningful action to advance reconciliation. We invite you to review our Reconciliation Action Plan.