Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a Playwright Locator to identify the element, then await the method that matches what you need to read. For ordinary DOM text, assign textContent() to a variable; for text as a user sees it, use innerText(). If you actually need to highlight text in the browser, call selectText() first. Form controls are different: read their current value with inputValue().

const text = await page.getByText('Welcome, John').textContent();

This distinction prevents a common mistake: selecting text on screen is an interaction, while storing text is a JavaScript value returned from Playwright.

The basic pattern

A locator identifies the intended element and Playwright waits for it according to its normal auto-waiting and retry behavior. Once you have the locator, await the appropriate method and assign the result.

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

test('read a heading into a variable', async ({ page }) => {
  await page.goto('https://example.com');

  const heading = page.getByRole('heading', { name: 'Example Domain' });
  const text = await heading.innerText();

  console.log(text);
  expect(text).toContain('Example Domain');
});

The variable contains a string (or, for some methods, an array of strings). The locator itself is not the text; it is a reusable description of where the text is.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

Selecting the right element

Use visible text for non-interactive content

getByText() is intended for text that a user can see but does not necessarily operate, such as a paragraph, status message, or card label.

const message = page.getByText('Payment complete', { exact: true });
const text = await message.textContent();

Text matching can use a substring, an exact string, or a regular expression. Playwright normalizes whitespace for text matching: repeated spaces are treated as one, line breaks as spaces, and leading or trailing whitespace is ignored.

Prefer roles for interactive elements

Buttons, links, headings, text boxes, and other controls are usually more reliably located by their accessible role and name.

const title = page.getByRole('heading', { name: 'Account settings' });
const buttonLabel = await page.getByRole('button', { name: 'Save changes' }).innerText();

This approach reflects the page’s user-facing interface instead of depending on a fragile CSS or XPath chain tied to a particular DOM structure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scope a locator when text is repeated

If several elements contain the same words, first locate a meaningful container and then search inside it.

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
const order = page.getByRole('listitem').filter({ hasText: 'Order 1042' });
const status = await order.getByText('Shipped').innerText();

You can also use nth(), first(), or last(), but narrowing by a stable label or container is generally easier to maintain.

Read text or select it?

Goal Method Result
Read the node’s DOM text textContent() String or null
Read rendered, user-visible text innerText() String
Highlight text in the page selectText() Performs a browser selection; returns no text value
Read all matching nodes’ DOM text allTextContents() Array of strings
Read all matching nodes’ rendered text allInnerTexts() Array of strings
Read an input, textarea, or select value inputValue() Current control value

textContent(): the DOM value

Use this when hidden descendants, source markup, or exact node content matters. It follows the DOM’s textContent property and can return null when the matched node has no text content.

const rawText = await page.locator('[data-testid="product-description"]').textContent();
const description = rawText ?? '';

innerText(): rendered text

Use this when your assertion or stored value should resemble what a user sees. Rendering, visibility, and line-break behavior affect the result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const visibleText = await page.getByRole('heading', { name: 'Welcome' }).innerText();

selectText(): a browser action

selectText() focuses the matched element and selects all of its text in the browser. It does not return the selected characters for assignment.

const paragraph = page.getByText('Copy this paragraph', { exact: true });
await paragraph.selectText();
// The text is highlighted in the page; use textContent() or innerText()
// separately if your test also needs a JavaScript string.

For an input or textarea, selection is also an action. To read its contents, use inputValue() instead.

Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.

Reading controls and setting values

Form controls expose a value rather than ordinary child text. Read it with inputValue():

const email = await page.getByRole('textbox', { name: 'Email' }).inputValue();
const country = await page.getByRole('combobox', { name: 'Country' }).inputValue();

Use fill() to set an input, textarea, or contenteditable element. It is not a method for reading normal page text.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const notes = page.getByRole('textbox', { name: 'Notes' });
await notes.fill('Call customer tomorrow');
const savedNotes = await notes.inputValue();

Collecting text from lists and tables

Return an array with collection methods

const rows = page.getByRole('listitem');
const labels = await rows.allTextContents();
const visibleLabels = await rows.allInnerTexts();

