typescript - Φιλτράρισμα για μια κλάση και ρόλο στο Playwright;


Θέλω να φιλτράρω για έναν σύνδεσμο με την κλάση navbar__brand στον ιστότοπο του Playwright - μέσω Playwright:

Ο κώδικάς μου:

test("homepage has title and links to intro page", async ({ page }) => {
  await page.goto("https://playwright.dev/");

  const links = page.getByRole("link").locator(".navbar__brand");

  const count = await links.count();
  console.log("count is " + count); // zero instead of the expected one!
});

Τι κάνω λάθος; Γιατί δεν βρίσκει τον σύνδεσμο;

Απάντηση #1

Δεν βρίσκει τον σύνδεσμο επειδή ο εντοπιστής αναζητά μόνο τα παιδιά του στοιχείου <a>, το οποίο έχει ήδη βρεθεί μέσω getByRole. Με άλλα λόγια, δεν μπορεί να βρει τον εαυτό του στα παιδιά του.

Αν καταλαβαίνω σωστά το HTML σας, ο ψευδοεκλεκτής :scope θα πρέπει να λειτουργεί, ο οποίος ουσιαστικά επιτρέπει σε ένα στοιχείο να κάνετε ερώτημα στον εαυτό του καθώς και στα παιδιά του:

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

test("nav link has text 'hello world'", async ({page}) => {
  const html = `<a class="navbar__brand" href="/">hello world</a>`;
  await page.setContent(html); // for demonstration

  const navLink = page
    .getByRole("link")
    .locator(":scope.navbar__brand"); // or ".navbar__brand:scope"

  await expect(navLink).toHaveText("hello world");
});

Φυσικά, page.getByRole("a.navbar__brand") είναι δυνατό, αλλά είναι λιγότερο πρακτική επιλογή web-first σε σχέση με την επιλογή ανά ρόλο. Από την άλλη, το .navbar__brand δεν είναι επίσης web-first, οπότε ιδανικά θα συνδύαζες τα πάντα σε ένα μόνο page.getByRole("link", {name: "link text"}) κλήση.

Απάντηση #2

Μπορείτε να χρησιμοποιήσετε απευθείας έναν εντοπιστή με έναν επιλογέα CSS:

const links = page.locator("a.navbar__brand");
const count = await links.count();
console.log("count is " + count); // Should now output 1