Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium Select - Selecting dropdown option by part of the text

The class Selenium Select has 3 methods of different option selection:

  1. selectByIndex
  2. selectByValue
  3. selectByVisibleText

Now, I have a situation where I want to select an option by some text that partially appear in one of the options visible text (don't want to expose myself to changes in the WHOLE text).

For example:

<option value="0" label="not-intresting">VERY-LONG-TEXT-THAT-I-NEED-TO-SELECT-DOLLAR</option>

And i want to select this option only by providing the "DOLLAR", something like:

select.selectByPartOfVisibleText("DOLLAR") 

How would you implement it effectively?

like image 365
Johnny Avatar asked Apr 21 '15 12:04

Johnny


4 Answers

My solution is to use xpath to find options that are children of the select. Any xpath method can be used to find the select; in this example I am finding the select by id.

List<WebElement> options = driver.findElements(By.xpath("//select[@id = 'selectId')]/option"));

for (WebElement option : options) {
    if (option.getText().contains("DOLLAR")) {
        option.click();
        break;
    }
}

After a little more thought I realize the option can be found entirely with xpath:

driver.findElements(By.xpath("//select[@id = 'selectId')]/option[contains(text(), 'DOLLAR')]")).click();
like image 90
Cash_m Avatar answered Sep 18 '22 23:09

Cash_m


You can try a logic like this hope this helps

List <WebElements> optionsInnerText= driver.findElements(By.tagName("option"));
for(WebElement text: optionsInnerText){
    String textContent = text.getAttribute("textContent");
    if(textContent.toLowerCase.contains(expectedText.toLowerCase))
           select.selectByPartOfVisibleText(expectedText);
    }
}
like image 24
Zach Avatar answered Sep 20 '22 23:09

Zach


Using Java 8 Stream/Lambda:

protected void selectOptionByPartText(WebElement elementAttr, String partialText) {
        Select select = new Select(elementAttr);
        select.getOptions().parallelStream().filter(option -> option.getAttribute("textContent").toLowerCase().contains(partialText.toLowerCase()))
                .findFirst().ifPresent(option -> select.selectByVisibleText(option.getAttribute("textContent")));
    }
like image 31
Saikat Avatar answered Sep 17 '22 23:09

Saikat


Eventually I combined the answers here and that's the result:

Select select = new Select(driver.findElement(By.xpath("//whatever")));

public void selectByPartOfVisibleText(String value) {
    List<WebElement> optionElements = driver.findElement(By.cssSelector("SELECT-SELECTOR")).findElements(By.tagName("option"));

    for (WebElement optionElement: optionElements) {
        if (optionElement.getText().contains(value)) {
            String optionIndex = optionElement.getAttribute("index");
            select.selectByIndex(Integer.parseInt(optionIndex));
            break;
        }
    }

    Thread.sleep(300);
}

And in Scala (need it eventually in Scala) it looks like:

  def selectByPartOfVisibleText(value: String) = {
    val optionElements: util.List[WebElement] = selectElement.findElements(By.tagName("option"))

    breakable {
      optionElements.foreach { elm =>
        if (elm.getText.contains(value)) {
          val optionIndex = elm.getAttribute("index")
          selectByIndex(optionIndex.toInt)
          break
        }
      }
    }
    Thread.sleep(300)
  }
like image 31
Johnny Avatar answered Sep 18 '22 23:09

Johnny