How do I find a row or card that contains a specific element in Playwright?
Written by Jatin Thacker, Automation Architect · Updated
This answer is one piece of Chapter 10: Locators II: Scoping and Rot.
- Scoping and Filtering
- CSS Selectors, and the Ones That Rot
- XPath, and What Replaced It
- Locators That Rot
- Locator Factories
- Practice and interview questions: Locators Masterclass
hasText checks for text. has checks for an element, which is more precise when the text alone is ambiguous. On the catalog page, Halcyon Burr Grinder is also the start of Halcyon Burr Grinder Mini, so filtering cards by that text matches two cards.
The example asks a sharper question: which article contains a heading whose name is exactly Halcyon Burr Grinder? That is one card. toHaveCount(1) proves it, and the price and the Add to cart button are then found inside that card only.
The inner locator is relative. Playwright runs it starting from each card, not from the document root, so it must describe something inside the card. A locator that starts outside, such as page.getByTestId('product-grid').getByRole('heading'), will not match, because the grid is not inside any card.
hasNot is the opposite: keep the cards that do not contain a matching element. You can chain filter() calls to combine conditions, such as a card with that heading that also has an Add to cart button.
import { test, expect } from '@playwright/test';
test('find the product card that has a given heading', async ({ page }) => {
await page.goto('/catalog.html?mock=static&seed=42&autologin=1');
const grinder = page.getByRole('article').filter({
has: page.getByRole('heading', { name: 'Halcyon Burr Grinder', exact: true }),
});
await expect(grinder).toHaveCount(1);
await expect(grinder.getByTestId('product-price')).toHaveText('₹11,900');
await grinder.getByRole('button', { name: 'Add to cart' }).click();
await expect(page.getByTestId('cart-total')).toHaveText('₹11,900');
});1 passed (2.5s)
cards.filter({ has: inner }), where does Playwright start searching for inner?Practised in the full course: the drill The card, not the heading.
See the chapterRelated questions
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