QA Tester Beginner Series: A beginner's guide to Page Object Model (POM) and Page Factory
If you've have an interest in software test automation, at some point you will find yourself asking one or all of the following questions "What on earth is Page Object Model (POM)","Is it important to test automation", "Do i have to learn it" "How long will it take me to learn it". If you're like me which you probably are, you probably find yourself in a state of panic asking yourself all these questions in quick succession. Now while i'm no "expert" (not yet anyways), i can offer some perspective on the subject (feel free to disregard). And although i cannot answer all of those questions explicitly, i can provide you with some insights in this not so brief post.
Page Object Model(POM)
If you're familiar with any sort of front-end web development, you've probably come across the Document Object Model(DOM). The DOM is widely considered as a sort of Application Programming Interface (API) for HTML and XML documents that allows the logical structure of a document to be accessed and manipulated; the Page Object Model(POM) operates somewhat similarly in principle. You could effectively "argue" that POM is to web application test automation what DOM is to front-end web development. Page Object Model is a design pattern in Selenium that creates an object repository for storing all web elements. This is useful because it helps test automation engineers reduce code duplication and improves their ability to maintain test cases. In page object model, each web-page of an application is considered as a class file. With each class file containing the web elements of a particular web-page. These elements are then used by testers to perform operations on the website under test.
Upsides
- Immediately, the obvious advantage with the POM is the ease with which it allows you to maintain your test cases on the likelihood that there is some change in a UI/Web element. A good example of this would be if an element like a drop-down menu was changed to a check-box. POM would help you to identify the modified page due to every individual page having a separate class file.
- The object repository is independent of test cases i.e they are separate entities and what this means is that the same object repository can be re-used for a different purpose and with different tools. For example, a repository can be used to execute functional tests with a framework like TestNG and at the same time be used for acceptance testing with Cucumber.
- By separating repository objects and test cases, less code is used and the operation is optimized as the pages become re-usable.
- Scripts become more readable and easy to follow as methods get more realistic names which can easily associated to the operation they are performing.
Implementation
Say the Application under Test (AUT) is a your private gmail account, the basic structure of the POM framework where all the web elements and the various methods that operate on them are maintained inside a class file. A simple task like verification should be separate as part of the test methods.
Sidebar- To implement the POM, we shall be making use of the Guru99 demo site which you can get to using the link demo.guru99.com/v4 Initially the site asks you to enter your email Id to get access to the demo test site. Don't worry it's completely safe, just enter a valid email address and a few moments later, you will be issued with a user profile complete with an id and password which should grant you access to the demo site.
Test-Case: Go to the guru99 Demo site.
- Navigate to the guru99 login page; demo.guru99.com/V4
- To validate that you're in the right homepage, check that the text "Guru99bank" is present
- Login to the application with the credentials you were provided
- Verify that the homepage contains the text "Welcome To Manager's Page of GTPL Bank".
For this use-case, we are concerned with 2 pages namely
- The Login Page
- The Manager's page (the page shown when you enter your user credentials) For this reason, we create 2 separate java classes for Objects/Web Elements in selenium
Guru99 Login page POM
Taking a look at this page, we can observe a couple of crucial web elements we use on this page. Namely ;
- The Username element.
- The password element.
- The title text (which we use to verify that we're actually on the right webpage)
- The Login button
For the login page, the code below defines all the elements on that page
To test that this page of the application works as intended, the test page has the code below
Guru99 Manager's page in Selenium
For this page the crucial element that we use is the title of the page that validates that login to the Manager's page was successfully completed.
Page Factory
Page Factory is an in-built Page Object Model framework concept for Selenium WebDriver but it is very optimized and used for initialization of page objects or to instantiate the Page object itself. Page Factory initializes Page class elements without the use of "FindElement(s)" instead using the @FindBy annotation to find WebElements. The annotation can find elements by tagName, partialLinkText, linkText, name, id, css, xpath, and className. It also uses the initElements method to initialize web elements.
Implementation
From the previous example, PageFactory can be implemented as follows:
From the practice exercise, the code below is used to identify elements present on the BrowserStack Home Page, speciffically the page header. As earlier mentioned, this is done using the "@FindBy" annotation on both pages of the AUT.
@FindBy(xpath = "//h1")
WebElement Header;
After items have been identified, the next step is to initialize these items using the snippet below. Again this is done on both pages of your application.
public "ClassName"(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
Actions are performed on the identified items using public void methods. This is repeated for both pages of the application under test (AUT).
public void "methodName"(){
//code that signifies what you want the method to do e.g verify the header of the page String getheadertext = Header.getText(); assertEquals("Testing Made Easy", getheadertext);
}
After identifying the objects and initializing them,the next step is to create the test. The test is created on a seperate class file. On this class file you create your tests. Since we have to pages on the AUT, it makes sense to use TestNG test annotations to initialize the browser object and navigate to the website. We can then use "priority=0" to prioritze our testcases in the order that makes the most sense for our execution. However, for these tests to be executed effectively, we have to ensure that objects we created on both pages of the AUT are properly referenced on the test page. We can achieve this by importing both pages of the AUT on the test page. This would look something like this: import PackageName.ApplicationPage;. Now we can properly reference the items that we initialized. Our test annotation looks something like the snippet below:
@Test(priority = 1)
public void navigate_to_homepage_click_on_getstarted() {
objApplicationHomePage = new ApplicationHomePage(driver);
objApplicationHomePage.verifyHeader();
objApplicatHomePage.clickOnLogin();
}
Overall, POM and PageFactory are effective in creating page object repositories that come in handy when automating web application tests. This is a core skill you want to be able to demonstrate should you be required to take a technical assessment as part of a hiring process. This approach indicates to your potential employer that you have a "big-picture" approach to testing by considering facets like long-term test-case maintainability. Not to mention that implementing POM gives your code a far more structured and readable appearance for documentation purposes.
This is an image of test automation code in POM format
For comparison, if you were to write a snippet of the exact same code implemented without POM, you will probably end up writing somewhere around the same number of lines of code. Now i know what you're thinking "but QATestBro the difference isn't all that noticeable, I thought POM was supposed to make the code more concise? Why am i writing the same amount of code? It looks just about the same to me". Yes you're absolutely right and normally i would agree with you on that but bear in mind that this a fairly simple implementation of POM and when dealing with more complex projects with multiple pages and more web elements that need to be interacted with, the distinction is quite clear and the benefits of POM really comes to the fore. There is some claim that the results of implementing POM is not necessarily worth the effort required. But while i do agree that sometimes its implementation for simple and basic web automation tasks might be considered as "over-engineering", the POM approach can be considered a best-practice for web-automation. For more information on POM and Page-factory, you can check out the guru99.com website along with browserstack.com which are both valuable resources for anyone looking to start a career in software test automation. You can also check out Test Automation University, they have a lot of useful resources and provide you with a more structured pathway for your test automation career journey. That does it for this edition of our beginners series and my very first blog-post on hashnode.com. Hope you've enjoyed reading. This blog-post took me a lot longer than i care to admit and has given me a new found appreciation for content creators and the work they do. If you liked this post and found it useful, you can leave a comment or follow me on twitter @4EVER1CONIC where i tweet some useful stuff you might find interesting. Hopefully we can do this again soon. Until next time.