The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Use Selenium’s Java PageFactory to initialize a Page Object whose WebElement fields are declared with @FindBy. In the page class constructor, call PageFactory.initElements(driver, this) with an existing WebDriver. PageFactory sets up lazy element proxies; by default, an element is looked up when your code calls a method on its proxy, not necessarily when the page object is constructed. See the Selenium Java PageFactory API for the current API contract.
Build and initialize a PageFactory Page Object
This example models a login page. It assumes your test has already created and configured a Selenium WebDriver, and that the page has elements matching the explicit locators.
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 {
private final WebDriver driver;
@FindBy(id = "username")
private WebElement username;
@FindBy(id = "password")
private WebElement password;
@FindBy(css = "button[type='submit']")
private WebElement submit;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void signIn(String user, String pass) {
username.sendKeys(user);
password.sendKeys(pass);
submit.click();
}
}
Navigate and use the object from test setup:
driver.get("https://example.com/login");
LoginPage login = new LoginPage(driver);
login.signIn("reader", "secret");
The example’s URL and credentials are illustrative: replace them with your application’s login address and test credentials. The class stores the driver here for page-specific navigation or other operations; PageFactory itself only needs it to initialize the fields.
Initialize an existing object or let PageFactory construct it
PageFactory.initElements(driver, this) decorates eligible fields on the object you have already constructed. If you want PageFactory to create the object and return it, use the class overload:
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
LoginPage login = PageFactory.initElements(driver, LoginPage.class);
The Java API prefers a constructor that takes WebDriver as its only argument and falls back to a no-argument constructor. It throws if the class cannot be instantiated. Use the existing-object overload when you want constructor control; use the class overload when its constructor requirements fit your page class.
How @FindBy and field-name lookup work
For a field annotated with @FindBy, the annotation supplies the locator. In the example, Selenium locates the username by HTML id, the password by id, and the submit button by CSS selector. Choose locators that match the actual page markup.
If an eligible WebElement field has no locator annotation, the default field decorator assumes that its Java field name corresponds to an element’s HTML id or name. For example, a field named email relies on matching page markup. This convention can be unclear or wrong when names differ, so use @FindBy when you need a specific locator or want the locator visible in the page class.
Rank #2
PageFactory also supports List<WebElement> fields. As with a single element, the list is represented by a proxy and is resolved when code uses it. The available lookup and decorator extension points are described in the Selenium pagefactory package API.
Free tools Windows power users keep installed
One-click scans. No signup required.
Understand lazy proxies, waits, and caching
When a lookup happens
Initialization does not mean that PageFactory has immediately found every annotated element. It prepares proxies for the fields. Under the default behavior, Selenium looks up the element when your code invokes a method on the proxy, such as sendKeys or click. This can be useful when a page object is created before an element is needed, but it does not itself guarantee that the page has finished loading or that the element is ready for interaction.
Wait for elements that appear asynchronously
The PageFactory package includes AjaxElementLocatorFactory and AjaxElementLocator, which support waiting up to a configured time for an element to appear before lookup fails. This is an available locator strategy, not a guarantee that every interaction will succeed: the element can still be absent, hidden, obstructed, or replaced after it is found. Choose a wait duration appropriate to the application and handle the relevant Selenium exceptions in the test.
Rank #3
Use @CacheLookup only when the element is stable
@CacheLookup changes the default repeated-lookup behavior by caching the element after it is found. That may be suitable for an element whose identity and presence remain stable for the relevant test interaction. It can cause stale-element problems when the page updates or replaces that DOM node. Do not apply it as a general speed setting to dynamic pages.
PageFactory versus direct By locators
PageFactory is an initialization style for Java Page Objects, not a requirement for using the Page Object pattern. Selenium’s design guidance describes page objects as models of pages or components that centralize page-specific behavior. Its official example uses direct By locators rather than PageFactory, so either approach can fit a well-designed page object. See Selenium’s Page Object Models guidance.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →| Choice | How locators are expressed | Lookup and refresh behavior | Useful consideration |
|---|---|---|---|
| PageFactory fields | Declare WebElement or List<WebElement> fields, commonly with @FindBy. |
Fields use proxies; by default lookup occurs when a proxy method is called. @CacheLookup changes repeated lookup behavior. |
Convenient when the team prefers annotated page fields; the locator is declared separately from the method that uses it. |
Direct By locators |
Declare a By locator and call driver.findElement(locator) where needed. |
The method controls when lookup is repeated, making a fresh lookup easy to express for each action. | The locator and action can sit close together; this is the style shown in Selenium’s official Page Object example. |
For dynamic interfaces, direct lookup inside a page method can make refresh behavior more explicit. If you use PageFactory, understand that a proxy is not the same as a permanently stored, already-found element; be especially deliberate before enabling caching.
Rank #4
Keep the Page Object focused on page behavior
Keep locators and interactions inside the page or component object, and expose methods that describe what a user or test can do, such as signIn, rather than making tests manipulate page internals. Selenium’s guidance says page objects generally should not make test assertions; tests should verify outcomes. A page object can represent a reusable component as well as a whole page. PageFactory helps initialize fields, but it does not enforce these design choices.
Troubleshoot common PageFactory problems
- Element not found when interacting: Check that the locator matches the current DOM and that navigation or rendering has reached the required state. Remember that lazy lookup may happen on the first proxy method call rather than during construction.
- Field resolves to the wrong element or nothing: If relying on an unannotated field, verify its name matches the element’s HTML
idorname. Otherwise, add an explicit@FindBylocator. - Stale element after a page update: A cached element may refer to a DOM node that has been replaced. Remove
@CacheLookupwhere appropriate and consider a fresh lookup or an explicit wait for the updated state. - PageFactory cannot create the page class: With the class overload, provide a constructor accepting only
WebDriveror a no-argument constructor, and make sure the class can be instantiated. Alternatively, construct the page yourself and callinitElements(driver, page). - Intermittent failure on a slowly appearing element: Initialization alone is not a readiness wait. Consider the pagefactory Ajax locator support or an explicit Selenium wait suited to the condition you need.
Or skip the browser setup
If the task is to capture a website rather than interact with it through a Selenium test, ScreenshotNeo offers a screenshot API and MCP server. One GET request returns an image or PDF; this cURL example saves a WebP capture:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsSign up free for 1,000 screenshots a month with no card.
Best Value
Frequently Asked Questions
Does PageFactory work with Selenium in languages other than Java?
The PageFactory API discussed here is Selenium’s Java support API; this guide’s imports, annotations, and examples are Java-specific.
Does PageFactory wait for an element to become clickable?
No. Its default lazy lookup is not a clickable-condition wait. Use a suitable wait for the state your interaction requires.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




