Page Object Model – Framework

Most of the times, many project demands start of best fit automation framework from scratch. Page Object Model (POM) is most popular design pattern for the Selenium automation.

In this post, lets try to figure out the details. Before diving in its better to look at this post to get insight of what we are talking here.

Page Object Model – Approach

Lets us look at the following different packages for the purpose of the understanding.

pages contains the test pages for the site, where as each page contains the objects corresponding to that page.

In any UI testing we typically do two things with objects, either we retrieve properties for it or we perform actions on it.

eclipsstructure

In the start section we write necessary code to start the browser. Driver session creation, extent test creation, logger creation etc.

The tests section contains the test classes we are intended to write.

The utilities section contains the common actions class and the reusable action classes.

expandedpackages

Also, its better use config properties for the entire test setup along with the test data sheets. Also maintain drivers in different folder for better readability.

projectStructure

As shown above utilities package contains the excel manipulations such as get and set data operations.

Lets deep dive into start class and what it is doing.

Start class has all declarations and webdriver creation depending the config settings.

Create config file with browser type and other details so that we can use them in the code.

config

Start class will have the entire code for reading the config file and depending on the browser type mentioned in the config it creates the web driver session.

If we look at the declarations, the entire project is using extent reports as it will generate beautiful reports for the test execution.

Also, all other variables are declared as static where as driver is non static. The report logger is also static, since once we create start instance driver will be recreated but not the report logger. This will help to run the same test in multiple iterations keeping the same report.

If we look at the declarations, we are declaring the xldriver, extent report and logger properties as static as they dont need to be re initialized for loop execution. (Static variables are created once, they are not recreated for each instance of class)

start2

the launch_browser method returns the pagefactory object with created driver. This will flow to subsequent pages.

return.PNG

Will see why it is returning the page factory object.

If we look at the pagefactory class, it has definitions of all pages.

We are using pagefactory constructor to send the driver to all the sub subsequent classes.

And, the home and other pages will inherit this class so that they can get the latest driver created by the start class.

pagefactory

Each page class is contains the deification of elements and initialization of elements.

We will use PageFactory class (Selenium specific class) along with ajaxelemetlocator since it has advantage of creating element only when it is being used, we can also define the time duration for the locating element. We are also using reference class object for the common functions.

The reference, and the home class gets the driver created in the start class.

home1.PNG

Also the each class in the page returns the same page for better creation of tests.

home2

And finally coming to writing test cases.

Starting with method name, we are using the data sheet name as test method name.

So to avoid hard coding of the methodname passing to excel setExcelSheet method , we are programatically getting method name and assigning it.

Since xldriver and set_logger method is static, we dont have create start class object to use them.

And looking at the loop, we are getting rows in the excel sheet and running the required actions for each row. That means creating driver doing all actions and logging out.

We can restrict this for certain actions if we dont want to quit the browser, by keeping the creating of start object outside the for loop.

And by keeping (.) at the launch_browser(), we get access to the methods in pagefactory class, and since all other classes are extending pagefactory class, all of them gets access to pagefactory class methods. Thats the reason for writing page navigation methods in the pagefactory class.

This way we can write single line test cases, this will ease the reading of test case and writing and debugging them.

TestCase

the output for the test looks like below.

reports

This is gist of implement page object model with one sample testcase.

In this post we have not included the excel data manulations, hash maps and extent report creation.

We will try to address them in subseqnet posts.

Thank you.

 

 

 

Advertisement

Synchronization in Automation Testing with selenium.

When you ask selenium tester what is the most common issues he is facing during his automation testing experience, the first thing he would say is Sync problem.

Let’s take a bird eye view on this and will take deep dive on the synchronization issues and how to address them.

Selenium framework has several methods to address the synchronization issues. Mainly they are segregated into two different varieties.

  • Implicit waits
  • Explicit waits

Implicit wait:

This is the most common wait type we use; it is also called as default wait. The page load time out, and the timeouts.implicitwait is the two types of implicit wait. The implicit wait meaning that the driver has to wait until the web element is existed on the dom. It will come out of the waiting loop if element exists beforehand. Example you have given 10 seconds on element x, and it has loaded in 2 seconds web driver knows it and goes to next step without waiting for 10 seconds. It is called as implicit wait.

driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Explicit wait:

Explicit waits are defined on the particular web element to wait until the property value becomes true.

