Extract values from the DOM
Read data out of the page so you can assert on values you don't know up front.
The matchers from the last two lessons cover the common case. You locate something and assert on it directly. They compare against something you already know, such as a fixed string, a count, or a role.
Often you don't know the value up front. You click a random product and need to confirm that same product shows up in the cart. You sort by price and need to verify the order. The value only exists at runtime, so read it off the page first, then assert on it.
Extract a single value
locator.innerText() reads the visible text of a single element. It's the one I reach for most often.
const productHeading = page.getByRole("heading", { level: 2 });// Extract the product name to reuse it elsewhereconst productName = await productHeading.innerText();const cartContainer = page.getByTestId("cart");await expect(cartContainer.getByText(`1x, ${productName}`)).toBeVisible();
Unlike web-first assertions, innerText() and friends do not auto-wait.
They snapshot the DOM at the moment you call them. Make sure the elements are
settled first (typically by awaiting an assertion on the parent or by awaiting
a navigation).
If you need to access values that innerText doesn't see, there are some alternatives. textContent returns everything in the source: hidden text, raw whitespace, etc.
Given const heading = page.getByRole("heading", { name: "Online" }):
<h3>
Online
<span hidden>(maintenance soon)</span>
</h3>heading.innerText()"Online"Visible text only, whitespace collapsed.
heading.textContent()"\nOnline\n(maintenance soon)\n"Raw markup, hidden text and whitespace included.
Form fields don't have inner text. Use inputValue to read what's currently in the field.
Given const search = page.getByLabel("Search"):
<input aria-label="Search" value="snowboards" />search.inputValue()"snowboards"Reflects what's typed, not the static `value` attribute.
Use getAttribute for anything stored in an attribute: href, data-*, aria-label, alt, etc.
Given const link = page.getByRole("link", { name: "Snowboard X" }):
<a href="/products/snowboard-x">
Snowboard X
</a>link.getAttribute("href")"/products/snowboard-x"Any attribute by name. Returns null if it isn't set.
Extract many values
For locators that match multiple elements, use allInnerTexts or allTextContents.
// grab every price on the page
const allPrices = await page.getByTestId("price").allInnerTexts();
// ["100.00", "250", "1234", ...]
So, let's see what we can extract!
Practice extracting values
Verify price sorting works

- Click on the top-left Products link.
- Sort the products by price (ascending, then descending).
- Read all visible prices and assert the order is correct using the helpers below.
Here are some helper methods:
const isSortedAsc = (arr) =>
arr.every((element, index, array) => !index || +array[index - 1] <= +element);
const isSortedDesc = (arr) =>
arr.every((element, index, array) => !index || +array[index - 1] >= +element);
Validate your add-to-cart flow
- Take your previously recorded add to cart test.
- Read each product's name and price from the product detail page using
innerText. - Assert the cart contains the correct items by name.
- Tip: look out for
data-testidattributes. They make extraction easier.