Frank
Frank

Reputation: 871

What is the best wait strategy in Selenium for interacting with a WebElement

I just started with implementing some UItests for a new WebApplication and noticed that sometimes tests are failing when I wait for an Element to Exist while the same test succeeds when waiting for the Element to be Visible.

So my question is, is there a fixed order in which a webelement becomes "existing", "clickable", "visible","displayed" etc. or does this fully depends on how the developer has implemented the webpage or maybe the JS Framework which is used implementing the application?

Upvotes: 0

Views: 651

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193058

Precisely, Selenium can deal with 3 distinct states of a WebElement with in the HTML DOM:

  • Element is Exists i.e. Present.
  • Element is Visible.
  • Element is Interactive / Clickable.

Honestly, you don't have to keep track of the order in which a webelement becomes existing, clickable, visible, displayed etc.

  • If your usecase is to validate the existence of any element you need to induce WebDriverWait setting the ExpectedConditions as ElementExists() which is the expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible. So the effective line of code will be:

    IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementExists(By.CssSelector("element_cssSelector")));
    
  • If your usecase is to extract any attribute of any element you need to induce WebDriverWait setting the ExpectedConditions as ElementIsVisible(locator) which is an expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0. So in your usecase effectively the line of code will be:

    IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementIsVisible(By.ClassName("element_classname")));
    
  • If your usecase is to invoke click() on any element you need to induce WebDriverWait setting the ExpectedConditions as ElementToBeClickable() which is an expectation for for checking an element is visible and enabled such that you can click it. So in your usecase effectively the line of code will be:

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("element_xpath"))).Click();
    

Upvotes: 0

Jonah
Jonah

Reputation: 674

It all depends on how the page was written. Web element does not evolve from one status to another. It may change, but as a result of some dynamic content, actions performed on the page etc.

What those statuses tell us:

  1. Existing - is when the element is in the page DOM. It does not necessarily has to be visible or interactable. It is the basic status, as element cannot have other statuses, without existing. Using the driver.FindElement(By.Xpath(".//*")) will find all elements on the page.
  2. Displayed - when element exists it may be visible. Use IWebElement.Displayed (C# syntax) to check if the element is displayed.
  3. Clickable - sometimes when you try to click the element, the exception may be thrown, saying that something else would get the click. To deal with those issues, see this answer.

How do you check if the element exists? If you are just searching for element, it will throw exception, when element is not found. I suggest using WebDriverWait, to look for element, for certain time period, to deal with loading:

Wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSecond));
Wait.Until(d => d.FindElement(by));

Upvotes: 0

Related Questions