ddp_utils.browser.facade.waits¶
import ddp_utils.browser.facade.waits
Synchronous backend-aware wait primitives.
- class ddp_utils.browser.facade.waits.BrowserWait(browser: Browser)¶
Bases:
WaitScopeMixinWait for arbitrary and browser-specific conditions synchronously.
Parameters
Name
Type
Description
browser
Owning browser facade.
Examples
Wait for any project predicate without backend branching:
value = browser.wait.until(lambda _: read_ready_value(), timeout=15)
Bind wait operations to one browser session.
Parameters
Name
Type
Description
browser
Owning browser facade.
Examples
Browser constructs one stable wait helper:
wait = BrowserWait(browser)
- until(predicate: Callable[['Browser'], T], *, timeout: float, interval: float = 0.1, message: str | None = None) T¶
Wait until a callable returns a truthy value.
Selenium sessions use
WebDriverWait.until. Playwright sessions use their native event-loop-aware timeout sleep between observations.Parameters
Name
Type
Description
predicate
Callable[['Browser'], T]
Callable receiving the browser and returning a truthy final value when satisfied.
timeout
float
Seconds to wait. Zero performs one immediate observation.
interval
float
Poll interval in seconds for repeated observations.
message
str | None
Optional timeout explanation.
Returns
Type
Description
T
The truthy value returned by
predicate.Raises
Exception
Description
The condition remains false.
Timeout or interval is negative.
Examples
Wait for a project state transition:
record = browser.wait.until(load_record, timeout=30)
- until_not(predicate: Callable[['Browser'], Any], *, timeout: float, interval: float = 0.1, message: str | None = None) bool¶
Wait until a callable returns a false value.
Parameters
Name
Type
Description
predicate
Callable[['Browser'], Any]
Callable receiving the browser.
timeout
float
Seconds to wait.
interval
float
Poll interval in seconds.
message
str | None
Optional timeout explanation.
Returns
Type
Description
bool
Truewhen the callable becomes false.Raises
Exception
Description
The condition remains true.
Timeout or interval is negative.
Examples
Wait for a loading marker to disappear:
browser.wait.until_not(lambda b: b.find("div", attrs={"class": "loading"}))
- first_of(conditions: Mapping[str, Callable[['Browser'], Any]], *, timeout: float, interval: float = 0.1, required: bool = True, message: str | None = None) WaitMatch | None¶
Wait until the first ordered condition returns a truthy value.
Conditions are evaluated in mapping insertion order on every observation. They must only inspect state; perform clicks, navigation, CAPTCHA solving, and other side effects after this method returns.
Parameters
Name
Type
Description
conditions
Mapping[str, Callable[['Browser'], Any]]
Non-empty ordered mapping of names to callables receiving the active browser. A false value means not ready; a truthy value becomes
WaitMatch.value.timeout
float
Shared deadline in seconds for all conditions.
interval
float
Delay between complete observation cycles.
required
bool
Raise on timeout when
True; returnNoneotherwise.message
str | None
Optional timeout explanation.
Returns
Type
Description
WaitMatch | None
Winning condition metadata, or
Noneafter an optional timeout.Raises
Exception
Description
Conditions are empty, unnamed, not callable, or timing values are negative.
No condition wins and
requiredisTrue.Exception
Any condition exception is propagated unchanged.
Examples
Return the first available navigation choice:
match = browser.wait.first_of( { "search": lambda b: b.find("a", text="Search", timeout=0), "login": lambda b: b.find("a", text="Login", timeout=0), }, timeout=30, )
Treat timeout as an ordinary missing state:
match = browser.wait.first_of(checks, timeout=5, required=False) if match is None: return False
Pass existing bound methods without a lambda:
match = browser.wait.first_of( {"captcha": self.detect_captcha}, timeout=20, )
- cycle(*, timeout: float, interval: float = 0.1, max_total: float | None = None) WaitCycle¶
Create an extendable deadline for repeated state decisions.
Parameters
Name
Type
Description
timeout
float
Initial soft deadline in seconds.
interval
float
Default polling interval for
WaitCycle.first_of().max_total
float | None
Optional hard lifetime cap measured from cycle creation.
Returns
Type
Description
A cycle bound to this browser wait facade.
Raises
Exception
Description
A duration is negative or
max_totalis shorter than the initial timeout.Examples
Extend the same decision cycle after servicing a checkpoint:
cycle = browser.wait.cycle(timeout=30, max_total=180) match = cycle.first_of(checks) if match.name == "captcha": solve(match.value) cycle.extend(60)
- class ddp_utils.browser.facade.waits.WaitCycle(wait: BrowserWait, *, timeout: float, interval: float = 0.1, max_total: float | None = None)¶
Bases:
objectTrack one reusable browser decision deadline and state occurrences.
Parameters
Name
Type
Description
wait
Browser wait facade that performs all observations.
timeout
float
Initial soft deadline in seconds.
interval
float
Default polling interval between observation cycles.
max_total
float | None
Optional non-extendable lifetime cap in seconds.
Examples
Continue after checkpoints and return on a business state:
cycle = browser.wait.cycle(timeout=30, max_total=180) while (match := cycle.first_of(checks, required=False)) is not None: if match.name == "confirmation": match.value.click() cycle.extend(10) continue return match.value
Initialize monotonic soft and optional hard deadlines.
Parameters
Name
Type
Description
wait
Browser wait facade used for observations.
timeout
float
Initial soft deadline in seconds.
interval
float
Default polling interval in seconds.
max_total
float | None
Optional hard lifetime cap in seconds.
Raises
Exception
Description
Timing values are invalid.
Examples
Construct a bounded cycle through its public factory:
cycle = browser.wait.cycle(timeout=30, max_total=180)
- property elapsed: float¶
Return monotonic seconds since cycle creation.
Returns
Non-negative elapsed seconds.
Examples
diagnostics.record("wait.elapsed", cycle.elapsed).
- property remaining: float¶
Return seconds remaining before the effective deadline.
Returns
Non-negative remaining seconds, clamped by
max_total.Examples
if cycle.remaining < 5: cycle.extend(10).
- property expired: bool¶
Return whether no effective wait time remains.
Returns
Truewhen the soft or hard deadline is exhausted.Examples
if cycle.expired: return False.
- property attempts: int¶
Return cumulative successful decision observation attempts.
Returns
Attempts reported by matches returned during this cycle.
Examples
print(cycle.attempts).
- count(name: str) int¶
Return how often one named condition won this cycle.
Parameters
Name
Type
Description
name
str
Condition name supplied to
first_of().Returns
Type
Description
int
Zero or a positive occurrence count.
Examples
Stop repeated CAPTCHA checkpoints:
if cycle.count("captcha") >= 3: raise RuntimeError("CAPTCHA retry limit reached")
- extend(seconds: float) WaitCycle¶
Add seconds to the soft deadline without exceeding
max_total.Parameters
Name
Type
Description
seconds
float
Non-negative extension duration.
Returns
Type
Description
This cycle for optional chaining.
Raises
Exception
Description
secondsis negative.Examples
Grant CAPTCHA solving one additional minute:
cycle.extend(60)
- reset(timeout: float | None = None) WaitCycle¶
Start a fresh soft deadline from now, respecting
max_total.Parameters
Name
Type
Description
timeout
float | None
New duration, or
Noneto reuse the initial timeout.Returns
Type
Description
This cycle for optional chaining.
Raises
Exception
Description
The requested duration is negative.
Examples
Give the page a fresh thirty seconds after confirmation:
cycle.reset(30)
Reuse the original cycle timeout:
cycle.reset()
- first_of(conditions: Mapping[str, Callable[['Browser'], Any]], *, required: bool = True, message: str | None = None) WaitMatch | None¶
Wait for one state using the cycle’s remaining budget.
Parameters
Name
Type
Description
conditions
Mapping[str, Callable[['Browser'], Any]]
Ordered named state probes accepted by
BrowserWait.first_of().required
bool
Raise when the cycle expires; return
Noneotherwise.message
str | None
Optional timeout explanation.
Returns
Type
Description
WaitMatch | None
Winning state with cycle-wide timing and occurrence metadata, or
Noneafter an optional timeout.Raises
Exception
Description
No time remains or no condition wins while
requiredisTrue.A condition contract is invalid.
Exception
Any condition exception is propagated unchanged.
Examples
Service a checkpoint and continue the same cycle:
match = cycle.first_of(checks, required=False) if match and match.name == "confirmation": match.value.click() cycle.extend(10)
Stop normally when the shared budget expires:
if cycle.first_of(checks, required=False) is None: return False
- class ddp_utils.browser.facade.waits.WaitMatch(name: str, value: Any, elapsed: float, attempts: int, occurrence: int = 1)¶
Bases:
objectDescribe the first condition accepted by a browser wait.
Parameters
Name
Type
Description
name
str
Stable caller-defined condition name.
value
Any
Truthy value returned by the winning condition.
elapsed
float
Monotonic seconds elapsed in the owning wait or cycle.
attempts
int
Observation cycles completed before the match.
occurrence
int
Number of times this named state won in the cycle.
Examples
Branch on the detected state and use its returned value:
if match.name == "confirmation": match.value.click()