Automation
AI
Test Automation
Waitless v1.0: The End of Flaky Tests Has Arrived

Waitless v1.0: The End of Flaky Tests Has Arrived

January 5, 2026 3 min read

*(In continuation of the previous blog: waitless: Eliminate Flaky Tests Forever)*

I shipped the first version of waitless with a simple promise: eliminate `time.sleep()` from your Selenium tests forever. The response was incredible. A shoutout from PyCoder's Weekly. And most importantly—real engineers giving valuable comments and improvements to be made.

They told me what was missing:

  • "What about WebSocket?"
  • "What about Shadow DOM?"
  • "My React app re-renders unpredictably. Can waitless understand React?"
  • "We have iframes everywhere. Tests fail randomly."

Today, I'm thrilled to announce waitless v1.0.0—and it addresses *all* of these.

🔌

WebSocket & SSE Awareness

Modern apps aren't just request-response anymore. They're real-time. WebSockets. Server-Sent Events. Streaming data. Before v1.0, waitless was blind to this. A WebSocket message could trigger a re-render, and waitless wouldn't know about it.

Now? We intercept the WebSocket and EventSource constructors:

Code
from waitless import stabilize, StabilizationConfig

config = StabilizationConfig(
    track_websocket=True,    # Enable WebSocket monitoring
    track_sse=True,          # Enable SSE monitoring
    websocket_quiet_time=0.5 # Wait for 500ms of silence
)

driver = stabilize(driver, config=config)

When you enable WebSocket tracking, waitless:

  • Intercepts every new `WebSocket()` connection
  • Tracks open/close/message events
  • Records the timestamp of every message received
  • Waits for a configurable "quiet period" before declaring stability

An active WebSocket with frequent messages? Unstable. A WebSocket that's just idling? Stable—it's just chilling. Server-Sent Events work the same way. Your real-time dashboards finally have test coverage that doesn't rely on `time.sleep(5)`.

⚛️

Framework Hook Adapters

Here's a truth bomb: DOM mutations alone don't tell the whole story. React batches updates. Angular uses NgZone. Vue has nextTick. By the time the DOM changes, the framework is already two steps ahead.

v1.0 introduces Framework Adapters—plugins that hook directly into framework internals:

Code
config = StabilizationConfig(
    framework_hooks=['react', 'angular', 'vue']
)
AdapterWhat It Hooks Into
React`onCommitFiberRoot`, scheduler batch updates, concurrent mode transitions
AngularNgZone stability via `zone.onStable`, `getAllAngularTestabilities()`
VueVue DevTools hook, `nextTick` queue completion, component:updated events
Before vs After
Before: `button.click()` → Framework is batching updates → `find_element()` → 💥 FAILS. After: `button.click()` → Waitless waits for React commit / Vue nextTick / Angular NgZone.onStable → `find_element()` → ✅ WORKS
📺

iframe Monitoring

You know what's worse than testing a single-page app? Testing an app with iframes. Payment widgets. Embedded content. Legacy integrations. Iframes are everywhere, and they each have their own DOM, their own scripts, their own timing.

Code
config = StabilizationConfig(
    track_iframes=True  # Monitor same-origin iframes
)
  • Existing iframes on page load
  • Dynamically added iframes via MutationObserver
  • Load events for each iframe
  • Cross-origin handling (gracefully logged, not crashed)
📊

Performance Benchmarks

"But doesn't all this tracking slow things down?" Fair question. That's why v1.0 includes a built-in benchmark suite:

MetricValue
Instrumentation injection~5-10ms
Per-poll overhead~1-2ms
Poll interval (default)50ms
Typical stabilization50-200ms after activity
ROI Calculation
Before waitless: 100 tests × 3 sleeps × 2 seconds = 600 seconds of waiting. After waitless: 100 tests × actual wait time ≈ 60 seconds total. That's a 10x improvement in test suite speed.
🩺

Enhanced Diagnostics

When things go wrong (and they always do eventually), you need to know *why*. The CLI doctor now shows v1.0 feature status, and diagnostic reports include active WebSocket connections with URLs and states, active SSE connections, and iframe status.

Code
waitless doctor
🎯

The Complete v1.0 Config

Here's what full coverage looks like:

Code
from waitless import stabilize, StabilizationConfig

config = StabilizationConfig(
    # Core settings
    timeout=15,
    dom_settle_time=0.1,
    mutation_rate_threshold=50,
    network_idle_threshold=2,
    
    # v1.0 features
    track_websocket=True,
    track_sse=True,
    websocket_quiet_time=0.5,
    framework_hooks=['react'],  # or 'angular', 'vue'
    track_iframes=True,
    
    # Debugging
    debug_mode=True,
)

driver = stabilize(webdriver.Chrome(), config=config)

One line. All signals monitored. No more flaky tests.

📈

By The Numbers

  • Featured by PyCoder's Weekly
  • Zero breaking changes to the core API
  • 100% backward compatible
🛣️

What's Next?

  • Playwright support — Same intelligence, different driver
  • Async/await API — For modern Python codebases
  • Service Worker interception — The last blind spot
  • Visual regression integration — Stability + screenshots
🙏

Thank You

To everyone who downloaded waitless, suggested features, and shared it with their teams—thank you. Building developer tools is only meaningful when developers actually use them. Your feedback shaped v1.0.

Get Started

Code
pip install waitless==1.0.0
Built by Dhiraj Das
Automation Architect. Making Selenium tests as reliable as the applications you're building.
Dhiraj Das

About the Author

Dhiraj Das | Senior Automation Consultant | 10+ years building test automation that actually works. He transforms flaky, slow regression suites into reliable CI pipelines—designing self-healing frameworks that don't just run tests, but understand them.

Creator of many open-source tools solving what traditional automation can't: waitless (flaky tests), sb-stealth-wrapper (bot detection), selenium-teleport (state persistence), selenium-chatbot-test (AI chatbot testing), lumos-shadowdom (Shadow DOM), and visual-guard (visual regression).

Share this article:

Get In Touch

Interested in collaborating or have a question about my projects? Feel free to reach out. I'm always open to discussing new ideas and opportunities.