Selenium Page Factory with JSON and Properties

Hemanth Sridhar
2 min readSep 8, 2019

Selenium Page Factory helps us to implement the Page Object Model design pattern. One of the limitations with the page factory however, is that we can’t read locators from an external resource like a property file or a JSON. To achieve this I have developed custom page factory which is available in maven central.

An example project on the usage is available in github.

In Maven,

In Gradle,

HOW TO USE

If we have a JSON for example,

  • name : name of the locator (forgottenPasswordLinkInAlert)
  • type : type of the locator ( xpath, css, id etc..)
  • value : value of the locator (//div[@role=’alert’)

@SearchBy

  • The @FilePath value must be the path to the json
  • The nameOfTheLocator value is optional. By default, the variable name is picked up.

Page Factory Initialization

@SearchAll & @SearchBys

There is also support to use @SearchAll just like @FindAll

There is also support to use @SearchBys just like @FindBys

HANDLING DYNAMIC LOCATORS

Let us assume we have a json link below,

[
{
"name": "multipleParamsLink",
"type": "xpath",
"value": "//a[normalize-space()='%1$s']/following-sibling::a[normalize-space()='%2$s']/following-sibling::a[normalize-space()='%3$s']/following-sibling::a[normalize-space()='%4$s']"
}
]

Internally, String.format is used.

Observe %s or %1$s, %2$s and so on are important. These are the params that get replaced.

PageFactory.initElements(new SearchWithFieldDecorator(new FileBasedElementLocatorFactory(driver, this)), this);

protected ByLocators byLocators;

public InitPageObjects(WebDriver driver) {
this.driver = driver;
byLocators = PageFactoryLoader.newInstance().initElements(ByLocators.class);
}

byLocators = PageFactoryLoader.newInstance().initElements(ByLocators.class);


@FilePath(value = "classpath:page_objects/json/page_objects.json")
protected interface ByLocators {

@SearchBy
By multipleParamsLink(String about, String advertising, String business, String howSearchWorks);

}

USAGE

By imagesRelativeLink = RelativeLocator.with(byLocators.linkByText("Images")).toRightOf(byLocators.linkByText("Gmail"));
driver.findElement(imagesRelativeLink).click();

TYPE

type we provide in JSON is case-sensitive

Below is a list of all the types supported

  • id
  • css
  • className
  • xpath
  • linkText
  • partialLinkText
  • name
  • tagName
  • accessibilityId
  • uiautomator
  • IosUIautomation
  • iosClassChain
  • androidViewTag
  • iOSNsPredicateString
  • image
  • windowsAutomation
  • custom

--

--