Click here to Skip to main content
14,430,233 members

How to generate Page Object Pattern Classes (SeleniumQA) to test Web/Mobile Pages

Rate this:
0.00 (No votes)
Please Sign up or sign in to vote.
0.00 (No votes)
6 Sep 2018CPOL
A utility for generating Selenium based Page Object Pattern classes used in web/mobile test cases.

Introduction

What is NEO PageFactory?

Intro to SeleniumQA PageFactory

Selenium QA PageFactory is a well known utility that enables developers and testers to implement automated web / mobile tests based on the Page Object Pattern. In a nutshell, all pages under test are individually (1:1) mapped to a phyical (Java,C# .NET,...) page test class. An instance of a page test class is refered to as a Page Object. This object is typically used to programmically interact with the page under test, for example, by automatically filling in a form.

Page objects contain getters and setters which prepresent page elements of the page under test. These getters/setters are typeically used to set/get data to/from these elements. There are also methods in the class which are used to fire of a physical page events, such as click, doubleClick etc.

Problems when using SeleniumQA PageFactory

Using Selenium QA PageFactory out of the box, all page classes are created manually by the tester (or developer). This can often lead to complications especially in cases where pages under test are rich with page elements (i.e. where the number of elements on pages is significantly large). Problems can also occur around the initial stage of development from a testers perspective, where element id's, names, xpath locations etc are frequently changed by developers (especially when these changes are not expected). 

SeleniumQA problems can be minimised using NEO PageFactory

NEO PageFactory was developed to (at least) minimise these issues. It does so by by going one step further and GENERATES all page classes being used for all tests. This a. reduces time taken in creating page classes (as these classes can be used straight away within the test) and can also be used at the UNIT testing stage for every build as a diff between page class generations. The latter becomes very useful because it minimises (dev page modification) issues during the acceptance testing phase (which is normally the stage that page modification issues are generally discovered).

How does it work?

Neo PageFactory works by scanning all HTML documents (via HTTP or a local HTML text file) for standard (or tailored) elements such as, input, a, select etc and, based on elements discovered, generates page object pattern class files containing getters and setters, etc. These getters/setters (and action methods, such as click, doubleClick etc) represent the elements found. The naming convension of each method is determined either by their element id's, name's or text used to display the element.

Usage

1. Clone and Install neopagefactory

(NOTE: This step need only be done once)

# Assuming your root workspace for all projects is ~/projects
cd ~/projects

# Clone NEO PageFactory ...
git clone https://github.com/desmccarter/neopagefactory

# Go into the newly created/cloned folder ...
cd neopagefactory

# Install ...
mvn clean install

2. Generate Your POP (Page Object Pattern) Classes

# Assuming your project workspace is ~/projects/myproject
# and that you are working in a BASH instance ...

# Go to YOUR test project folder
cd ~/project/myproject

# Generate Google.com (for example) Page Object Pattern classes
# for your project ...

~/project/nopagefactory/generateclasses -url https://www.google.com

Page class output

Page classes are (by default for now) created in the current working directory under src/main/java/com/dmcc/sample/pages. The naming convention is NameOfPagePage.java, where NameOfPage is formed from the URL name. For example, a page class generated from www.google.com would have the name GooglePage.java, under src/main/java/com/dmcc/sample/pages/google.

 

Example Classes Generated by NEO PageFactory

The following page classes shown were generated from NEO PageFactory.

Google.com

package com.dmcc.sample.pages.google;

import com.dmcc.pagegen.exceptions.PageException;
import com.dmcc.sample.pages.google.GoogleField;
import com.dmcc.pagegen.page.mccarterp.McCarterPage;

public class GooglePage extends McCarterPage{

private final String url="https://www.google.com";
private final String rRoot="../pgenexamples/src/test/resources";

	public GooglePage navigate()throws PageException {
		this.setResourcesRoot(rRoot);
		this.navigate(url);
		return this;
	}

	public void setQ(final String value) throws PageException{
		this.setValue(GoogleField.Q, value);
	}

	public void clickQ()throws PageException{
		this.click(GoogleField.Q);
	}

	public void clickGoogleSearch()throws PageException{
		this.click(GoogleField.GoogleSearch);
	}

	public void clickIMFeelingLucky()throws PageException{
		this.click(GoogleField.IMFeelingLucky);
	}
}

Facebook.com

package com.dmcc.sample.pages.facebook;

import com.dmcc.pagegen.exceptions.PageException;
import com.dmcc.sample.pages.facebook.FacebookField;
import com.dmcc.pagegen.page.mccarterp.McCarterPage;

public class FacebookPage extends McCarterPage{

private final String url="https://www.facebook.com";
private final String rRoot="../pgenexamples/src/test/resources";

	public FacebookPage navigate()throws PageException {
		this.setResourcesRoot(rRoot);
		this.navigate(url);
		return this;
	}

	public void setEmail(final String value) throws PageException{
		this.setValue(FacebookField.Email, value);
	}

	public void clickEmail()throws PageException{
		this.click(FacebookField.Email);
	}

	public void setPass(final String value) throws PageException{
		this.setValue(FacebookField.Pass, value);
	}

	public void clickPass()throws PageException{
		this.click(FacebookField.Pass);
	}

	public void clickLogIn()throws PageException{
		this.click(FacebookField.LogIn);
	}

	public void setFirstname(final String value) throws PageException{
		this.setValue(FacebookField.Firstname, value);
	}

	public void clickFirstname()throws PageException{
		this.click(FacebookField.Firstname);
	}

	public void setLastname(final String value) throws PageException{
		this.setValue(FacebookField.Lastname, value);
	}

	public void clickLastname()throws PageException{
		this.click(FacebookField.Lastname);
	}

	public void setRegEmail(final String value) throws PageException{
		this.setValue(FacebookField.RegEmail, value);
	}

	public void clickRegEmail()throws PageException{
		this.click(FacebookField.RegEmail);
	}
...

Lastminute.com

package com.dmcc.sample.pages.lastminute;

import com.dmcc.pagegen.exceptions.PageException;
import com.dmcc.sample.pages.lastminute.LastminuteField;
import com.dmcc.pagegen.page.mccarterp.McCarterPage;

public class LastminutePage extends McCarterPage{

private final String url="https://www.lastminute.com";
private final String rRoot="../pgenexamples/src/test/resources";

	public LastminutePage navigate()throws PageException {
		this.setResourcesRoot(rRoot);
		this.navigate(url);
		return this;
	}

	public void setDpSearchFrom(final String value) throws PageException{
		this.setValue(LastminuteField.DpSearchFrom, value);
	}

	public void clickDpSearchFrom()throws PageException{
		this.click(LastminuteField.DpSearchFrom);
	}

	public void setDpSearchTo(final String value) throws PageException{
		this.setValue(LastminuteField.DpSearchTo, value);
	}

	public void clickDpSearchTo()throws PageException{
		this.click(LastminuteField.DpSearchTo);
	}

	public void setDpCheckIn(final String value) throws PageException{
		this.setValue(LastminuteField.DpCheckIn, value);
	}

	public void clickDpCheckIn()throws PageException{
		this.click(LastminuteField.DpCheckIn);
	}

	public void setDpCheckOut(final String value) throws PageException{
		this.setValue(LastminuteField.DpCheckOut, value);
	}

	public void clickDpCheckOut()throws PageException{
		this.click(LastminuteField.DpCheckOut);
	}

	public void setGoingTo(final GoingToEnum value) throws PageException{
		this.setValue(LastminuteField.GoingTo, value.toString());
	}

	public void clickGoingTo()throws PageException{
		this.click(LastminuteField.GoingTo);
	}

	public void setLeavingFrom(final LeavingFromEnum value) throws PageException{
		this.setValue(LastminuteField.LeavingFrom, value.toString());
	}

	public void clickLeavingFrom()throws PageException{
		this.click(LastminuteField.LeavingFrom);
	}
}

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Desmond McCarter
Web Developer
United Kingdom United Kingdom
Des is a Technical Architect working for a private telecoms based company in the United Kingdom. He has been involved in programming for over 14 years and has worked on many platforms including UNIX, Linux and Windows.

Language specialities are C, C++, C#.NET, Java & J2EE and shell scripting (especially on UNIX/Linux). Also enjoys writing and optimising SQL scripts.

Des is engaged to a lovely girl called Lisa!

Comments and Discussions

 
-- There are no messages in this forum --
Article
Posted 6 Sep 2018

Stats

4.1K views
1 bookmarked