1. Enhanced Explicit Waits with Fluent Conditions
Instead of generic waitForElementVisible
, create custom wait methods that combine multiple conditions for robustness:
// Custom wait for critical elements to be fully interactive
def waitForPageStability(TestObject to, int timeout = 30) {
WebUI.waitForElementPresent(to, timeout)
WebUI.waitForElementClickable(to, timeout)
WebUI.waitForElementNotHasAttribute(to, "disabled", timeout)
}
Usage:
waitForPageStability(findTestObject('LoginPage/btnSubmit'), 45)
2. Page Ready State + Network Idle Detection
Use JavaScript to monitor both DOM readiness and network activity:
groovy
@Keyword
def waitForPageComplete(int timeout = 30) {
WebDriver driver = DriverFactory.getWebDriver()
WebUI.waitForCondition(
{
((JavascriptExecutor) driver).executeScript(
"return document.readyState === 'complete' && " +
"window.performance.getEntriesByType('navigation')[0].responseEnd > 0 && " +
"window.performance.getEntriesByType('resource').filter(r => r.requestStart > (performance.now() - 1000)).length === 0"
) == true
},
timeout
)
}
Triggers when:
- DOM is fully loaded
- No network calls in last 1 second
- Page rendering is complete
3. Application-Specific Load Triggers
Leverage your app’s unique indicators:
groovy
// Wait for Angular apps
WebUI.waitForAngularLoad(30)
// Wait for React hydration
WebUI.waitForElementHasAttribute(findTestObject('AppRoot'), 'data-hydrated', 30)
// Wait for loader disappearance
WebUI.waitForElementNotPresent(findTestObject('Spinner'), 30)
4. Dynamic Polling with Retry Logic
Implement adaptive waits with exponential backoff:
groovy
@Keyword
def smartWaitForElement(TestObject to, int maxTimeout = 60) {
int attempts = 0
int delay = 2
while (attempts < (maxTimeout/delay)) {
try {
WebUI.verifyElementPresent(to, 1)
return
} catch (Exception e) {
sleep(delay * 1000)
delay = Math.min(delay * 1.5, 5) // Cap at 5s intervals
attempts++
}
}
throw new Exception("Element not found after ${maxTimeout} seconds")
}
5. Browser-Level Monitoring
Force-enable Smart Wait compatibility via Edge policies (requires admin rights):
- Create Registry Key:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\ExtensionSettings
- Add policy to allow extensions in InPrivate:
json
{
"*": {
"allowed_in_incognito": true,
"runtime_allowed_hosts": ["*"]
}
}
- Re-launch Edge with
--enable-extensions
flag in Katalon:
groovy
EdgeOptions options = new EdgeOptions()
options.addArguments("inprivate", "enable-extensions", "load-extension=/path/to/katalon/smartwait")
WebUI.openBrowser('', options)
6. Hybrid Wait Strategy
Combine multiple approaches for maximum reliability:
groovy
def safeInteraction(TestObject to) {
waitForPageComplete(20) // JS-level readiness
waitForPageStability(to, 10) // Element-specific checks
WebUI.click(to) // Final action
}