It will pole every 500 milliseconds to get the property value and verifies it with defined value.

Examples:

//webdriver wait class
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath(menu))));

//for multiple elements
WebDriverWait wait = new WebDriverWait(driver, 30);
List options = driver.findElements(By.xpath(option_to_select));
wait.until(ExpectedConditions.visibilityOfAllElements(options));

//Another example
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.invisibilityOfElementWithText(By.className("jqx-fill-state-normal"), "Loading..."));

Fluent wait:

Fluent waits also called as explicit waits, but only difference being we can define interval to pole and can tell to ignore any exceptions. It will be useful to save resources not to check every 500 milliseconds if element load takes long time.

Wait<WebDriver> fluentwait = new FluentWait<WebDriver>(driver)
                        .withTimeout(20, TimeUnit.SECONDS)
                        .pollingEvery(1, TimeUnit.SECONDS)
                        .ignoring(java.util.NoSuchElementException.class);
fluentwait.until(ExpectedConditions.invisibilityOfElementWithText(By.className("jqx-fill-state-normal"), "Loading..."));

The another type of wait is normally not recommended is static wait or pause the program.

Thread.sleep(500);

So, the gist is the know when to use what. Fluent wait is used when application slower and running in a slow paced machine where we don’t want driver to hit every 500 milliseconds, and you know it will not come till 2 sec or 3 seconds, we can define the polling interval. I am guessing this as it is synonymous to implicit wait where the default polling is 500 ms.

We can use web driver wait almost in all cases where we know element loading is taking place, but the properties are not loaded until some other action is completed, example, state dropdown is enabled only when country drop down is selected, in that case we can use expected conditions on the enabled of the state dropdown after country select.

Default waits or implicit waits are used when we know dom loading is taking some time and not to give wait on existence of each element. Normally this would serve the purpose, but angular applications waits plays key role in test execution failures.

If we use waits wisely and where ever we need depending the application behavior with limited use of static waits will improve the script quality drastically.

Thank you.

Page Object Model – Approach

In selenium, most frequently we hear page object model.

I have asked people why did they call it as page object model ? Is there any specific reason behind this ?

I got general answer saying “we store all locators in a page as static final strings in a page class”

Is this correct explanation ? are we doing page object model as is ? below is another view point.

In general we call page object model because every method in a page returns the page object instead of string/float/int or any standard return types.  This will provide flexibility in writing test cases easily.

Step 1 : Define Page class

package test.pom;
public class page1 extends pageRep
{  
public page1() 
{
super(); 
} 
public page1 testM1() 
{ 
System.out.println("Method 1 Page 1");  
return this; 
} 
public page1 testM2() 
{ 
System.out.println("Method 2 Page 1");  
return this; 
} 

}

Create another page to illustrate navigation between pages.

package test.pom;
public class page2 extends pageRep 
{
 public page2() 
{ 
super(); 
} 
public page2 test_M1() 
{ 
System.out.println("Method 1 Page 2");  
return this; 
} 
public page2 test_M2() 
{ 
System.out.println("Method 2 Page 2");  
return this; 
} 
}

If you observe clearly, the above classes are returning the page class as object and extending the class page repository. The class page repository is the class where we use to navigate between the pages.

Step 2: Create page repository for navigation between pages

package test.pom;
public class pageRep { 
public pageRep() 
{
 System.out.println("Calling the super class"); 
}
public page1 navigateToPage1() 
{ 
return new page1();
} 
public page2 navigateTopage2() 
{ 
return new page2(); 
} 
}

Step 4 : While creating the test case you can see it will be simple as we can keep “.” to see the methods in the class as each method returns the class object again, you will have visibility of all methods.

Page repository helps us to navigate between pages.

This is the best illustration of the Java extends concept which we can use to write our tests in selenium.

package test.testcases;
import test.pom.pageRep;
public class tests {
public static void main(String[] args) 
{ 
 pageRep start = new pageRep();
 start     
.navigateToPage1().testM1().testM2()
.navigateTopage2().test_M1().test_M2()     
.navigateToPage1().testM1(); 
 }
}

output:

Calling the super class
Calling the super class
Method 1 Page 1
Method 2 Page 1
Calling the super class
Method 1 Page 2
Method 2 Page 2
Calling the super class
Method 1 Page 1