Question

My application must be used in IE. I am automating test in which the script first has to select an option in 1st drop-box, "Category", to get category-associated options displayed in 2nd drop-box, "Name". Script then selects an option in "Name", and an associated page will display.
"Name" does not have any options until a selection is made in "Category". HTML source:

<select id="drop_Category">
   <option value =""/>
   <option value = "Category1">
     Text - Category1
   <option value = "Category2">
     Text - Category2
<select id="drop_Name">

After option "Category1" selected, HTML source changes to:

<select id="drop_Category">
   <option value =""/>
   <option value = "Category1">
     Text - Category1
   <option value = "Category2">
     Text - Category2
<select id="drop_Name">
   <option value =""/>
   <option value = "C1_Name1">
     Text - C1_Name1
   <option value = "C1_Name2">
     Text - C1_Name2
   <option value = "C1_Name3">
     Text - C1_Name3

For the script to select "Category1" and "C1_Name3", my first version of code is:

//Select option in drop-box "Category"
stringText = "Category1";
var dropCategory = new SelectElement(driver.FindElement(By.Id("drop_Category")));
dropCategory.SelectByText(stringText);

//Select option in drop-box "Name"
stringText = "C1_Name3";
var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
dropName.SelectByText(stringText);

This code did not work because the list in "Name" has not been loaded and script cannot find option with text "C1_Name3", so I added implicit wait. Wait did not help, so I tried to catch the exception. This is 2nd version of code:

//Select option in drop-box "Category"
stringText = "Category1";
var dropCategory = new SelectElement(driver.FindElement(By.Id("drop_Category")));
dropCategory.SelectByText(stringText);

//Select option in drop-box "Name"
stringText = "C1_Name3"
try
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);   
}
catch (NoSuchElementException)
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);   
}

It worked but still crashed sometimes due to InvalidSelectorException or StaleElementReferenceException exceptions. I don't know what to do to get this work consistently. Also, I am new in the field so I am not sure if this is bad practice to write code as in my 2nd version. Any help is very appreciated.

Was it helpful?

Solution

Initial Approach

Typically (in my experience) a sleep time is required in addition to the wait-time approach; so try combining the two.

For example, I would try looping until the element you want is found. Pseudo-code follows:

boolean found = false;
while (!found) {
try
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);
   found = true;  
}
catch (NoSuchElementException)
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText); 
   //do a short sleep here e.g. 500ms depending on the speed of your site  
}

}

From the documentation on the InvalidSelectorException, that exception is also thrown when "the selector which is used to find an element does not return a WebElement." So catching NoSuchElementException should be enough.

Alternate Approach

  • From your question <select id="drop_Name"> exists in the code from the start.
  • Therefore driver.findElement will always find a WebElement by ID drop_Name
  • The difference is that until you select Category1, drop_Name has no <option> values.
  • Therefore you could try the following wait function:

(Note: code is in Java; can be easily ported to C#)

private static void waitUntilOptionsLoad() {
    while(true) {
        Thread.sleep(1000);
        List<WebElement> options = driver.findElement(By.id("drop_Name"))
                        .findElements(By.tagName("option"));
        if (options.size() > 0 ) { 
            System.out.println("More than one option tag found; therefore options have loaded");
            break;
        }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top