{"record":{"id":"5b1b1ac1f1ee4842","repo":"grafana/k6","slug":"tapping-element-w","errorCode":null,"errorMessage":"tapping element: %w","messagePattern":"tapping element: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1509,"sourceCode":"\tif !ok {\n\t\treturn fmt.Errorf(\"unexpected type %T\", result)\n\t}\n\tif v != \"done\" {\n\t\treturn errorFromDOMError(v)\n\t}\n\n\treturn nil\n}\n\n// Tap scrolls element into view and taps in the center of the element.\nfunc (h *ElementHandle) Tap(opts *ElementHandleTapOptions) error {\n\ttap := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {\n\t\treturn nil, handle.tap(apiCtx, p)\n\t}\n\ttapAction := h.newPointerAction(tap, &opts.ElementHandleBasePointerOptions)\n\n\tif _, err := call(h.ctx, tapAction, opts.Timeout); err != nil {\n\t\treturn fmt.Errorf(\"tapping element: %w\", err)\n\t}\n\n\tapplySlowMo(h.ctx)\n\n\treturn nil\n}\n\nfunc (h *ElementHandle) tap(_ context.Context, p *Position) error {\n\treturn h.frame.page.Touchscreen.tap(p.X, p.Y)\n}\n\n// TextContent returns the text content of the element.\n// The second return value is true if the text content exists, and false otherwise.\nfunc (h *ElementHandle) TextContent() (string, bool, error) {\n\ttextContent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn handle.textContent(apiCtx)\n\t}\n\topts := NewElementHandleBaseOptions(h.DefaultTimeout())","sourceCodeStart":1491,"sourceCodeEnd":1527,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/browser/common/element_handle.go#L1491-L1527","documentation":"Thrown by the k6 browser module's ElementHandle.tap(). It wraps the whole pointer-action pipeline: scrolling the element into view, actionability checks (visible/stable/enabled), computing the tap point, hit-target verification, and finally Touchscreen.tap at the page level. Any stage failure — timeout, detached element, or 'another element is intercepting pointer action' (error:intercept) — surfaces wrapped in this message.","triggerScenarios":"Calling el.tap() when the browser context was launched without touch support enabled (hasTouch not set), so tap events misbehave; an overlay (cookie banner, modal backdrop) covering the element; element hidden/animating past the timeout; element detached by rerender.","commonSituations":"Testing mobile flows on a desktop-launched context without the hasTouch browser option; cookie-consent or chat-widget overlays intercepting the tap point; sticky headers covering the target after scroll.","solutions":["Launch the browser with touch enabled: const context = await browser.newContext({ hasTouch: true, viewport: { width: 390, height: 844 } }) and prefer page.tap or locator-based tap.","Dismiss blocking overlays first (cookie banner, modal) or wait for them to disappear before tapping.","Increase the timeout: el.tap({ timeout: '60s' }).","Use { position: { x, y } } to tap a part of the element not covered by the overlay, or { force: true } as a last resort.","Re-query the element to get a fresh attached handle."],"exampleFix":"// before\nconst el = await page.$('#menu-item');\nawait el.tap(); // intercepting overlay or no touch emulation\n\n// after\nconst context = await browser.newContext({ hasTouch: true, viewport: { width: 390, height: 844 } });\nconst page = await context.newPage();\nawait page.click('#cookie-accept', { timeout: '5s' }).catch(() => {});\nconst el = await page.waitForSelector('#menu-item', { state: 'visible' });\nawait el.tap({ timeout: '30s' });","handlingStrategy":"try-catch","validationCode":"const context = await browser.newContext({ hasTouch: true, viewport: { width: 390, height: 844 } });\nconst visible = await el.isVisible().catch(() => false);\nif (visible) { await el.tap({ timeout: '30s' }); }","typeGuard":null,"tryCatchPattern":"try {\n  await el.tap({ timeout: '30s' });\n} catch (e) {\n  if (String(e).includes('intercept')) {\n    await page.click('#cookie-accept').catch(() => {});\n    await el.tap({ timeout: '30s' });\n  } else { throw e; }\n}","preventionTips":["Create the context with hasTouch:true before scripting tap flows.","Dismiss known overlays (cookie banners, chat widgets) at test start as a standard step.","Prefer page.tap/locator APIs over raw ElementHandle so auto-waiting applies."],"tags":["k6","browser","element-handle","tap","touch","actionability"],"backgroundTag":"click-intercepted","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}