If you need to work with mouse hovers in your tests it may not be obvious how to do this with Selenium. And a quick search through the documentation will likely leave you befuddled forcing you to go spelunking through StackOverflow for the solution.
By leveraging Selenium’s Action Builder we can handle more complex user interactions like hovers. This is done by telling Selenium which element we want to move the mouse to, and then performing what we need to after.
Let’s check an example.
Sample Code
Java
// filename: Hovers.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
public class Hovers {
WebDriver driver;
@Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
}
@After
public void tearDown() throws Exception {
driver.quit();
}
@Test
public void hoversTest() {
driver.get("http://the-internet.herokuapp.com/hovers");
WebElement avatar = driver.findElement(By.className("figure"));
Actions builder = new Actions(driver);
builder.moveToElement(avatar).build().perform();
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("figcaption")));
assertThat(driver.findElement(By.className("figcaption")).isDisplayed(), is(Boolean.TRUE));
}
}
Python
# filename: hovers.py
import unittest
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
class Hovers(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def tearDown(self):
self.driver.quit()
def test_example_1(self):
driver = self.driver
driver.get('http://the-internet.herokuapp.com/hovers')
avatar = driver.find_element_by_class_name('figure')
ActionChains(driver).move_to_element(avatar).perform()
avatar_caption = driver.find_element_by_class_name('figcaption')
assert avatar_caption.is_displayed()
if __name__ == "__main__":
unittest.main()
Ruby
# filename: hover.rb
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
def setup
@driver = Selenium::WebDriver.for :firefox
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
run do
@driver.get 'http://the-internet.herokuapp.com/hovers'
an_avatar = @driver.find_element(class: 'figure')
@driver.action.move_to(an_avatar).perform
expect(@driver.find_element(class: 'figcaption').displayed?).to eql true
end
C#
// filename: Hovers.cs
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Interactions;
public class Hovers
{
IWebDriver Driver;
[SetUp]
public void SetUp()
{
Driver = new FirefoxDriver();
}
[TearDown]
public void TearDown()
{
Driver.Quit();
}
[Test]
public void MouseHoverDisplays()
{
Driver.Navigate().GoToUrl("http://the-internet.herokuapp.com/hovers");
IWebElement Avatar = Driver.FindElement(By.ClassName("figure"));
Actions Builder = new Actions(Driver);
Builder.MoveToElement(Avatar).Build().Perform();
By Hover = By.ClassName("figcaption");
Assert.That(Driver.FindElement(Hover).Displayed);
}
}
When you save this file and run it the expected behaviour is,
- Open the browser
- Visit the page
- Hover over the first avatar
- Assert that the caption displayed to the user
- Close the browser