Skip to contentPlayForge

Should page objects contain assertions?

Written by Jatin Thacker, Automation Architect · Updated

Keep the assertions that check behaviour in the test, and let a page object assert only that its own page is ready. A reader should see what a test claims without opening another file.

This answer is one piece of Chapter 20: Page Objects.

  • Page Objects in Playwright
  • Building the Page Object Layer
  • Anti-Patterns & Best Practices
  • Practice and interview questions: Framework Architecture & Page Object Model

This is a practitioner's rule rather than something Playwright enforces, and teams draw the line in slightly different places. The line this course uses is ownership: the page never loaded is the page object's problem, the total was wrong is the test's.

Playwright's own page object example does put an expect inside a method. Its getStarted() clicks a link and then waits for the next page's header with toBeVisible(). That is a readiness guard: the method refuses to return until the navigation it started has landed, so no caller has to repeat the wait.

A method like verifyCartTotal() is different. It hides the claim the test exists to make. When it fails, the report points at a line inside a helper, and anyone reviewing the test has to open the class to learn what was checked.

In the example, goto() waits until all 24 product cards are present. The test then adds the grinder and states the business claim where it can be seen: toHaveText('₹11,900').

po-assertions.spec.js(https://practice.learnplayforge.com)
import { test, expect } from '@playwright/test'; class CatalogPage { constructor(page) { this.page = page; this.products = page.getByTestId('product-card'); this.cartTotal = page.getByTestId('cart-total'); } // Readiness guard: the method does not return until the grid has loaded. async goto() { await this.page.goto('/catalog.html?mock=static&seed=42&autologin=1'); await expect(this.products).toHaveCount(24); } async addToCart(sku) { await this.page.locator(`article[data-sku="${sku}"]`) .getByRole('button', { name: 'Add to cart' }).click(); } } test('the grinder costs ₹11,900 in the cart', async ({ page }) => { const catalog = new CatalogPage(page); await catalog.goto(); await catalog.addToCart('MRD-1003'); // The business claim stays in the test, where a reader can see it. await expect(catalog.cartTotal).toHaveText('₹11,900'); });
Output
1 passed (2.6s)
Test yourself
Which expect belongs inside a page object method, by the rule on this page?

Practised in the full course: the drill Un-awaited Page Object chains.

See the chapter

AI can write the test now. The job is knowing whether it checks anything. That's what the course teaches, one chapter at a time.

163 lessons · 226 drills · start free

← All questions

Training a team? Talk to us.