Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

An object repository in Selenium WebDriver is a central place where you store the locators of your web elements, kept separate from your test logic. Instead of hard-coding an XPath or CSS selector inside every test, you keep all locators in one location and reference them by name. Selenium WebDriver has no built-in object repository, so you build one yourself, most commonly with a properties file, an XML or JSON map, the What Is an Object Repository in Selenium? approach known as the Page Object Model, or PageFactory.
A locator is the address Selenium uses to find an element on a page, for example an ID, a name, a CSS selector, or an XPath. In a small script it is tempting to drop these locators straight into your test code. As soon as the suite grows, that becomes a maintenance trap: the same locator appears in several tests, and when the UI changes you have to hunt down and fix every copy.
An object repository solves this by treating locators as data rather than code. The benefits are concrete:
No. This is the point that trips up testers moving from commercial tools. UFT (formerly QTP) ships a dedicated, GUI-driven object repository out of the box. Selenium WebDriver does not. It is a browser automation library, not a full test framework, so it leaves the repository design up to you. The upside is flexibility: you can store locators in whatever format fits your project, from a flat text file to a fully encapsulated set of page classes.
Because there is no default, several patterns have become standard. They all serve the same goal, separating locators from logic, but differ in structure and effort:
The properties file is the simplest concrete object repository, and it is a great way to understand the idea. The flow is short:
First, the repository itself. A locator file might look like this:
# objectRepo.properties
# key = locator value
username.input = //input[@id='user-name']
password.input = //input[@id='password']
login.button = #login-button
error.message = .error-message-containerNext, a small utility class reads the file and hands back any locator by its key:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ObjectRepository {
private final Properties properties = new Properties();
public ObjectRepository() throws IOException {
// Load the repository once when the class is created
FileInputStream file = new FileInputStream(
System.getProperty("user.dir") + "/src/test/resources/objectRepo.properties");
properties.load(file);
file.close();
}
// Fetch a locator string by its key
public String getLocator(String key) {
return properties.getProperty(key);
}
}Your test then refers to locators by name. If the login button's selector changes, you edit only the properties file:
ObjectRepository repo = new ObjectRepository();
driver.findElement(By.xpath(repo.getLocator("username.input"))).sendKeys("standard_user");
driver.findElement(By.xpath(repo.getLocator("password.input"))).sendKeys("secret_sauce");
driver.findElement(By.cssSelector(repo.getLocator("login.button"))).click();As suites grow, most teams move from a flat file to the Page Object Model. Here the object repository is the page class itself: locators and the actions that use them live together. PageFactory makes this cleaner by letting you declare locators with @FindBy annotations, while PageFactory.initElements wires the elements to the driver:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage {
// Locators live here as the page's object repository
@FindBy(id = "user-name")
private WebElement usernameInput;
@FindBy(id = "password")
private WebElement passwordInput;
@FindBy(css = "#login-button")
private WebElement loginButton;
public LoginPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
// Behavior is exposed as methods, hiding the locators from tests
public void login(String user, String pass) {
usernameInput.sendKeys(user);
passwordInput.sendKeys(pass);
loginButton.click();
}
}Tests now call new LoginPage(driver).login(user, pass) and never touch a raw locator. That keeps the test readable and confines every locator to a single class.
These two terms are often used interchangeably, but they sit at different levels. The object repository is the concept: keep locators in one central place. The Page Object Model is one implementation of that concept, where each page becomes a class and its locators are class fields. A properties or XML file is a different implementation that keeps the same locators in an external file. In short, POM is a kind of object repository, not a competitor to it.
The table below contrasts the two most common implementations so you can pick the right one for your project:
| Aspect | Properties File | Page Object Model |
|---|---|---|
| Where locators live | External .properties file | Inside page classes |
| Setup effort | Low, needs a small reader class | Higher, one class per page |
| Type safety | No, locators are plain strings | Yes, with WebElement fields |
| Best suited to | Small to medium suites | Large, long-lived suites |
No. Unlike commercial tools such as UFT/QTP, Selenium WebDriver ships no built-in object repository. You implement one yourself using a properties file, an XML or JSON map, plain Java constants, the Page Object Model, or PageFactory.
An object repository is the concept of storing locators in one central place. The Page Object Model is one way to implement that concept, where each page becomes a class and its locators live as fields inside that class. A properties or XML file is another implementation that keeps locators in an external file instead of in code.
Load the file with a Java Properties object: open the .properties file in a FileInputStream, call load() on it, then fetch each locator by key with getProperty("loginButton"). Pass the returned value into a locator strategy such as By.xpath() or By.cssSelector() before calling findElement.
A properties file is a good fit for small to medium suites where you want a lightweight, editable list of locators. The Page Object Model scales better for large projects because it encapsulates locators and page actions in classes, gives you type safety, and keeps related behavior together.
PageFactory is a built-in Selenium support class for the Page Object Model. You annotate WebElement fields with @FindBy to declare their locators, then call PageFactory.initElements(driver, this) to lazily initialize those elements when they are first used.
Because UI locators change often. Centralizing them means a changed XPath or ID is updated in one place, and every test that references it picks up the fix automatically. It also removes duplicate locators, reduces typos, and keeps test logic readable.
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance