Page Object Model
The Page Object Model (POM) keeps UI tests readable and easy to maintain as the application grows.
On this page · 5 min · Intermediate
On this page
- Learning objectives
- Explanation
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Intermediate
- Updated
- Oct 29, 2026
Related tutorials
Learning objectives#
- Create page object classes
- Keep locators private
- Return the next page from actions
- Write readable tests on top
Explanation#
Each page or reusable component gets a class exposing user actions (LoginAs, SearchFor) and read-only state (ErrorMessage).
Locators stay private inside the class; if the UI changes, you fix one place.
Actions that navigate return the next page object, giving fluent, readable tests.
Keep assertions in tests, not page objects, so pages stay reusable.
Code example: Login page object and test#
public class LoginPage(IWebDriver driver)
{
private readonly By email = By.Id("email");
private readonly By password = By.Id("password");
private readonly By submit = By.CssSelector("[data-testid='login-submit']");
private readonly By error = By.CssSelector("[role='alert']");
public LoginPage Open() { driver.Navigate().GoToUrl(Config.BaseUrl + "/login"); return this; }
public DashboardPage LoginAs(string user, string pass)
{
driver.FindElement(email).SendKeys(user);
driver.FindElement(password).SendKeys(pass);
driver.FindElement(submit).Click();
return new DashboardPage(driver);
}
public string ErrorMessage => driver.FindElement(error).Text;
}
[Test]
public void Valid_user_sees_their_name()
{
var dashboard = new LoginPage(driver).Open().LoginAs("asha@example.com", "Passw0rd!");
Assert.That(dashboard.Greeting, Is.EqualTo("Namaste, Asha"));
}
The test reads like a user story; a changed login button selector is fixed in LoginPage only.
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- Locators are private fields.
- Open and LoginAs describe user actions.
- LoginAs returns the DashboardPage.
- The test asserts on the result.
Real-world use case#
A suite of 300 UI tests survives a login redesign with a two-line change in one class.
Common mistakes#
One UI change breaks dozens of files.
It hides intent and limits reuse.
Best practices#
- One class per page/component
- Private locators
- Return next page objects
- Assertions in tests only
Remember this#
Page = class with actions.
Locators in one place.
Tests assert; pages act.
Practice exercise#
Your task: Add a SearchFor(term) action to a HeaderComponent that returns a ResultsPage.
Show solution
public ResultsPage SearchFor(string term)
{
driver.FindElement(By.Name("q")).SendKeys(term + Keys.Enter);
return new ResultsPage(driver);
}
Mini quiz#
Where should assertions normally live in POM?
Want more? Practise all Automation Testing MCQs · Automation Testing interview questions
My notes#
Saved in this browser.