简体   繁体   中英

Is there any way to reduce element locating time in Selenium WebDriver?

I have one select city dropdown and there are around 8000 city presents. My usecase are:

  1. Get the selected city name
  2. If city name is not as expected then select the desired city
  3. Now again get the city name to verify that desired city has been selected

My code is working fine but the issue is to complete these 3 steps it takes around 5-8 minutes. I know its due to the large set of city name available in dropdown

This is the dropdown HTML structure :

<div class="col-md-12">
  <label class="mmk-filter-control">Preferred Source City : </label>
     <div class="pull-right refe-link">
     <div class="mmk-filter-control mmk-select-filter pull-right mr5">
     <select id="ddlPrefferedSourceCity" class="form-control" name="ddlPrefferedSourceCity">
          <option value="-1">- Select -</option>
          <option value="A.S.Peta Bypass">A.S.Peta Bypass</option>
          <option value="aadsar">aadsar</option>
          <option value="aagariya">aagariya</option>
          <option value="aahur">aahur</option>
          <option value="aakadiya">aakadiya</option>
          <option value="Aala">Aala</option>
          <option value="Aanjangaon">Aanjangaon</option>
           .
           .
          around 8000 options

And code is:

if(usersname.size()>0)
{
     Select s = new Select(preferredCity);
     Comman.wait.until(ExpectedConditions.invisibilityOf(loader));
     String cityName  = s.getFirstSelectedOption().getText();
     if(cityName.equals(preferredCityName))
     {
         LogWriter.logger.info("Preferred City is already Selected");
         TakeScreenshot.passedScreenShot();
     }
     else
     {
         Comman.wait.until(ExpectedConditions.invisibilityOf(loader));
         LogWriter.logger.info("Last Selected Preferred City is : " + s.getFirstSelectedOption().getText());
         TakeScreenshot.passedScreenShot();
         s.selectByVisibleText(preferredCityName);
         setPreferenceButton.click();
         Comman.wait.until(ExpectedConditions.invisibilityOf(loader));
         LogWriter.logger.info("New Selected Preferred City is : " + s.getFirstSelectedOption().getText());
         TakeScreenshot.passedScreenShot();
     }
}

Is there any way to overcome and make the test fast?

The issue is likely due to getFirstSelectedOption since the method sends the isSelected command for each option:

https://github.com/SeleniumHQ/selenium/blob/master/java/client/src/org/openqa/selenium/support/ui/Select.java#L93

So instead of :

s.getFirstSelectedOption().getText()

, I would use a selector to get the first selected option:

preferredCity.findElement(By.cssSelector("option[selected]")).getText()

Update

The selected attribute is not updated in the DOM when the selection changes. So an alternative would be to read the selectedIndex property on <select> :

int selectedIndex = Integer.parseInt(preferredCity.getAttribute("selectedIndex"));

WebElement selectedOption = preferredCity.findElement(By.cssSelector(
    String.format("option:nth-child(%s)", selectedIndex + 1)));

String text = selectedOption.getText();

or with executeScript :

String JS_GET_FIRST_SELECTED_OPTION = 
    "var e=arguments[0], i=e.selectedIndex; return i < 0 ? null : e.options[i];";

JavascriptExecutor jse = (JavascriptExecutor)driver;
WebElement selectedOption = (WebElement)jse.executeScript(JS_GET_FIRST_SELECTED_OPTION, preferredCity);

if (selectedOption == null)
  throw new NoSuchElementException("No options are selected");)

String text = selectedOption.getText();

While 8000 cities in a single dropdown is a questionable design, it might not be the whole issue. I created a simple HTML file that contained 100,000 options and selected a value from that list and it was complete in 12s, including loading the entire page. Granted it wasn't hosted on the web. Your internet connection and/or the site's speed may be factors.

I would look at a few things:

  1. You seem to be using WebDriverWait in Comman.wait (Common is misspelled, btw). Are you also using an implicit wait? If so, the docs state not to mix both.

    WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times.

    If you are, remove the implicit wait and see if that helps.

  2. Next I would try getting some timings. Add a timing between each of the steps to see where the long waits lie. With that info, you will have a better idea of where the delays are coming from and how to address them.

  3. You are waiting for the loader to be invisible more than I think is necessary. It shouldn't matter but removing some of them might help, especially if you are using an implicit wait (see #1). You wait for it after you grab the SELECT, which shouldn't be needed. You wait for it again in the first line of the else but you haven't done anything that should trigger a loader. The only place that seems reasonable is the 3rd instance, after you select the item from the dropdown.

  4. Have you tried selecting by value instead of by visible text? It may not matter but I'm not really sure how it finds visible text.

  5. Another option is to avoid use of the Select class altogether. While it's a good practice to use it normally because it makes dealing with SELECT so much easier, in this case it may be contributing to the performance issue.

    One way to get around it may be to go after the option directly using a CSS selector, eg #ddlPrefferedSourceCity > option[value='" + preferredCityName + "'] . I tried this on my local machine and it was slightly faster... but it's a difference of 1.2s vs .6s.

I really don't know why it is taking time to get the dropdown value using getFirstSelectedOption

I have tried JavascriptExecutor where i have populated value of the dropdown using jQuery command

public String getDropdownValue()
{
        JavascriptExecutor e = (JavascriptExecutor) driver;
        return (String) e.executeScript("return $('#ddlPrefferedSourceCity').val();");
}

Now I'm able to get the value even change the dropdown value and again find the selected value. And now the time is 5-8 second .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM