【问题标题】:Selenium WebDriver - Strange behavior in simulating mouseoverSelenium WebDriver - 模拟鼠标悬停时的奇怪行为
【发布时间】:2014-05-07 19:26:12
【问题描述】:

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

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

“服务”和“操作”链接是菜单项,将鼠标悬停在其上会弹出一个带有两个子菜单项的下拉 div。

现在,如果我必须使用 WebDriver 来单击“服务 1”链接,我必须将鼠标悬停在“服务”菜单选项上,然后单击“服务 1”。

我正在使用以下代码进行此操作:

WebElement menu = driver.findElement(By.linkText("Services"));
Actions builder = new Actions(driver);
builder.moveToElement(menu).build().perform();
WebElement li = menu.findElement(By.xpath("ancestor::li"));
WebElement menuDrop = li.findElement(By.className("menu-drop"));
WebElement subMenuLink = menuDrop.findElement(By.linkText("Service 1"));
subLink.click();

顺便说一句,我使用 Eclipse 来开发我的框架。

现在,上面的代码工作得很好,只有当我在 Eclipse 中调试它时。意思是,我在这里给出的代码-sn-p 的第一行旁边有一个断点,然后按 F6 并继续这样做,它工作得很好。

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

WebElement subMenuLink = menuDrop.findElement(By.linkText("Service 1"));

返回无此类元素异常。

可能是什么问题?

【问题讨论】:

    标签: java selenium-webdriver webdriver mouseover


    【解决方案1】:

    如果这在调试模式下工作,这意味着它可能是一个同步问题。您可能正在尝试在 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();
    

    如果你得到NoSuchElementException for linkText,那么你必须使用WebDriverWait,因为你试图在元素实际出现在DOM中之前找到它。在这种情况下,请尝试以下操作。

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

    【讨论】:

    • 我认为问题不在于同步,因为,看,当我执行“builder.moveToElement(menu).build().perform();”时,实际上会发生悬停。子菜单 div 会瞬间加载和消失。我所需要的只是一种保持 div 可见直到我的下一个语句的方法,这将是单击子菜单链接。如果我添加一个 WebDriverWait,它就没有用了,因为子菜单的 DIV 已经出现和消失了。
    【解决方案2】:

    请尝试以下方法:

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

    【讨论】:

      【解决方案3】:

      好的。我想到了。但我不能说它是解决方案还是解决方法。后者似乎更具吸引力。

      我偶然发现了这个链接

      Issue with losing focus of “hover” command when the mouse is outside of the active window

      根据那里讨论的内容,我只是将真正的鼠标光标移动到正在运行测试的活动窗口中的一个点(任何点),并且它工作了。

      这确实很有趣,但如果有人能阐明问题的确切原因并帮助我找到解决方案,我将不胜感激。

      【讨论】:

        【解决方案4】:

        我也遇到了同样的问题。使用 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;
        }
        

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题,原因是元素还不可用,DOM 没有及时更新,所以我让它在一些 driver.findelements() 之前插入了一个 thread.sleep(),就像这样:

          try {
               Thread.sleep(1500);
              } catch (InterruptedException e) {
               e.printStackTrace();
              }
               driver.findElement(By.xpath("<xpath_here>").click();
          

          我知道这不是最漂亮的方法,但是即使使用 WebdriverWait 也失败了,它可以为我节省一些痛苦。

          【讨论】:

            猜你喜欢
            • 2014-06-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多