【问题标题】:Selenium Select - Selecting dropdown option by part of the textSelenium Select - 通过部分文本选择下拉选项
【发布时间】:2022-03-14 11:55:04
【问题描述】:

Selenium Select 类有 3 种不同选项选择的方法:

  1. 按索引选择
  2. 按值选择
  3. selectByVisibleText

现在,我有一种情况,我想通过一些文本选择一个选项,该文本部分出现在选项可见文本之一中(不想让自己暴露在整个文本中的更改中) )。

例如:

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

我只想通过提供“DOLLAR”来选择此选项,例如:

select.selectByPartOfVisibleText("DOLLAR") 

您将如何有效地实施它?

【问题讨论】:

标签: java selenium selenium-webdriver webdriver selenium-chromedriver


【解决方案1】:

我的解决方案是使用 xpath 来查找属于 select 子项的选项。任何xpath方法都可以用来查找select;在这个例子中,我通过 id 找到了选择。

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

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

经过深思熟虑后,我意识到可以完全使用 xpath 找到该选项:

driver.findElements(By.xpath("//select[@id = 'selectId')]/option[contains(text(), 'DOLLAR')]")).click();

【讨论】:

  • 为什么'selectId'后面有括号?
  • 我在python中使用了以下代码。注意引号。 driver.find_element_by_xpath("//select[@id = 'selectId']/option[contains(text(), '" + myVariable + "')]").click()
【解决方案2】:

你可以试试这样的逻辑,希望对你有帮助

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);
    }
}

【讨论】:

  • 如果选项具有 text-content 属性,这可能会起作用,但在 OP 的情况下,它不会。
  • 检查元素并查看 DOM 面板,您会发现包括 textContent 在内的所有属性
  • 谢谢,这正是我所需要的。我认为应该使用 element.getText 而不是 text.getAttribute("textContent") 部分。
【解决方案3】:

使用 Java 8 流/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")));
    }

【讨论】:

  • 效果很好。虽然如果您不想过滤页面上的每个选项,而只想搜索内部文本,您可以尝试:protected void selectOptionByPartText(WebElement select, String partialText) { Select s = new Select(select); s.getOptions() .stream() .filter(option -&gt; option.getText().toLowerCase().contains(partialText.toLowerCase())) .findFirst() .ifPresent(option -&gt; s.selectByValue(option.getAttribute("value"))); }
【解决方案4】:

最终我在这里结合了答案,这就是结果:

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);
}

Scala 中(在 Scala 中最终需要它)它看起来像:

  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)
  }

【讨论】:

  • 我遇到了下一个操作没有发生的问题,因为下拉关闭没有足够快地呈现。
【解决方案5】:

在最新的 Selenium 版本 3.x 或 4.x 中,可以使用 Select 类从下拉列表中选择一个选项。

例如:有一个风味下拉菜单,需要选择包含名称为Vanilla 的风味。

WebElement flavour = driver.findElement(By.id("attribute178"));
Select select = new Select(flavour);
String expectedFlavourName = "Vanilla";
List<WebElement> allFlavourList = select.getOptions();
for (WebElement option : allFlavourList) {
    String currentFlavourName = option.getText();
    if (currentFlavourName.contains(expectedFlavourName)) {
        select.selectByVisibleText(currentFlavourName);
        break;
    }
}

【讨论】:

    【解决方案6】:

    获取所有option 值的列表,然后检查该值是否包含您的部分文本。像这样的:

    List<WebElement> list = driver.findElements(By.tagName("option"));
    Iterator<WebElement> i = list.iterator();
    while(i.hasNext()) {
        WebElement wel = i.next();    
        if(wel.getText().contains("your partial text"))
        {
           //select this option
        }
    } 
    

    【讨论】:

    • 酷,谢谢。我只是不太喜欢明确地使用迭代器,会有所不同。
    【解决方案7】:

    这会起作用

    WebElement element = driver.findEle(By.xpath(loc));
                Select select = new Select(element);
                for(int i=1;i<=select.getOptions().size();i++)
                {
                    if(select.getOptions().get(i-1).getText().contains(containsTxt))
                    {
                        select.selectByIndex(i-1);
                        break;
                    }
                    if(i==select.getOptions().size())
                    {   
                        //"Fail"
                    }
                }
    

    【讨论】:

      【解决方案8】:

      这是我用来解决python问题的方法。

      我使用了此选项,因此它选择使用单词DOLLAR 的文本,而不是输入整个单词作为值。

      Select(driver.find_element_by_name(ELEMENT)).select_by_value("DOLLAR")
      

      而不是

      Select(driver.find_element_by_name(ELEMENT)).select_by_visible_text(text)
      

      【讨论】:

        猜你喜欢
        • 2019-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-11
        • 2015-05-15
        • 1970-01-01
        • 1970-01-01
        • 2018-02-17
        相关资源
        最近更新 更多