{"record":{"id":"af156028f788e1ef","repo":"grafana/k6","slug":"hovering-on-element-w","errorCode":null,"errorMessage":"hovering on element: %w","messagePattern":"hovering on element: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":978,"sourceCode":"\ts, ok := v.(string)\n\tif !ok {\n\t\treturn \"\", false, fmt.Errorf(\n\t\t\t\"getting attribute %q of element: unexpected type %T (expecting string)\",\n\t\t\tname, v,\n\t\t)\n\t}\n\n\treturn s, true, nil\n}\n\n// Hover scrolls element into view and hovers over its center point.\nfunc (h *ElementHandle) Hover(opts *ElementHandleHoverOptions) error {\n\thover := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {\n\t\treturn nil, handle.hover(apiCtx, p)\n\t}\n\thoverAction := h.newPointerAction(hover, &opts.ElementHandleBasePointerOptions)\n\tif _, err := call(h.ctx, hoverAction, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"hovering on element: %w\", err)\n\t}\n\n\tapplySlowMo(h.ctx)\n\n\treturn nil\n}\n\n// InnerHTML returns the inner HTML of the element.\nfunc (h *ElementHandle) InnerHTML() (string, error) {\n\tinnerHTML := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn handle.innerHTML(apiCtx)\n\t}\n\topts := NewElementHandleBaseOptions(h.DefaultTimeout())\n\tinnerHTMLAction := h.newAction(\n\t\t[]string{}, innerHTML, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,\n\t)\n\tv, err := call(h.ctx, innerHTMLAction, opts.Timeout)\n\tif err != nil {","sourceCodeStart":960,"sourceCodeEnd":996,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L960-L996","documentation":"Returned by ElementHandle.hover() when the pointer action fails. Hover is a pointer action: before moving the mouse, k6 waits for the element to be visible, stable (not animating), and to actually receive pointer events at the hover point. Any of those checks timing out, a stale handle, or a CDP error is wrapped with %w here.","triggerScenarios":"Hovering a hidden element; hovering an element that is still animating/moving so it never becomes 'stable'; another element (sticky header, cookie banner, overlay) intercepting pointer events at the target point; a stale handle after re-render; a Position option that lands outside the element.","commonSituations":"Hover menus that only open after another hover (element not yet visible); CSS transitions that never settle (infinite animation); fixed/sticky headers covering the target in small viewports; SPAs re-rendering between query and hover.","solutions":["Open the parent menu / wait for visibility first: page.waitForSelector(sel, { state: 'visible' })","Disable or settle CSS animations before hovering (inject a style rule or wait for the transition to end)","Use { force: true } when an overlay legitimately covers the element and you just need the mouse move","Pass an explicit { timeout: ms } larger than the animation duration","Re-query the handle right before hover to avoid staleness"],"exampleFix":"// before\nawait page.hover('#menu-item');\n// after\nawait page.waitForSelector('#menu-item', { state: 'visible' });\nawait page.hover('#menu-item', { timeout: 10000 });\n// or, when an overlay intentionally covers the item\nawait page.hover('#menu-item', { force: true });","handlingStrategy":"try-catch","validationCode":"const sel = '#menu-item';\nawait page.waitForSelector(sel, { state: 'visible', timeout: 5000 });\nconst visible = await (await page.$(sel)).isVisible();\nif (visible) {\n  await page.hover(sel, { timeout: 10000 });\n}","typeGuard":null,"tryCatchPattern":"try {\n  await handle.hover();\n} catch (e) {\n  if (String(e).includes('hovering on element')) {\n    await page.waitForSelector(sel, { state: 'visible' });\n    await page.hover(sel, { force: true });\n  } else {\n    throw e;\n  }\n}","preventionTips":["Open parent menus before hovering children","Settle or disable CSS animations before pointer actions","Account for sticky headers/overlays covering the hover point","Pass a timeout sized to the longest transition"],"tags":["browser","element-handle","hover","pointer-events","timeout"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}