Waits
Introduction
CSTesting performs a set of actionability checks on elements before performing actions, so that actions run only when the element is ready. It auto-waits for the relevant checks to pass and then runs the requested action. If the checks do not pass within the timeout (default 30 seconds), the action fails with an error.
For example, for locator.click(), CSTesting ensures that:
- The locator resolves to an element (when using
.first(),.last(), or.nth(index)for multiple matches). - The element is Visible.
- The element is Enabled.
For locator.type(text), CSTesting ensures the element is visible and Editable. Other actions use the checks that apply (see table below).
Here is the list of actionability checks performed for each action in CSTesting:
| Action | Visible | Enabled | Editable |
|---|---|---|---|
locator.check() |
Yes | Yes | — |
locator.click() |
Yes | Yes | — |
locator.doubleClick() |
Yes | Yes | — |
locator.rightClick() |
Yes | Yes | — |
locator.uncheck() |
Yes | Yes | — |
locator.hover() |
Yes | — | — |
locator.dragAndDrop(other) |
Yes (both) | — | — |
locator.type(text) |
Yes | — | Yes |
locator.select(option) |
Yes | Yes | — |
locator.selectOptions(...) |
Yes | Yes | — |
You typically do not need to call waitForSelector before an action; CSTesting waits for the element to be actionable first. After navigation, use browser.waitForLoad() for page-level readiness.
Assertions
CSTesting provides assertThat(locator) for element assertions and assertThat() for page assertions. These evaluate once (no auto-retry). To wait then assert, use waitForSelector first, or rely on auto-wait before a follow-up action.
| Assertion | Description |
|---|---|
assertThat(locator).isVisible() | Element is visible |
assertThat(locator).isEditable() | Element is editable (not disabled, not readonly) |
assertThat(locator).isEmpty() | Element value or text is empty |
assertThat(locator).isEnabled() | Element is enabled |
assertThat(locator).isDisabled() | Element is disabled |
assertThat(locator).contains(expected) | Text or value contains the string |
assertThat(locator).hasText(expected) | Text content matches or contains |
assertThat(locator).containText(expected) | Text content contains the string |
assertThat(locator).hasValue(expected) | Input/select value equals |
assertThat(locator).containValue(expected) | Input/select value contains |
assertThat(locator).hasAttribute(name) | Element has the attribute |
assertThat(locator).hasAttribute(name, value) | Attribute equals the value |
assertThat(locator).count(n) | Number of matching elements equals n |
assertThat(locator).hasCount(n) | Same as count(n) |
assertThat().hasTitle(expected) | Page title contains or equals |
assertThat().hasURL(pattern) | Page URL contains or matches pattern (* wildcard) |
Visible
An element is considered visible when it has a non-zero size and is not visibility: hidden in computed style.
- Elements with zero size are not considered visible.
- Elements with
display: noneare not considered visible. - Elements with
opacity: 0are still considered visible by this definition.
Enabled
An element is considered enabled when it is not disabled.
An element is disabled when:
- It is a
<button>,<select>,<input>,<textarea>,<option>, or<optgroup>with a[disabled]attribute; or - It is one of those elements inside a
<fieldset>with[disabled]; or - It is inside an element with
[aria-disabled="true"].
CSTesting uses the element's disabled property and DOM structure for this check.
Editable
An element is considered editable when it is enabled and not readonly.
An element is readonly when:
- It is a
<input>or<textarea>with a[readonly]attribute; or - It has
[aria-readonly="true"]with a role that supports it.
<select> elements are treated as editable when enabled (they can be changed). CSTesting checks disabled and readOnly (and tag type) for inputs and textareas.
Example
CSTesting will wait for the Sign Up button to become actionable before clicking, even if it appears only after a delay:
- The page checks that the user name is unique and shows a disabled Sign Up button.
- After the server responds, the button is replaced with an enabled one.
locator.click()waits for the element to exist, be visible, and be enabled, then clicks.
browser.gotoUrl("https://example.com/signup");
browser.locator("name=username").type("alice");
// Sign Up may be disabled until username is validated.
browser.locator("//button[contains(.,'Sign Up')]").first().click();
browser.assertThat().hasURL("**/welcome");
No explicit waitForSelector or sleep is needed; the click auto-waits for the button to be ready (within the default timeout).