VLearnVibium

How to Wait for AJAX Content in Vibium

Wait for AJAX content in Vibium in Python — let find() auto-wait for rendered elements, wait_for_response() for the network call, and wait_for_function() for state.

By Pramod Dutta··4 min read·Verified with Vibium 26.2
▶ Animated overview · made with Remotion

To wait for AJAX content in Vibium, just find() the element the response renders — Vibium auto-waits for it to appear and become actionable, so no manual wait is needed. Most asynchronous content ends up as a new element in the DOM, and because find() polls until the element exists and is actionable, asserting on that element is your wait. When you need to wait on the network call itself rather than the rendered result, use vibe.wait_for_response(pattern) to block until a matching response completes, or vibe.wait_for_request(pattern) for the outgoing request. For arbitrary page state — a spinner disappearing, a counter reaching a value — vibe.wait_for_function() polls a JavaScript condition until it's true. All three approaches wait for a real signal instead of a guessed duration, which is why Vibium scripts avoid the flaky time.sleep() calls that plague classic AJAX automation.

How do I wait for AJAX-rendered content?

The simplest answer is to find the element the AJAX call produces. Vibium's find() waits until that element exists and is actionable, so the wait is implicit.

from vibium import browser_sync as browser
 
vibe = browser.launch()
vibe.go("https://example.com/dashboard")
 
# Clicking triggers an AJAX fetch that renders results.
vibe.find(role="button", text="Load data").click()
 
# find() waits until the first result row is actually in the DOM.
first = vibe.find(".result-row")
print(first.text())
 
# Now it's safe to read the whole set.
rows = vibe.findAll(".result-row")
print(f"Loaded {len(rows)} rows")
 
vibe.quit()

The key detail: findAll() returns immediately with whatever currently matches, so it would return an empty list if you called it before the data arrived. By first find()-ing a single result row — which waits — you let Vibium pace the script to the network, then read the full list. This element-first pattern handles the vast majority of AJAX cases with zero explicit waiting.

How do I wait for a specific network response?

Use vibe.wait_for_response(pattern) when you must confirm the API call itself finished — for example before asserting on the exact data it returned. It blocks until a response whose URL matches the pattern completes.

from vibium import browser_sync as browser
 
vibe = browser.launch()
vibe.go("https://example.com/dashboard")
 
vibe.find(role="button", text="Load data").click()
 
# Block until the matching API response completes, then inspect it.
response = vibe.wait_for_response("**/api/data**")
print("status:", response.status())
print("payload:", response.json())
 
vibe.quit()

This waits on the network layer through WebDriver BiDi, so you get the response object with status(), headers(), and json() — handy for verifying an endpoint returned 200 with the right body before you check how the UI renders it. Pair it with an element find() afterward to assert the data also reached the screen.

How do I wait for arbitrary page state?

When the signal isn't a single element or a network call — a loading spinner vanishing, a count reaching a threshold — use vibe.wait_for_function() to poll a JavaScript condition until it's true.

from vibium import browser_sync as browser
 
vibe = browser.launch()
vibe.go("https://example.com/dashboard")
 
vibe.find(role="button", text="Refresh").click()
 
# Wait until the loading spinner is gone from the DOM.
vibe.wait_for_function("!document.querySelector('.spinner')")
 
# Or wait until at least 10 items have rendered.
vibe.wait_for_function("document.querySelectorAll('.item').length >= 10")
 
vibe.quit()

wait_for_function() re-evaluates the expression in the page until it returns truthy or the timeout is hit, which makes it the right tool for conditions that don't map to a single locator. Use it sparingly — an element find() is clearer when one exists — but it's invaluable for "wait until the spinner disappears" style checks.

How do I wait for an element to disappear?

To confirm a loader or placeholder has gone, wait for that element to reach the hidden or detached state with wait_until().

from vibium import browser_sync as browser
 
vibe = browser.launch()
vibe.go("https://example.com/dashboard")
 
vibe.find(role="button", text="Save").click()
 
# Wait for the spinner to be removed before reading the result.
vibe.find(".spinner").wait_until("detached")
 
print(vibe.find(".save-confirmation").text())
 
vibe.quit()

wait_until() polls until the element reaches the requested state — visible, hidden, attached, or detached — so waiting for a spinner to detach is a precise, readable way to know an in-flight AJAX action has settled. See waiting and actionability for how these states tie into Vibium's auto-wait model.

Why not just use time.sleep()?

A fixed time.sleep() is the number-one cause of flaky AJAX tests: pick a value too short and the script reads before the data lands; too long and every test pays the cost on every run. Vibium's auto-waiting find(), wait_for_response(), and wait_for_function() all wait for the actual condition and proceed the instant it's met — fast machines run fast, slow CI runners still pass. Reserve sleeps for the rare case where nothing observable changes, and reach for a real wait everywhere else. This is the same principle that makes SPA testing reliable.

Next steps

Frequently asked questions

How do I wait for AJAX content in Vibium?

In most cases just find() the element the AJAX response renders. Vibium auto-waits for it to exist and become actionable, so you do not need a manual wait. For the network call itself, use vibe.wait_for_response(url) to block until the matching response arrives.

How do I wait for a specific network request in Vibium?

Call vibe.wait_for_response(pattern) to wait until a response whose URL matches the pattern completes, or vibe.wait_for_request(pattern) for the outgoing request. This is ideal when you must confirm an API call finished before asserting on the data it returns.

Why are time.sleep() waits bad for AJAX in Vibium?

Fixed sleeps either waste time or race the network: too short and they read before the data arrives, too long and the suite crawls. Vibium's auto-wait and wait_for_response() poll for the real condition, so they proceed the instant the content is ready on fast and slow connections alike.

Vibium is created by Jason Huggins. This is an independent tutorial — see the official Vibium site and GitHub repo for canonical docs.

Related guides