Recommended Free Tools
Use a locator for the tag, then call a bulk method: const divs = page.locator('div');, await divs.count() to count current matches, and await divs.allTextContents() or await divs.allInnerTexts() to read text from all of them. For a test that checks an expected count, use Playwright’s retrying toHaveCount() assertion instead of reading once and comparing manually. The key distinction is whether you need rendered text, DOM text, or custom fields such as IDs and classes.
Select div elements and count matches
Playwright’s Locator API can target every div with a CSS tag selector. A locator is a description of what to find; it does not return a fixed array of element handles when created.
const divs = page.locator('div');
const count = await divs.count();
console.log(count);
count() reports how many elements match when the method runs. It is useful for a snapshot or a diagnostic, but a one-time count is not itself a wait for the page to finish rendering. If content is still being added, the count can change between calls.
Use an assertion when the count is part of a test
For an expected count, use toHaveCount() from Playwright Test. This is a web-first assertion that retries while the condition is not yet met, reducing timing-related flakiness compared with reading the count once and asserting on that number.
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
await expect(divs).toHaveCount(3);
The number 3 is only an example; set the expected value from the behavior your test is meant to verify. An assertion for an exact count is appropriate when the count is a meaningful requirement, not merely because the page happens to contain that many divs today.
Extract text from every matched div
For a collection, use a bulk locator method. Both methods below return arrays, with one text value for each matched element.
| Method | Value returned | Choose it when |
|---|---|---|
allInnerTexts() |
The innerText value for each match |
You want rendered text as represented by the browser. |
allTextContents() |
The textContent value for each match |
You want the text content held in the DOM nodes. |
const renderedTexts = await divs.allInnerTexts();
const domTexts = await divs.allTextContents();
console.log(renderedTexts);
console.log(domTexts);
These choices are not interchangeable in every page. Rendered text is often a better fit when the test concerns what is displayed; DOM text content is useful when the test needs node text rather than rendered presentation. Select the method that corresponds to the data requirement instead of assuming one is universally more correct.
Extract custom fields with evaluateAll()
When text alone is not enough, evaluateAll() runs a callback in the page context with the array of matched elements. Map that array into the data shape the rest of your test needs.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesconst rows = await divs.evaluateAll(elements =>
elements.map(element => ({
text: element.textContent,
id: element.id,
className: element.className,
}))
);
This example reads each element’s text content, ID and class. Replace or extend the fields to match the page’s actual DOM attributes. Keep the callback focused on reading the matched elements; the locator defines which nodes are included, and the mapping defines what you collect from each one.
Rank #2
Choose a locator that describes the target
If the requirement literally concerns every div, page.locator('div') is direct. But a page can contain many divs that are layout wrappers, not the records or messages your test intends to examine. A broad tag selector may therefore count or extract more than the meaningful content.
- For a literal tag-based task: use
page.locator('div'). - For non-interactive content identifiable by text: Playwright’s locator guidance recommends considering text locators for elements such as
div,spanandp. - For interactive controls: prefer role locators where appropriate.
- For durable test targeting: prefer user-facing attributes or explicit testing contracts when the application provides them.
Playwright discusses these strategies in its Locators guide. Long CSS or XPath chains tied to incidental DOM structure can break when that structure changes. A locator should express the element’s role in the test where possible, not merely reproduce a fragile path through today’s markup.
Handle dynamic pages without flaky snapshots
Bulk reads operate on the matches available when the operation runs. In particular, locator.all() immediately returns locators for elements currently present; it does not wait for the list to appear or finish loading. The Locator API warns that using it on a changing list can produce unpredictable results.
Before collecting text or custom fields, wait for a condition that represents the page state your test needs. That might be the appearance of a known content element or another meaningful application-specific signal. Avoid treating an arbitrary delay as proof that asynchronous content is complete.
For expectations about count or text, use retrying assertions such as toHaveCount() or toHaveText() rather than collecting a value once and asserting on the returned value. For a data export or one-time snapshot rather than a test assertion, first establish that the page has reached the relevant loaded or stable condition, then call the bulk extraction method.
Rank #3
Complete Playwright Test example
This test navigates to a page, locates divs, checks an illustrative count and prints their DOM text. Change the URL and expected count to match the page and behavior under test.
import { test, expect } from '@playwright/test';
test('count and read divs', async ({ page }) => {
await page.goto('https://example.com');
const divs = page.locator('div');
await expect(divs).toHaveCount(3);
const texts = await divs.allTextContents();
console.log(texts);
});
The expected count is illustrative, not a claim about the current markup of the example URL. The test should assert a count that represents an intentional page contract. If a page contains unrelated layout divs or the structure is expected to evolve, narrow the locator to the relevant content rather than pinning the test to a broad page-wide count.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Troubleshoot common count and extraction problems
The count is different on different runs
Likely cause: the page is dynamic, or the locator matches a broad set whose contents change as the page renders.
Fix: identify a meaningful loaded condition before reading a snapshot. In tests, assert the intended condition with a retrying assertion such as toHaveCount(). If the count is not a stable product requirement, do not assert an exact page-wide div count.
The text array is empty or missing expected content
Likely cause: the matching elements were not present when the read ran, the locator does not identify the intended content, or the relevant page state has not been reached.
Fix: verify the target locator against the intended page content and wait for the application-specific condition that makes that content available before extracting.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →The returned text does not match what the user sees
Likely cause: the test is reading textContent when it needs rendered innerText, or vice versa.
Fix: choose between allInnerTexts() and allTextContents() based on whether rendered text or DOM text content is the actual requirement.
A single-element operation fails because several divs match
Likely cause: a locator matching multiple nodes is being used with an operation that expects one target. Playwright applies strictness to single-element operations; a broad div locator should not be treated as though it identifies just one element.
Fix: use bulk methods such as count(), allInnerTexts(), allTextContents() or evaluateAll() when the task concerns the full collection. If you need one particular element, refine the locator to describe that target.
A locator breaks after a layout change
Likely cause: the locator depends on a long CSS or XPath path through incidental DOM structure.
Fix: target meaningful user-facing content, a role for interactive elements, or an explicit testing contract where available. Keep a tag selector only when selecting by tag is genuinely the requirement.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
Playwright is the right approach when you need to count page elements or extract their text and attributes. ScreenshotNeo is a separate option for capturing a page image or PDF; it does not replace Playwright’s DOM extraction methods. It is a website screenshot API and MCP server for developers, made by Yorker Media. One GET request can return a PNG, JPEG, WebP or PDF. See the ScreenshotNeo site and API documentation for setup and options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
For this screenshot workflow, ScreenshotNeo accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month with no card.
Sources
- Playwright Locator API for locator counts, bulk text methods,
evaluateAll()and dynamic-list behavior. - Playwright Locators guide for locator strategies, strictness and assertion guidance.
Frequently Asked Questions
Does page.locator(‘div’) include nested div elements?
Yes. The CSS tag selector matches div elements throughout the locator’s scope, including nested divs. If nested wrappers should not be counted as separate records, narrow the locator to the actual data elements.
Can I use these methods with Playwright in another language?
The examples here use the TypeScript/JavaScript Playwright Test API. Playwright has language-specific APIs; check the documentation for the language and version used by your project before translating method names or syntax.
Quick Recap
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.

