Use await page.locator(selector).hover() to move Puppeteer’s mouse over a DOM element, or await page.mouse.move(x, y) to move it to a specific point. Locator hover is the direct choice for an element; coordinate movement is for tasks that need a precise position or lower-level mouse control.
Hover over an element with a locator
Puppeteer’s interaction guide recommends locators for selecting and interacting with page elements. A locator’s hover() waits for the target to be ready: it checks that the element is in the viewport and visible, and that its bounding box stays stable across two consecutive animation frames before acting. Locator actions can retry when a target is not ready.
await page.locator('button').hover();
Replace button with a selector for the element you want to hover. This is usually preferable to calculating coordinates yourself when the target is known by its place in the page’s DOM. See Puppeteer’s page interactions guide.
Use the page-level hover shortcut
page.hover(selector) is another selector-based option. It scrolls the matched element into view if needed and hovers over its center. If multiple elements match, it uses the first; if none match, the call rejects.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
await page.hover('button');
Use this shortcut when its first-match behavior is suitable. If the selector can match multiple elements and you need a particular one, make the selector more specific or use a locator that identifies the intended target. See the Page.hover() API reference.
Move the mouse to a viewport coordinate
For a point rather than an element, call page.mouse.move(x, y). The coordinates are main-frame CSS pixels measured from the viewport’s top-left corner: x is horizontal and y is vertical.
Rank #2
await page.mouse.move(250, 120);
The optional steps setting controls how many intermediate movements Puppeteer makes between the current mouse position and the destination. It defaults to 1.
await page.mouse.move(250, 120, { steps: 10 });
More steps can be useful when a task depends on movement along a path rather than simply arriving at a point. They do not make Puppeteer’s synthetic mouse events identical to input from physical hardware. See Mouse.move() and the Mouse class reference.
Calculate a point from an element’s bounding box
If you need coordinate-based movement to an element, get its bounding box and calculate a point inside it. The box is relative to the main frame. Check for null before using it: Puppeteer returns null when an element is not part of layout, such as when it has display: none.
const box = await element.boundingBox();
if (!box) {
throw new Error('Element has no layout box');
}
await page.mouse.move(
box.x + box.width / 2,
box.y + box.height / 2,
);
This moves to the center of the box. If a center point is unsuitable for the interaction, choose another point within the box. When you only need to hover the element, locator hover avoids managing the bounding box and coordinates yourself. See ElementHandle.boundingBox().
Rank #4
Choose the right method
| Need | Use | What to account for |
|---|---|---|
| Hover a DOM element | page.locator(selector).hover() |
Locator readiness checks handle viewport presence, visibility, and a stable bounding box. |
| Hover a selector match using the page shortcut | page.hover(selector) |
Scrolls into view and targets the center; uses the first match and rejects if there is no match. |
| Move to a known viewport point | page.mouse.move(x, y) |
Coordinates are main-frame CSS pixels from the viewport’s top-left; readiness and target selection are up to your code. |
| Move to a point derived from an element | boundingBox() followed by page.mouse.move() |
Check for a null box and choose a point within it. |
Troubleshoot failed or misplaced movement
- The locator hover does not complete: confirm the selector identifies the intended element and that it becomes visible and stable. Locator hover waits for those conditions; a hidden or continually moving target may not become ready.
page.hover()rejects: the selector may have no match. Check the selector against the current page, and make it specific if several elements match and the first is not the intended target.- The bounding-box code throws the layout error: the element may not be in layout, including because it is
display: none. Make it part of the layout before requesting a box, then check again. - The mouse lands at the wrong place: use viewport-relative main-frame CSS pixels, not screen coordinates. If deriving the point from an element, use its bounding box and confirm the chosen point is inside it.
- A hover effect does not behave like a person’s mouse: Puppeteer dispatches synthetic
MouseEvents; these do not fully replicate everything physical mouse input can do.
Or skip the browser setup
If your goal is a screenshot rather than controlling a Puppeteer session, ScreenshotNeo can return an image or PDF with one GET request. For example, using cURL:
Quick Recap
Best Value
- Used Book in Good Condition
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for its request options. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use screenshot tools, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free and get 1,000 screenshots a month with no card.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

