【问题标题】:How to perform mouseover function in Selenium WebDriver using Java?如何使用 Java 在 Selenium WebDriver 中执行鼠标悬停功能?
【发布时间】:2013-06-22 01:09:29
【问题描述】:

我想在下拉菜单上执行鼠标悬停功能。当我们将鼠标悬停在菜单上时,它将显示新选项。 我尝试使用 xpath 单击新选项。但不能直接点击菜单。 因此,作为手动方式,我尝试将鼠标悬停在下拉菜单上,然后单击新选项。

Actions action = new Actions(webdriver);
WebElement we = webdriver.findElement(By.xpath("//html/body/div[13]/ul/li[4]/a"));
action.moveToElement(we).build().perform();

【问题讨论】:

标签: java selenium selenium-webdriver mouseover


【解决方案1】:

实际上不可能执行“鼠标悬停”操作,相反,您需要一次性链接所有想要实现的操作。所以移动到显示其他元素的元素,然后在同一个链中,移动到现在显示的元素并单击它。

使用动作链时,您必须记住“像用户那样做”。

Actions action = new Actions(webdriver);
WebElement we = webdriver.findElement(By.xpath("html/body/div[13]/ul/li[4]/a"));
action.moveToElement(we).moveToElement(webdriver.findElement(By.xpath("/expression-here"))).click().build().perform();

【讨论】:

  • 对我来说这行不通。只有在 moveToElement() 之后执行 build().perform() 时,我的菜单才会悬停
  • 这行不通的原因是所有对webdriver.findElement(By... something) 的调用都在执行其他任何操作之前执行(这是它们的结果可以传递给moveElement 的唯一方法)。那时您要查找的第二个元素尚不可见,因为第一个元素仍必须悬停在上面。如您所说,要解决此问题,您可以插入中间.perform()s,然后对于第二个findElement,第一个悬停将是performed。给定的解决方案可能会起作用,具体取决于页面的实现,但显然您和我的里程有所不同。
【解决方案2】:

根据 this 博客文章,我能够使用 Selenium 2 Webdriver 使用以下代码触发悬停:

String javaScript = "var evObj = document.createEvent('MouseEvents');" +
                    "evObj.initMouseEvent(\"mouseover\",true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);" +
                    "arguments[0].dispatchEvent(evObj);";


((JavascriptExecutor)driver).executeScript(javaScript, webElement);

【讨论】:

  • 不太明显的解决方案,但对于我的 IE11 测试来说是 100% 可靠的。如果您在使用moveToElement 时遇到问题,请使用这个!我用 C# 编写代码,所以这不仅仅是 Java 的方式。
  • 这是什么arguments[0]
  • @ArianHosseinzadeh 传入的 dom 引用传递给executeScript() 的第二个参数,即webElement
  • 我得到了 Javascript 执行器的错误引用。我需要在 C# 中添加什么引用
【解决方案3】:

尝试执行以下操作时,这些答案都不起作用:

  1. 将鼠标悬停在菜单项上。
  2. 找到仅在悬停后可用的隐藏元素。
  3. 点击子菜单项。

如果在 moveToElement 之后插入“执行”命令,它会移动到元素,并且子菜单项会显示一小段时间,但这不是悬停。隐藏元素在被发现之前立即消失,从而导致 ElementNotFoundException。我尝试了两件事:

Actions builder = new Actions(driver);
builder.moveToElement(hoverElement).perform();
builder.moveToElement(clickElement).click().perform();

这对我不起作用。以下对我有用:

Actions builder = new Actions(driver);
builder.moveToElement(hoverElement).perform();
By locator = By.id("clickElementID");
driver.click(locator);

使用操作悬停和标准 WebDriver 点击,我可以悬停然后点击。

【讨论】:

  • 第二个例子在添加 .perform() 时也对我有用
  • 不敢相信这仍然是一个问题......即使这样也行不通:builder.moveToElement(settings) .moveByOffset(0, 30) .moveToElement(stagingMenu) .pause(20000) .keyDown(Keys .CONTROL) .click(stagingMenu) .keyUp(Keys.CONTROL) .sendKeys(Keys.ENTER) .perform();我什至看到在超时范围内的元素上触发了悬停 css。但无论我尝试什么都不会触发点击
  • 如果可点击元素不是普通元素并且类似于 ::before,您将如何处理。当鼠标悬停时,这之前可见
【解决方案4】:

