Build UI tests around what users can see and do—not the CSS classes or DOM structure your interface happens to use today. Prefer accessible locators or a deliberate test-ID contract, wait for the state the test needs, and give each test controlled browser state and data. When a test fails, investigate the evidence before adding a delay or accepting a passing rerun.
Test the user-visible contract
A UI test should protect behavior that matters to a user: for example, submitting a form and seeing a confirmation, or opening a menu and choosing an item. A selector tied to a styling class or a deep DOM path often reflects the current implementation rather than that behavior. A redesign may change those details without changing what users can do.
Playwright’s best-practices guidance puts the principle plainly: “The end user will see or interact with what is rendered on the page, so your test should typically only see/interact with the same rendered output.” That means choosing locators based on rendered, user-facing attributes when possible.
Prefer accessible locators
Use a control’s role and accessible name, or its label, when those identify the same control a user would encounter. If a page contains repeated buttons such as “Edit,” scope the locator to a meaningful region—such as the relevant row or dialog—so the test identifies the intended control rather than whichever match appears first.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, 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 minuteUse test IDs as an explicit contract
Sometimes visible text is intentionally changeable, repeated, or insufficient to distinguish a control. In that case, use a deliberate test ID, and treat it as a stable interface for tests. Keep it separate from styling classes: changing a color or refactoring CSS should not require rewriting a test selector. A test ID should still point to a meaningful target, not become an excuse to test arbitrary internal structure.
Update tests according to product intent
If a locator breaks because a class was renamed during a visual refactor, repair the coupling while keeping the expected user behavior. If the product deliberately changed the copy or interaction, update the test’s expected behavior to match the new intent. Do not change an assertion merely to make a failing test green when the underlying behavior is still required.
Wait for the condition the test needs
UI work is asynchronous: a click may trigger navigation, a request, validation, or a delayed update. A fixed sleep guesses how long that work will take. It can be too short on a slow run and unnecessarily long on a fast one. Playwright supports auto-waiting for actionability and retrying assertions that wait for the expected condition up to a timeout.
Assert an observable outcome
After an action, wait for the result that matters—for example, a success message to appear or a dialog to close—instead of sleeping for an arbitrary interval. A retrying, web-first assertion expresses both the condition and the wait. Use the test runner’s normal timeout behavior and investigate when the condition does not arrive; do not treat a longer timeout as a substitute for understanding a slow or broken flow.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Use fixed delays sparingly
A delay can be appropriate when the product behavior itself includes a known pause that cannot be observed through another condition, but it should not be the default synchronization strategy. Google Testing Blog’s 2021 article on test flakiness warns: “Do NOT add arbitrary delays as these can become flaky again over time and slow down the test unnecessarily.”
Keep tests independent
Tests that depend on another test’s browser state, cookies, or leftover data become order-sensitive: a failure in one can create misleading failures in others. Give tests independent storage and controlled data so each can establish its own starting conditions and verify its own outcome.
- Set up the data a test needs explicitly rather than relying on a previous test to create it.
- Keep browser storage and cookies isolated between tests where the runner allows it.
- Make external services and execution conditions predictable where practical, while retaining the user-visible behavior the test is intended to protect.
- When a test shares resources by necessity, make that dependency explicit and ensure cleanup or reset is reliable.
Choose end-to-end coverage deliberately
End-to-end tests exercise behavior through the interface a user sees, but they also require ongoing care. Start with a small set of consequential journeys—such as completing a core transaction or account action—and define the observable outcome that proves each journey works. Avoid turning every implementation detail into a browser test; protect the journeys where a failure would matter, then maintain those tests as part of product changes.
There is no universal framework winner established here. When evaluating a runner for your application, compare whether its locators can express accessible behavior or a stable explicit contract; how it synchronizes actions and assertions; how it isolates test and browser state; what failure diagnostics and CI behavior it provides; and how well it fits your app, languages, browsers, and team skills.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Diagnose failures before calling a test flaky
“Flaky” describes a symptom, not a cause. A failure may come from an application defect, a changed user-facing contract, timing, shared state, a dependency, the framework, or the execution environment. A rerun that passes is evidence of inconsistency, not proof that the test or product is fixed.
Rank #4
- Read the failed assertion. Identify the exact expected condition and whether the test reached the relevant action.
- Inspect the available evidence. Use the runner’s logs, trace, screenshot, or other failure artifact to see what rendered and what happened before the failure.
- Classify the likely cause. Check for an intentional copy or interaction change, an implementation-coupled locator, a missing wait for the needed state, shared browser or data state, an application failure, or a dependency/environment issue.
- Fix the cause and verify the behavior. Update a selector when its coupling is wrong; update an expectation only when product intent changed; repair the application if the user-visible contract is broken. Then run the test under the relevant conditions rather than relying on one successful retry.
Environment sensitivity is also worth checking. Chromium’s testing tips, for example, illustrate that viewport and environment conditions can affect tests. Make the conditions your test depends on explicit where possible, and inspect the actual run context when a failure cannot be reproduced locally.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Capture a page image when visual evidence helps
A screenshot can help explain what a browser rendered at a point in a test, but it is diagnostic evidence—not a substitute for assertions about user behavior. Prefer the test runner’s own failure artifacts when they show the relevant moment. If you need a separate screenshot of a URL for a visual reference or an artifact, an API can capture it without setting up a browser script. That does not recreate the test’s isolated state or prove that an interaction works.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request captures a URL; see the ScreenshotNeo API documentation for the request options.
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 problemsBest Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and 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 and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents 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 to try it with 1,000 screenshots a month and no card.
Frequently Asked Questions
Should UI tests use text selectors or test IDs?
Use a role, accessible name, or label when it identifies the intended user-facing control. Choose a deliberate test ID when visible text is unstable or ambiguous, and keep that contract independent of styling.
Does a screenshot prove that a UI test passed?
No. An image records rendered appearance; it does not establish that the required interaction or outcome succeeded. Use assertions for behavior and screenshots as supporting evidence.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →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.




