skip to Main Content

I am trying to verify if the text exists when opening the page, I tried using toHaveText and toEqual but I encountered the same error as provided below:

Error: expect(received).toContain(expected) // indexOf
Expected value: "Your Versatile Partner for Better Offshoring" 
Received object: {"page": {"_guid": "page@a8169cc2ca7780c3f53341729020b35a", "_type": "Page"}} 
19 | const Homepage = new HomePage(page); 
20 | const expectedTitle = 'Your Versatile Partner for Better Offshoring'; 
> 21 | expect (Homepage).toContain(expectedTitle);

Here is my full code:

export class HomePage {
    constructor(page) {
        this.page = page;
    }

    async getTitle() {
        const Homepage = await this.page.locator("h1[class='display-4 mb-4 mt-8']");
    }
}

Important class:

import { test, expect } from "@playwright/test";
import { LoginPage } from "../pages/unientSite-page/LoginPage";   
import { HomePage } from "../pages/unientSite-page/Homepage";

test.use({
    launchOptions: { slowMo: 1000 },
    headless: false
});


test('Login', async ({ page }) => {
    //Login page
    const loginPage = new LoginPage(page);
    await loginPage.goto();

    //Homepage
    const Homepage = new HomePage(page);
    const expectedTitle = 'Your Versatile Partner for Better Offshoring';
    expect (Homepage).toContain(expectedTitle);

});

I’m not sure how to fix this or maybe you can suggest an alternative way to verify the text when accessing the page?

2

Answers


  1. Suggested way to verify page title:

    await expect(page).toHaveTitle(/.*expectedText/);
    
    Login or Signup to reply.
  2. A word of advice: try to avoid writing premature abstractions. If you’re new to Playwright and struggling to get correct code, I would forget about the POM for starters. Once you have correct code, then you can factor it out to the POM. If you try to do multiple unfamiliar things at once, it’s easy to get into a confused state.

    The assertion toContain checks whether a string has a substring. Passing in a POM object won’t work.

    Most of your assertions will probably be locator assertions. The idiomatic Playwright approach is to use web-first assertions, so you probably won’t be using toContain much, unless it’s on some primitive string and there’s no locator involved. This doesn’t apply here–we have a locator.

    Here’s a minimal example of using toHaveText, which appears to be the most appropriate assertion:

    import {expect, test} from "@playwright/test"; // ^1.30.0
    
    test("header has correct text", async ({page}) => {
      await page.setContent(
        `<h1>Your Versatile Partner for Better Offshoring</h1>`
      );
      await expect(page.locator("h1"))
        .toHaveText("Your Versatile Partner for Better Offshoring");
    });
    

    Make sure you can run this test and see it pass:

    $ npx playwright test
    
    Running 1 test using 1 worker
    
      ok 1 test.spec.mjs:5:1 › header has correct text (1.0s)
    
    
      1 passed (13.0s)
    

    Always temporarily break the test to make sure it’s not giving false positives:

    await expect(page.locator("h1")).toHaveText("NO");
    
        Error: expect(received).toHaveText(expected)
    
        Expected string: "NO"
        Received string: "hello world"
        Call log:
          - expect.toHaveText with timeout 5000ms
          - waiting for locator('h1')
          -   locator resolved to <h1>hello world</h1>
          -   unexpected value "hello world"
    
          4 |
          5 | test("header has 'hello world' text", async ({page}) => {
        > 6 |   await expect(page.locator("h1")).toHaveText("NO");
            |                                    ^
          7 | });
    

    Next, write a POM. I’ll keep it simple and do it in one file, but you can break this into a separate file and import it.

    class HomePage {
      constructor(page) {
        this.page = page;
        this.header = page.locator("h1");
      }
    
      async goto() {
        // replace this.page.goto for example purposes
        await this.page.setContent(
          `<h1>Your Versatile Partner for Better Offshoring</h1>`
        );
      }
    }
    
    test.describe("home page", () => {
      test("header has correct text", async ({page}) => {
        const homePage = new HomePage(page);
        await homePage.goto();
        await expect(homePage.header)
          .toHaveText("Your Versatile Partner for Better Offshoring");
      });
    });
    

    Running this should give the same output.

    Once you have this set up, just add more locators as necessary to the construtor, then add higher-level action methods like fillOutCredentials, acceptCookies, etc, which consist of .fill() and .click() calls on your locators. A test might look like:

    const loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.fillOutCredentials();
    await expect(loginPage.username).toHaveText("some sample username");
    await expect(loginPage.password).toHaveText("**********");
    await loginPage.authenticate();
    await expect(page).toHaveTitle("Welcome to the App");
    

    Remember, the low-level page.click(), page.fill() calls can be generated and inlined in the test for starters, then factored out to a POM once all assertions are passing and thoroughly tested.

    Note that in defining the locator, a CSS selector like h1[class='display-4 mb-4 mt-8'] is not recommended in Playwright because it’s not user facing. Since I don’t have your DOM, I can’t offer a better suggestion, but maybe look for an aria role or use Playwright’s generator to have it pick the best one for you.

    Even if you do use a CSS selector, prefer h1.display-4.mb-4.mt-8 to the above [class='...'] attribute selector. The reason is that if the order of the classes change, or an extra class is added, the attribute selector breaks. The dot notation version isn’t so picky about things like class ordering and whitespace that you probably don’t need to verify.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search