Why Do We Need Custom Waiters?
In mobile automation with Appium, there are scenarios where standard explicit waits (e.g., elementToBeVisible) are not sufficient. Some elements may be present in the DOM but not fully loaded, especially when dealing with dynamic content updates. A common case is waiting for a specific label or text to appear before proceeding with interactions.
For instance, in a mobile application, a loading screen might disappear, but the main screen elements may still be rendering. If we try to interact with elements too soon, we may encounter NoSuchElementException or StaleElementReferenceException.
A custom waiter can help ensure that the screen is fully loaded before continuing test execution.
Example Scenario
Let's say we have a mobile screen where a title dynamically loads. Instead of just waiting for the element to be present, we should wait until the label is actually populated.
Java Example
public boolean isScreenFullyLoaded() {
return wait.until(mobileDriver -> {
String label = mobileDriver.findElementByName(screenTitle).getAttribute("label");
return !label.isEmpty();
});
}
How This Helps
Ensures that the screen title has loaded before proceeding.
Avoids false positives where the element exists but is not ready.
Prevents flaky tests by ensuring interactions occur only when the screen is fully rendered.
TypeScript Example (WebdriverIO + Appium)
async function isScreenFullyLoaded(): Promise<boolean> {
return await browser.waitUntil(async () => {
const label = await $(`~${screenTitle}`).getAttribute("label");
return label !== "";
}, {
timeout: 10000,
timeoutMsg: "Screen did not fully load within the expected time"
});
}
How This Helps
Uses WebdriverIO's waitUntil function to check for the label.
Ensures that the text is present before interacting with the screen.
Provides a timeout message to improve debugging.
Python Example (Appium-Python-Client)
from selenium.webdriver.support.ui import WebDriverWait
def is_screen_fully_loaded(driver):
return WebDriverWait(driver, 10).until(lambda mobile_driver:
mobile_driver.find_element_by_accessibility_id(screen_title).get_attribute("label") != "")
How This Helps
Uses WebDriverWait with a lambda function to check if the label is populated.
Prevents interacting with elements before they are fully rendered.
Reduces flakiness in mobile automation.
Conclusion
Using a custom waiter like this improves test stability by ensuring that elements are not just present but fully loaded and ready for interaction. This approach is particularly useful when dealing with dynamically loaded content in mobile applications.
Top comments (0)