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.double_click() Yes Yes
locator.right_click() Yes Yes
locator.uncheck() Yes Yes
locator.hover() Yes
browser.drag_and_drop(src, dst) Yes (both)
locator.type(text) Yes Yes
locator.select(option) Yes Yes

With Playwright, you usually do not call wait_for_selector before click / type—actions wait for the target. For navigation readiness use await browser.wait_for_load() or await browser.wait_for_url(...). To wait explicitly: await browser.wait_for_selector(sel, {"timeout": 5000}).

After waiting, assert with expect

Python CSTesting has no assertThat. Read state with await, then from cstesting import expect. See Assertions.

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: none are not considered visible.
  • Elements with opacity: 0 are 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:

  1. The page checks that the user name is unique and shows a disabled Sign Up button.
  2. After the server responds, the button is replaced with an enabled one.
  3. locator.click() waits for the element to exist, be visible, and be enabled, then clicks.
from cstesting import expect

await browser.goto("https://example.com/signup")
await browser.locator("name=username").type("alice")
# Sign Up may be disabled until username is validated — click waits
await browser.locator("//button[contains(.,'Sign Up')]").first().click()
await browser.wait_for_url("**/welcome", {"timeout": 10000})

No extra sleep is needed; Playwright waits for the button to be actionable (within the timeout).