javascriptnode.jsplaywrightplaywright-test

In playwright asserting for the existence of a text in a element


There is an element that loads up after a few seconds the form is submitted(page doesn't reload after submission). I want to assert that this element has some text value in it. Value doesn't matter but there should be some text in the element.

Currently I am asserting it like this -

await expect(await targetPage.locatorToSomeElement.innerText()).toBeTruthy();

OR this -

await expect(targetPage.locatorToSomeElement).toBeTruthy();

targetPageis class instance of Page Object Model class TargetPage and locatorToSomeElement is locator with value page.getByTestId("some-span-element");

Please let me know the best way to achieve this. Please check below points as well.

  1. The first statement seems like a manual assertion? await is inside expect? It's a bad practice? https://playwright.dev/docs/best-practices#use-web-first-assertions

  2. toBeTruthy() is an assertion that doesn't not auto wait so I believe second statement will always be true?


Solution

  • Correct--you need to use web-first assertions to ensure auto-waiting.

    How about:

    await expect(targetPage.locatorToSomeElement).not.toBeEmpty();
    

    toBeEmpty Added in: v1.20

    Ensures the Locator points to an empty editable element or to a DOM node that has no text.

    or, more flexibly:

    await expect(targetPage.locatorToSomeElement).toHaveText(/\S/);
    

    The regex here means "contains at least one non-space character".

    Complete, runnable example:

    import {expect, test} from "@playwright/test"; // ^1.30.0
    
    test("h1 is eventually not empty", async ({page}) => {
      await page.setContent(`<h1></h1><script>
        setTimeout(() =>
          document.querySelector("h1").textContent = "ok",
          2000
        )</script>
      `);
      await expect(page.locator("h1")).toBeEmpty();
      await expect(page.locator("h1")).toHaveText(/\S/);
      await expect(page.locator("h1")).not.toBeEmpty();
    });
    
    test("h1 is eventually empty", async ({page}) => {
      await page.setContent(`<h1>test</h1><script>
        setTimeout(() =>
          document.querySelector("h1").textContent = "   ",
          2000
        )</script>
      `);
      await expect(page.locator("h1")).not.toHaveText(/\S/);
      await expect(page.locator("h1")).toHaveText(/^\s*$/);
    });
    
    test("multiple paragraphs have text", async ({page}) => {
      await page.setContent(`<p>a</p><p>b</p>`);
      await expect(page.locator("p")).toHaveText([/\S/, /\S/]);
    });
    

    I'm not sure what your use case is, but you may want to strengthen the assertion further. For example, .toHaveText(/.{42,}/) ensures there are at least 42 characters present.