【问题标题】:How to select an option from a dynamic dropdown using Selenium?如何使用 Selenium 从动态下拉列表中选择一个选项?
【发布时间】:2018-12-15 18:58:20
【问题描述】:

我正在尝试单击下拉值以从“我的旅行”http://www.makemytrip.com/ 的字段中选择城市。但是得到过时的元素引用异常。页面加载时 ID 会发生变化。 尝试以下代码:

driver.findElement(By.xpath(".//*[@id='hp-widget__sfrom']")).clear();
driver.findElement(By.xpath(".//*[@id='ui-id-1']"));
driver.findElement(By.xpath(".//*[@id='hp-widget__sfrom']")).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeSelected(driver.findElement(By.xpath(".//*[@class='ui-menu-item'][2]"))));

【问题讨论】:

  • 请提供所面临的全部异常以更好地解释为什么会发生。
  • 感谢@muraliselenium 的回复,但现在已解决。

标签: java selenium selenium-webdriver autosuggest staleelementreferenceexception


【解决方案1】:

您可以使用此工作代码:

WebDriver driver = new ChromeDriver();
driver.get("https://www.makemytrip.com/");

driver.findElement(By.xpath(".//*[@id='hp-widget__sfrom']")).clear();
driver.findElement(By.xpath(".//*[@id='hp-widget__sfrom']")).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@class='ui-menu-item'][2]/div/p[1]/span[1]"))).click();

我已经修复了下拉列表元素的 xPath。始终尝试指定要与之交互的确切元素。例如,如果你想点击按钮,尝试找到<span><button> 标签,链接<a> 标签和输入字段<input> 标签。

【讨论】:

    【解决方案2】:

    你可以试试这个代码:

    在这种情况下,我看不到 xpath 的任何用途。我已经将一些 xpath 转换为 css 选择器或 id. 并且只保留了一个。虽然我没有遇到任何过时的元素参考。

    System.setProperty("webdriver.chrome.driver", "D:\\Automation\\chromedriver.exe");
            driver  = new ChromeDriver();
            driver.manage().window().maximize();
            WebDriverWait wait = new WebDriverWait(driver, 30);
            driver.get("https://www.makemytrip.com/");
            WebElement from =  wait.until(ExpectedConditions.elementToBeClickable(By.id("hp-widget__sfrom")));
            from.click();
            from.clear();
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("ul[class*='ui-widget-content hp-widget__sfrom']")));
            wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[contains(@aria-label,'Top Cities : Mumbai, India ')]"))).click();
    

    【讨论】:

      【解决方案3】:

      点击下拉值,例如孟买您可以使用以下解决方案:

      • 代码块:

        driver.get("https://www.makemytrip.com/")
        new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[@class='input_fromto checkSpecialCharacters ui-autocomplete-input' and @id='hp-widget__sfrom']"))).click();
        List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//li[@class='ui-menu-item'][starts-with(@id,'ui-id-')]//span[@class='autoCompleteItem__label']")));
        for (WebElement element:myList)
            if(element.getText().contains("Mumbai"));
                element.click();
        
      • 浏览器快照:

      【讨论】:

      • 感谢您的回复,只是想了解一下,为什么在 From 的 id 是唯一的情况下,我需要在 'From' 的 xpath 中给出类名。
      • @user2377826 所以基本上你的问题是为什么我们在 id 存在时使用 xpath 。总之使用类名idname标签名转换成css选择器 i> 默认情况下由 Java 客户端。所以选择是使用 css 选择器 还是 xpath。由于您的代码试验基于 xpath,因此我这样做了。详细讨论可以在Official locator strategies for the webdriver
      【解决方案4】:

      下面的代码对我来说很好,它也被参数化了,它适用于任何输入值而不改变 xpath。在这个例子中,我以孟买作为测试数据。

          driver.get("https://www.makemytrip.com/");
          driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
          driver.findElement(By.xpath("//input[contains(@id,'hp-widget__sfrom')]")).clear();
          driver.findElement(By.xpath("//input[contains(@id,'hp-widget__sfrom')]")).click();
          driver.findElement(By.xpath("//input[contains(@id,'hp-widget__sfrom')]")).sendKeys("Mumbai");
          Thread.sleep(2000);
          WebDriverWait wait = new WebDriverWait(driver, 30);
          By option = By.xpath("//div[@class='autoCompleteItem']/p/span[contains(text(),'Mumbai')]");
          wait.until(ExpectedConditions.elementToBeClickable(option));
          driver.findElement(option).click();
      

      【讨论】:

        猜你喜欢
        • 2011-07-13
        • 2021-06-11
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 2021-07-16
        • 1970-01-01
        相关资源
        最近更新 更多