In our previous blog, we have seen how to create a Base class(we named it as TestEngine.java). In this session we will see about POM and how to create .java file for each screen and manage our Mobile Elements.
Page Object Model(POM):
Guys, if you are new to Automation world, it is must for you to know about POM. I will explain the POM logic using simple examples in this session, so that you can understand it well. Most importantly POM is a very easy concept to understand and its one of a Best Practice to implement it in our project/framework.
In simple words, POM means creating java files based on “Pages/Screens”. For example let’s consider “RedBus” mobile application and its pages, (listed few pages for reference)
- Login page
- Home page for Bus search
- Home page for Train search
- Home page for Flight search
- Home page for Hotel search
- Bus seat selection page
- Payment Page
- Confirmation page and so on….
Like this we can have up to some 20 pages. Imagine each page are having approximately 70 elements.
In our framework, do you think it’s really a good idea to declare and maintain all 1400 elements in a single java file? No definitely not!!!
To overcome this issue we are going for POM design. In POM, each pages are considered as a java file, like below
|Mobile Pages/Screens/ Activity||Corresponding Java file||Number of Elements|
|Home page for Bus search||HomePage_Bus.java||50|
|Home page for Train search||HomePage_Train.java||70|
|Home page for Flight search||HomePage_Flight.java||65|
|Home page for Hotel search||HomePage_Hotels.java||80|
|Bus seat selection page||BusSelection.java||55|
|Confirmation page and so on….||ConfirmationPage.java||90|
Quick Tips: Java class file name should start with a Capital letter.
Valid class name: Login.java
Invalid class name: login.java
We can have all POM files under our parent project folder “Src/test/java” with a package named “com.projectName.pages”. This picture will definitely enhance your understanding.
Hope you guys are now clear with what is “POM”, our next step is creating java files based on POM and declaring the MobileElements. Please follow the steps and understand how it works.
I'm using an app called "Invoice Manager", please refer the blog "Connect to Appium using Java / Python" for getting the app details and desired capabilities.
Step 1: Create a new Package and name it as “pages” under src/java/test.
Step 2: Once Package is created, start adding java files under those package, File name should be the name of Mobile page/activity. For example, “Loginscreen.java”
Step 3: Created a java file and named it as “Company_Setup.java” because I’m going to work in “Company setup” page in my mobile application.
Now, our java file is created successfully. Here the question comes, How can I connect my Base class “Testengine” to this “Company_Setup” class? the answer is using Inheritance concept in Java.
Guys, If you are not clear with OOPS concept, please understand it from our video
Using the keyword “extends” we can inherit the properties of our Base class, like below. Please make sure to import the correct package of Base class.
All set guys, now java will allow us to use the variables and methods from my “Testengine” class in “Company_Setup” class using inheritance.
Before starting with element declaration in our class, please take a look on this small video to understanding how to Inspect element in Appium and adding it in to our class file.
Below image describes how to declare our elements using By class. Also created two methods, One for clicking the Logo button another for Signature button.
Quick Tip: Method name in java should always starts with a small letter. Best practice is using camel case, we can use underscore(_) to make it readable
Valid method name: clickOnLoginButton() or clickOn_LoginButton()
Invalid method name: ClickOnloginbutton()
Here comes the Important rule, How to declare my Elements in Java file?
There are lot of ways we can declare an element. Here I demonstrate 3 most commonly used approaches, (please scroll down to understand what is By and MobileBy)
Approach #1: Using locator string directly in findElement() method using By class,
Approach #2: Using String class to save the locator string and declaring in findElement() method,
String loginbtn = "loginbutton"; driver.findElement(MobileBy.id(loginbtn)).click();
Approach #3: Using “By” class to declare the element in findElement() method.
By addLogo = MobileBy.id("loginbutton"); driver.findElement(addLogo).click();
All approaches does the same action of clicking the “loginbutton” element, but the way of declaring the element is important here. Lets see the advantages and disadvantages of each,
Approach# 1, in this case, no re-usability concept . If there is a change in locator string, then we need to find and update everywhere. One of the worst way of declaring our elements.
Approach# 2, this approach is okay to use because we have reusability concept here. But the problem is, we don’t know what locator strategy to use in driver.findElement() method. Whether loginButton is an “ID”, or “name” or “tagname”. Also we are wasting the memory by declaring lot of String variables.
Approach# 3: It is one of a best method to declare our element. Using “By” class we are directly declaring our locator string. We have reusability concept, Ease of maintenance and we know the strategy as well.
So, for now I prefer to use Approach 3 in our framework.
Note: Best practice and industry standard approach is using POM with “PageFactory”. We will see about PageFactory in upcoming blogs.
What is “By” and “MobileBy”?
Guys this is little tricky to understand, Please understand this carefully. Lot of questions may comes from this in Interview point of view
- Both “By” and “MobileBy” are abstract class, which hold the locator strategy methods.
- “By” class comes from the package “org.openqa.selenium” and “MobileBy” comes from the package “io.appium.java_client.MobileBy”.
- All methods inside “By” and “MobileBy” are static in nature. That is why java is allowing the methods “id”, “xpath”, “classname” to use directly with By or MobileBy without creating any class reference.
- “MobileBy” extends “By” class(inheritance). It means we can use all methods of “By” class using “MobileBy” class.
- Using “By” class we cannot use methods belongs to “MobileBy”. For example if you want to use the MobileBy method like “AndroidUIAutomator()”, “AccessibilityId()”, “iOSNsPredicateString()” ect… are not allowed.
- “MobileBy” supports platform (iOS & Android) based location strategy for mobiles.
|By||MobileBy||Inherited from By|
|public static By id(String)||public static By id(String)||Yes|
|public static By linkText(String)||Not applicable for Appium||N/A|
|public static By partialLinkText(String)||Not applicable for Appium||N/A|
|public static By name(String)||public static By name(String)||Yes|
|public static By tagName(String)||Not applicable for Appium||N/A|
|public static By xpath(String)||public static By xpath(String)||Yes|
|public static By className(String)||public static By className(String)||Yes|
|public static By cssSelector(String)||public static MobileBy.AndroidUIAutomator(String)||No|
|public static MobileBy.iOSNsPredicateString(String)||No|
|public static MobileBy.iOSClassChain(String)||No|
|public static MobileBy.IosUIAutomation(String)||No|
|public static MobileBy.ByAccessibilityId(String)||No|
Guys, in our next session we will see how to create a simple test case which will call our methods as a test step using TestNG…
I’m so excited about the next topic because, we are going to create a java files for our “Test cases” and handle multiple methods as a steps in our test case. Stay focused…
I will commit the codes discussed here in my Github repo. You can clone it and start modifying as per your idea.
Ragav, having 10+ years of testing experience on which 7 years of rich experience in automation using UFT, Selenium (Java/Python). Expertise in Web and Mobile automation testing using Appium.
Reviewer: Naveen Khunteta