DEV Community

Cover image for Modern UI Testing Is Mostly State Management
David Frei
David Frei

Posted on

Modern UI Testing Is Mostly State Management

Modern frontend testing is often described as a locator problem.

It is usually a state problem.

The element exists, but not yet. The page is loaded, but the data is not. The button is visible, but a transition is still running. The user preference changed, but persistence has not completed. A screenshot looks different, but nothing meaningful broke.

Dynamic applications expose dozens of temporary states, and browser tests fail when they confuse those temporary states with final behavior.

The most reliable tests are built around state transitions rather than DOM snapshots.

Dynamic tables are small distributed systems

A filter-heavy dashboard may combine:

  • Debounced search
  • Server-side pagination
  • Infinite scrolling
  • Virtualized rows
  • Column sorting
  • Saved filters
  • Background refreshes
  • Permission-aware actions

A test that clicks a filter and immediately counts rows will eventually fail.

The right sequence is closer to:

  1. Record the current query or table state.
  2. Apply the filter.
  3. Wait for the application to acknowledge the new state.
  4. Confirm stale results are gone.
  5. Verify the visible rows match the filter.
  6. Check that scrolling or pagination preserves it.

This practical guide to testing dynamic tables, infinite scroll, and filter-heavy dashboards with Endtest shows why these flows need more than a sequence of clicks.

For virtualized tables, remember that rows outside the viewport may not exist in the DOM. Counting DOM nodes is not the same as counting records. Test the behavior the user can observe: result totals, loaded ranges, row content, and scroll recovery.

Visual baselines need governance

Visual regression testing sounds simple:

  • Capture a screenshot.
  • Compare it later.
  • Fail when pixels change.

The difficulty is deciding which pixels matter.

Fast-changing frontends contain unstable visual input:

  • Dates and timestamps
  • Random avatars
  • Animated transitions
  • Loading skeletons
  • Advertising slots
  • User-generated content
  • Browser font rendering
  • Charts built from changing data

Before trusting a baseline, measure how often it changes without a product regression. This article on what to measure before trusting visual regression baselines provides a useful starting point.

Useful metrics include:

  • Baseline update frequency
  • Percentage of diffs accepted as harmless
  • Review time per diff
  • False-positive rate by component
  • Failure rate by browser and viewport
  • Percentage of screenshots containing dynamic regions
  • Time between a legitimate UI change and baseline approval

A baseline that requires constant approval trains reviewers to click “accept” without looking.

Collaboration interfaces have multiple truths

Real-time collaboration is difficult because each participant sees a local version of shared state.

A test may need to coordinate two browser sessions and verify:

  • User A sees User B join.
  • Presence indicators disappear after disconnect.
  • Cursors move to the correct document location.
  • Concurrent edits merge predictably.
  • Conflict messages appear when necessary.
  • Permission changes propagate.
  • Reconnection restores the latest state.

This Endtest selection guide for real-time collaboration testing covers the unusual requirements behind presence, cursors, and multi-user edits.

The main mistake is assuming both browsers become consistent immediately. Tests need explicit synchronization points:

  • Server acknowledgement
  • Version number change
  • Presence event
  • Saved-state indicator
  • Reconnection completion
  • Shared document revision

Waiting a fixed number of seconds is not synchronization.

Preferences must survive the right boundaries

Theme switching looks trivial until you define what should persist.

Should dark mode survive:

  • A page refresh?
  • A new tab?
  • A logout?
  • A new browser session?
  • A different device?
  • An account switch?
  • A cleared local-storage state?

The answer depends on product design.

This comparison of Endtest and Playwright for theme switching and persisted UI state is a useful reminder that the test should reflect the intended storage boundary.

A clean preference test separates three things:

  1. The immediate UI change
  2. The storage or server update
  3. The restoration behavior after a boundary is crossed

For example, a dark-mode toggle test might verify:

  • The theme attribute changes.
  • The correct control state is displayed.
  • The preference is stored.
  • A reload restores the theme.
  • Logging into another user does not leak the previous user's preference.

That last check often catches more serious bugs than the visual assertion.

OAuth flows cross application boundaries

Authentication tests are difficult because the browser leaves your application.

A realistic OAuth flow can include:

  • Redirect to an identity provider
  • Consent screen
  • MFA
  • Account selection
  • Cross-domain cookies
  • Callback parameters
  • Error recovery
  • Return to the original destination

This guide on testing OAuth redirects, consent screens, and cross-domain login handoffs outlines the platform capabilities these tests require.

The test should validate more than “login succeeded.”

Check:

  • The correct identity provider was used.
  • State and redirect parameters were preserved.
  • The user returned to the intended page.
  • A denied consent request produced a safe error.
  • Expired or reused callbacks were rejected.
  • The session belongs to the correct account.
  • Logout clears the expected application session.

Cross-domain tests are not inherently bad. They simply require deliberate session and window handling.

SVG dashboards produce noisy screenshots

SVG-heavy interfaces introduce their own stability problems:

  • Anti-aliasing differences
  • Fractional positioning
  • Font rendering
  • Animation
  • Responsive scaling
  • Data-driven path changes
  • Icons with slightly different bounding boxes

A screenshot comparison may detect thousands of changed pixels even when users would not notice a regression.

This guide to benchmarking screenshot stability on SVG-heavy dashboards focuses on measuring that noise before declaring visual testing reliable.

For these interfaces, combine screenshot checks with structural assertions:

  • Chart title and legend
  • Number of series
  • Axis labels
  • Tooltip behavior
  • Selected range
  • Accessible names
  • Data values exposed outside the SVG
  • Error and empty states

Visual checks are strongest when they complement behavioral checks.

Use state-based waits

The common thread across all these interfaces is waiting for a meaningful state.

Prefer waits based on:

  • A loading indicator disappearing
  • A network-backed result version changing
  • A button becoming enabled
  • A row count reaching the expected value
  • A saved-state badge appearing
  • A callback completing
  • A collaboration revision updating
  • An animation reaching a settled state

Avoid using a fixed delay as the main synchronization strategy.

A fixed delay is either too short, causing failures, or too long, wasting time. Sometimes it is both.

Tool selection matters less than state modeling

Framework and platform comparisons can be useful. This overview of the 12 best test automation tools in 2026 gives a broad view of available options, and this video on test automation provides another format for exploring the space.

But no tool can infer every state transition correctly without clear intent.

Before automating a flow, write down:

  • Initial state
  • Trigger
  • Expected intermediate states
  • Completion signal
  • Persistent result
  • Recovery behavior
  • Cleanup boundary

That small model will prevent more flaky tests than another selector trick.

Modern UI testing is not mainly about finding elements.

It is about proving that the application moves from one meaningful state to another—and stays there when the user expects it to.

Top comments (0)