From a8d0fde5a4b4ce0d024d50fae39b6528c4679f1f Mon Sep 17 00:00:00 2001 From: David Burns Date: Wed, 4 Nov 2026 11:43:32 +0000 Subject: [PATCH 1/3] List built-in wait conditions on the Waits page Agents reading the Waits page concluded that the condition they needed did not exist, because the page only showed one lambda per language. Add a Built-in conditions section with the full list of ready-made conditions for Java (ExpectedConditions), Python (expected_conditions) and JavaScript (until), taken from the Selenium trunk sources, and say that .NET and Ruby use lambdas and blocks instead. Add one tested example per binding that waits for a title, an element, its visibility and its text with built-in conditions only. The new imports move existing lines by one, so update the gh-codeblock ranges that point to the Java and Python waits tests in all languages. Link the Expected Conditions page to the new list. Fixes #2971 Claude-Session: https://claude.ai/code/session_01LA4X4y2cMRjKqDaAwexzDp --- .../java/dev/selenium/waits/WaitsTest.java | 18 ++ examples/javascript/test/waits/waits.spec.js | 13 ++ examples/python/tests/waits/test_waits.py | 15 ++ .../ai_agents/outdated_patterns.en.md | 4 +- .../documentation/guides/waiting.en.md | 4 +- .../expected_conditions.en.md | 3 + .../documentation/webdriver/waits.en.md | 188 +++++++++++++++++- .../documentation/webdriver/waits.ja.md | 188 +++++++++++++++++- .../documentation/webdriver/waits.pt-br.md | 188 +++++++++++++++++- .../documentation/webdriver/waits.zh-cn.md | 188 +++++++++++++++++- 10 files changed, 781 insertions(+), 28 deletions(-) diff --git a/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java b/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java index de6347620b74..e089f6f72819 100644 --- a/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java +++ b/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java @@ -10,6 +10,7 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; import org.openqa.selenium.support.ui.WebDriverWait; @@ -93,4 +94,21 @@ public void explicitWithOptions() { Assertions.assertEquals("Displayed", revealed.getDomProperty("value")); } + + @Test + public void expectedConditions() { + startChromeDriver(new ChromeOptions()); + + driver.get("https://www.selenium.dev/selenium/web/web-form.html"); + driver.findElement(By.id("my-text-id")).sendKeys("Selenium"); + driver.findElement(By.cssSelector("button")).click(); + + Wait wait = new WebDriverWait(driver, Duration.ofSeconds(2)); + wait.until(ExpectedConditions.titleIs("Web form - target page")); + WebElement message = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("message"))); + wait.until(ExpectedConditions.visibilityOf(message)); + wait.until(ExpectedConditions.textToBePresentInElement(message, "Received!")); + + Assertions.assertEquals("Received!", message.getText()); + } } diff --git a/examples/javascript/test/waits/waits.spec.js b/examples/javascript/test/waits/waits.spec.js index dbc3c83e93f2..b63d072a74bc 100644 --- a/examples/javascript/test/waits/waits.spec.js +++ b/examples/javascript/test/waits/waits.spec.js @@ -53,4 +53,17 @@ describe('Waits', function () { await revealed.sendKeys("Displayed"); assert.equal(await revealed.getAttribute("value"), "Displayed") }) + + it('expected conditions', async function () { + await driver.get('https://www.selenium.dev/selenium/web/web-form.html'); + await driver.findElement(By.id("my-text-id")).sendKeys("Selenium"); + await driver.findElement(By.css("button")).click(); + + await driver.wait(until.titleIs("Web form - target page"), 2000); + let message = await driver.wait(until.elementLocated(By.id("message")), 2000); + await driver.wait(until.elementIsVisible(message), 2000); + await driver.wait(until.elementTextIs(message, "Received!"), 2000); + + assert.equal(await message.getText(), "Received!") + }) }); \ No newline at end of file diff --git a/examples/python/tests/waits/test_waits.py b/examples/python/tests/waits/test_waits.py index aa3d773a6018..a4370da9af7d 100644 --- a/examples/python/tests/waits/test_waits.py +++ b/examples/python/tests/waits/test_waits.py @@ -2,6 +2,7 @@ import time from selenium.common import NoSuchElementException, ElementNotInteractableException from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait @@ -55,3 +56,17 @@ def test_explicit_options(driver): wait.until(lambda _ : revealed.send_keys("Displayed") or True) assert revealed.get_property("value") == "Displayed" + + +def test_expected_conditions(driver): + driver.get('https://www.selenium.dev/selenium/web/web-form.html') + driver.find_element(By.ID, "my-text-id").send_keys("Selenium") + driver.find_element(By.CSS_SELECTOR, "button").click() + + wait = WebDriverWait(driver, timeout=2) + wait.until(EC.title_is("Web form - target page")) + message = wait.until(EC.presence_of_element_located((By.ID, "message"))) + wait.until(EC.visibility_of(message)) + wait.until(EC.text_to_be_present_in_element((By.ID, "message"), "Received!")) + + assert message.text == "Received!" diff --git a/website_and_docs/content/documentation/ai_agents/outdated_patterns.en.md b/website_and_docs/content/documentation/ai_agents/outdated_patterns.en.md index c716a02c6e72..b5ed32a9be85 100644 --- a/website_and_docs/content/documentation/ai_agents/outdated_patterns.en.md +++ b/website_and_docs/content/documentation/ai_agents/outdated_patterns.en.md @@ -136,10 +136,10 @@ Current form: {{< tabpane text=true >}} {{< tab header="Java" >}} -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L68-L69" >}} {{< /tab >}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L41-L42" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L42-L43" >}} {{< /tab >}} {{< /tabpane >}} diff --git a/website_and_docs/content/documentation/guides/waiting.en.md b/website_and_docs/content/documentation/guides/waiting.en.md index d8fd8a9c4ced..be74da04341b 100644 --- a/website_and_docs/content/documentation/guides/waiting.en.md +++ b/website_and_docs/content/documentation/guides/waiting.en.md @@ -31,10 +31,10 @@ This example waits for an element that is revealed a couple of seconds after a c {{< tabpane text=true >}} {{< tab header="Java" >}} -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L68-L69" >}} {{< /tab >}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L41-L42" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L42-L43" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57" >}} diff --git a/website_and_docs/content/documentation/webdriver/support_features/expected_conditions.en.md b/website_and_docs/content/documentation/webdriver/support_features/expected_conditions.en.md index 2513b3eeb5df..2722fc87680b 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/expected_conditions.en.md +++ b/website_and_docs/content/documentation/webdriver/support_features/expected_conditions.en.md @@ -19,6 +19,9 @@ These methods can include conditions such as: * text is visible * title contains specified value +The [Waits]({{< ref "../waits#built-in-conditions" >}}) page lists every built-in condition +for each language. + {{< tabpane text=true >}} {{% tab header="Java" %}} [Expected Conditions Documentation](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html) diff --git a/website_and_docs/content/documentation/webdriver/waits.en.md b/website_and_docs/content/documentation/webdriver/waits.en.md index cd12f96126ef..27df1e362223 100644 --- a/website_and_docs/content/documentation/webdriver/waits.en.md +++ b/website_and_docs/content/documentation/webdriver/waits.en.md @@ -71,10 +71,10 @@ Solving our example with an implicit wait looks like this: {{< tabpane text=true >}} {{< tab header="Java" >}} -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L51" >}} {{< /tab >}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L27" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L28" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39" >}} @@ -104,12 +104,12 @@ Another nice feature is that, by default, the Selenium Wait class automatically {{% tab header="Java" %}} This example shows the condition being waited for as a _lambda_. Java also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L68-L69" >}} {{% /tab %}} {{% tab header="Python" %}} This example shows the condition being waited for as a _lambda_. Python also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L41-L42" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L42-L43" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57" >}} @@ -126,6 +126,182 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte {{< /tab >}} {{< /tabpane >}} +### Built-in conditions + +Instead of writing a lambda for every wait, most bindings ship a library of ready-made +conditions for the things that are most often waited on. +Conditions that take a locator find the element on every poll, +so they also wait for the element to exist. +Many of them return the element (or elements) once the condition is met, +so the result of the wait can be used directly. + +This example locates an element, waits for it to be visible, +and then waits for its text, using only built-in conditions: + +{{< tabpane text=true >}} + {{< tab header="Java" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L106-L110" >}} + {{< /tab >}} + {{< tab header="Python" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L66-L70" >}} + {{< /tab >}} + {{% tab header="CSharp" %}} +.NET does not ship built-in conditions. Pass a lambda to `WebDriverWait.Until()`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. Pass a block to `Selenium::WebDriver::Wait#until`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{< tab header="JavaScript" >}} +{{< gh-codeblock path="/examples/javascript/test/waits/waits.spec.js#L62-L65" >}} + {{< /tab >}} + {{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class listed in the Java tab below. + {{% /tab %}} +{{< /tabpane >}} + +The complete list of built-in conditions for each binding: + +{{< tabpane text=true >}} +{{% tab header="Java" %}} +Class `org.openqa.selenium.support.ui.ExpectedConditions` +([API docs](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html)). +Use with `new WebDriverWait(driver, timeout).until(...)`. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(title)` | The page title contains the value | +| `urlToBe(url)` | The current URL equals the value | +| `urlContains(fraction)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `presenceOfElementLocated(By)` | An element is in the DOM (not necessarily visible); returns it | +| `presenceOfAllElementsLocatedBy(By)` | At least one element is in the DOM; returns them all | +| `presenceOfNestedElementLocatedBy(By or WebElement, By)` | A child element is in the DOM under a parent; returns it | +| `presenceOfNestedElementsLocatedBy(By, By)` | Child elements are in the DOM under a parent; returns them | +| `visibilityOfElementLocated(By)` | An element is in the DOM and displayed; returns it | +| `visibilityOf(WebElement)` | A known element is displayed; returns it | +| `visibilityOfAllElementsLocatedBy(By)` | All matching elements are displayed; returns them | +| `visibilityOfAllElements(WebElement...)` | All given elements are displayed; returns them | +| `visibilityOfNestedElementsLocatedBy(By or WebElement, By)` | Child elements under a parent are displayed; returns them | +| `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | +| `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | +| `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | +| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | +| `elementToBeSelected(By or WebElement)` | An element is selected | +| `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | +| `stalenessOf(WebElement)` | An element is no longer attached to the DOM | +| `textToBe(By, text)` | An element's text equals the value | +| `textToBePresentInElement(WebElement, text)` | An element's text contains the value | +| `textToBePresentInElementLocated(By, text)` | A located element's text contains the value | +| `textToBePresentInElementValue(By or WebElement, text)` | An element's `value` contains the value | +| `textMatches(By, Pattern)` | An element's text matches the regular expression | +| `attributeToBe(By or WebElement, attribute, value)` | An element's attribute or CSS property equals the value | +| `attributeContains(By or WebElement, attribute, value)` | An element's attribute or CSS property contains the value | +| `attributeToBeNotEmpty(WebElement, attribute)` | An element's attribute or CSS property is not empty | +| `domAttributeToBe(WebElement, attribute, value)` | An element's DOM attribute equals the value | +| `domPropertyToBe(WebElement, property, value)` | An element's DOM property equals the value | +| `numberOfElementsToBe(By, number)` | The number of matching elements equals the value; returns them | +| `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | +| `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | +| `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | +| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +| `jsReturnsValue(script)` | The JavaScript returns a value; returns it | +| `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | +| `and(conditions...)` | All of the conditions are true | +| `or(conditions...)` | Any of the conditions is true | +| `not(condition)` | The condition is false | +| `refreshed(condition)` | The condition is true, retrying it after a stale element error | +{{% /tab %}} +{{% tab header="Python" %}} +Module `selenium.webdriver.support.expected_conditions` +([API docs](https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html)), +usually imported as `EC`. +Use with `WebDriverWait(driver, timeout).until(...)`. +Locators are tuples, such as `(By.ID, "message")`. + +| Condition | Waits until | +|-----------|-------------| +| `title_is(title)` | The page title equals the value | +| `title_contains(title)` | The page title contains the value | +| `url_to_be(url)` | The current URL equals the value | +| `url_contains(url)` | The current URL contains the value | +| `url_matches(pattern)` | The current URL matches the regular expression | +| `url_changes(url)` | The current URL is different from the value | +| `presence_of_element_located(locator)` | An element is in the DOM (not necessarily visible); returns it | +| `presence_of_all_elements_located(locator)` | At least one element is in the DOM; returns them all | +| `visibility_of_element_located(locator)` | An element is in the DOM and displayed; returns it | +| `visibility_of(element)` | A known element is displayed; returns it | +| `visibility_of_any_elements_located(locator)` | At least one matching element is displayed; returns the displayed ones | +| `visibility_of_all_elements_located(locator)` | All matching elements are displayed; returns them | +| `invisibility_of_element_located(locator or element)` | An element is hidden or not in the DOM | +| `invisibility_of_element(element or locator)` | An element is hidden or not in the DOM | +| `element_to_be_clickable(locator or element)` | An element is displayed and enabled; returns it | +| `element_to_be_selected(element)` | A known element is selected | +| `element_located_to_be_selected(locator)` | A located element is selected | +| `element_selection_state_to_be(element, is_selected)` | A known element's selected state matches the value | +| `element_located_selection_state_to_be(locator, is_selected)` | A located element's selected state matches the value | +| `staleness_of(element)` | An element is no longer attached to the DOM | +| `text_to_be_present_in_element(locator, text)` | An element's text contains the value | +| `text_to_be_present_in_element_value(locator, text)` | An element's `value` contains the value | +| `text_to_be_present_in_element_attribute(locator, attribute, text)` | An element's attribute contains the value | +| `element_attribute_to_include(locator, attribute)` | An element has the attribute | +| `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | +| `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | +| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `alert_is_present()` | An alert is open; returns it | +| `all_of(*conditions)` | All of the conditions are true | +| `any_of(*conditions)` | Any of the conditions is true | +| `none_of(*conditions)` | None of the conditions is true | +{{% /tab %}} +{{% tab header="CSharp" %}} +.NET does not ship built-in conditions. +The `ExpectedConditions` class was removed from the bindings in Selenium 4. +Pass a lambda to `WebDriverWait.Until()` that returns a non-null value or `true` +when the condition is met. +{{% /tab %}} +{{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. +Pass a block to `Selenium::WebDriver::Wait#until` that returns a truthy value +when the condition is met. +{{% /tab %}} +{{% tab header="JavaScript" %}} +Module `until` from `selenium-webdriver` +([API docs](https://www.selenium.dev/selenium/docs/api/javascript/index.html)). +Use with `await driver.wait(until.condition(...), timeout)`. +Conditions that check an element resolve to that element once they are met. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(substr)` | The page title contains the value | +| `titleMatches(regex)` | The page title matches the regular expression | +| `urlIs(url)` | The current URL equals the value | +| `urlContains(substrUrl)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `elementLocated(locator)` | An element is in the DOM; returns it | +| `elementsLocated(locator)` | At least one element is in the DOM; returns them all | +| `elementIsVisible(element)` | An element is displayed | +| `elementIsNotVisible(element)` | An element is not displayed | +| `elementIsEnabled(element)` | An element is enabled | +| `elementIsDisabled(element)` | An element is disabled | +| `elementIsSelected(element)` | An element is selected | +| `elementIsNotSelected(element)` | An element is not selected | +| `elementTextIs(element, text)` | An element's text equals the value | +| `elementTextContains(element, substr)` | An element's text contains the value | +| `elementTextMatches(element, regex)` | An element's text matches the regular expression | +| `stalenessOf(element)` | An element is no longer attached to the DOM | +| `ableToSwitchToFrame(frame)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +{{% /tab %}} +{{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class. See the Java tab. +{{% /tab %}} +{{< /tabpane >}} + ### Customization The Wait class can be instantiated with various parameters that will change how the conditions are evaluated. @@ -143,10 +319,10 @@ make sure that the code returns `true` when it is successful): {{< tabpane text=true >}} {{% tab header="Java" %}} The easiest way to customize Waits in Java is to use the `FluentWait` class: -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L83-L93" >}} {{% /tab %}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L53-L55" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L54-L56" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79" >}} diff --git a/website_and_docs/content/documentation/webdriver/waits.ja.md b/website_and_docs/content/documentation/webdriver/waits.ja.md index 26e4d38cf3a9..e0c743a5aed3 100644 --- a/website_and_docs/content/documentation/webdriver/waits.ja.md +++ b/website_and_docs/content/documentation/webdriver/waits.ja.md @@ -66,10 +66,10 @@ Solving our example with an implicit wait looks like this: {{< tabpane text=true >}} {{< tab header="Java" >}} -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L51" >}} {{< /tab >}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L27" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L28" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39" >}} @@ -99,12 +99,12 @@ Another nice feature is that, by default, the Selenium Wait class automatically {{% tab header="Java" %}} This example shows the condition being waited for as a _lambda_. Java also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L68-L69" >}} {{% /tab %}} {{% tab header="Python" %}} This example shows the condition being waited for as a _lambda_. Python also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L41-L42" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L42-L43" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57" >}} @@ -121,6 +121,182 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte {{< /tab >}} {{< /tabpane >}} +### Built-in conditions + +Instead of writing a lambda for every wait, most bindings ship a library of ready-made +conditions for the things that are most often waited on. +Conditions that take a locator find the element on every poll, +so they also wait for the element to exist. +Many of them return the element (or elements) once the condition is met, +so the result of the wait can be used directly. + +This example locates an element, waits for it to be visible, +and then waits for its text, using only built-in conditions: + +{{< tabpane text=true >}} + {{< tab header="Java" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L106-L110" >}} + {{< /tab >}} + {{< tab header="Python" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L66-L70" >}} + {{< /tab >}} + {{% tab header="CSharp" %}} +.NET does not ship built-in conditions. Pass a lambda to `WebDriverWait.Until()`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. Pass a block to `Selenium::WebDriver::Wait#until`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{< tab header="JavaScript" >}} +{{< gh-codeblock path="/examples/javascript/test/waits/waits.spec.js#L62-L65" >}} + {{< /tab >}} + {{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class listed in the Java tab below. + {{% /tab %}} +{{< /tabpane >}} + +The complete list of built-in conditions for each binding: + +{{< tabpane text=true >}} +{{% tab header="Java" %}} +Class `org.openqa.selenium.support.ui.ExpectedConditions` +([API docs](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html)). +Use with `new WebDriverWait(driver, timeout).until(...)`. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(title)` | The page title contains the value | +| `urlToBe(url)` | The current URL equals the value | +| `urlContains(fraction)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `presenceOfElementLocated(By)` | An element is in the DOM (not necessarily visible); returns it | +| `presenceOfAllElementsLocatedBy(By)` | At least one element is in the DOM; returns them all | +| `presenceOfNestedElementLocatedBy(By or WebElement, By)` | A child element is in the DOM under a parent; returns it | +| `presenceOfNestedElementsLocatedBy(By, By)` | Child elements are in the DOM under a parent; returns them | +| `visibilityOfElementLocated(By)` | An element is in the DOM and displayed; returns it | +| `visibilityOf(WebElement)` | A known element is displayed; returns it | +| `visibilityOfAllElementsLocatedBy(By)` | All matching elements are displayed; returns them | +| `visibilityOfAllElements(WebElement...)` | All given elements are displayed; returns them | +| `visibilityOfNestedElementsLocatedBy(By or WebElement, By)` | Child elements under a parent are displayed; returns them | +| `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | +| `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | +| `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | +| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | +| `elementToBeSelected(By or WebElement)` | An element is selected | +| `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | +| `stalenessOf(WebElement)` | An element is no longer attached to the DOM | +| `textToBe(By, text)` | An element's text equals the value | +| `textToBePresentInElement(WebElement, text)` | An element's text contains the value | +| `textToBePresentInElementLocated(By, text)` | A located element's text contains the value | +| `textToBePresentInElementValue(By or WebElement, text)` | An element's `value` contains the value | +| `textMatches(By, Pattern)` | An element's text matches the regular expression | +| `attributeToBe(By or WebElement, attribute, value)` | An element's attribute or CSS property equals the value | +| `attributeContains(By or WebElement, attribute, value)` | An element's attribute or CSS property contains the value | +| `attributeToBeNotEmpty(WebElement, attribute)` | An element's attribute or CSS property is not empty | +| `domAttributeToBe(WebElement, attribute, value)` | An element's DOM attribute equals the value | +| `domPropertyToBe(WebElement, property, value)` | An element's DOM property equals the value | +| `numberOfElementsToBe(By, number)` | The number of matching elements equals the value; returns them | +| `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | +| `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | +| `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | +| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +| `jsReturnsValue(script)` | The JavaScript returns a value; returns it | +| `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | +| `and(conditions...)` | All of the conditions are true | +| `or(conditions...)` | Any of the conditions is true | +| `not(condition)` | The condition is false | +| `refreshed(condition)` | The condition is true, retrying it after a stale element error | +{{% /tab %}} +{{% tab header="Python" %}} +Module `selenium.webdriver.support.expected_conditions` +([API docs](https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html)), +usually imported as `EC`. +Use with `WebDriverWait(driver, timeout).until(...)`. +Locators are tuples, such as `(By.ID, "message")`. + +| Condition | Waits until | +|-----------|-------------| +| `title_is(title)` | The page title equals the value | +| `title_contains(title)` | The page title contains the value | +| `url_to_be(url)` | The current URL equals the value | +| `url_contains(url)` | The current URL contains the value | +| `url_matches(pattern)` | The current URL matches the regular expression | +| `url_changes(url)` | The current URL is different from the value | +| `presence_of_element_located(locator)` | An element is in the DOM (not necessarily visible); returns it | +| `presence_of_all_elements_located(locator)` | At least one element is in the DOM; returns them all | +| `visibility_of_element_located(locator)` | An element is in the DOM and displayed; returns it | +| `visibility_of(element)` | A known element is displayed; returns it | +| `visibility_of_any_elements_located(locator)` | At least one matching element is displayed; returns the displayed ones | +| `visibility_of_all_elements_located(locator)` | All matching elements are displayed; returns them | +| `invisibility_of_element_located(locator or element)` | An element is hidden or not in the DOM | +| `invisibility_of_element(element or locator)` | An element is hidden or not in the DOM | +| `element_to_be_clickable(locator or element)` | An element is displayed and enabled; returns it | +| `element_to_be_selected(element)` | A known element is selected | +| `element_located_to_be_selected(locator)` | A located element is selected | +| `element_selection_state_to_be(element, is_selected)` | A known element's selected state matches the value | +| `element_located_selection_state_to_be(locator, is_selected)` | A located element's selected state matches the value | +| `staleness_of(element)` | An element is no longer attached to the DOM | +| `text_to_be_present_in_element(locator, text)` | An element's text contains the value | +| `text_to_be_present_in_element_value(locator, text)` | An element's `value` contains the value | +| `text_to_be_present_in_element_attribute(locator, attribute, text)` | An element's attribute contains the value | +| `element_attribute_to_include(locator, attribute)` | An element has the attribute | +| `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | +| `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | +| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `alert_is_present()` | An alert is open; returns it | +| `all_of(*conditions)` | All of the conditions are true | +| `any_of(*conditions)` | Any of the conditions is true | +| `none_of(*conditions)` | None of the conditions is true | +{{% /tab %}} +{{% tab header="CSharp" %}} +.NET does not ship built-in conditions. +The `ExpectedConditions` class was removed from the bindings in Selenium 4. +Pass a lambda to `WebDriverWait.Until()` that returns a non-null value or `true` +when the condition is met. +{{% /tab %}} +{{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. +Pass a block to `Selenium::WebDriver::Wait#until` that returns a truthy value +when the condition is met. +{{% /tab %}} +{{% tab header="JavaScript" %}} +Module `until` from `selenium-webdriver` +([API docs](https://www.selenium.dev/selenium/docs/api/javascript/index.html)). +Use with `await driver.wait(until.condition(...), timeout)`. +Conditions that check an element resolve to that element once they are met. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(substr)` | The page title contains the value | +| `titleMatches(regex)` | The page title matches the regular expression | +| `urlIs(url)` | The current URL equals the value | +| `urlContains(substrUrl)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `elementLocated(locator)` | An element is in the DOM; returns it | +| `elementsLocated(locator)` | At least one element is in the DOM; returns them all | +| `elementIsVisible(element)` | An element is displayed | +| `elementIsNotVisible(element)` | An element is not displayed | +| `elementIsEnabled(element)` | An element is enabled | +| `elementIsDisabled(element)` | An element is disabled | +| `elementIsSelected(element)` | An element is selected | +| `elementIsNotSelected(element)` | An element is not selected | +| `elementTextIs(element, text)` | An element's text equals the value | +| `elementTextContains(element, substr)` | An element's text contains the value | +| `elementTextMatches(element, regex)` | An element's text matches the regular expression | +| `stalenessOf(element)` | An element is no longer attached to the DOM | +| `ableToSwitchToFrame(frame)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +{{% /tab %}} +{{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class. See the Java tab. +{{% /tab %}} +{{< /tabpane >}} + ### Customization The Wait class can be instantiated with various parameters that will change how the conditions are evaluated. @@ -138,10 +314,10 @@ make sure that the code returns `true` when it is successful): {{< tabpane text=true >}} {{% tab header="Java" %}} The easiest way to customize Waits in Java is to use the `FluentWait` class: -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L83-L93" >}} {{% /tab %}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L53-L55" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L54-L56" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79" >}} diff --git a/website_and_docs/content/documentation/webdriver/waits.pt-br.md b/website_and_docs/content/documentation/webdriver/waits.pt-br.md index 0afab4ee5b2e..6e54759c40cd 100644 --- a/website_and_docs/content/documentation/webdriver/waits.pt-br.md +++ b/website_and_docs/content/documentation/webdriver/waits.pt-br.md @@ -66,10 +66,10 @@ Solving our example with an implicit wait looks like this: {{< tabpane text=true >}} {{< tab header="Java" >}} -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L51" >}} {{< /tab >}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L27" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L28" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39" >}} @@ -99,12 +99,12 @@ Another nice feature is that, by default, the Selenium Wait class automatically {{% tab header="Java" %}} This example shows the condition being waited for as a _lambda_. Java also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L68-L69" >}} {{% /tab %}} {{% tab header="Python" %}} This example shows the condition being waited for as a _lambda_. Python also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L41-L42" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L42-L43" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57" >}} @@ -121,6 +121,182 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte {{< /tab >}} {{< /tabpane >}} +### Built-in conditions + +Instead of writing a lambda for every wait, most bindings ship a library of ready-made +conditions for the things that are most often waited on. +Conditions that take a locator find the element on every poll, +so they also wait for the element to exist. +Many of them return the element (or elements) once the condition is met, +so the result of the wait can be used directly. + +This example locates an element, waits for it to be visible, +and then waits for its text, using only built-in conditions: + +{{< tabpane text=true >}} + {{< tab header="Java" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L106-L110" >}} + {{< /tab >}} + {{< tab header="Python" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L66-L70" >}} + {{< /tab >}} + {{% tab header="CSharp" %}} +.NET does not ship built-in conditions. Pass a lambda to `WebDriverWait.Until()`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. Pass a block to `Selenium::WebDriver::Wait#until`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{< tab header="JavaScript" >}} +{{< gh-codeblock path="/examples/javascript/test/waits/waits.spec.js#L62-L65" >}} + {{< /tab >}} + {{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class listed in the Java tab below. + {{% /tab %}} +{{< /tabpane >}} + +The complete list of built-in conditions for each binding: + +{{< tabpane text=true >}} +{{% tab header="Java" %}} +Class `org.openqa.selenium.support.ui.ExpectedConditions` +([API docs](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html)). +Use with `new WebDriverWait(driver, timeout).until(...)`. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(title)` | The page title contains the value | +| `urlToBe(url)` | The current URL equals the value | +| `urlContains(fraction)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `presenceOfElementLocated(By)` | An element is in the DOM (not necessarily visible); returns it | +| `presenceOfAllElementsLocatedBy(By)` | At least one element is in the DOM; returns them all | +| `presenceOfNestedElementLocatedBy(By or WebElement, By)` | A child element is in the DOM under a parent; returns it | +| `presenceOfNestedElementsLocatedBy(By, By)` | Child elements are in the DOM under a parent; returns them | +| `visibilityOfElementLocated(By)` | An element is in the DOM and displayed; returns it | +| `visibilityOf(WebElement)` | A known element is displayed; returns it | +| `visibilityOfAllElementsLocatedBy(By)` | All matching elements are displayed; returns them | +| `visibilityOfAllElements(WebElement...)` | All given elements are displayed; returns them | +| `visibilityOfNestedElementsLocatedBy(By or WebElement, By)` | Child elements under a parent are displayed; returns them | +| `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | +| `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | +| `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | +| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | +| `elementToBeSelected(By or WebElement)` | An element is selected | +| `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | +| `stalenessOf(WebElement)` | An element is no longer attached to the DOM | +| `textToBe(By, text)` | An element's text equals the value | +| `textToBePresentInElement(WebElement, text)` | An element's text contains the value | +| `textToBePresentInElementLocated(By, text)` | A located element's text contains the value | +| `textToBePresentInElementValue(By or WebElement, text)` | An element's `value` contains the value | +| `textMatches(By, Pattern)` | An element's text matches the regular expression | +| `attributeToBe(By or WebElement, attribute, value)` | An element's attribute or CSS property equals the value | +| `attributeContains(By or WebElement, attribute, value)` | An element's attribute or CSS property contains the value | +| `attributeToBeNotEmpty(WebElement, attribute)` | An element's attribute or CSS property is not empty | +| `domAttributeToBe(WebElement, attribute, value)` | An element's DOM attribute equals the value | +| `domPropertyToBe(WebElement, property, value)` | An element's DOM property equals the value | +| `numberOfElementsToBe(By, number)` | The number of matching elements equals the value; returns them | +| `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | +| `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | +| `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | +| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +| `jsReturnsValue(script)` | The JavaScript returns a value; returns it | +| `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | +| `and(conditions...)` | All of the conditions are true | +| `or(conditions...)` | Any of the conditions is true | +| `not(condition)` | The condition is false | +| `refreshed(condition)` | The condition is true, retrying it after a stale element error | +{{% /tab %}} +{{% tab header="Python" %}} +Module `selenium.webdriver.support.expected_conditions` +([API docs](https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html)), +usually imported as `EC`. +Use with `WebDriverWait(driver, timeout).until(...)`. +Locators are tuples, such as `(By.ID, "message")`. + +| Condition | Waits until | +|-----------|-------------| +| `title_is(title)` | The page title equals the value | +| `title_contains(title)` | The page title contains the value | +| `url_to_be(url)` | The current URL equals the value | +| `url_contains(url)` | The current URL contains the value | +| `url_matches(pattern)` | The current URL matches the regular expression | +| `url_changes(url)` | The current URL is different from the value | +| `presence_of_element_located(locator)` | An element is in the DOM (not necessarily visible); returns it | +| `presence_of_all_elements_located(locator)` | At least one element is in the DOM; returns them all | +| `visibility_of_element_located(locator)` | An element is in the DOM and displayed; returns it | +| `visibility_of(element)` | A known element is displayed; returns it | +| `visibility_of_any_elements_located(locator)` | At least one matching element is displayed; returns the displayed ones | +| `visibility_of_all_elements_located(locator)` | All matching elements are displayed; returns them | +| `invisibility_of_element_located(locator or element)` | An element is hidden or not in the DOM | +| `invisibility_of_element(element or locator)` | An element is hidden or not in the DOM | +| `element_to_be_clickable(locator or element)` | An element is displayed and enabled; returns it | +| `element_to_be_selected(element)` | A known element is selected | +| `element_located_to_be_selected(locator)` | A located element is selected | +| `element_selection_state_to_be(element, is_selected)` | A known element's selected state matches the value | +| `element_located_selection_state_to_be(locator, is_selected)` | A located element's selected state matches the value | +| `staleness_of(element)` | An element is no longer attached to the DOM | +| `text_to_be_present_in_element(locator, text)` | An element's text contains the value | +| `text_to_be_present_in_element_value(locator, text)` | An element's `value` contains the value | +| `text_to_be_present_in_element_attribute(locator, attribute, text)` | An element's attribute contains the value | +| `element_attribute_to_include(locator, attribute)` | An element has the attribute | +| `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | +| `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | +| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `alert_is_present()` | An alert is open; returns it | +| `all_of(*conditions)` | All of the conditions are true | +| `any_of(*conditions)` | Any of the conditions is true | +| `none_of(*conditions)` | None of the conditions is true | +{{% /tab %}} +{{% tab header="CSharp" %}} +.NET does not ship built-in conditions. +The `ExpectedConditions` class was removed from the bindings in Selenium 4. +Pass a lambda to `WebDriverWait.Until()` that returns a non-null value or `true` +when the condition is met. +{{% /tab %}} +{{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. +Pass a block to `Selenium::WebDriver::Wait#until` that returns a truthy value +when the condition is met. +{{% /tab %}} +{{% tab header="JavaScript" %}} +Module `until` from `selenium-webdriver` +([API docs](https://www.selenium.dev/selenium/docs/api/javascript/index.html)). +Use with `await driver.wait(until.condition(...), timeout)`. +Conditions that check an element resolve to that element once they are met. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(substr)` | The page title contains the value | +| `titleMatches(regex)` | The page title matches the regular expression | +| `urlIs(url)` | The current URL equals the value | +| `urlContains(substrUrl)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `elementLocated(locator)` | An element is in the DOM; returns it | +| `elementsLocated(locator)` | At least one element is in the DOM; returns them all | +| `elementIsVisible(element)` | An element is displayed | +| `elementIsNotVisible(element)` | An element is not displayed | +| `elementIsEnabled(element)` | An element is enabled | +| `elementIsDisabled(element)` | An element is disabled | +| `elementIsSelected(element)` | An element is selected | +| `elementIsNotSelected(element)` | An element is not selected | +| `elementTextIs(element, text)` | An element's text equals the value | +| `elementTextContains(element, substr)` | An element's text contains the value | +| `elementTextMatches(element, regex)` | An element's text matches the regular expression | +| `stalenessOf(element)` | An element is no longer attached to the DOM | +| `ableToSwitchToFrame(frame)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +{{% /tab %}} +{{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class. See the Java tab. +{{% /tab %}} +{{< /tabpane >}} + ### Customization The Wait class can be instantiated with various parameters that will change how the conditions are evaluated. @@ -138,10 +314,10 @@ make sure that the code returns `true` when it is successful): {{< tabpane text=true >}} {{% tab header="Java" %}} The easiest way to customize Waits in Java is to use the `FluentWait` class: -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L83-L93" >}} {{% /tab %}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L53-L55" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L54-L56" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79" >}} diff --git a/website_and_docs/content/documentation/webdriver/waits.zh-cn.md b/website_and_docs/content/documentation/webdriver/waits.zh-cn.md index 7eecda95402d..52cb1e415e92 100644 --- a/website_and_docs/content/documentation/webdriver/waits.zh-cn.md +++ b/website_and_docs/content/documentation/webdriver/waits.zh-cn.md @@ -76,10 +76,10 @@ Selenium 内置了一种自动等待元素出现的方式, 称为 _隐式等待_ {{< tabpane text=true >}} {{< tab header="Java" >}} -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L51" >}} {{< /tab >}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L27" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L28" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39" >}} @@ -114,12 +114,12 @@ Selenium 等待类会自动等待指定的元素存在. {{% tab header="Java" %}} This example shows the condition being waited for as a _lambda_. Java also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L68-L69" >}} {{% /tab %}} {{% tab header="Python" %}} This example shows the condition being waited for as a _lambda_. Python also supports [Expected Conditions]({{< ref "support_features/expected_conditions" >}}) -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L41-L42" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L42-L43" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57" >}} @@ -138,6 +138,182 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte +### Built-in conditions + +Instead of writing a lambda for every wait, most bindings ship a library of ready-made +conditions for the things that are most often waited on. +Conditions that take a locator find the element on every poll, +so they also wait for the element to exist. +Many of them return the element (or elements) once the condition is met, +so the result of the wait can be used directly. + +This example locates an element, waits for it to be visible, +and then waits for its text, using only built-in conditions: + +{{< tabpane text=true >}} + {{< tab header="Java" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L106-L110" >}} + {{< /tab >}} + {{< tab header="Python" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L66-L70" >}} + {{< /tab >}} + {{% tab header="CSharp" %}} +.NET does not ship built-in conditions. Pass a lambda to `WebDriverWait.Until()`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. Pass a block to `Selenium::WebDriver::Wait#until`, as in the +[explicit wait](#explicit-waits) example. + {{% /tab %}} + {{< tab header="JavaScript" >}} +{{< gh-codeblock path="/examples/javascript/test/waits/waits.spec.js#L62-L65" >}} + {{< /tab >}} + {{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class listed in the Java tab below. + {{% /tab %}} +{{< /tabpane >}} + +The complete list of built-in conditions for each binding: + +{{< tabpane text=true >}} +{{% tab header="Java" %}} +Class `org.openqa.selenium.support.ui.ExpectedConditions` +([API docs](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html)). +Use with `new WebDriverWait(driver, timeout).until(...)`. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(title)` | The page title contains the value | +| `urlToBe(url)` | The current URL equals the value | +| `urlContains(fraction)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `presenceOfElementLocated(By)` | An element is in the DOM (not necessarily visible); returns it | +| `presenceOfAllElementsLocatedBy(By)` | At least one element is in the DOM; returns them all | +| `presenceOfNestedElementLocatedBy(By or WebElement, By)` | A child element is in the DOM under a parent; returns it | +| `presenceOfNestedElementsLocatedBy(By, By)` | Child elements are in the DOM under a parent; returns them | +| `visibilityOfElementLocated(By)` | An element is in the DOM and displayed; returns it | +| `visibilityOf(WebElement)` | A known element is displayed; returns it | +| `visibilityOfAllElementsLocatedBy(By)` | All matching elements are displayed; returns them | +| `visibilityOfAllElements(WebElement...)` | All given elements are displayed; returns them | +| `visibilityOfNestedElementsLocatedBy(By or WebElement, By)` | Child elements under a parent are displayed; returns them | +| `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | +| `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | +| `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | +| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | +| `elementToBeSelected(By or WebElement)` | An element is selected | +| `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | +| `stalenessOf(WebElement)` | An element is no longer attached to the DOM | +| `textToBe(By, text)` | An element's text equals the value | +| `textToBePresentInElement(WebElement, text)` | An element's text contains the value | +| `textToBePresentInElementLocated(By, text)` | A located element's text contains the value | +| `textToBePresentInElementValue(By or WebElement, text)` | An element's `value` contains the value | +| `textMatches(By, Pattern)` | An element's text matches the regular expression | +| `attributeToBe(By or WebElement, attribute, value)` | An element's attribute or CSS property equals the value | +| `attributeContains(By or WebElement, attribute, value)` | An element's attribute or CSS property contains the value | +| `attributeToBeNotEmpty(WebElement, attribute)` | An element's attribute or CSS property is not empty | +| `domAttributeToBe(WebElement, attribute, value)` | An element's DOM attribute equals the value | +| `domPropertyToBe(WebElement, property, value)` | An element's DOM property equals the value | +| `numberOfElementsToBe(By, number)` | The number of matching elements equals the value; returns them | +| `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | +| `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | +| `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | +| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +| `jsReturnsValue(script)` | The JavaScript returns a value; returns it | +| `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | +| `and(conditions...)` | All of the conditions are true | +| `or(conditions...)` | Any of the conditions is true | +| `not(condition)` | The condition is false | +| `refreshed(condition)` | The condition is true, retrying it after a stale element error | +{{% /tab %}} +{{% tab header="Python" %}} +Module `selenium.webdriver.support.expected_conditions` +([API docs](https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html)), +usually imported as `EC`. +Use with `WebDriverWait(driver, timeout).until(...)`. +Locators are tuples, such as `(By.ID, "message")`. + +| Condition | Waits until | +|-----------|-------------| +| `title_is(title)` | The page title equals the value | +| `title_contains(title)` | The page title contains the value | +| `url_to_be(url)` | The current URL equals the value | +| `url_contains(url)` | The current URL contains the value | +| `url_matches(pattern)` | The current URL matches the regular expression | +| `url_changes(url)` | The current URL is different from the value | +| `presence_of_element_located(locator)` | An element is in the DOM (not necessarily visible); returns it | +| `presence_of_all_elements_located(locator)` | At least one element is in the DOM; returns them all | +| `visibility_of_element_located(locator)` | An element is in the DOM and displayed; returns it | +| `visibility_of(element)` | A known element is displayed; returns it | +| `visibility_of_any_elements_located(locator)` | At least one matching element is displayed; returns the displayed ones | +| `visibility_of_all_elements_located(locator)` | All matching elements are displayed; returns them | +| `invisibility_of_element_located(locator or element)` | An element is hidden or not in the DOM | +| `invisibility_of_element(element or locator)` | An element is hidden or not in the DOM | +| `element_to_be_clickable(locator or element)` | An element is displayed and enabled; returns it | +| `element_to_be_selected(element)` | A known element is selected | +| `element_located_to_be_selected(locator)` | A located element is selected | +| `element_selection_state_to_be(element, is_selected)` | A known element's selected state matches the value | +| `element_located_selection_state_to_be(locator, is_selected)` | A located element's selected state matches the value | +| `staleness_of(element)` | An element is no longer attached to the DOM | +| `text_to_be_present_in_element(locator, text)` | An element's text contains the value | +| `text_to_be_present_in_element_value(locator, text)` | An element's `value` contains the value | +| `text_to_be_present_in_element_attribute(locator, attribute, text)` | An element's attribute contains the value | +| `element_attribute_to_include(locator, attribute)` | An element has the attribute | +| `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | +| `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | +| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `alert_is_present()` | An alert is open; returns it | +| `all_of(*conditions)` | All of the conditions are true | +| `any_of(*conditions)` | Any of the conditions is true | +| `none_of(*conditions)` | None of the conditions is true | +{{% /tab %}} +{{% tab header="CSharp" %}} +.NET does not ship built-in conditions. +The `ExpectedConditions` class was removed from the bindings in Selenium 4. +Pass a lambda to `WebDriverWait.Until()` that returns a non-null value or `true` +when the condition is met. +{{% /tab %}} +{{% tab header="Ruby" %}} +Ruby does not ship built-in conditions. +Pass a block to `Selenium::WebDriver::Wait#until` that returns a truthy value +when the condition is met. +{{% /tab %}} +{{% tab header="JavaScript" %}} +Module `until` from `selenium-webdriver` +([API docs](https://www.selenium.dev/selenium/docs/api/javascript/index.html)). +Use with `await driver.wait(until.condition(...), timeout)`. +Conditions that check an element resolve to that element once they are met. + +| Condition | Waits until | +|-----------|-------------| +| `titleIs(title)` | The page title equals the value | +| `titleContains(substr)` | The page title contains the value | +| `titleMatches(regex)` | The page title matches the regular expression | +| `urlIs(url)` | The current URL equals the value | +| `urlContains(substrUrl)` | The current URL contains the value | +| `urlMatches(regex)` | The current URL matches the regular expression | +| `elementLocated(locator)` | An element is in the DOM; returns it | +| `elementsLocated(locator)` | At least one element is in the DOM; returns them all | +| `elementIsVisible(element)` | An element is displayed | +| `elementIsNotVisible(element)` | An element is not displayed | +| `elementIsEnabled(element)` | An element is enabled | +| `elementIsDisabled(element)` | An element is disabled | +| `elementIsSelected(element)` | An element is selected | +| `elementIsNotSelected(element)` | An element is not selected | +| `elementTextIs(element, text)` | An element's text equals the value | +| `elementTextContains(element, substr)` | An element's text contains the value | +| `elementTextMatches(element, regex)` | An element's text matches the regular expression | +| `stalenessOf(element)` | An element is no longer attached to the DOM | +| `ableToSwitchToFrame(frame)` | A frame is available, then switches to it | +| `alertIsPresent()` | An alert is open; returns it | +{{% /tab %}} +{{% tab header="Kotlin" %}} +Kotlin uses the Java `ExpectedConditions` class. See the Java tab. +{{% /tab %}} +{{< /tabpane >}} + ### 定制 Wait 类可以通过各种参数进行实例化, @@ -158,10 +334,10 @@ Wait 类可以通过各种参数进行实例化, {{< tabpane text=true >}} {{% tab header="Java" %}} The easiest way to customize Waits in Java is to use the `FluentWait` class: -{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92" >}} +{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L83-L93" >}} {{% /tab %}} {{< tab header="Python" >}} -{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L53-L55" >}} +{{< gh-codeblock path="/examples/python/tests/waits/test_waits.py#L54-L56" >}} {{< /tab >}} {{< tab header="CSharp" >}} {{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79" >}} From ffdc3c34f2f82de298e3eef2f59368c0630fccbf Mon Sep 17 00:00:00 2001 From: David Burns Date: Thu, 5 Nov 2026 11:08:09 +0000 Subject: [PATCH 2/3] Fix condition descriptions and zh-cn anchor invisibilityOfElementWithText also succeeds when a displayed element's text changes, so describe it as "no displayed element has the text". Describe the frame conditions as taking one frame argument in several forms, instead of listing the forms like separate parameters. The zh-cn page heading for explicit waits is translated, so link the .NET and Ruby tabs to its real anchor. Claude-Session: https://claude.ai/code/session_01LA4X4y2cMRjKqDaAwexzDp --- .../content/documentation/webdriver/waits.en.md | 6 +++--- .../content/documentation/webdriver/waits.ja.md | 6 +++--- .../content/documentation/webdriver/waits.pt-br.md | 6 +++--- .../content/documentation/webdriver/waits.zh-cn.md | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/website_and_docs/content/documentation/webdriver/waits.en.md b/website_and_docs/content/documentation/webdriver/waits.en.md index 27df1e362223..888c37098bdc 100644 --- a/website_and_docs/content/documentation/webdriver/waits.en.md +++ b/website_and_docs/content/documentation/webdriver/waits.en.md @@ -188,7 +188,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | | `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | | `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | -| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `invisibilityOfElementWithText(By, text)` | No displayed element matching the locator has the given text | | `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | | `elementToBeSelected(By or WebElement)` | An element is selected | | `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | @@ -207,7 +207,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | | `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | | `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | -| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `frameToBeAvailableAndSwitchToIt(frame)` | A frame, given as a `By`, name or ID, index, or `WebElement`, is available; then switches to it | | `alertIsPresent()` | An alert is open; returns it | | `jsReturnsValue(script)` | The JavaScript returns a value; returns it | | `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | @@ -251,7 +251,7 @@ Locators are tuples, such as `(By.ID, "message")`. | `element_attribute_to_include(locator, attribute)` | An element has the attribute | | `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | | `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | -| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `frame_to_be_available_and_switch_to_it(frame)` | A frame, given as a locator, name or ID, or element, is available; then switches to it | | `alert_is_present()` | An alert is open; returns it | | `all_of(*conditions)` | All of the conditions are true | | `any_of(*conditions)` | Any of the conditions is true | diff --git a/website_and_docs/content/documentation/webdriver/waits.ja.md b/website_and_docs/content/documentation/webdriver/waits.ja.md index e0c743a5aed3..868e778a9627 100644 --- a/website_and_docs/content/documentation/webdriver/waits.ja.md +++ b/website_and_docs/content/documentation/webdriver/waits.ja.md @@ -183,7 +183,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | | `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | | `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | -| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `invisibilityOfElementWithText(By, text)` | No displayed element matching the locator has the given text | | `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | | `elementToBeSelected(By or WebElement)` | An element is selected | | `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | @@ -202,7 +202,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | | `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | | `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | -| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `frameToBeAvailableAndSwitchToIt(frame)` | A frame, given as a `By`, name or ID, index, or `WebElement`, is available; then switches to it | | `alertIsPresent()` | An alert is open; returns it | | `jsReturnsValue(script)` | The JavaScript returns a value; returns it | | `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | @@ -246,7 +246,7 @@ Locators are tuples, such as `(By.ID, "message")`. | `element_attribute_to_include(locator, attribute)` | An element has the attribute | | `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | | `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | -| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `frame_to_be_available_and_switch_to_it(frame)` | A frame, given as a locator, name or ID, or element, is available; then switches to it | | `alert_is_present()` | An alert is open; returns it | | `all_of(*conditions)` | All of the conditions are true | | `any_of(*conditions)` | Any of the conditions is true | diff --git a/website_and_docs/content/documentation/webdriver/waits.pt-br.md b/website_and_docs/content/documentation/webdriver/waits.pt-br.md index 6e54759c40cd..5f9569bfa93c 100644 --- a/website_and_docs/content/documentation/webdriver/waits.pt-br.md +++ b/website_and_docs/content/documentation/webdriver/waits.pt-br.md @@ -183,7 +183,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | | `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | | `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | -| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `invisibilityOfElementWithText(By, text)` | No displayed element matching the locator has the given text | | `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | | `elementToBeSelected(By or WebElement)` | An element is selected | | `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | @@ -202,7 +202,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | | `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | | `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | -| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `frameToBeAvailableAndSwitchToIt(frame)` | A frame, given as a `By`, name or ID, index, or `WebElement`, is available; then switches to it | | `alertIsPresent()` | An alert is open; returns it | | `jsReturnsValue(script)` | The JavaScript returns a value; returns it | | `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | @@ -246,7 +246,7 @@ Locators are tuples, such as `(By.ID, "message")`. | `element_attribute_to_include(locator, attribute)` | An element has the attribute | | `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | | `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | -| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `frame_to_be_available_and_switch_to_it(frame)` | A frame, given as a locator, name or ID, or element, is available; then switches to it | | `alert_is_present()` | An alert is open; returns it | | `all_of(*conditions)` | All of the conditions are true | | `any_of(*conditions)` | Any of the conditions is true | diff --git a/website_and_docs/content/documentation/webdriver/waits.zh-cn.md b/website_and_docs/content/documentation/webdriver/waits.zh-cn.md index 52cb1e415e92..7e7455a75a24 100644 --- a/website_and_docs/content/documentation/webdriver/waits.zh-cn.md +++ b/website_and_docs/content/documentation/webdriver/waits.zh-cn.md @@ -159,11 +159,11 @@ and then waits for its text, using only built-in conditions: {{< /tab >}} {{% tab header="CSharp" %}} .NET does not ship built-in conditions. Pass a lambda to `WebDriverWait.Until()`, as in the -[explicit wait](#explicit-waits) example. +[explicit wait](#显式等待) example. {{% /tab %}} {{% tab header="Ruby" %}} Ruby does not ship built-in conditions. Pass a block to `Selenium::WebDriver::Wait#until`, as in the -[explicit wait](#explicit-waits) example. +[explicit wait](#显式等待) example. {{% /tab %}} {{< tab header="JavaScript" >}} {{< gh-codeblock path="/examples/javascript/test/waits/waits.spec.js#L62-L65" >}} @@ -200,7 +200,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `invisibilityOfElementLocated(By)` | An element is hidden or not in the DOM | | `invisibilityOf(WebElement)` | A known element is hidden or no longer in the DOM | | `invisibilityOfAllElements(WebElement...)` | All given elements are hidden | -| `invisibilityOfElementWithText(By, text)` | An element with the given text is hidden or not in the DOM | +| `invisibilityOfElementWithText(By, text)` | No displayed element matching the locator has the given text | | `elementToBeClickable(By or WebElement)` | An element is displayed and enabled; returns it | | `elementToBeSelected(By or WebElement)` | An element is selected | | `elementSelectionStateToBe(By or WebElement, selected)` | An element's selected state matches the value | @@ -219,7 +219,7 @@ Use with `new WebDriverWait(driver, timeout).until(...)`. | `numberOfElementsToBeMoreThan(By, number)` | The number of matching elements is more than the value; returns them | | `numberOfElementsToBeLessThan(By, number)` | The number of matching elements is less than the value; returns them | | `numberOfWindowsToBe(number)` | The number of open windows or tabs equals the value | -| `frameToBeAvailableAndSwitchToIt(By, String, int or WebElement)` | A frame is available, then switches to it | +| `frameToBeAvailableAndSwitchToIt(frame)` | A frame, given as a `By`, name or ID, index, or `WebElement`, is available; then switches to it | | `alertIsPresent()` | An alert is open; returns it | | `jsReturnsValue(script)` | The JavaScript returns a value; returns it | | `javaScriptThrowsNoExceptions(script)` | The JavaScript runs without throwing | @@ -263,7 +263,7 @@ Locators are tuples, such as `(By.ID, "message")`. | `element_attribute_to_include(locator, attribute)` | An element has the attribute | | `number_of_windows_to_be(num_windows)` | The number of open windows or tabs equals the value | | `new_window_is_opened(current_handles)` | A window or tab has opened since the handles were read | -| `frame_to_be_available_and_switch_to_it(locator, name or element)` | A frame is available, then switches to it | +| `frame_to_be_available_and_switch_to_it(frame)` | A frame, given as a locator, name or ID, or element, is available; then switches to it | | `alert_is_present()` | An alert is open; returns it | | `all_of(*conditions)` | All of the conditions are true | | `any_of(*conditions)` | Any of the conditions is true | From a0ef3152d292ed357a0f570a51858313ccccbe26 Mon Sep 17 00:00:00 2001 From: David Burns Date: Thu, 5 Nov 2026 13:04:20 +0000 Subject: [PATCH 3/3] Rephrase built-in conditions intro Use the wording suggested in review for the opening paragraph of the Built-in conditions section on all language pages. Claude-Session: https://claude.ai/code/session_01LA4X4y2cMRjKqDaAwexzDp --- .../content/documentation/webdriver/waits.en.md | 13 +++++++------ .../content/documentation/webdriver/waits.ja.md | 13 +++++++------ .../content/documentation/webdriver/waits.pt-br.md | 13 +++++++------ .../content/documentation/webdriver/waits.zh-cn.md | 13 +++++++------ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/website_and_docs/content/documentation/webdriver/waits.en.md b/website_and_docs/content/documentation/webdriver/waits.en.md index 888c37098bdc..7dccfa21ad0a 100644 --- a/website_and_docs/content/documentation/webdriver/waits.en.md +++ b/website_and_docs/content/documentation/webdriver/waits.en.md @@ -128,12 +128,13 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte ### Built-in conditions -Instead of writing a lambda for every wait, most bindings ship a library of ready-made -conditions for the things that are most often waited on. -Conditions that take a locator find the element on every poll, -so they also wait for the element to exist. -Many of them return the element (or elements) once the condition is met, -so the result of the wait can be used directly. +Most bindings include a set of ready-made conditions +for the situations that come up most often in waits. +You don't have to write a custom lambda for each one. +Conditions that take a locator search for the element on every poll, +so they also wait for it to appear. +Many of them hand back the element (or elements) once the condition is met, +letting you use the result of the wait directly. This example locates an element, waits for it to be visible, and then waits for its text, using only built-in conditions: diff --git a/website_and_docs/content/documentation/webdriver/waits.ja.md b/website_and_docs/content/documentation/webdriver/waits.ja.md index 868e778a9627..2b86f8a72762 100644 --- a/website_and_docs/content/documentation/webdriver/waits.ja.md +++ b/website_and_docs/content/documentation/webdriver/waits.ja.md @@ -123,12 +123,13 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte ### Built-in conditions -Instead of writing a lambda for every wait, most bindings ship a library of ready-made -conditions for the things that are most often waited on. -Conditions that take a locator find the element on every poll, -so they also wait for the element to exist. -Many of them return the element (or elements) once the condition is met, -so the result of the wait can be used directly. +Most bindings include a set of ready-made conditions +for the situations that come up most often in waits. +You don't have to write a custom lambda for each one. +Conditions that take a locator search for the element on every poll, +so they also wait for it to appear. +Many of them hand back the element (or elements) once the condition is met, +letting you use the result of the wait directly. This example locates an element, waits for it to be visible, and then waits for its text, using only built-in conditions: diff --git a/website_and_docs/content/documentation/webdriver/waits.pt-br.md b/website_and_docs/content/documentation/webdriver/waits.pt-br.md index 5f9569bfa93c..a1256775e5d7 100644 --- a/website_and_docs/content/documentation/webdriver/waits.pt-br.md +++ b/website_and_docs/content/documentation/webdriver/waits.pt-br.md @@ -123,12 +123,13 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte ### Built-in conditions -Instead of writing a lambda for every wait, most bindings ship a library of ready-made -conditions for the things that are most often waited on. -Conditions that take a locator find the element on every poll, -so they also wait for the element to exist. -Many of them return the element (or elements) once the condition is met, -so the result of the wait can be used directly. +Most bindings include a set of ready-made conditions +for the situations that come up most often in waits. +You don't have to write a custom lambda for each one. +Conditions that take a locator search for the element on every poll, +so they also wait for it to appear. +Many of them hand back the element (or elements) once the condition is met, +letting you use the result of the wait directly. This example locates an element, waits for it to be visible, and then waits for its text, using only built-in conditions: diff --git a/website_and_docs/content/documentation/webdriver/waits.zh-cn.md b/website_and_docs/content/documentation/webdriver/waits.zh-cn.md index 7e7455a75a24..be0ab300dae9 100644 --- a/website_and_docs/content/documentation/webdriver/waits.zh-cn.md +++ b/website_and_docs/content/documentation/webdriver/waits.zh-cn.md @@ -140,12 +140,13 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte ### Built-in conditions -Instead of writing a lambda for every wait, most bindings ship a library of ready-made -conditions for the things that are most often waited on. -Conditions that take a locator find the element on every poll, -so they also wait for the element to exist. -Many of them return the element (or elements) once the condition is met, -so the result of the wait can be used directly. +Most bindings include a set of ready-made conditions +for the situations that come up most often in waits. +You don't have to write a custom lambda for each one. +Conditions that take a locator search for the element on every poll, +so they also wait for it to appear. +Many of them hand back the element (or elements) once the condition is met, +letting you use the result of the wait directly. This example locates an element, waits for it to be visible, and then waits for its text, using only built-in conditions: