grafana/k6 · error

tapping element: %w

Error message

tapping element: %w

What it means

Wrapped failure from ElementHandle.Tap (elementHandle.tap()). Tap is a pointer action built by newPointerAction: scroll into view, actionability checks (visible/stable/enabled), hit-target check, then Touchscreen.tap dispatch. The wrapped error can originate at any of those stages — element not visible or without layout, unstable, intercepted by another element, or the CDP touch-event dispatch itself failing.

Source

Thrown at internal/js/modules/k6/browser/common/element_handle.go:1505

	if !ok {
		return fmt.Errorf("unexpected type %T", result)
	}
	if v != "done" {
		return errorFromDOMError(v)
	}

	return nil
}

// Tap scrolls element into view and taps in the center of the element.
func (h *ElementHandle) Tap(opts *ElementHandleTapOptions) error {
	tap := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {
		return nil, handle.tap(apiCtx, p)
	}
	tapAction := h.newPointerAction(tap, &opts.ElementHandleBasePointerOptions)

	if _, err := call(h.ctx, tapAction, opts.Timeout); err != nil {
		return fmt.Errorf("tapping element: %w", err)
	}

	applySlowMo(h.ctx)

	return nil
}

func (h *ElementHandle) tap(_ context.Context, p *Position) error {
	return h.frame.page.Touchscreen.tap(p.X, p.Y)
}

// TextContent returns the text content of the element.
// The second return value is true if the text content exists, and false otherwise.
func (h *ElementHandle) TextContent() (string, bool, error) {
	textContent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return handle.textContent(apiCtx)
	}
	opts := NewElementHandleBaseOptions(h.DefaultTimeout())

View on GitHub (pinned to 93accf6570)

Solutions

  1. Wait for the element first: page.waitForSelector(sel, { state: 'visible' }) and dismiss any covering overlay
  2. Increase the timeout: el.tap({ timeout: '30s' })
  3. If actionability checks are the blocker and interception is expected, use force: el.tap({ force: true })
  4. If the tap target shifts after scroll, tap at an explicit position: el.tap({ position: { x: 10, y: 10 } })

Example fix

// before
page.$('#btn').tap(); // overlay intercepts the tap

// after
const banner = page.$('#cookie-banner');
if (banner && banner.isVisible()) page.$('#accept').click();
page.waitForSelector('#btn', { state: 'visible' }).tap({ timeout: '20s' });
Defensive patterns

Strategy: try-catch

Validate before calling

const el = page.waitForSelector('#btn', { state: 'visible' });
if (!el.isEnabled()) {
  throw new Error('#btn is disabled; tap would fail actionability');
}

Try / catch

try {
  el.tap({ timeout: '20s' });
} catch (e) {
  const msg = String(e);
  if (msg.includes('intercepting')) {
    page.$('#accept-cookies')?.click();
    el.tap();
  } else if (msg.includes('tapping element')) {
    el.tap({ force: true }); // last resort: skip checks
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Tapping an element covered by an overlay or sticky header (hit-target check fails with 'another element is intercepting with pointer action'); tapping a hidden/display:none element (scroll fails with 'Node does not have a layout object'); continuously animating element never becomes stable; timeout exceeded while retrying pointer checks.

Common situations: Cookie banners or modals covering the tap target; fixed headers intercepting after scrolling; mobile-emulated pages where the target moves on scroll; taps issued on pages without touch handlers so nothing responds as expected.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/5b1b1ac1f1ee4842. Report an issue: GitHub.