{"record":{"id":"87402e09873b79d1","repo":"grafana/k6","slug":"hovering-on-q-w","errorCode":null,"errorMessage":"hovering on %q: %w","messagePattern":"hovering on %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/locator.go","lineNumber":605,"sourceCode":"\topts.Strict = true\n\tif err := l.frame.typ(l.selector, text, opts); err != nil {\n\t\treturn spanRecordErrorf(span, \"typing %q in %q: %w\", text, l.selector, err)\n\t}\n\n\tapplySlowMo(l.ctx)\n\n\treturn nil\n}\n\n// Hover moves the pointer over the element that matches the locator's\n// selector with strict mode on.\nfunc (l *Locator) Hover(opts *FrameHoverOptions) error {\n\tl.log.Debugf(\"Locator:Hover\", \"fid:%s furl:%q sel:%q opts:%+v\", l.frame.ID(), l.frame.URL(), l.selector, opts)\n\n\topts.Strict = true\n\topts.retry = true\n\tif err := l.frame.hover(l.selector, opts); err != nil {\n\t\treturn fmt.Errorf(\"hovering on %q: %w\", l.selector, err)\n\t}\n\n\tapplySlowMo(l.ctx)\n\n\treturn nil\n}\n\n// Tap the element found that matches the locator's selector with strict mode on.\nfunc (l *Locator) Tap(opts *FrameTapOptions) error {\n\tl.log.Debugf(\"Locator:Tap\", \"fid:%s furl:%q sel:%q opts:%+v\", l.frame.ID(), l.frame.URL(), l.selector, opts)\n\n\topts.Strict = true\n\topts.retry = true\n\tif err := l.frame.tap(l.selector, opts); err != nil {\n\t\treturn fmt.Errorf(\"tapping on %q: %w\", l.selector, err)\n\t}\n\n\tapplySlowMo(l.ctx)","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/locator.go#L587-L623","documentation":"Thrown by Locator.Hover() when the wrapped frame.hover call fails. Strict mode is forced on and the call retries, so the element must resolve to exactly one element and become hoverable (visible, stable, receiving pointer events) before the timeout. Common failures: another element overlays the target and intercepts pointer events, strict-mode violation, or timeout.","triggerScenarios":"locator.hover() where the selector matches 0 or >1 elements; the element is hidden or has zero size; an overlay (cookie banner, spinner, sticky header) covers it so pointer events are intercepted; the element keeps moving (animation) past the timeout.","commonSituations":"Hovering menu items under a sticky navbar or modal overlay; hovering elements inside accordions/tabs that are not yet expanded; CSS animations preventing the stability check.","solutions":["Dismiss or wait for overlays (spinners, banners) to disappear before hovering","Expand the parent container/tab so the element is visible and stable","Use a unique selector matching exactly one element","As a last resort pass force: true in opts to skip actionability checks, or increase timeout"],"exampleFix":"// before\nawait page.locator('.menu-item').hover(); // covered by cookie banner\n\n// after\nconst banner = page.locator('#cookie-banner');\nif (await banner.count()) await banner.locator('button.accept').click();\nawait page.locator('.menu-item').hover();","handlingStrategy":"try-catch","validationCode":"const el = page.locator('a.menu-item');\nawait el.waitFor({ state: 'visible' });\nawait el.hover();","typeGuard":"async function isUnobstructed(page, sel) {\n  const handle = await page.$(sel);\n  if (!handle) return false;\n  const box = await handle.boundingBox();\n  if (!box) return false;\n  const hit = await handle.evaluate((n, x, y) => {\n    const t = document.elementFromPoint(x, y);\n    return !!t && (t === n || n.contains(t));\n  }, box.x + box.width / 2, box.y + box.height / 2);\n  return hit;\n}","tryCatchPattern":"try {\n  await page.locator(sel).hover();\n} catch (e) {\n  if (/intercepts pointer events|not stable|timeout/i.test(e.message)) {\n    await dismissOverlays(page); // app-specific helper\n    await page.locator(sel).hover();\n  } else throw e;\n}","preventionTips":["Dismiss cookie banners/spinners before hover assertions","Disable CSS animations in test builds for stability checks","Prefer locator.hover() over mouse.move()+down for UI elements"],"tags":["browser","locator","hover","pointer-events","strict-mode"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}