Lessons in this course (10)

5. Page Object Model and framework design

Intermediate★ Must knowLesson 5 of 10

Page Object Model (POM): one class per page/component holding its locators and actions; tests call meaningful methods instead of raw locators — locator changes are fixed in one place.

csharp
public class LoginPage(IWebDriver driver)
{
    private IWebElement Email => driver.FindElement(By.Id("email"));
    private IWebElement Password => driver.FindElement(By.Id("password"));
    private IWebElement SignIn => driver.FindElement(By.CssSelector("[data-testid='sign-in']"));

    public DashboardPage LoginAs(string email, string password)
    {
        Email.SendKeys(email); Password.SendKeys(password); SignIn.Click();
        return new DashboardPage(driver);   // fluent navigation
    }
}

[Test]
public void Valid_user_reaches_dashboard()
{
    var dashboard = new LoginPage(Driver).LoginAs(TestUsers.Standard.Email, TestUsers.Standard.Password);
    Assert.That(dashboard.Title, Is.EqualTo("Dashboard"));
}

Typical framework layout:

text
Tests/            test classes (NUnit/xUnit or Reqnroll features)
Pages/            page objects / components
Core/             DriverFactory (browser, headless, grid), config (appsettings.json), waits, logging
Data/             test data builders (Bogus), JSON/Excel data
Api/              API clients for setup/teardown (create data via API, not UI)
Reports/          Allure/Extent configuration, screenshots on failure

Principles: tests independent and order-free, data created per test (via API/DB), no hard-coded waits or environments, parallel-safe (one driver per test/thread), screenshot + logs on failure.