Java Selenium WebDriver-模拟鼠标悬停时的奇怪行为

Java Selenium WebDriver-模拟鼠标悬停时的奇怪行为,java,selenium-webdriver,webdriver,mouseover,Java,Selenium Webdriver,Webdriver,Mouseover,我有一个下拉菜单,其标记如下: <li> <a href="#">Services</a> <div class="menu-drop"> <a href="#">Service 1</a> <a href="#">Service 2</a> </div> </li> <li> <a href="#">Operations

我有一个下拉菜单,其标记如下:

<li>
  <a href="#">Services</a>
  <div class="menu-drop">
    <a href="#">Service 1</a>
    <a href="#">Service 2</a>
  </div>
</li>
<li>
  <a href="#">Operations</a>
  <div class="menu-drop">
    <a href="#">Operation 1</a>
    <a href="#">Operation 2</a>
  </div>
</li>
顺便说一下,我使用Eclipse来开发我的框架

现在,只有在eclipse中调试时,上面的代码才能正常工作。也就是说,我在这里给出的代码片段的第一行旁边有一个断点,然后按F6并继续这样做,它工作得非常好

但是如果我没有,也就是说,当我在没有断点的情况下运行代码时,它就不起作用了。发生的情况是,悬停被执行,但只执行了几分之一秒,下面一行

WebElement subMenuLink = menuDrop.findElement(By.linkText("Service 1"));
返回一个无此类元素异常


可能是什么问题?

请尝试以下方法:

action.moveToElement(menu).moveToElement(subMenuLink).click().build().perform();

嗯。我想出来了。但我不能说这是一个解决方案还是一个变通办法。后者似乎更具吸引力

我偶然发现了这个链接

根据这里讨论的内容,我只是将真实的鼠标光标移动到活动窗口中运行测试的一个点(任意点),它就工作了


当然,这很有趣,但我希望有人能解释问题的确切原因并帮助我找到解决方案。

如果它在调试模式下工作,这意味着它可能是一个同步问题。您可能正在尝试在DOM更新之前单击该元素。你发现周围的工作可能只是虚惊一场。当您将鼠标移动到活动窗口时,DOM可能会被加载,这就是为什么您可以单击元素的原因

你试过这样的吗

WebDriverWait wait = new WebDriverWait(driver,30);
WebElement menu = driver.findElement(By.linkText("Services"));
Actions builder = new Actions(driver);
builder.moveToElement(menu).build().perform();
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Service 1"))).click();
编辑#1 试试这个

 builder.moveToElement(menu).click(driver.findElement(By.linkText("Service 1"))).perform();
如果为linkText获取
NoTouchElementException
,则必须使用
WebDriverWait
,因为您试图在元素实际出现在DOM中之前找到它。在这种情况下,请尝试下面的方法

builder.moveToElement(menu).click(wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Service 1")))).perform();

我也面临同样的问题。使用javascript作为解决方法

public static void mouseHoverJScript(WebElement HoverElement) {
        try {
            if (isElementPresent(HoverElement)) {

                String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover',true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
                ((JavascriptExecutor) Selenium.webDriver).executeScript(mouseOverScript,HoverElement);

        } else {
            System.out.println("Element was not visible to hover " + "\n");

        }
    } catch (StaleElementReferenceException e) {
        System.out.println("Element with " + HoverElement
                + "is not attached to the page document"
                + e.getStackTrace());
    } catch (NoSuchElementException e) {
        System.out.println("Element " + HoverElement + " was not found in DOM"
                + e.getStackTrace());
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Error occurred while hovering"
                + e.getStackTrace());
    }
}

public static boolean isElementPresent(WebElement element) {
    boolean flag = false;
    try {
        if (element.isDisplayed()
                || element.isEnabled())
            flag = true;
    } catch (NoSuchElementException e) {
        flag = false;
    } catch (StaleElementReferenceException e) {
        flag = false;
    }
    return flag;
}

我也有同样的问题,原因是元素还不可用,DOM没有及时更新,所以我在一些驱动程序之前插入了thread.sleep(),类似这样:

try {
     Thread.sleep(1500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
     driver.findElement(By.xpath("<xpath_here>").click();
试试看{
睡眠(1500);
}捕捉(中断异常e){
e、 printStackTrace();
}
findElement(By.xpath(“”).click();

我知道这不是最漂亮的方法,但即使使用WebdriverWait也会失败,这会让我省去一些痛苦。

我认为问题不在于同步,因为,请看,当我执行“builder.moveToElement(menu.build().perform();”时,悬停实际上发生了。子菜单div加载并在一瞬间消失。我所需要的是一种方法,使div保持可见,直到我的下一个语句,即单击子菜单链接。如果我添加WebDriverWait,它将没有用,因为子菜单的div已经出现并消失。
try {
     Thread.sleep(1500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
     driver.findElement(By.xpath("<xpath_here>").click();