for (const label of visibleLabels) {
  console.log(label);
}

These methods query all current matches and return arrays in document order. Choose allTextContents() for DOM text or allInnerTexts() for rendered text.

Be careful with locator.all()

locator.all() immediately returns whatever matches at that moment. It does not wait for matches, so it can be unpredictable while a list is loading or changing. Wait for a stable condition first, or use a locator assertion, then iterate.

const items = page.getByRole('listitem');
await expect(items.first()).toBeVisible();
const currentItems = await items.all();
for (const item of currentItems) {
  console.log(await item.innerText());
}

Normalize only when your test requires it

Do not trim, collapse, or lowercase text automatically if spacing and capitalization are meaningful. If the application deliberately varies whitespace, normalize in your own code and document why.

Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
const actual = (await page.getByTestId('status').innerText()).trim();
expect(actual).toBe('Ready');

Waiting, dynamic content, and reliability

Locators are Playwright’s central unit for auto-waiting and retry-ability. Keep the locator live until you read it rather than caching an element handle early. For content populated after navigation, wait for a user-visible state:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const result = page.getByRole('status');
await expect(result).toHaveText('Loaded');
const text = await result.innerText();

If a page replaces the node during rendering, a locator can re-resolve the current node. A one-time handle or an immediate all() call may instead refer to an obsolete or incomplete state.

Hidden text and CSS-generated content

textContent() can include text from hidden descendants. innerText() is closer to rendered text, but neither method should be expected to read text painted only through a CSS pseudo-element. In that case, inspect the relevant attribute or computed style, or change the application markup so the content is accessible.

Frames and shadow DOM

Locate content inside an iframe through frameLocator() before reading it:

const frameTitle = page.frameLocator('#checkout-frame').getByRole('heading');
const text = await frameTitle.innerText();

For open shadow DOM, Playwright locators can generally pierce the boundary. Use stable roles, labels, or test IDs exposed by the component.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common errors and fixes

  • “strict mode violation”: your locator matches multiple elements. Add an accessible name, exact matching, a container filter, or an intentional index.
  • Timeout while reading: the locator never became actionable or the expected content never appeared. Verify the URL, selector, frame, authentication state, and loading condition; wait for a meaningful assertion instead of adding an arbitrary delay.
  • Empty string: you may have selected a container before its children rendered, chosen innerText() for hidden text, or targeted the wrong element. Inspect the locator with Playwright’s trace or locator count and choose the appropriate method.
  • null from textContent(): the matched node has no text content. Handle the nullable result or assert that content exists before storing it.
  • Input text is missing: an input’s value is not ordinary child text. Replace textContent() or innerText() with inputValue().
  • Flaky list reads: the list is still changing. Wait for a stable item or completion status before calling allTextContents(), and avoid immediate all() on a dynamic locator.
  • Selection appears not to work: selectText() changes browser selection but returns no string. Read the value separately and ensure the target is selectable, such as a text-bearing element or form control.

Performance and test design

Read only the text you need. A single scoped locator is cheaper and clearer than collecting the entire page’s text. For many rows, one allTextContents() call avoids repeated selector construction; for a single assertion, read one locator. Keep extraction close to the assertion or transformation that consumes it, and use role-based or test-ID locators that remain stable when layout markup changes.

Or skip the browser setup

If your broader workflow needs a screenshot rather than text extraction, ScreenshotNeo can capture a URL through one request instead of maintaining browser setup. It removes cookie banners, newsletter popups, and chat widgets before the capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and each response identifies the page and billing result in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for options. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo free.

Frequently Asked Questions

Should I use textContent() or innerText() for assertions?

Use innerText() when the assertion represents rendered user-visible text, and textContent() when DOM content, including hidden descendants, is the intended value.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I store text selected with selectText() directly?

No. selectText() performs the browser selection and does not return the selected string. Call textContent() or innerText() separately and assign that result.

How do I read a value from a select element?

Use the select’s locator with inputValue(); control values should not be read with ordinary text methods.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.