diff --git a/docs/src/actionability.md b/docs/src/actionability.md
index a9484ba053..35ab93bccc 100644
--- a/docs/src/actionability.md
+++ b/docs/src/actionability.md
@@ -8,8 +8,8 @@ title: "Auto-waiting"
Playwright performs a range of actionability checks on the elements before making actions to ensure these actions
behave as expected. It auto-waits for all the relevant checks to pass and only then performs the requested action. If the required checks do not pass within the given `timeout`, action fails with the `TimeoutError`.
-For example, for [`method: Page.click`], Playwright will ensure that:
-- element is [Attached] to the DOM
+For example, for [`method: Locator.click`], Playwright will ensure that:
+- locator resolves to an exactly one element
- element is [Visible]
- element is [Stable], as in not animating or completed animation
- element [Receives Events], as in not obscured by other elements
@@ -17,68 +17,66 @@ For example, for [`method: Page.click`], Playwright will ensure that:
Here is the complete list of actionability checks performed for each action:
-| Action | [Attached] | [Visible] | [Stable] | [Receives Events] | [Enabled] | [Editable] |
-| :- | :-: | :-: | :-: | :-: | :-: | :-: |
-| check | Yes | Yes | Yes | Yes | Yes | - |
-| click | Yes | Yes | Yes | Yes | Yes | - |
-| dblclick | Yes | Yes | Yes | Yes | Yes | - |
-| setChecked | Yes | Yes | Yes | Yes | Yes | - |
-| tap | Yes | Yes | Yes | Yes | Yes | - |
-| uncheck | Yes | Yes | Yes | Yes | Yes | - |
-| hover | Yes | Yes | Yes | Yes | - | - |
-| scrollIntoViewIfNeeded | Yes | - | Yes | - | - | - |
-| screenshot | Yes | Yes | Yes | - | - | - |
-| fill | Yes | Yes | - | - | Yes | Yes |
-| selectText | Yes | Yes | - | - | - | - |
-| dispatchEvent | Yes | - | - | - | - | - |
-| focus | Yes | - | - | - | - | - |
-| getAttribute | Yes | - | - | - | - | - |
-| innerText | Yes | - | - | - | - | - |
-| innerHTML | Yes | - | - | - | - | - |
-| press | Yes | - | - | - | - | - |
-| setInputFiles | Yes | - | - | - | - | - |
-| selectOption | Yes | Yes | - | - | Yes | - |
-| textContent | Yes | - | - | - | - | - |
-| type | Yes | - | - | - | - | - |
-
-
+| Action | [Visible] | [Stable] | [Receives Events] | [Enabled] | [Editable] |
+| :- | :-: | :-: | :-: | :-: | :-: |
+| [`method: Locator.check`] | Yes | Yes | Yes | Yes | - |
+| [`method: Locator.click`] | Yes | Yes | Yes | Yes | - |
+| [`method: Locator.dblclick`] | Yes | Yes | Yes | Yes | - |
+| [`method: Locator.setChecked`] | Yes | Yes | Yes | Yes | - |
+| [`method: Locator.tap`] | Yes | Yes | Yes | Yes | - |
+| [`method: Locator.uncheck`] | Yes | Yes | Yes | Yes | - |
+| [`method: Locator.hover`] | Yes | Yes | Yes | - | - |
+| [`method: Locator.dragTo`] | Yes | Yes | Yes | - | - |
+| [`method: Locator.screenshot`] | Yes | Yes | - | - | - |
+| [`method: Locator.fill`] | Yes | - | - | Yes | Yes |
+| [`method: Locator.clear`] | Yes | - | - | Yes | Yes |
+| [`method: Locator.selectOption`] | Yes | - | - | Yes | - |
+| [`method: Locator.selectText`] | Yes | - | - | - | - |
+| [`method: Locator.scrollIntoViewIfNeeded`] | - | Yes | - | - | - |
+| [`method: Locator.blur`] | - | - | - | - | - |
+| [`method: Locator.dispatchEvent`] | - | - | - | - | - |
+| [`method: Locator.focus`] | - | - | - | - | - |
+| [`method: Locator.press`] | - | - | - | - | - |
+| [`method: Locator.pressSequentially`] | - | - | - | - | - |
+| [`method: Locator.setInputFiles`] | - | - | - | - | - |
## Forcing actions
-Some actions like [`method: Page.click`] support `force` option that disables non-essential actionability checks,
-for example passing truthy `force` to [`method: Page.click`] method will not check that the target element actually
+Some actions like [`method: Locator.click`] support `force` option that disables non-essential actionability checks,
+for example passing truthy `force` to [`method: Locator.click`] method will not check that the target element actually
receives click events.
## Assertions
-You can check the actionability state of the element using one of the following methods as well. This is typically
-not necessary, but it helps writing assertive tests that ensure that after certain actions, elements reach
-actionable state:
+Playwright includes auto-retrying assertions that remove flakiness by waiting until the condition is met, similarly to auto-waiting before actions.
-- [`method: ElementHandle.isChecked`]
-- [`method: ElementHandle.isDisabled`]
-- [`method: ElementHandle.isEditable`]
-- [`method: ElementHandle.isEnabled`]
-- [`method: ElementHandle.isHidden`]
-- [`method: ElementHandle.isVisible`]
-- [`method: Page.isChecked`]
-- [`method: Page.isDisabled`]
-- [`method: Page.isEditable`]
-- [`method: Page.isEnabled`]
-- [`method: Page.isHidden`]
-- [`method: Page.isVisible`]
-- [`method: Locator.isChecked`]
-- [`method: Locator.isDisabled`]
-- [`method: Locator.isEditable`]
-- [`method: Locator.isEnabled`]
-- [`method: Locator.isHidden`]
-- [`method: Locator.isVisible`]
+| Assertion | Description |
+| :- | :- |
+| [`method: LocatorAssertions.toBeAttached`] | Element is attached |
+| [`method: LocatorAssertions.toBeChecked`] | Checkbox is checked |
+| [`method: LocatorAssertions.toBeDisabled`] | Element is disabled |
+| [`method: LocatorAssertions.toBeEditable`] | Element is editable |
+| [`method: LocatorAssertions.toBeEmpty`] | Container is empty |
+| [`method: LocatorAssertions.toBeEnabled`] | Element is enabled |
+| [`method: LocatorAssertions.toBeFocused`] | Element is focused |
+| [`method: LocatorAssertions.toBeHidden`] | Element is not visible |
+| [`method: LocatorAssertions.toBeInViewport`] | Element intersects viewport |
+| [`method: LocatorAssertions.toBeVisible`] | Element is visible |
+| [`method: LocatorAssertions.toContainText`] | Element contains text |
+| [`method: LocatorAssertions.toHaveAttribute`] | Element has a DOM attribute |
+| [`method: LocatorAssertions.toHaveClass`] | Element has a class property |
+| [`method: LocatorAssertions.toHaveCount`] | List has exact number of children |
+| [`method: LocatorAssertions.toHaveCSS`] | Element has CSS property |
+| [`method: LocatorAssertions.toHaveId`] | Element has an ID |
+| [`method: LocatorAssertions.toHaveJSProperty`] | Element has a JavaScript property |
+| [`method: LocatorAssertions.toHaveText`] | Element matches text |
+| [`method: LocatorAssertions.toHaveValue`] | Input has a value |
+| [`method: LocatorAssertions.toHaveValues`] | Select has options selected |
+| [`method: PageAssertions.toHaveTitle`] | Page has a title |
+| [`method: PageAssertions.toHaveURL`] | Page has a URL |
+| [`method: APIResponseAssertions.toBeOK`] | Response has an OK status |
-
-
-## Attached
-
-Element is considered attached when it is [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
+Learn more in the [assertions guide](./test-assertions.md).
## Visible
@@ -101,7 +99,7 @@ Element is considered editable when it is [enabled] and does not have `readonly`
Element is considered receiving pointer events when it is the hit target of the pointer event at the action point. For example, when clicking at the point `(10;10)`, Playwright checks whether some other element (usually an overlay) will instead capture the click at `(10;10)`.
-For example, consider a scenario where Playwright will click `Sign Up` button regardless of when the [`method: Page.click`] call was made:
+For example, consider a scenario where Playwright will click `Sign Up` button regardless of when the [`method: Locator.click`] call was made:
- page is checking that user name is unique and `Sign Up` button is disabled;
- after checking with the server, the disabled `Sign Up` button is replaced with another one that is now enabled.
@@ -110,4 +108,3 @@ For example, consider a scenario where Playwright will click `Sign Up` button re
[Enabled]: #enabled "Enabled"
[Editable]: #editable "Editable"
[Receives Events]: #receives-events "Receives Events"
-[Attached]: #attached "Attached"
diff --git a/docs/src/api/class-elementhandle.md b/docs/src/api/class-elementhandle.md
index 12edbe1817..2ee1a77d4e 100644
--- a/docs/src/api/class-elementhandle.md
+++ b/docs/src/api/class-elementhandle.md
@@ -1090,7 +1090,7 @@ Depending on the [`param: state`] parameter, this method waits for one of the [a
to pass. This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
* `"visible"` Wait until the element is [visible](../actionability.md#visible).
* `"hidden"` Wait until the element is [not visible](../actionability.md#visible) or
- [not attached](../actionability.md#attached). Note that waiting for hidden does not throw when the element detaches.
+ not attached. Note that waiting for hidden does not throw when the element detaches.
* `"stable"` Wait until the element is both [visible](../actionability.md#visible) and
[stable](../actionability.md#stable).
* `"enabled"` Wait until the element is [enabled](../actionability.md#enabled).
diff --git a/docs/src/api/class-locatorassertions.md b/docs/src/api/class-locatorassertions.md
index 7322d15cbe..ad06c25142 100644
--- a/docs/src/api/class-locatorassertions.md
+++ b/docs/src/api/class-locatorassertions.md
@@ -403,7 +403,7 @@ Expected options currently selected.
* langs:
- alias-java: isAttached
-Ensures that [Locator] points to an [attached](../actionability.md#attached) DOM node.
+Ensures that [Locator] points to an element that is [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
**Usage**
@@ -837,7 +837,7 @@ element should intersect viewport at any positive ratio. Defaults to `0`.
* langs:
- alias-java: isVisible
-Ensures that [Locator] points to an [attached](../actionability.md#attached) and [visible](../actionability.md#visible) DOM node.
+Ensures that [Locator] points to an attached and [visible](../actionability.md#visible) DOM node.
To check that at least one element from the list is visible, use [`method: Locator.first`].
diff --git a/docs/src/test-assertions-csharp-java-python.md b/docs/src/test-assertions-csharp-java-python.md
index 0cf50c8d7b..0fa60874b0 100644
--- a/docs/src/test-assertions-csharp-java-python.md
+++ b/docs/src/test-assertions-csharp-java-python.md
@@ -7,6 +7,7 @@ title: "Assertions"
| Assertion | Description |
| :- | :- |
+| [`method: LocatorAssertions.toBeAttached`] | Element is attached |
| [`method: LocatorAssertions.toBeChecked`] | Checkbox is checked |
| [`method: LocatorAssertions.toBeDisabled`] | Element is disabled |
| [`method: LocatorAssertions.toBeEditable`] | Element is editable |
@@ -14,6 +15,7 @@ title: "Assertions"
| [`method: LocatorAssertions.toBeEnabled`] | Element is enabled |
| [`method: LocatorAssertions.toBeFocused`] | Element is focused |
| [`method: LocatorAssertions.toBeHidden`] | Element is not visible |
+| [`method: LocatorAssertions.toBeInViewport`] | Element intersects viewport |
| [`method: LocatorAssertions.toBeVisible`] | Element is visible |
| [`method: LocatorAssertions.toContainText`] | Element contains text |
| [`method: LocatorAssertions.toHaveAttribute`] | Element has a DOM attribute |
@@ -44,7 +46,7 @@ The error would look like this:
def test_foobar(page: Page) -> None:
> expect(page.get_by_text("Name"), "should be logged in").to_be_visible()
E AssertionError: should be logged in
-E Actual value: None
+E Actual value: None
E Call log:
E LocatorAssertions.to_be_visible with timeout 5000ms
E waiting for get_by_text("Name")
diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts
index 8c1144a875..4ce24d9297 100644
--- a/packages/playwright-core/types/types.d.ts
+++ b/packages/playwright-core/types/types.d.ts
@@ -10589,9 +10589,8 @@ export interface ElementHandle extends JSHandle {
* Depending on the `state` parameter, this method waits for one of the [actionability](https://playwright.dev/docs/actionability) checks to
* pass. This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
* - `"visible"` Wait until the element is [visible](https://playwright.dev/docs/actionability#visible).
- * - `"hidden"` Wait until the element is [not visible](https://playwright.dev/docs/actionability#visible) or
- * [not attached](https://playwright.dev/docs/actionability#attached). Note that waiting for hidden does not throw when the element
- * detaches.
+ * - `"hidden"` Wait until the element is [not visible](https://playwright.dev/docs/actionability#visible) or not attached. Note that
+ * waiting for hidden does not throw when the element detaches.
* - `"stable"` Wait until the element is both [visible](https://playwright.dev/docs/actionability#visible) and
* [stable](https://playwright.dev/docs/actionability#stable).
* - `"enabled"` Wait until the element is [enabled](https://playwright.dev/docs/actionability#enabled).
diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts
index 2cd20a69d7..bbbcdb4c53 100644
--- a/packages/playwright/types/test.d.ts
+++ b/packages/playwright/types/test.d.ts
@@ -5425,7 +5425,8 @@ interface APIResponseAssertions {
*/
interface LocatorAssertions {
/**
- * Ensures that {@link Locator} points to an [attached](https://playwright.dev/docs/actionability#attached) DOM node.
+ * Ensures that {@link Locator} points to an element that is
+ * [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
*
* **Usage**
*
@@ -5620,8 +5621,7 @@ interface LocatorAssertions {
}): Promise;
/**
- * Ensures that {@link Locator} points to an [attached](https://playwright.dev/docs/actionability#attached) and
- * [visible](https://playwright.dev/docs/actionability#visible) DOM node.
+ * Ensures that {@link Locator} points to an attached and [visible](https://playwright.dev/docs/actionability#visible) DOM node.
*
* To check that at least one element from the list is visible, use
* [locator.first()](https://playwright.dev/docs/api/class-locator#locator-first).