Skip to main content

Configuring synchronization behavior

Web automation can be challenging due to dynamic page loading, asynchronous content, and varying page response times. Kolibrium provides a flexible synchronization mechanism that goes beyond simple visibility checks, allowing developers to define precise conditions for element readiness.

Single elements: Defining readiness

By default, Kolibrium checks if an element is displayed using the WebElement's isDisplayed property.

val button by driver.id("submit-button") // Default behavior: checks if element is displayed

When working with web elements, simply checking if an element is displayed might not be sufficient. Kolibrium allows you to define complex readiness conditions using Kotlin's powerful lambda syntax.

Common practice is to wait until the element is displayed and enabled so it can be clicked. In order to facilitate this waiting strategy, we can specify what WebElement properties should be evaluated to be true before performing an action on it. This is done by providing a predicate that determines when the found element is considered ready for use.

val button by driver.id("button") { isDisplayed && isEnabled } // Wait until button is both visible and enabled

Or, by using Kolibrium's extension property on WebElement, it can be simplified to

val button by driver.id("button") { isClickable }

where isClickable is defined as

public val WebElement.isClickable: Boolean
get() = isDisplayed && isEnabled

If you are using IntelliJ IDEA or Aqua, and have enabled Inlay Hints (Settings -> Editor -> Inlay Hints -> Lambdas -> Kotlin -> Implicit receivers and parameters), you will see a this: WebElement hint after the opening bracket.

intellij_inlay_hint

This indicates that we have access to the WebElement, meaning we can use other properties as well, such as isSelected to determine when the element is ready for use.

In fact, we can write any code in between the bracket as long as it's evaluated to true.

Speaking of true: if we don't want to perform any checks on a WebElement we can set the default waiting strategy to { true }, which means the element is considered ready regardless of its state.

Advanced readiness conditions

The following locator definitions require all three conditions to be true before being considered "ready".

val searchInput by driver.id("search-input") { 
isDisplayed &&
getAttribute("placeholder")?.isNotEmpty() == true &&
isEnabled
}
val dynamicElement by driver.id("dynamic-content") {
isDisplayed &&
getAttribute("class")?.contains("loading") == false &&
text.contains("Ready")
}

Multiple elements: Collective readiness

When working with collections of elements, Kolibrium provides flexible synchronization strategies.

Wait until all elements are visible

val links by driver.classNames("navigation-link") // Default behavior: checks if all elements are displayed

Specific size validation

val productCards by driver.classNames(
lovator = "product",
cacheLookup = false,
) {
size == 9 // Wait until exactly 9 elements are present
}
note

Notice that element caching is disabled in this case. This is because, with caching enabled:

  1. Kolibrium would find the first element.
  2. Cache it for consecutive accesses, which also means it would stop searching for new elements appearing on the UI.

Advanced collection conditions

val formInputs by driver.cssSelectors("form input") {
all { it.isEnabled && it.getAttribute("value")?.isNotEmpty() == true } // Ensure all inputs are enabled and have values
}

Synchronization strategies for collections

  • all { }: Every element must satisfy the condition.
  • any { }: At least one element must satisfy the condition.
  • count { }: Validates number of elements meeting a condition.