Skip to main content

selenium-nanowait

State-based adaptive synchronization for Selenium — powered by the NanoWait engine.

🚀 What is selenium-nanowait?

selenium-nanowait is a support library for Selenium that eliminates fragile time-based waits, synchronizing browser actions with the actual page state, not with arbitrary timeouts.

Instead of guessing how long to wait (time.sleep(5) or WebDriverWait(10)), selenium-nanowait waits for what really matters:

  • Element visibility
  • Layout stability (constant position and size)
  • DOM readiness (document.readyState === "complete")

Furthermore, selenium-nanowait is designed for direct and transparent integration with testing frameworks, allowing for immediate adoption in QA, GUI automation, and teaching environments.

It's not a replacement for Selenium, but rather a direct enhancement that works alongside your existing code. You continue using Selenium as you always have — selenium-nanowait simply makes the wait deterministic, adaptive, and reliable.


🧠 Design Philosophy

selenium-nanowait follows three strict rules:

  1. Complementary, never replace Selenium.

  2. Wait for states, not for time.

  3. Remain explicit, predictable, and opt-in.

There is no monkey-patching, hidden globals, or custom drivers. Integration with testing frameworks is plug-and-play, non-invasive.


🛠️ Installation

pip install selenium-nanowait

Requirements

  • Python ≥ 3.8
  • Selenium ≥ 4.x
  • NanoWait ≥ 4.0.0

💡 Quick Start: The wait_for Function

The wait_for function is the main entry point of the library. It encapsulates all the adaptive synchronization logic and returns an element ready for interaction.

Before (Fragile, Time-Based)

import time
from selenium.webdriver.common.by import By

time.sleep(3)
driver.find_element(By.ID, "submit").click()

After (State-Aware, Deterministic)

from selenium_nanowait import wait_for

wait_for(driver, "#submit").click()

⚙️ Main API

wait_for()

wait_for(
driver,
selector: str,

*,
timeout: float | None = None,
**nano_kwargs

Returns an AdaptiveElement, a lightweight wrapper that extends Selenium's behavior without Replace it.

AdaptiveElement Methods

| Method | Description | Example |

| ------------------------- | ----------------------------------------- | --------------------------------------------------- |

| .click() | Waits for stability and executes the click | wait_for(driver, "#login").click() |

| .type(text, clear=True) | Waits for readiness and types text | wait_for(driver, "#email").type("user@email.com") |

| .raw() | Returns the native Selenium WebElement | el = wait_for(driver, "#submit").raw() |


🔎 Visual Stability Check

An element is only considered ready when:

  • It is visible (is_displayed)
  • The DOM is fully loaded
  • Its position and size remain constant between consecutive checks

This approach eliminates intermittent failures caused by layout shifts, animations, or late reflows.

--

🧪 Plug-and-Play Integration with Testing Frameworks

selenium-nanowait is designed for immediate adoption in testing environments, without requiring manual configuration or structural changes to the project.

✅ Pytest (Automatic)

def test_login(driver):

wait_for(driver, "#login").click()

The Pytest plugin is automatically loaded via entrypoint, allowing future extensions such as:

  • automatic screenshots on failures
  • logs per test
  • integration with reports

✅ unittest (Optional Mixin)

from selenium_nanowait.unittest_adapter import NanoWaitTestCaseMixin

class TestUI(NanoWaitTestCaseMixin, unittest.TestCase):

...

✅ Robot Framework

Wait For css:#submit

⚙️ Global Configuration (Optional)

from selenium_nanowait import configure

configure(
default_timeout=10,
nano_kwargs={"smart": True, "verbose": False}

The configuration is applied globally, respecting the opt-in philosophy.


🔬 NEW: Stateful Deterministic Diagnostics

selenium-nanowait can generate deterministic diagnostic reports when a wait fails, explaining why the element did not become ready.

Enabling Diagnostics

from selenium_nanowait import configure

configure(diagnostic=True)

When enabled, the library logs a state timeline during the wait.

Example of error generated

[selenium-nanowait] Timeout waiting for element '#submit'
Timeout: 5.00s

Timeline: 
- INIT @ 0ms 
- DOM_LOADING @ 140ms 
-NOT_VISIBLE @ 780ms

- UNSTABLE_LAYOUT @ 2200ms

- UNSTABLE_LAYOUT @ 4100ms

This report makes UI crashes:

* **explainable**
* **reproducible**
* **diagnosable in CI**

No generic *logs* or blind *timeouts*.

> 💡 Diagnostics are fully *opt-in* and do not affect performance when disabled.

---

## ⏱️ Adaptive Waiting (NanoWait)

The NanoWait engine:

* dynamically adjusts the *polling* frequency
* avoids *busy-waiting*
* adapts to system performance

---

## 🧠 Why is `selenium-nanowait` different?

| Feature | ❌ Traditional Waits | ✅ `selenium-nanowait` |

| -------------- | -------------------- | ---------------------- |

| Base | Fixed time | Actual page state |

| Scope | Global/conditional | Adaptive element |

| Wait | Estimate | Adaptive backoff |

| Robustness | Fragile | Layout-aware |

| Diagnostic | Non-existent | Deterministic |

| QA Integration | Manual | Plug-and-play |

---

## 📦 Project Metadata

* **License**: MIT
* **Author**: Luiz Filipe Seabra de Marco
* **Status**: Production ready (v0.4)
* **Summary**: `selenium-nanowait` makes Selenium wait for reality — and now explains when it doesn't happen.

Metadata

Release files for selenium-nanowait 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for selenium-nanowait 0.3.1
File Size Uploaded Provenance Actions
selenium_nanowait-0.3.1.tar.gz 9.9 kB Without provenance Details for selenium_nanowait-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for selenium-nanowait 0.3.1
File Interpreter ABI Platform Actions
selenium_nanowait-0.3.1-py3-none-any.whl Python 3 none any Details for selenium_nanowait-0.3.1-py3-none-any.whl

Total release size: 19.9 kB

Release files / selenium_nanowait-0.3.1.tar.gz

Download URL selenium_nanowait-0.3.1.tar.gz
Size 9.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0c5a24b6eb172d73c0f0ed63c3c1752511fd3f029abbbe3702b33cf35e90d93b
BLAKE2b-256 checksum
How to use checksums
b636a2cebe6bda6d0fa255a834536c554423ee2dbb0c52b413b36bb5960ff4ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.7

Release files / selenium_nanowait-0.3.1-py3-none-any.whl

Download URL selenium_nanowait-0.3.1-py3-none-any.whl
Size 10.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0de557a93eae87ed4b674e0c4e2305397d9fc2f3e9192d6276bb1d20e7e0f4a0
BLAKE2b-256 checksum
How to use checksums
cfd14e0cedb586cf6935c7ece165d55f65160d08cfbac3a3f8d3d54aee85b22d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.7

Security for selenium-nanowait 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page