I have one select city dropdown and there are around 8000 city presents. My usecase are:
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:
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:
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.
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.
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.
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.
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.