我发现这个问题正在寻找一种方法来为我的 Javascript 测试做同样的事情,使用 Protractor(Selenium 的 javascript 前端)。

我使用 protractor 1.2.0 和 webdriver 2.1 的解决方案:

browser.actions()
.mouseMove(
  element(by.css('.material-dialog-container'))
)
.click()
.perform();

这也接受一个偏移量(我用它来点击元素的上方和左侧:)

browser.actions()
.mouseMove(
  element(by.css('.material-dialog-container'))
  , -20, -20  // pixel offset from top left
)
.click()
.perform();

【讨论】:

    【解决方案5】:

    使用 Selenium java WebDriver 进行鼠标悬停的示例程序:

    public class Mhover {
        public static void main(String[] args){
           WebDriver driver = new FirefoxDriver();
           driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
           driver.get("http://www.google.com");
           WebElement ele = driver.findElement(By.id("gbqfba"));
           Actions action = new Actions(driver);
           action.moveToElement(ele).build().perform();
        }
    }
    

    【讨论】:

    • 请考虑包含一些关于您的答案的信息,而不是简单地发布代码。我们试图提供的不仅仅是“修复”,而是帮助人们学习。您应该解释原始代码中的问题、您所做的不同之处以及您的更改为何有效。
    • @AndrewBarber - 给定的程序可以真正帮助用户。该程序运行正常。用户已经接受了..
    • 我不怀疑它会工作;我的意思是你应该解释为什么它可能会起作用,为什么他们没有起作用,以及你改变了什么。
    • 此代码等效于 OP,不回答问题。没有任何上下文信息是多余的。
    【解决方案6】:

    这段代码运行良好:

     Actions builder = new Actions(driver);
     WebElement element = driver.findElement(By.linkText("Put your text here"));
     builder.moveToElement(element).build().perform();
    

    鼠标悬停后,您可以继续对显示的信息执行下一个操作

    【讨论】:

    • 优秀只需要添加using OpenQA.Selenium.Interactions;
    【解决方案7】:

    查看这个例子我们如何实现它。

    public class HoverableDropdownTest {
    
        private WebDriver driver;
        private Actions action;
    
        //Edit: there may have been a typo in the '- >' expression (I don't really want to add this comment but SO insist on ">6 chars edit"...
        Consumer < By > hover = (By by) -> {
            action.moveToElement(driver.findElement(by))
                  .perform();
        };
    
        @Test
        public void hoverTest() {
            driver.get("https://www.bootply.com/render/6FC76YQ4Nh");
    
            hover.accept(By.linkText("Dropdown"));
            hover.accept(By.linkText("Dropdown Link 5"));
            hover.accept(By.linkText("Dropdown Submenu Link 5.4"));
            hover.accept(By.linkText("Dropdown Submenu Link 5.4.1"));
        }
    
        @BeforeTest
        public void setupDriver() {
            driver = new FirefoxDriver();
            action = new Actions(driver);
        }
    
        @AfterTest
        public void teardownDriver() {
            driver.quit();
        }
    
    }
    

    详细答案请看这里-http://www.testautomationguru.com/selenium-webdriver-automating-hoverable-multilevel-dropdowns/

    【讨论】:

      【解决方案8】:

      你可以试试:

      WebElement getmenu= driver.findElement(By.xpath("//*[@id='ui-id-2']/span[2]")); //xpath the parent
      
      Actions act = new Actions(driver);
      act.moveToElement(getmenu).perform();
      
      Thread.sleep(3000);
      WebElement clickElement= driver.findElement(By.linkText("Sofa L"));//xpath the child
      act.moveToElement(clickElement).click().perform();
      

      如果您的网站有很多类别,请使用第一种方法。对于你想要的菜单,你只需要第二种方法。

      【讨论】:

        【解决方案9】:

        我试过了,正常

        action = ActionChains(driver)
        element = driver.find_element_by_xpath("XPath_selector")
        action.move_to_element(element).perform()
        

        【讨论】:

          【解决方案10】:

          试试这个可重复使用的方法,

          public void MoveThePoiterToElement(By by){
              log.info("Moving the cursor to the element");
              Actions action = new Actions(driver);
              action.moveToElement(driver.findElement(by));
              action.build().perform();
              log.info("Cursor moved to the element");
          }
          

          【讨论】:

            猜你喜欢
            • 2013-10-17
            • 1970-01-01
            • 2018-04-25
            • 2015-10-25
            • 2013-09-22
            • 2013-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多