Sreedhar Danturthi
Sreedhar Danturthi

Reputation: 7571

Selecting dropdown value without ID using Selenium

Got below HTMLcode for dropdown:

<select name="PWCMasterPage$PWCWebPartManager$gwpTemplateFr1$TemplateFr1$drpProductType" id="PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType" tabindex="2" class="PWCDropDownList" profiledatamember="" profileid="TEMPLATE" onblur="this.Holder = GetControlHolder(this);" onchange="this.Holder = GetControlHolder(this);" onfocus="this.Holder = GetControlHolder(this);" data-val-subtype-type="none" controlscollectionname="TemplateFr1_drpProductType" data-configid="TemplateFr1_drpProductType" holdername="TemplateFr1Holder">
<option value=""></option>
<option value="7">Expedited</option>
<option value="8">Premier</option>
<option value="9">Value</option>
</select>

Have been trying to select the dropdown values with:

Select dropDown = new Select(driver.findElement(By.xpath("//*[@id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]")));
dropDown.selectByValue("8");

Getting below error:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: Cannot locate option with value: 8

Select dropDown = new Select(driver.findElement(By.xpath("//*[@id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]")));
dropDown.selectByVisibleText("Expedited");

Which resulted in below error:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: Cannot locate element with text: Expedited

Have tried alternately with selectByVisibleText and selectByIndex as well which resulted in similar errors.

Upvotes: 1

Views: 1272

Answers (3)

RichEdwards
RichEdwards

Reputation: 3753

The issue isn't the java code you provided or the HTML source.

I created a simple web page with your html:

<html><body>
<select name="PWCMasterPage$PWCWebPartManager$gwpTemplateFr1$TemplateFr1$drpProductType" id="PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType" tabindex="2" class="PWCDropDownList" profiledatamember="" profileid="TEMPLATE" onblur="this.Holder = GetControlHolder(this);" onchange="this.Holder = GetControlHolder(this);" onfocus="this.Holder = GetControlHolder(this);" data-val-subtype-type="none" controlscollectionname="TemplateFr1_drpProductType" data-configid="TemplateFr1_drpProductType" holdername="TemplateFr1Holder">
    <option value=""></option>
    <option value="7">Expedited</option>
    <option value="8">Premier</option>
    <option value="9">Value</option>
</select>
</body></html>

I created a simple test class - and it works lovely! Pasting the lot so you can see i do nothing other than open the page, use your code and select the element.


public class StackTest {

    private String baseUrl = "C:\\Git\\stackTest.html";
    private WebDriver driver;

    @Before
    public void CreateWebDriver()
    {
        System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get(baseUrl);
    }

    @After
    public void CloseAndQuitWebDriver() {
        driver.close();
        driver.quit();
    }

    @Test
    public void approach1_ExistingCode()
    {
        Select dropDown = new Select(driver.findElement(By.xpath("//*[@id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]")));
        dropDown.selectByValue("8");
    }
}

In my opinion, the problem isn't selenium, the problem isn't the xpath, as long as you're doing what @SeleniumUser002 says in his answer then the problem isn't object accessibility.

Have a think about:

  • What is your site doing that's special?
  • Is it doing anything script based which creates/populates this drop down at run time?
  • When you captured the html did you capture it from chrome manually or chromedriver at runtime? (try the latter if you didn't already - Running manually is what a user sees, but chromedriver is what selenium sees. Be careful not to click on anything else other than the object when inspecting so you don't skew the results)
  • Are you doing any other steps in the script that can influence this dropdown?

First thing i would say to really fixing this issue is to use a breakpoint before your broken line and slowly step though the actions that lead the issue. See if the page is behaving differently at runtime. Walking through slowly also removes synchronisation issues and once the code works once, if it goes back to being flaky you can rule out the code and focus on a better wait strategy.

If that doesn't work and you're STILL seeing all the options present but cannot select, do a dump of what selenium can see:

@Test
public void debug_WhatAreMyOptions()
    {
        Select dropDown = new Select(driver.findElement(dropdownIdentifier));
        System.out.println("dropdown has "+ dropDown.getOptions().size()+" options");

        System.out.println("the options are....");
        for (var dropdownOptions : dropDown.getOptions()) {
            System.out.println(dropdownOptions.getText());
        }

    }

That might help you actually figure out what's happening to solve the issue. Without that debugging information no one can tell you what the problem is - but i can suggest work arounds!

Try these...

Set this up:

private By dropdownIdentifier = By.xpath("//*[@id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]");
    

Then try old fashioned clicks without a select object:

public void approach2_Clicks()
    {
        driver.findElement(dropdownIdentifier ).click(); // to activate
        driver.findElement(dropdownIdentifier ).findElement(By.xpath("//*[@value='8']")).click();
    }

Or try our old friend javascript:

 public void approach3_Javascript()
    {
        var dropdown = driver.findElement(dropdownIdentifier);
        ((JavascriptExecutor) driver).executeScript("arguments[0].value='8'", dropdown);
    }

However - these work arounds are only possible if the list is populated... My gut tells me that the data isn't there to select at runtime, but as you say it's an internal link so only you can verify that :-)

Give it a go and let us know.

Upvotes: 2

SeleniumUser
SeleniumUser

Reputation: 4177

try below solution with WebDriverWait to avoid synchronization issue:

    WebDriverWait wait = new WebDriverWait(driver,30);
    WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("PWCDropDownList")));
    Select drpCountry = new Select(element);
    drpCountry.selectByValue("8");

Upvotes: 0

RichEdwards
RichEdwards

Reputation: 3753

Are you using safari?

If so, there's known issues with webdriver and safari. The long and short of it is to use the driver provided by apple.

This is the selenium issue: https://github.com/SeleniumHQ/selenium/issues/3145

If you look at: https://webkit.org/blog/6900/webdriver-support-in-safari-10/

They say:

"Safari’s driver is launchable via the /usr/bin/safaridriver executable, and most client libraries provided by Selenium will automatically launch the driver this way without further configuration."

Upvotes: 2

Related Questions