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).