Selenium - Wait Until Element Is Present, Visible and Interactable

Selenium wait until element by ID is present or visible

You can use this.

Java:

WebDriverWait w1 = new WebDriverWait(driver, 5);
w1.until(ExpectedConditions.visibilityOfElementLocated(By.id("submit_btn")));

Python:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()

See more on: https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html

Selenium Expected Conditions, Wait until element is interactable?

element_to_be_clickable()

element_to_be_clickable() is the expectation for for checking if an element is visible and enabled so that you can click() it.



ElementNotInteractableException

Unfortunately there is no specific expected_conditions as ElementNotInteractableException and it can occur for a lot of reasons and some of them are:

  • Lower Timeout interval. In these cases you have to increase the timeout as follows:

    wait = WebDriverWait(driver, 20)
  • Selecting and invoking click() the outer/parent element rather then the child element.

  • A typical scenario is targetting the <input> where there is a related <label> element.

Python Selenium: Wait until element is clickable - Element is found using find_elements

You need to take care of a couple of things here as follows:

  • As the searchBar element is a clickable element ideally you need you need to induce WebDriverWait for the element_to_be_clickable() as follows:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "react-select-3-input"))).send_keys(address)
  • Again as the searchButton element is a clickable element you need you need to induce WebDriverWait for the element_to_be_clickable() as follows (in the worst case scenario assuming the searchButton gets enabled when search text is populated):

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "sc-1mx0n6y-0"))).click()
  • Ideal dropdowns are html-select tags and ideally you should be using the Select class inducing WebDriverWait as follows:

    Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "cssSelector_select_element")))).select_by_visible_text("visible_text")
  • Finally, the ID and CLASS_NAME values which you have used e.g. react-select-3-input, sc-1mx0n6y-0, css-19bqh2r, etc looks dynamic and may change when you would access the application afresh or in short intervals. So you may opt to lookout for some other static attributes.

  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC

Python + Selenium: Wait until element is fully loaded

First of all I strongly believe you were pretty close. You simply need to format your code in a Pythonic which may solve your issue straight away as follows :

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="accountStandalone"]/div/div/div[2]/div/div/div[1]/button'))).click()

You have pulled a rug over the actual issue by mentioning it doesn't wait until it found but goes instant and does other stuff which it shouldn't rather than mentioning what your program is supposed to do (e.g. your code trials) and what wrong your program is doing (i.e. error stack trace).

As per the HTMLs you have shared you can induce a waiter for either of the WebElements as follows :

  • Waiter for the visibility of the text NU ÄR DU MEDLEM, Hello. :

    • CSS_SELECTOR :

      WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.confirmation-title.nsg-font-family--platform.nsg-text--black.edf-title-font-size--xlarge.js-confirmationTitle")))
    • XPATH :

      WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='confirmation-title nsg-font-family--platform nsg-text--black edf-title-font-size--xlarge js-confirmationTitle' and contains(.,'NU ÄR DU MEDLEM, Hello.')]")))
  • Waiter for the button with text FORTSÄTT :

    • CSS_SELECTOR :

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.nsg-button.nsg-bg--black.register-next-step-cta.js-nextStepCta")))
    • XPATH :

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='nsg-button nsg-bg--black register-next-step-cta js-nextStepCta' and contains(.,'FORTSÄTT')]")))

Selenium, use Wait Until Element Is Visible with xpath Text() instead of Element Text Should Be

Yes, they are functionally the same - in the sense they will only pass if the text is the one you expect.

Still there are differences between them - obviously, the "Wait Until" will give some time for the string to appear (rendering, or js changing it) vs the immediate check of the other.

And another difference is the Element Text Should Be returns the visible text of the element - e.g. "close to what a user sees in their browser" , while the xpath with text()="FirstName" looks for a node with precisely this content - any whitespace around it or child nodes having portions of the string (not done in your example) will cause it to fail.

There is another difference - if the element is hidden, the selenium method used in Element Text Should Be will return an empty string (it's just how SE works), while the xpath will match it (as it doesn't "care" about visibility, it just parses xml). But that is not an issue with your example, the "Wait Until Element Is Visible" implies the check is on visualized elements.



Related Topics



Leave a reply



Submit