Nishanth Balaji
Nishanth Balaji

Reputation: 11

Playwright - Get by Role locator with Dynamic elements

I've got an element with locator as getByRole('cell', {name : 'Hold (10)}). Now the (2) is dynamic and changes based on the number of entries. How can I write the framework to only check for Hold and ignore the last 4 characters?

I tried with * but I think this would be incorrect. Any help is appreciated. I've got multiple elements which are suffixed with dynamic entries in our page, so this would help almost all of them.

Upvotes: 0

Views: 7597

Answers (1)

ggorlen
ggorlen

Reputation: 57195

From the comments, it sounds like you have a table cell:

const playwright = require("playwright"); // ^1.39.0

const html = `<!DOCTYPE html><html><body>
<table>
  <tr>
    <td>  Hold (10)  </td>
  </tr>
</table>
</body></html>`;

let browser;
(async () => {
  browser = await playwright.firefox.launch();
  const page = await browser.newPage();
  await page.setContent(html);
  const cell = page.getByRole("cell", {name: /\bhold\b/i});
  console.log(await cell.textContent()); // => Hold (10)
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

The regex can be whatever you want. /\bhold\b/i is case insensitive and uses word boundaries. You could use /^Hold/ to make sure the name starts with Hold, or be ultra-precise, like /^Hold \(\d+\)$/.

As an assertion, I'd use:

import {expect, test} from "@playwright/test";

const html = `<same as above>`;

test("cell has Hold text", async ({page}) => {
  await page.setContent(html); // or goto in a real test
  await expect(page.getByRole("cell")).toHaveText(/^ *Hold\b/);
});

Regex behavior is a bit different for .toHaveText, so be sure to test both happy and sad paths thoroughly to avoid a false positive.

Upvotes: 0

Related Questions