Adaptive, resilient waits for Selenium powered by nano-wait
Project description
selenium-nanowait
Adaptive, state-based waiting utilities for Selenium — built on NanoWait
🚀 What is selenium-nanowait?
selenium-nanowait is a lightweight companion library for Selenium that eliminates fragile, time-based waits by synchronizing browser actions with real page states, not arbitrary timeouts.
Instead of guessing how long to wait (time.sleep(5) or WebDriverWait(10)), selenium-nanowait waits for what actually matters:
- Element visibility
- Layout stability
- DOM readiness
It is not a Selenium replacement. It is a drop-in enhancement that works alongside existing Selenium code. In short: you keep using Selenium exactly as you always have — selenium-nanowait simply makes waiting deterministic, adaptive, and reliable.
🧠 Design Philosophy
selenium-nanowait follows three strict rules:
- Complement, never replace Selenium
- Wait for states, not time
- Stay explicit and opt-in
There is no monkey-patching, no hidden globals, and no custom drivers.
🛠️ Installation
pip install selenium-nanowait
Requirements
- Python ≥ 3.8
- Selenium ≥ 4.x
- NanoWait ≥ 4.0.0 (core adaptive engine)
💡 Quick Start
Before (Fragile, Time-Based)
import time
from selenium.webdriver.common.by import By
# You are guessing how long the element will take to appear
time.sleep(3)
driver.find_element(By.ID, "submit").click()
After (State-Aware, Deterministic)
from selenium_nanowait import wait_for
# The click only happens when the element is ready
wait_for(driver, "#submit").click()
The click() in the "After" example only happens when the element:
- exists
- is visible
- is layout-stable
- and the DOM is ready
⚙️ Core API
wait_for()
wait_for(
driver,
selector: str,
*,
timeout: float | None = None
)
This function returns an AdaptiveElement, a thin helper that wraps Selenium’s behavior without replacing it.
🧩 AdaptiveElement API
The AdaptiveElement provides state-aware methods that automatically wait for the element to be ready before performing the action.
| Method | Description | Example |
|---|---|---|
.click() |
Safely waits and clicks when the element is ready. | wait_for(driver, "#login").click() |
.type(text, clear=True) |
Waits for readiness, then types text. | wait_for(driver, "#email").type("user@email.com") |
.raw() |
Returns the native Selenium WebElement, untouched. Guarantees full Selenium compatibility. |
el = wait_for(driver, "#submit").raw() |
Fine-Grained Control with .until(...)
Use the .until() method for fine-grained control over the waiting conditions:
wait_for(driver, "#pay").until(
visible=True,
stable=True,
dom_idle=True
)
| Condition | Meaning |
|---|---|
visible |
Element is displayed and interactable. |
stable |
Element’s bounding box stopped changing (layout stability). |
dom_idle |
document.readyState === "complete". |
🧠 What Makes selenium-nanowait Different?
| Feature | ❌ Traditional Selenium Waits | ✅ selenium-nanowait |
|---|---|---|
| Basis | Time-based | State-based |
| Scope | Global | Element-scoped |
| Waiting | Guess-driven | Adaptive backoff |
| Flakiness | Fragile under load | Layout-aware |
| Debugging | Hard to debug | Deterministic failure messages |
⏱️ Adaptive Waiting (via NanoWait)
Internally, selenium-nanowait delegates timing decisions to NanoWait, which:
- adapts polling frequency
- prevents busy-waiting
- applies a safe execution floor (50 ms)
- remains deterministic across runs
This ensures: faster tests on fast machines and safer waits on slow or overloaded systems.
🔬 Failure Diagnostics
Instead of generic errors like:
TimeoutException after 10 seconds
selenium-nanowait raises descriptive errors such as:
Element '#submit' was found but never became stable.
Observed multiple layout shifts before timeout.
This dramatically reduces debugging time.
🧪 Design Guarantees
- Deterministic execution
- No replacement of Selenium APIs
- No global side effects
- No forced DSL
- Explicit, opt-in usage
- Safe defaults
❌ What This Library Is NOT
- Not a Selenium fork
- Not a testing framework
- Not a Playwright competitor
- Not a browser controller
- Not a magic abstraction layer
selenium-nanowait does one thing well: it fixes waiting — without changing Selenium.
🧑💻 Example: Side-by-Side with Selenium
The library is designed to coexist peacefully with your existing Selenium code:
# selenium-nanowait (for state-aware actions)
wait_for(driver, "#email").type("test@email.com")
# plain Selenium (still valid for non-interactive elements or quick checks)
driver.find_element(By.ID, "email").send_keys("test@email.com")
📦 Project Metadata
- License: MIT
- Author: Luiz Filipe Seabra de Marco
- Python: 3.8+
- OS: Independent
- Status: Production-ready (v0.1)
🤝 Contribution & Philosophy
selenium-nanowait is open-source and intentionally small. Pull requests are welcome if they: improve determinism, reduce flakiness, and preserve Selenium’s mental model. If a feature tries to replace Selenium — it does not belong here.
One-Line Summary: selenium-nanowait makes Selenium wait for reality, not time.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file selenium_nanowait-0.1.0.tar.gz.
File metadata
- Download URL: selenium_nanowait-0.1.0.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
780f9875086230d9fbfee3a4bc1f6b834f8b4743b65c8a54e86303cd00bf91a2
|
|
| MD5 |
68d1530f68a524049b2f0cf53d27f63d
|
|
| BLAKE2b-256 |
368c9b03453b9d87d386393bc0d420a3f17f2a10e07685c08976cbac99aa8936
|
File details
Details for the file selenium_nanowait-0.1.0-py3-none-any.whl.
File metadata
- Download URL: selenium_nanowait-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1639dd7c27040dcce2bd837bb611fdf1ee54b8033bc022eff88534dc291ed08
|
|
| MD5 |
7c9fe5be239592de5ccd2e3be1c4b00c
|
|
| BLAKE2b-256 |
9b2fda9308a69528bdc372920dbf2004b8836ef81d211b8add76fd78e7744d16
|