> For the complete documentation index, see [llms.txt](https://docs.bugbug.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bugbug.io/preventing-failed-tests/waiting-conditions.md).

# Waiting conditions

How BugBug waits before each step: the step timeline, required and optional waiting conditions, defaults per step type, what each condition checks, and how to change them in the app, YAML and API.

Before each step, BugBug checks that the page and the element are ready, for example that the page has loaded, the button exists, is visible and isn't covered by a popup. These checks are called **waiting conditions**. They make tests stable without fixed delays: BugBug waits exactly as long as the page needs, up to the step's timeout.

## How a step waits

1. **Delay.** If the step has a [delay](/preventing-failed-tests/delay-sleep.md), BugBug waits for it first.
2. **Waiting conditions.** BugBug checks the step's active conditions again and again until they're met.
3. **Conditions time limit.** If some conditions still aren't met after part of the step's [timeout](/preventing-failed-tests/timeout.md), BugBug decides:
   * If all **required** conditions are met, it skips the other ones and runs the step. The step is marked as **passed with issues**.
   * If a required condition isn't met, it keeps waiting.
4. **Timeout.** If a required condition still isn't met when the timeout ends, the step fails with `FAILED_WAITING_CONDITIONS`. If the element doesn't exist at all, it fails with `ELEMENT_DOES_NOT_EXIST`.

The conditions time limit is 70% of the timeout for timeouts up to 10 seconds, and 50% for longer timeouts. With the default timeouts (30 seconds locally, 60 seconds in the cloud), BugBug skips unmet optional conditions after 15 seconds locally and 30 seconds in the cloud.

Skipped conditions are shown with a different green indicator ![](https://3168433179-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MKixgeBPbLvnD0l1eiV%2Fuploads%2FK728O2urlEVlpTbR6p46%2FScreenshot%202022-04-11%20at%2017.59.19.png?alt=media\&token=74c4ecc5-1fe2-45a1-8a4e-186ca914dda8). See [test statuses](/running-tests/statuses.md).

### Required conditions

Required conditions are never skipped. They depend on the step type:

| Step                                                                    | Required conditions                                                                   |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Click, Hover, Press mouse button, Move, Type text, Paste from clipboard | Element is visible, Element is not covered, Element must be active                    |
| Clear input                                                             | Element is visible, Element is not covered, Element must be active, Element has focus |
| Release mouse button, Scroll, Assertion, If condition                   | Element is visible                                                                    |
| Change value, Upload file                                               | Element must be active                                                                |
| Element visual regression                                               | Element is visible, Element is not covered                                            |
| Any step                                                                | Element has an attribute                                                              |

All other conditions are optional: when the time limit passes, BugBug skips them and continues.

## Available waiting conditions

| Condition                               | YAML / API name                | Checks                                                                 |
| --------------------------------------- | ------------------------------ | ---------------------------------------------------------------------- |
| Document readyState is complete         | `documentComplete`             | The page has loaded.                                                   |
| Page network requests are finished      | `networkIdle`                  | The page isn't waiting for more than a set number of network requests. |
| Element is visible                      | `elementIsVisible`             | The element is at least partly visible.                                |
| Element is not covered by the other one | `elementIsNotCovered`          | No other element covers the point where BugBug interacts.              |
| Element is not animating                | `elementIsNotAnimating`        | The element has stopped moving.                                        |
| Element must be active                  | `elementIsNotDisabled`         | The form element isn't disabled.                                       |
| Element has focus                       | `elementHasFocus`              | The field has focus before typing.                                     |
| Element must have expected attribute    | `elementHasAttribute`          | The element has an attribute with a given value.                       |
| Page will navigate after step execution | `pageNavigationAfterExecution` | After the step, BugBug waits for the page to navigate.                 |

### Document readyState is complete

BugBug waits until the page has loaded (`document.readyState` is `complete`, the `load` event). This condition is always optional. If the page doesn't finish loading in time, BugBug continues and marks the condition as skipped.

### Page network requests are finished

Web apps keep loading data after the page loads. BugBug runs the step once the number of pending network requests has stayed at or below a set maximum for at least 1 second. The maximum is called **Max. pending requests** and defaults to **2**. You can change it in [Project settings](/preventing-failed-tests/project-settings.md) or per step.

When this condition isn't met, the step details list the pending requests, so you can see what the page is waiting for. If your app keeps a connection open all the time, such as long polling, analytics or a websocket fallback, raise the number or turn the condition off for the affected steps.

### Element is visible

BugBug waits until the element is at least partly visible: in the viewport, not hidden and not transparent. For example, if a "Done" button appears after a few seconds, BugBug waits for it. That's why you rarely need a fixed delay.

### Element is not covered by the other one

BugBug checks the point where it will click or type, and waits until no other element, such as a cookie banner, a modal or a loader, covers it. When this condition isn't met, the step details show the covering element.

### Element is not animating

BugBug waits until the element and its parents stop moving and their CSS keyframe animations finish. For example, in a section that expands with an animation, BugBug waits until it's fully expanded.

* CSS transitions alone don't block the step.
* If the only animations are infinite (looping), BugBug treats the condition as skipped and continues.

### Element must be active

For form elements that can be disabled, BugBug waits until the element isn't disabled, for example until a **Submit** button becomes active after the form is valid.

### Element has focus

Before typing into a field, BugBug checks that the field has focus. If it doesn't, BugBug tries to focus it itself. This condition is active by default only for **Type text** and **Clear input**.

### Element must have expected attribute

BugBug waits until the element has an attribute with an exact value. This condition is always required and isn't active by default; add it in the step's **Waiting conditions** section.

Enter the expected value as `name="value"`, for example `class="bugbug"` or `data-state="ready"`.

### Page will navigate after step execution

BugBug adds this condition when it records a step that changed the URL, such as a click on a link. After the step, BugBug waits for the URL to change before it runs the next step. This also works for URL changes in single-page applications. **Reload page** steps also have this condition on by default.

A reload keeps the same URL, so BugBug waits for the browser to start showing the reloaded page, not for a URL change. The page may still be loading at that point, and the next step's own conditions wait for the rest.

This condition is optional: if the page doesn't navigate, the step is marked as **passed with issues**.

## Default conditions per step

BugBug sets the conditions for each step based on its type. *(off)* means the condition is available but not active by default.

| Step                                                                                                                   | Default conditions                                                                                                                                                                                      |
| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Click, Double click, Right click, Hover, Press/Release mouse button, Move, Drag & drop, Scroll, Type text, Clear input | Document complete, Network idle, Element is visible, not covered, not animating, must be active, has focus *(on only for Type text and Clear input)*, has attribute *(off)*, Page will navigate *(off)* |
| Change value, Select option, Upload file                                                                               | Same as above, without Element has focus                                                                                                                                                                |
| Run custom JavaScript                                                                                                  | Document complete, Network idle, Page will navigate *(off)*                                                                                                                                             |
| Go back, Go forward                                                                                                    | Document complete, Network idle, Page will navigate                                                                                                                                                     |
| Reload page                                                                                                            | Document complete *(off)*, Network idle *(off)*, Page will navigate                                                                                                                                     |
| Switch context, If condition, Page visual regression                                                                   | Document complete, Network idle                                                                                                                                                                         |
| Assertions on text, value, Custom JavaScript, checked / not checked                                                    | Document complete, Network idle, Element is visible, not covered, not animating, must be active *(off)*, has focus *(off)*, has attribute *(off)*                                                       |
| Element is visible, attribute and disabled assertions                                                                  | Document complete, Network idle, not animating, must be active *(off)*, has attribute *(off)*                                                                                                           |
| Page assertions, Number of elements, DOM element exists / does not exist, Element is not visible                       | Document complete, Network idle                                                                                                                                                                         |
| Download started                                                                                                       | Document complete                                                                                                                                                                                       |
| Go to URL, New tab, Close tab, Answer a prompt, Open inbox                                                             | None                                                                                                                                                                                                    |

## Change waiting conditions

Set the default behavior for the whole project in **Project settings → Waiting conditions**. All steps follow these settings.

![Waiting conditions in project settings](https://3168433179-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MKixgeBPbLvnD0l1eiV%2Fuploads%2F4lP77zb3Mk7qsLFDeguj%2FScreenshot%202022-04-11%20at%2018.39.36.png?alt=media\&token=f7e33698-b850-4d27-b480-92d2a945bb72)

You can override a condition for a single step in the step's **Waiting conditions** section, for example to turn off **Element is not covered** for a step where a harmless tooltip covers the button. A condition you change in a step no longer follows the project setting; the other conditions of the step still do.

![Waiting conditions of a step](https://3168433179-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MKixgeBPbLvnD0l1eiV%2Fuploads%2FRkz8oaNZfPO9pTFytqER%2Fimage.png?alt=media\&token=e9f2b38e-a154-418e-ac51-2396430bef03)

{% hint style="info" %}
Turn off a condition only for the steps where it isn't useful. Don't raise all timeouts or turn off all conditions to fix one failing step: find which condition fails in the step details first.
{% endhint %}

### In YAML and the API

In [YAML](/export-import-and-backup/yaml-schema.md) a step lists its conditions in `waiting_conditions`:

```yaml
waiting_conditions:
  - condition: networkIdle
    expected: 5
    is_active: true
  - condition: elementHasAttribute
    expected: data-state="ready"
  - condition: elementIsNotCovered
    is_active: false
```

`expected` is used by two conditions only:

* `networkIdle`: an integer, the **Max. pending requests** value.
* `elementHasAttribute`: a string in the form `name="value"`.

Other conditions take no `expected` value.

In the API and MCP the field is `waitingConditions`, and each condition has `type`, `expected`, `isActive` and `isOverridden`. Set `isOverridden: true` to keep the step's own setting, or `false` to follow the project setting.

```json
"waitingConditions": [
  { "type": "elementIsNotCovered", "isActive": false, "isOverridden": true }
]
```

* **Leave the field out** when you create a step, to get the defaults for its type.
* **An empty list** (`[]`) means no waiting conditions at all.
* **When you update** a step, the list replaces all its conditions, so include every condition the step should keep.

## Related errors

| Error code                  | Meaning                                                                                                                                           |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FAILED_WAITING_CONDITIONS` | The element exists, but a required condition wasn't met before the timeout. The step details show which one, with the expected and current value. |
| `ELEMENT_DOES_NOT_EXIST`    | No element matches the selector.                                                                                                                  |

See all [error codes](/debugging-tests/error-codes.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.bugbug.io/preventing-failed-tests/waiting-conditions.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
