无法从使用Selenium选择中获取选项

时间:2016-07-07 10:44:15

标签: java selenium select xpath webdriver

我无法使用Selenium Webdriver从下拉列表中选择选项。以下是HTML摘要:

<span id="id14">
    <div class="stadium-input-row">
        <span class="inputContainer">
            <select id="id1f" class="departurePoint stadiumSelect" onchange="var wcall=..........">
            <option value="">Please select</option>
            <option value="BHX"> Birmingham - (BHX) </option>
            <option value="GLA"> Glasgow - (GLA) </option>
            <option value="LON"> London - (LON) </option>
            <option value="MAN"> Manchester - (MAN) </option>............

每次加载DOM时,select标记id都会更改。

选择标记在与之交互之前显示为灰色。

我的代码

Select oSelect = new Select(driver.findElement(By.xpath("(.//select)[1]"));
oSelect.selectByVisibleText("Birmingham");

错误

  

org.openqa.selenium.NoSuchElementException:找不到元素   带文字:伯明翰

在调试模式下,驱动程序似乎没有激活(单击)下拉列表。

4 个答案:

答案 0 :(得分:1)

在该网站上发生的事情很奇怪(至少对我来说很奇怪)。您尝试访问的SELECT是永久隐藏的(这意味着它无法与使用Selenium进行交互)。用户通过虚假下拉列表与DIV等进行互动(它不是SELECT),这些选择的结果存储在隐藏的SELECT中。有两种方法可以完成您的任务。

  1. 处理您可以看到的内容。

    这个网站真的很痛苦。我认为它最终可以完成,但我不想再花时间在它上面,所以我会告诉你门,你必须从我离开的地方继续。以下代码将打开出发下拉列表。从那里,您可以找到出发机场并点击它。完成。比听起来更难......

    driver.findElement(By.cssSelector("div.custom-select.departurePoint.airportSelect")).click();
    
  2. 作弊并使用JavascriptExecutor

    注意:通过这样做,您不再执行真实的用户场景,因为用户无法点击隐藏的元素或将Javascript命令注入页面。只要你对此感到满意,这里就是一个样本。

    此代码使用JavascriptExecutor在页面上执行Javascript。您在选项中传递了要查找的字符串,例如你可以通过&#34; EMA&#34;或者&#34;东米德兰兹 - (EMA)&#34;或者介于两者之间。 JS代码将获取隐藏的SELECT,搜索OPTIONS,并选择匹配的第一个。

    另请注意:您不会看到带有选择的UI更新。单击SEARCH后,它将起作用。我自己尝试过,但它确实有效。

    另一个注意事项:我使用Eclipse作为我的编辑器,因此您在下面的代码中看到的// @formatter:off使Eclipse无法包装/重新格式化包含JS代码的超长字符串。您可以随意离开或删除它。我喜欢它,因为我仍然可以阅读它的格式和缩进的JS代码,并且我不希望Eclipse弄乱它。

    selectOption("EMA");
    
    public void selectOption(String option)
    {
        // @formatter:off
        String script =
            "function selectOption(s) {\r\n" +
            "   var sel = document.querySelector('select.departurePoint.airportSelect');\r\n" +
            "   for (var i = 0; i < sel.options.length; i++)\r\n" +
            "   {\r\n" +
            "       if (sel.options[i].text.indexOf(s) > -1)\r\n" +
            "       {\r\n" +
            "           sel.options[i].selected = true;\r\n" +
            "           break;\r\n" +
            "       }\r\n" +
            "   }\r\n" +
            "}\r\n" +
            "return selectOption('" + option + "');";
    
        // @formatter:on
        ((JavascriptExecutor) driver).executeScript(script);
    }
    

答案 1 :(得分:0)

正如您的exception清楚地说Cannot locate element with text: Birmingham表示它与整个可见文字选项进行比较,因此您应该尝试如下: -

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement select = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(.//select)[1]")));
Select oSelect = new Select(select);
oSelect.selectByVisibleText("Birmingham - (BHX)");

oSelect.selectByIndex(1);

oSelect.selectByValue("BHX");

已修改: - 如果上述解决方案无效,您应尝试使用JavascriptExecutor,如下所示: -

((JavascriptExecutor)driver).executeScript("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text.indexOf(arguments[1]) != -1){ select.options[i].selected = true; } }",
            driver.findElement(By.xpath("(.//select)[1]")),
            "Birmingham");

希望它会对你有所帮助.. :)

答案 2 :(得分:0)

你需要做什么:

List<WebElement> options = driver.findElement(By.xpath("//div[@class='stadium-input-row']//select")).findElements(By.tagName("option"));

将创建选项标签列表作为WebElement对象

Select oSelect = new Select(driver.findElement(By.xpath("//div[@class='stadium-input-row']//select"));

或者只选择select作为WebElement对象

WebElement selectElement = driver.findElement(By.xpath("//div[@class='stadium-input-row']//select"));

悬停元素

Actions action = new Actions(driver);
WebElement hoverElement = driver.findElement(By.xpath("//div[@class='stadium-input-row']//select"));
action.moveToElement(hoverElement);
action.click().build().perform();

答案 3 :(得分:-1)

选择在所有情况下都不起作用。试试这段代码

List <WebElement> options = driver.findElements(By.xpath("Target Element with Options"));
    String element;
    for(int i=0;i<options.size();i++)
    {
        element = options[i].get(i).getAttribute("value");
        if(element.equals("BHX")){
            options.get(i).click();
        }
    }