Like QTP, TestComplete and few other automation tools selenium webdriver does not provide any centralized repository where we can put object locator of page element. In POM object pattern we can accomplish this type approach.
What is POM:
In automated web testing, a Page Object is a class or object that represents a web page in your application. A Page Object hides the technical details about how you interact with a web page behind a more readable and business-focused facade. Following are the few points in details:
• Page Object Model is a design pattern to create Object Repository for web UI elements. Like it provide you to option to put all locators in corresponding page (java file ) like for home page you create a homepage java file and put all element locators of home page in same class.
• Under this model, you should create java file like above ( homePage.java ) home page and create functions related to this page like clickHomeMenu, clickProduct() verfiyHomePage() etc.
• So your page object class contains elements locator and corresponding function what you need to perform on that particular page.
• Name of these function and object locator must be logically defined like elements name username , password, loginButoon and corresponding function should be like enterUserName(), enterPassword(), clickLoginButton()
Advantages of POM
• The tests are much more readable as only function need to call from different-2 page class files into your test files.
• Page elements and logic is centralized in one place, this will help much easier in maintenance.
• Easy to understand any new develpoer.
• Easy to maintain in case of any changes in application or elements .
• Object repository and function or independent from test scripts so we can use them in multiple test files.
Implementation of page object model:
In this example I will show you some example how to create POM model by using below url:
http://book.theautomatedtester.co.uk
When you open this url you will land at home page. Also when you click on “Chapter1”, “Chapter2” and “Chapter3” etc you will get other pages.
In page object model you should create java file for corresponding pages like I have created “HomePage.java”, “ChapterFirstPage.java”, “ChapterSecondPage.java” for home page, chapter 1 page chapter 2 page respectively. And put corresponding elements locator and functions.
1. HomePage.java
2. ChapterFirstPage.java
3. ChapterSecondPage.java
So in above examples you can see that page elements locator are defined using @FindBy annotation and corresponding functions are defined which will separate from each others.
PageFactory class used to create run time object of page classes like:
You should return object of class where you application move after performing actions like when I click index in ChapterSecondPage.java file it returm HomePage object as after clicking on index page Home page will open.
Similar way another example when you click on clickbut2() then same page open
Now creating test file, you should create base class of all test scripts where you should put common functions related test case like I created “TestBase.java”
To create test scripts and import TestBase class and call corresponding functions from page java file as needed in your test script.
Hope this will help you to design page object model in selenium webdriver. Leave comment in case you have any query.
What is POM:
In automated web testing, a Page Object is a class or object that represents a web page in your application. A Page Object hides the technical details about how you interact with a web page behind a more readable and business-focused facade. Following are the few points in details:
• Page Object Model is a design pattern to create Object Repository for web UI elements. Like it provide you to option to put all locators in corresponding page (java file ) like for home page you create a homepage java file and put all element locators of home page in same class.
• Under this model, you should create java file like above ( homePage.java ) home page and create functions related to this page like clickHomeMenu, clickProduct() verfiyHomePage() etc.
• So your page object class contains elements locator and corresponding function what you need to perform on that particular page.
• Name of these function and object locator must be logically defined like elements name username , password, loginButoon and corresponding function should be like enterUserName(), enterPassword(), clickLoginButton()
Advantages of POM
• The tests are much more readable as only function need to call from different-2 page class files into your test files.
• Page elements and logic is centralized in one place, this will help much easier in maintenance.
• Easy to understand any new develpoer.
• Easy to maintain in case of any changes in application or elements .
• Object repository and function or independent from test scripts so we can use them in multiple test files.
Implementation of page object model:
In this example I will show you some example how to create POM model by using below url:
http://book.theautomatedtester.co.uk
When you open this url you will land at home page. Also when you click on “Chapter1”, “Chapter2” and “Chapter3” etc you will get other pages.
In page object model you should create java file for corresponding pages like I have created “HomePage.java”, “ChapterFirstPage.java”, “ChapterSecondPage.java” for home page, chapter 1 page chapter 2 page respectively. And put corresponding elements locator and functions.
1. HomePage.java
import
org.openqa.selenium.WebDriver;
import
org.openqa.selenium.WebElement;
import
org.openqa.selenium.support.FindBy;
import
org.openqa.selenium.support.PageFactory;
public class
HomePage {
private WebDriver driver;
@FindBy(linkText="Chapter1")
WebElement chapter1;
@FindBy(linkText="Chapter2")
WebElement chapter2;
@FindBy(linkText="Chapter3")
WebElement chapter3;
public HomePage(WebDriver driver) {
this.driver = driver;
}
public ChapterFirstPage clickChapterFirst(){
chapter1.click();
return PageFactory.initElements(driver,
ChapterFirstPage.class);
}
public ChapterSecond clickChapterSecond(){
chapter2.click();
return
PageFactory.initElements(driver, ChapterSecond.class);
}
public void clickChapterThird(){
chapter3.click();
}
}
2. ChapterFirstPage.java
package
com.test.page;
import
org.openqa.selenium.WebDriver;
import
org.openqa.selenium.WebElement;
import
org.openqa.selenium.support.FindBy;
import
org.openqa.selenium.support.PageFactory;
import
org.openqa.selenium.support.ui.Select;
public class
ChapterFirstPage {
private WebDriver driver;
@FindBy(id = "secondajaxbutton")
WebElement secondajax;
@FindBy(xpath =
"//select[@id='selecttype']")
WebElement dropdown;
@FindBy(id = "verifybutton")
WebElement verifybutton;
public ChapterFirstPage(WebDriver driver) {
this.driver = driver;
}
public ChapterFirstPage
clickSecondAjaxButton() {
secondajax.click();
return
PageFactory.initElements(driver, ChapterFirstPage.class);
}
public ChapterFirstPage
clickSecondAjaxButton1(String data1) {
System.out.println(data1);
return PageFactory.initElements(driver,
ChapterFirstPage.class);
}
public ChapterFirstPage selctDropDown() {
new
Select(dropdown).selectByVisibleText("Selenium Core");
return
PageFactory.initElements(driver, ChapterFirstPage.class);
}
public ChapterFirstPage verifyButton() {
verifybutton.click();
return
PageFactory.initElements(driver, ChapterFirstPage.class);
}
}
3. ChapterSecondPage.java
package
com.test.page;
import
org.openqa.selenium.WebDriver;
import
org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import
org.openqa.selenium.support.PageFactory;
public class
ChapterSecondPage {
private WebDriver driver;
@FindBy(id =
"//input[@name='but2']")
WebElement but2;
@FindBy(xpath =
"//input[@id='random']")
WebElement random;
@FindBy(id = "Index")
WebElement index;
public ChapterSecondPage(WebDriver driver) {
this.driver = driver;
}
public ChapterSecondPage clickRandom() {
random.click();
return
PageFactory.initElements(driver, ChapterSecondPage.class);
}
public ChapterSecondPage clickbut2() {
but2.click();
return
PageFactory.initElements(driver, ChapterSecondPage.class);
}
public HomePage clickIndex() {
index.click();
return
PageFactory.initElements(driver, HomePage.class);
}
public String getTest() {
return index.getText();
}
}
So in above examples you can see that page elements locator are defined using @FindBy annotation and corresponding functions are defined which will separate from each others.
PageFactory class used to create run time object of page classes like:
PageFactory.initElements(driver,
HomePage.class);
You should return object of class where you application move after performing actions like when I click index in ChapterSecondPage.java file it returm HomePage object as after clicking on index page Home page will open.
PageFactory.initElements(driver,
HomePage.class);
Similar way another example when you click on clickbut2() then same page open
PageFactory.initElements(driver,
ChapterSecondPage.class);
Now creating test file, you should create base class of all test scripts where you should put common functions related test case like I created “TestBase.java”
package
com.test.util;
import
java.util.concurrent.TimeUnit;
import
org.openqa.selenium.WebDriver;
import
org.openqa.selenium.firefox.FirefoxDriver;
import
org.testng.annotations.AfterSuite;
import
org.testng.annotations.BeforeSuite;
import
com.test.page.ChapterFirstPage;
import
com.test.page.ChapterSecondPage;
import
com.test.page.HomePage;
public class
TestBase {
protected WebDriver driver;
protected String baseUrl;
protected HomePage homePage;
protected ChapterSecondPage chapterSecond;
protected ChapterFirstPage chapterFirstPage;
@BeforeSuite
public void setUp() {
baseUrl =
"http://book.theautomatedtester.co.uk/";
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30,
TimeUnit.SECONDS);
}
@AfterSuite
public void tearDown() throws Exception {
driver.quit();
}
}
To create test scripts and import TestBase class and call corresponding functions from page java file as needed in your test script.
package
com.test.scripts;
import
org.openqa.selenium.support.PageFactory;
import
org.testng.annotations.Test;
import
com.test.page.HomePage;
import
com.test.util.TestBase;
public class
MyTest extends TestBase {
@Test
public void testPageObject() throws Exception
{
homePage =
PageFactory.initElements(driver, HomePage.class);
driver.get(baseUrl);
chapterSecond =
homePage.clickChapterSecond();
chapterSecond.clickbut2();
chapterSecond.clickRandom();
String data =
chapterSecond.getTest();
homePage =
chapterSecond.clickIndex();
chapterFirstPage =
homePage.clickChapterFirst();
chapterFirstPage.clickSecondAjaxButton();
chapterFirstPage.clickSecondAjaxButton1(data);
chapterFirstPage.selctDropDown();
chapterFirstPage.verifyButton();
}
}
Hope this will help you to design page object model in selenium webdriver. Leave comment in case you have any query.
Hi! very usefull article
ReplyDeleteI have idea how to improve thist test for more flexibuility
for example we have common page objects which are on each page but with different names such as:
1. PageWidget (same xpath in each page but with different name)
2. PageTable(same xpath in each page)
3. PageLink(same xpath in each page but with different name)
and i want to use this common page objects to get some element on page like this:
page().get(PageWidget .class, "Widget Name").get(PageTable.class, "Table Name").get(PageLink.class, "Link Name").click
is it any way to configure this test?
Hi i wanted to know if @FindBy annotation implicitly invokes Implicit wait written in the code?
ReplyDeleteHi,,
Could pls someone clarify these doubts:
One webdriver script that i wrote is failing sometimes(not all the times i run).
I feel the webdriver is passing the control to the next line of execution even before the browser loads the page completely. And since the element in that next line of code is not available that time,, the execution stops and the browser closes before executing next 7-8 steps.
I am using Page Object Model (@FindBy) annotations.
I wanted to know if @FindBy implicitly/internally invokes implicit wait?? Or do i need to include wait in some other place/way?
This is how my code looks:
@BeforeMethod
public void preCondition()
{
String browserName=GetData.fromProperties(".\\data\\config.properties","browser");
String url=GetData.fromProperties(".\\data\\config.properties","url");
if(browserName.equals("FF"))
{
driver=new FirefoxDriver();
}
else if(browserName.equals("IE"))
{
System.setProperty("webdriver.ie.driver",".\\browser_exe\\IEDriverServer64bit.exe");
driver=new InternetExplorerDriver();
}
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(url);
}
------------------------------------------------------------------------------------------
public class ImportDepartmentsPage {
WebDriver driver;
@FindBy(css = "a[id='btnDownloadTemplate']")
private WebElement clickingHereLink;
@FindBy(css = "a[id='btnImport']")
private WebElement importButton;
@FindBy(css = "input[id='Excel']")
private WebElement browseButton;
@FindBy(css = "a[id='btnClose']")
private WebElement closeButton;
@FindBy(css = "input[id='readOnly']")
private WebElement browseTextbox;
public ImportDepartmentsPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void clickClickingHereLink() {
clickingHereLink.click();
}
public void clickImportButton() {
waitForFileToBeSelected(browseTextbox,"value", "AddDepartments.xlsx");
importButton.click();
}
public void clickBrowseButton() {
browseButton.click();
}
public void typeBrowseTextbox(String loc) {
browseTextbox.sendKeys(loc);
}
public void clickCloseButton() {
closeButton.click();
}
}
Hi,
ReplyDeleteCan you please let me know how do we call two web element from other class in pom.
Thanks in advance.