20

我试图找到解决这个问题的方法,我花了很多时间,但我几乎不可能做到这一点。

问题:我在 Firefox 中使用 Selenium 和 Java。我需要找到一个元素(一个列表框)并单击它。因此,代码找到了元素,但单击操作不起作用。它每次都在 Google Chrome 中运行良好,有时在 Firefox 中运行良好(使用相同的 Java 代码有时可行,有时不可行)。

程序进入页面时,有部分代码带有元素:

    <div id="size-btn" class="size-btn">
      <span class="selected-size">SELECCIONA TALLA </span>
      <div class="size-select" style="display: none;">
        <table>
          <tbody>
            <tr id="selecsize_2" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051607">
            <tr id="selecsize_3" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051608">
            <tr id="selecsize_4" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051609">
            <tr id="selecsize_5" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051610">
          </tbody>
        </table>
      <button class="size-guide gaViewEvent gaTrack" data-ga-props="{action:'Seleccionar_Talla', opt_label:'Guia_de_tallas'}" data-href="http://www.anyweb.com/webapp/wcs/stores/servlet/ProductGuideSizeAjaxView?catalogId=24052&categoryId=358056&langId=-5&productId=1047599&storeId=10701">Guía de tallas</button>
      </div>
    </div>

当元素被点击时,有一部分代码会发生变化:

    <div id="size-btn" class="size-btn opened">

我尝试了许多解决方案,有时它可以工作,但是下次我运行该程序时,它就不再工作了。

一些解决方案:

  1. 它找到元素,但不运行单击操作。我检查了 xpath 和 cssSelector,并在这些表达式中找到了独特的元素。

    driver.findElement(By.xpath("//div[@id='size-btn' and not(contains(@class,'opened'))]/span")).click(); // Also checked with By.cssSelector("span.selected-size")
    
  2. 我虽然是因为时间的关系,所以我试图以这种方式解决它。

    WebElement we = driver.findElement(By.xpath("//div[@id='size-btn' and not(contains(@class,'opened'))]/span")); // By.cssSelector("span.selected-size")
    Thread.sleep(3000);
    we.click();
    
  3. 最后,我有点绝望,我创建了一个新函数来尝试这样做将近 60 次,寻找元素代码的变化,如果有任何变化,就再次尝试点击动作。

    clickAndWaitWhileElementIsNotPresent(By.xpath("//div[@id='size-btn' and not(contains(@class,'opened'))]/span"),By.xpath("//div[@class='size-btn opened']/span")); // By.cssSelector("span.selected-size")
    
    private void clickAndWaitWhileElementIsNotPresent(By by1, By by2) throws Exception {
        for (int second = 0;; second++) {
            if (second >= 60)
                fail("timeout");
            try {
                if (isElementPresent(by2))
                {
                    break;
                }
                else
                {
                    driver.findElement(by1).click();
                }
            } catch (Exception e) {
            }
            Thread.sleep(1000);
        }
    }
    

有元素的图像:

元素 1 元素 2

有人知道该怎么做吗?

4

6 回答 6

24

最后我找到了一个适用于 Firefox 和 Google Chrome 的答案。

WebElement we = this.driver.findElement(By.id("size-btn"));

JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", we);

waitForElementPresent(By.xpath("//div[@id='size-btn' and contains(@class,'opened')]/span"));
于 2013-03-12T10:15:43.357 回答
2

我不确定你为什么要使用这个 Xpath,如果你可以自由更改 Xpath,然后使用 selenium IDE 记录元素并Xpath::position从下拉列表中使用target(它选择相对于 html 标头的唯一路径),它将解决动态定位器的问题. 并尝试以下提到的事件。

1-使用clickAt

2- 使用fireevent(focus)然后单击。有时它会发生背景中的某些元素正在加载,当它被加载时,焦点移动到那里,因此 elementNotVisible 错误。

3-使用mouseDownRight

于 2013-03-09T14:51:27.683 回答
1

我在 Firefox 中遇到了同样的问题。诀窍是单击不是按钮本身内部的文本。

于 2013-09-18T18:40:05.847 回答
1

我有一些解决方案,用机器人创建一个类,将 TAB 事件键放在那里,然后调用该类。它的作用就像回到页面上一样。对于某些 razon,页面失去了焦点,再也找不到那个按钮。

   Robot robot;
    try {
        robot = new Robot();
        robot.keyPress(KeyEvent.VK_TAB);
        robot.keyRelease(KeyEvent.VK_TAB);

    } catch (AWTException e) {e.printStackTrace();}
于 2017-10-14T17:57:57.523 回答
0

您可以尝试使用 org.openqa.selenium.interactions 中的 Actions 类:

WebElement element = driver.findElement(By.id("size-btn"));
Actions builder = new Actions(driver);

builder.moveToElement(element).click(element);
builder.perform();
于 2017-04-22T15:21:16.290 回答
0
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.click(element);
Action action = actions.build();
action.perform();

这对我有用。

于 2020-04-30T09:04:23.100 回答