🎯 Selenium Advanced Waits: Custom Wait Conditions & Fluent Wait
The Story of the Patient Waiter
Imagine you’re at a fancy restaurant. The waiter doesn’t just bring your food the moment you sit down. They wait until:
- The chef finishes cooking
- The food is ready
- The plate looks perfect
If the waiter is too impatient? Disaster! Empty plates arrive. If they wait too long? Cold food!
Selenium waits work exactly the same way. We need to wait for web elements to be ready—but smartly, not blindly.
🌟 What Are Advanced Waits?
Basic waits are like setting a kitchen timer: “Wait 10 seconds, then check.”
Advanced waits are smarter. They’re like a waiter who:
- Keeps checking if the food is ready
- Stops the moment it’s done
- Doesn’t waste time
đź§© Two Heroes of Advanced Waiting
graph TD A[Advanced Waits] --> B[Custom Wait Conditions] A --> C[Fluent Wait] B --> D[You define WHAT to wait for] C --> E[You configure HOW to wait]
🎨 Custom Wait Conditions
What Is It?
Think of ordering a custom pizza. The menu has pepperoni, cheese, veggie—but you want something special.
Custom Wait Conditions let you tell Selenium:
“Wait until THIS specific thing happens—something not on the standard menu!”
Why Do We Need It?
Selenium has built-in waits like:
- Wait for element to be clickable
- Wait for element to be visible
But what if you need:
- Wait until a button’s text changes to “Complete”
- Wait until a counter reaches 100
- Wait until an element’s color turns green
That’s when you create your own custom condition!
How to Create Custom Wait Conditions
Python Example
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
# Custom condition: Wait for text to change
def text_to_be_present(locator, text):
def check(driver):
element = driver.find_element(*locator)
return text in element.text
return check
# Using the custom condition
wait = WebDriverWait(driver, 10)
wait.until(text_to_be_present(
(By.ID, "status"),
"Complete"
))
Java Example
Wait<WebDriver> wait = new WebDriverWait(driver, 10);
// Custom condition using lambda
wait.until(driver -> {
WebElement element = driver.findElement(
By.id("status")
);
return element.getText().contains("Complete");
});
Real-Life Analogy
You’re waiting for a package. The standard check is: “Is there a box at the door?”
Your custom check might be: “Is there a box at the door AND is it from Amazon AND is it heavy enough to be my laptop?”
That’s a custom wait condition—checking for YOUR specific needs!
⚙️ Fluent Wait Configuration
What Is Fluent Wait?
Imagine you’re baking cookies. You could:
- Check once after 10 minutes (might burn!)
- Check every second for 10 minutes (annoying!)
- Check every 30 seconds for 10 minutes (just right!)
Fluent Wait lets you control:
- How long to wait total (timeout)
- How often to check (polling interval)
- What errors to ignore while waiting
The Three Magic Settings
graph TD A[Fluent Wait Settings] --> B[⏱️ Timeout] A --> C[🔄 Polling Interval] A --> D[🚫 Ignored Exceptions] B --> E[Maximum wait time] C --> F[How often to check] D --> G[Errors to skip]
Python Fluent Wait Example
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
# Create Fluent Wait
wait = WebDriverWait(
driver,
timeout=30, # Wait up to 30 seconds
poll_frequency=2, # Check every 2 seconds
ignored_exceptions=[ # Ignore these errors
NoSuchElementException
]
)
# Use it
element = wait.until(
EC.presence_of_element_located((By.ID, "result"))
)
Java Fluent Wait Example
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(2))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(driver ->
driver.findElement(By.id("result"))
);
Breaking Down Each Setting
1. Timeout (Maximum Wait Time)
What: The longest you’ll wait before giving up.
Example: “I’ll wait at the bus stop for 30 minutes. If the bus doesn’t come, I’ll walk.”
# Wait maximum 30 seconds
timeout=30
2. Polling Interval (Check Frequency)
What: How often Selenium checks if the condition is met.
Example: Instead of staring at your phone for a text, you check every 5 minutes.
# Check every 2 seconds
poll_frequency=2
Pro Tip:
- Fast-loading pages? Poll every 500ms
- Slow applications? Poll every 2-5 seconds
- Don’t poll too fast—it wastes resources!
3. Ignored Exceptions (Errors to Skip)
What: Errors Selenium should ignore while waiting.
Example: While waiting for cookies to bake, you ignore the smoke alarm going off briefly (it happens!).
# Ignore "element not found" errors during waiting
ignored_exceptions=[NoSuchElementException]
Common exceptions to ignore:
NoSuchElementException- Element not found yetStaleElementReferenceException- Element changed
🎮 Combining Both: The Ultimate Wait
Here’s the magic—use Custom Conditions WITH Fluent Wait!
Python Combined Example
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import (
NoSuchElementException,
StaleElementReferenceException
)
# Custom condition: button becomes green
def button_is_green(locator):
def check(driver):
element = driver.find_element(*locator)
color = element.value_of_css_property(
"background-color"
)
return "green" in color or "rgb(0, 128, 0)" in color
return check
# Fluent wait with custom condition
wait = WebDriverWait(
driver,
timeout=20,
poll_frequency=1,
ignored_exceptions=[
NoSuchElementException,
StaleElementReferenceException
]
)
wait.until(button_is_green((By.ID, "submit-btn")))
print("Button is now green! Ready to click!")
Java Combined Example
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(20))
.pollingEvery(Duration.ofSeconds(1))
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
// Custom condition: element has specific attribute
wait.until(driver -> {
WebElement btn = driver.findElement(By.id("submit"));
String status = btn.getAttribute("data-status");
return "ready".equals(status);
});
🎯 When to Use What?
| Situation | Solution |
|---|---|
| Need to wait for something unusual | Custom Wait Condition |
| Element loads slowly, need patience | Increase Timeout |
| Page is laggy, don’t overload it | Increase Polling Interval |
| Element keeps disappearing/reappearing | Add Ignored Exceptions |
🚀 Pro Tips
1. Don’t Poll Too Fast
# ❌ Too aggressive - wastes resources
poll_frequency=0.1
# âś… Just right for most cases
poll_frequency=0.5
2. Chain Multiple Conditions
# Wait for element to be visible AND have text
def visible_with_text(locator, text):
def check(driver):
element = driver.find_element(*locator)
return element.is_displayed() and text in element.text
return check
3. Use Meaningful Timeouts
# ❌ Random number
timeout=47
# âś… Based on actual page behavior
timeout=30 # Page usually loads in 20s, add buffer
📝 Quick Summary
Custom Wait Conditions:
- Create YOUR OWN rules for waiting
- Perfect for unique scenarios
- You define the “until” condition
Fluent Wait Configuration:
- Control the WAITING BEHAVIOR
- Set timeout, polling, and ignored errors
- Fine-tune performance
Together: They give you complete control over waiting—patient, smart, and efficient!
🎬 The Happy Ending
Remember our restaurant waiter? With Custom Wait Conditions, they know exactly what “ready” means for YOUR order. With Fluent Wait, they check at just the right intervals without being annoying.
Your tests now wait intelligently—not too long, not too short, and always for the right thing!
You’ve mastered the art of waiting. Your Selenium tests are now patient, precise, and powerful! 🎉