ScreenshotNeo

BlogHow-to

How to Perform Mouse Hover in Selenium

Use Selenium’s Actions API to hover over menus, tooltips, and other elements. See runnable Java and Python examples, reliable waits, and fixes for common issues.

By the ScreenshotNeo team4 October 20267 min read

To perform a mouse hover in Selenium, move the pointer to the target element with the Actions API and execute the action. In Java, use new Actions(driver).moveToElement(element).perform(); in Python, use ActionChains(driver).move_to_element(element).perform(). These actions move the pointer without clicking.

This guide covers Java and Python WebDriver, choosing a target point, waiting for hover-dependent UI, Selenium IDE, troubleshooting, and when a screenshot can help inspect the result.

1. Java: hover over an element

This runnable example opens a page, moves to a menu item, waits for its submenu link to become visible, and prints the link text. Replace the URL and locators with those from your application.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;

public class HoverExample {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        try {
            driver.get("https://example.com");

            WebElement menu = driver.findElement(By.cssSelector(".menu-item"));
            new Actions(driver).moveToElement(menu).perform();

            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            WebElement submenuLink = wait.until(
                ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector(".submenu a")
                )
            );
            System.out.println(submenuLink.getText());
        } finally {
            driver.quit();
        }
    }
}

The key call is moveToElement(menu).perform(). Selenium queues the movement and perform() dispatches it. The default target is the element’s in-view center point, which Selenium describes as hovering. See the official Selenium mouse actions guide and the Java Actions API reference.

Target a point inside the element

If the center does not activate the desired state, use an offset from the in-view center. Java offsets are relative to that center; negative X moves left and negative Y moves above it.

new Actions(driver)
    .moveToElement(menu, 10, 5)
    .perform();

Choose a point over the actual interactive region, such as the visible label rather than empty padding. Offsets are in pixels and depend on the element’s current size and layout.

2. Python: hover over an element

Install Selenium with python -m pip install selenium. This example uses Selenium Manager through webdriver.Chrome() and waits for the submenu condition instead of assuming it appears immediately.

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)

try:
    driver.get("https://example.com")

    menu = driver.find_element(By.CSS_SELECTOR, ".menu-item")
    ActionChains(driver).move_to_element(menu).perform()

    submenu_link = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, ".submenu a"))
    )
    print(submenu_link.text)
finally:
    driver.quit()

Python’s move_to_element targets the middle of the element. To aim elsewhere, use move_to_element_with_offset(element, x, y):

ActionChains(driver).move_to_element_with_offset(menu, 10, 5).perform()

As in Java, the action is not sent until perform() is called. Consult Selenium’s Python ActionChains reference.

3. Wait for the hover result

Moving the pointer and waiting for the page to react are separate steps. A menu may open immediately, after a CSS transition, or after application code finishes running. Wait for the state the test needs: visibility before reading a tooltip, or clickability before selecting a submenu item.

// Java: wait until the hover menu is usable
WebElement link = new WebDriverWait(driver, Duration.ofSeconds(10)).until(
    ExpectedConditions.elementToBeClickable(By.cssSelector(".submenu a"))
);
link.click();
# Python: wait until the hover menu is usable
link = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, ".submenu a"))
)
link.click()

If the interface intentionally needs a short pause, Selenium’s Actions API supports pauses in an action sequence. Prefer a condition-based wait when the expected state can be identified; a fixed delay can be too short on a slow run and waste time on a fast one. See the official Actions API guide.

4. Selenium IDE

In Selenium IDE, use the mouse over command with a locator for the target element, then add a wait or assertion for the revealed state. Hover can be difficult to record automatically; Selenium IDE’s FAQ describes adding a Mouse Over step through the recording context menu or inserting a command in the editor. See the command reference and IDE FAQ.

5. Troubleshooting hover actions

Symptom Likely cause What to try
Element not found The locator is wrong, the element has not loaded, or the page is in a different frame. Confirm the locator in the current page state, wait for presence, and switch to the correct frame when needed.
Hover runs but no menu appears The pointer landed on a non-interactive part, the UI needs time, or the component responds to click or focus instead. Try an element-relative offset over the active area. Check the site’s interaction behavior, then wait for the expected state.
Element is obscured or intercepted A sticky header, overlay, animation, or another element covers the target. Wait for the overlay or animation to finish, close the obstruction through the UI, or target the unobstructed part of the element.
Move fails because the target is outside the viewport The page layout or binding/browser behavior prevents movement to the current target. Scroll the element into view, check the viewport and page layout, then retry. Selenium’s mouse guide warns about viewport requirements; the Java reference describes scrolling the element into view, so behavior should not be assumed identical across bindings and browsers.
Submenu disappears before it can be clicked The pointer leaves the hover region while moving from the trigger to the submenu, or the test acts before the menu is ready. Move to the submenu through a pointer path that stays inside the open menu, and wait for the destination to be clickable before clicking.
Test is flaky with a short sleep Page timing varies between runs. Replace the arbitrary sleep with an explicit wait for visibility, enabled state, or another observable result.
JavaScript event dispatch appears to work but the test is misleading Script-dispatched events do not exercise the same virtualized pointer movement as a WebDriver Actions sequence. Use Actions when the requirement is to verify user-like pointer interaction. Use script only when the test specifically concerns application event handling.

For general element interaction constraints, see Selenium’s WebDriver element interaction documentation.

6. Reliability, speed, and test cost

  • Use stable locators. Prefer selectors tied to a durable test attribute or semantic structure over positional selectors that change when layout changes.
  • Wait for outcomes, not elapsed time. An explicit condition documents what the test needs and avoids a fixed delay on every run.
  • Keep the pointer path realistic. For nested menus, moving directly to a distant child can cross a region that closes the menu. Keep the pointer within the active menu path where needed.
  • Account for responsive layout. The same element may move, wrap, or be replaced at different viewport sizes. Set a repeatable window size when layout is part of the test.
  • Do not add unnecessary steps. A single move is enough for a basic hover. Add offsets, pauses, or extra pointer movements only when the application’s behavior calls for them.

Browser automation costs include browser startup and page-load time, plus the maintenance burden of locators and synchronization. Hover itself is one pointer action; the page response and any subsequent wait usually determine how long the test step takes. Selenium’s documentation does not provide a universal hover timing benchmark, so measure in the browser and environment used by your suite.

7. Or skip the browser setup

If your goal is to inspect a page visually rather than test its interactive hover behavior, ScreenshotNeo can return a page screenshot or PDF with one GET request. Its capture is not a replacement for a Selenium hover test: use WebDriver when you need to move a pointer and verify the resulting interaction. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners, newsletter popups, and chat widgets are removed before the screenshot; each cleanup step can be turned off.
  • Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Response headers indicate the page verdict and billing status.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month, with no card.

8. FAQ

Does Selenium hover click the element?

No. Moving to an element with the Actions API moves the pointer; it does not click. Add a separate click action if the test needs one.

Can Selenium hover over an element by its text?

Yes. Locate the element using an appropriate text-based locator for your binding, then pass the resulting element to the Actions API. The hover operation itself takes a WebElement.

Can I test a hover-only menu on a touch device?

A touch interface may not expose hover in the same way as a desktop pointer. Test the interaction supported by the target device and application rather than assuming a hover state exists.