The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Use Playwright Test’s integrated expect with a Locator, then negate toBeEmpty(): await expect(locator).not.toBeEmpty();. Because this is a web assertion, await it so Playwright can retry until the locator is non-empty or the assertion timeout expires.
What not.toBeEmpty() checks
toBeEmpty() is a Locator assertion. The Playwright LocatorAssertions API reference defines it as ensuring that the Locator points to an empty editable element or to a DOM node that has no text. Adding .not reverses that condition: the matched target must not be empty according to that definition.
That definition is deliberately narrower than “looks visible” or “contains something useful.” The assertion does not, by itself, establish that an element is visible, that it has a particular descendant, or that a page is visually non-blank. Use it when the contract you need to test is that the located editable element or DOM node has content.
The smallest working test
import { test, expect } from '@playwright/test';
test('warning has content', async ({ page }) => {
const warning = page.locator('div.warning');
await expect(warning).not.toBeEmpty();
});
The locator is created first, then passed to Playwright’s expect. The assertion is awaited because locator assertions are asynchronous and retry while the page changes.
#1 Best Overall
Use the Playwright Test expect
Import expect from @playwright/test. The Playwright assertion guide cautions against substituting the separate expect package, which is not fully integrated with the Playwright test runner. If your project has custom fixtures, use a re-export of Playwright’s own expect.
Why the assertion must be awaited
Web assertions do not perform only one immediate check. Playwright re-fetches the located element and checks the expected condition until it succeeds or the configured assertion timeout is reached. An un-awaited assertion can let the test continue before that work completes and can produce an unreliable result.
For example, a warning that is inserted after a request can be checked without adding a hard-coded sleep:
import { test, expect } from '@playwright/test';
test('server warning eventually contains text', async ({ page }) => {
await page.goto('https://example.test/form');
const warning = page.locator('[role="alert"]');
await expect(warning).not.toBeEmpty();
});
The assertion waits for the expected non-empty state rather than forcing the test to guess how long the application needs.
Choosing a locator
The matcher is attached to a Locator, so the main design decision is identifying the element whose content matters. Keep that locator in a variable when the selector is reused or when a failure should clearly identify the target.
Message or status region
const status = page.locator('[role="status"]');
await expect(status).not.toBeEmpty();
This expresses a contract that the status region contains text after the operation under test.
Rank #2
Editable control
const notes = page.locator('textarea[name="notes"]');
await expect(notes).not.toBeEmpty();
This uses the matcher’s documented editable-element meaning. It does not assert that the value has a particular string; it only checks the matcher’s non-empty counterpart.
Avoid a selector that describes the whole page
A broad locator can make a passing test meaningless or make a failure difficult to diagnose. Select the warning, result panel, field, or other specific node whose content is part of the behavior being tested. If the page has several similar regions, narrow the locator using the stable attributes your application owns.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Timeouts and retry control
The assertion guide gives a default assertion timeout of five seconds. The timeout is configurable through the test configuration’s expect settings, and the LocatorAssertions API documents a per-assertion timeout option in milliseconds.
Set a project-level expectation timeout
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
timeout: 10000
}
});
A project-level value is appropriate when many assertions in the suite need the same waiting budget. Keep it high enough for the application’s normal response time, but avoid using a large value to hide a broken page or selector.
Override one assertion
await expect(page.locator('[role="alert"]')).not.toBeEmpty({
timeout: 15000
});
Use a local timeout when one operation is known to take longer than the rest of the test suite. The value is in milliseconds.
Abort a retrying assertion
The LocatorAssertions reference documents an optional signal (AbortSignal) for toBeEmpty(), added in Playwright v1.62. If the signal is already aborted, or becomes aborted while Playwright is retrying, the assertion fails without continuing to retry.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsRank #3
const controller = new AbortController();
const result = page.locator('#result');
// Abort from your own cancellation condition when appropriate.
await expect(result).not.toBeEmpty({
signal: controller.signal
});
Only abort when cancellation is part of your test’s control flow. A normal content check should be allowed to use its configured timeout.
Version and API details
The API reference records toBeEmpty() as added in Playwright v1.20. The assertion syntax remains the same when negated: the method name is still toBeEmpty(), and .not is the modifier. The v1.62 addition concerns the optional AbortSignal, not the basic assertion form.
Assertion behavior and configuration are version-sensitive. If a project pins an older Playwright release, check that release’s API reference before using newer options such as signal.
Common failures and fixes
The assertion times out
A timeout means the locator never reached the expected non-empty state within the assertion’s budget. First confirm that the selector identifies the intended element and that the test performs the action that should populate it. Then inspect whether the application actually renders text in that node. Increase the timeout only when the slower timing is expected; do not use it as a substitute for fixing a selector or application failure.
Free tools Windows power users keep installed
One-click scans. No signup required.
The wrong expect was imported
If the assertion does not behave like a Playwright web assertion, check the import. The normal test-runner form is import { test, expect } from '@playwright/test';. A separate assertion library is not the same integration.
await is missing
Write await expect(locator).not.toBeEmpty() inside the asynchronous test body. Without await, the test can move on before the retrying assertion has completed.
The locator is valid but the contract is wrong
A node can exist while still having no text, and a visually prominent page can be unsuitable for this matcher if the relevant content is not represented as text in the matched node. Revisit the element you selected and the exact condition you want to prove. not.toBeEmpty() is not a general visual-completeness test.
A cancellation signal stops the check
When an AbortSignal is aborted, the assertion fails without further retries. Check the code that owns the controller and ensure it is not cancelling the assertion prematurely. Remove the signal when cancellation is not required.
Practical test structure
Put the state-changing action before the assertion, and keep the locator close enough to the assertion that a failure is easy to understand:
import { test, expect } from '@playwright/test';
test('saving a profile produces a non-empty result', async ({ page }) => {
await page.goto('https://example.test/profile');
await page.getByRole('button', { name: 'Save' }).click();
const result = page.locator('#save-result');
await expect(result).not.toBeEmpty();
});
This structure lets Playwright wait for the result rather than relying on a fixed delay. If the test fails, you can separately determine whether the click did not occur, the result node stayed empty, or the locator targeted the wrong node.
Using screenshots to diagnose a failed assertion
A screenshot can help you see the page state at the point of failure, but it does not replace the semantic assertion. Capture the relevant state after the failure or in a diagnostic branch, and keep not.toBeEmpty() as the check that enforces the content contract.
Or skip the browser setup
If you need a rendered page image for debugging, documentation, or a visual record rather than a Playwright assertion, ScreenshotNeo provides a website screenshot API. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
For a one-call capture, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request from 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)
And from 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}`);
ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan. Sign up free for 1,000 screenshots a month with no card.
FAQ
Is the syntax not.toBeEmpty() or toNotBeEmpty()?
Use toBeEmpty() with Playwright’s .not modifier: expect(locator).not.toBeEmpty().
When was toBeEmpty() introduced?
The LocatorAssertions API reference lists it as added in Playwright v1.20.
Recommended Free Tools
What does the timeout option measure?
It sets the maximum time, in milliseconds, that this retrying locator assertion may wait before failing.
Frequently Asked Questions
Can I use this assertion without Playwright Test?
The documented form uses Playwright Test’s integrated expect. Projects with custom fixtures may re-export that same Playwright expect.
Does a passing assertion prove that an element is visible?
No. It proves only the non-empty condition defined by toBeEmpty’s Locator assertion semantics.
The Bottom Line
For a non-empty content check, use await expect(locator).not.toBeEmpty(); with Playwright Test’s expect, a precise Locator, and an appropriate assertion timeout.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteQuick 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.

