Using webdriver to check if an element WITHOUT throwing an exception exists?

I'm new to Selenium webdriver, maybe this question is obvious. I am after such a situation:

If the item exists, click it and return to the index page:

driver.findElement(By.id("...."])).click(); 

if it doesn’t work out, skip it and return to the index page. The test is still ongoing without any exceptions.

I know one solution:

 driver.findElements( By.id("...") ).size() != 0 

so i tried:

 if(driver.findElements(By.id("....")).size() > 0) { driver.findElement(By.id("....")).click(); driver.findElement(By.cssSelector("...")).click(); } else { driver.findElement(By.cssSelector("....")).click(); } 

This turned out to be really ugly, because if I have 10 elements to check, this IF condition needs to be written 10 times.

Any workaround to make it neat?

+6
source share
3 answers

There may be many solutions, but it may interfere with your architecture.

The easiest solution may be as follows:

Just create a method like optionalClick() in some utility class or somewhere with arguments like:

  • locator_keyword : {values: id or cssSelector or xpath, etc.}
  • locator : {values: "q"}

The steps in the method:

  • Get item based on locator_keyword and locator
  • Check if there is an item and click it
  • Otherwise do nothing

This method can be used as a general type of objects for any type of objects.

+1
source

There are ways to find elements without exception by using try-catch conditions inside loops. For example, this method that I wrote (which may be simplified depending on what you use if for) will return a WebElement and it will make sure that it will be clickable before returning it to you:

 public static WebElement getElementByLocator( By locator ) { driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS ); WebElement we = null; boolean unfound = true; int tries = 0; while ( unfound && tries < 10 ) { tries += 1; try { we = driver.findElement( locator ); unfound = false; // FOUND IT } catch ( StaleElementReferenceException ser ) { unfound = true; } catch ( NoSuchElementException nse ) { unfound = true; } catch ( Exception e ) { staticlogger.info( e.getMessage() ); } } driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS ); return we; } 
+1
source

Thanks for the pointer to using findelements. I think you will also need a wait logic if you do not want it to return too soon.

here is my solution in c #.

Basically, it restores the wait logic in the selenium library - unfortunately, the method that makes the wait is not displayed (it is annoying that it also incorrectly cancels exceptions and loses stack traces!).

You probably have to change it a bit for java - I don’t know what the selenium API is when you cannot just execute functions.

Waiting for re-implementation:

  private IWebElement WaitAndSeeIf(Func<IWebElement> canGet) { var end = DateTime.Now.AddSeconds(1); IWebElement element; while (true) { element = canGet(); if (element != null) break; var time = DateTime.Now; if (time > end) break; Thread.Sleep(200); } return element; } 

call code:

  var dashboardButton = WaitAndSeeIf(() => { var elements = Driver.FindElements(By.XPath("//button[contains(.//*,'Dashboard')]")); return elements.Any() ? elements.Single() : null; }); 

So far, I have found this useful in several places (checking for dialogs in extjs, etc.), but still they had to quench and configure it. I believe that the best part to do is force it to accept an implicit wait time, as indicated in another answer.

0
source

Source: https://habr.com/ru/post/911270/


All Articles