grafana/k6 · error

tapping on %q: %w

Error message

tapping on %q: %w

What it means

Thrown by Locator.Tap() when the wrapped frame.tap call fails. Strict mode is forced on and the call retries; the element must resolve to exactly one element and be tap-able (visible, stable, receiving touch events) before the timeout. Failures mirror hover: overlay intercepting pointer events, strict-mode violation, hidden/unstable element, or timeout.

Source

Thrown at internal/js/modules/k6/browser/common/locator.go:620

	opts.Strict = true
	opts.retry = true
	if err := l.frame.hover(l.selector, opts); err != nil {
		return fmt.Errorf("hovering on %q: %w", l.selector, err)
	}

	applySlowMo(l.ctx)

	return nil
}

// Tap the element found that matches the locator's selector with strict mode on.
func (l *Locator) Tap(opts *FrameTapOptions) error {
	l.log.Debugf("Locator:Tap", "fid:%s furl:%q sel:%q opts:%+v", l.frame.ID(), l.frame.URL(), l.selector, opts)

	opts.Strict = true
	opts.retry = true
	if err := l.frame.tap(l.selector, opts); err != nil {
		return fmt.Errorf("tapping on %q: %w", l.selector, err)
	}

	applySlowMo(l.ctx)

	return nil
}

// DispatchEvent dispatches an event for the element matching the
// locator's selector with strict mode on.
func (l *Locator) DispatchEvent(typ string, eventInit any, opts *FrameDispatchEventOptions) error {
	l.log.Debugf(
		"Locator:DispatchEvent", "fid:%s furl:%q sel:%q typ:%q eventInit:%+v opts:%+v",
		l.frame.ID(), l.frame.URL(), l.selector, typ, eventInit, opts,
	)

	opts.Strict = true
	if err := l.frame.dispatchEvent(l.selector, typ, eventInit, opts); err != nil {
		return fmt.Errorf("dispatching locator event %q to %q: %w", typ, l.selector, err)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Make the target visible and unobstructed (close overlays, expand panels)
  2. Use a unique selector matching exactly one element
  3. Scroll the element into view and wait for stability before tapping
  4. Pass force: true in opts to bypass actionability checks if interception is expected

Example fix

// before
await page.locator('button.submit').tap(); // overlay intercepts touch

// after
await page.locator('button.submit').waitFor();
await page.locator('.modal-backdrop').click({ force: true }); // dismiss overlay
await page.locator('button.submit').tap();
Defensive patterns

Strategy: try-catch

Validate before calling

const el = page.locator('button.submit');
await el.waitFor({ state: 'visible' });
await el.tap();

Type guard

async function isTappable(page, sel) {
  const handle = await page.$(sel);
  if (!handle) return false;
  const style = await handle.evaluate(n => getComputedStyle(n));
  return style.pointerEvents !== 'none' && style.visibility !== 'hidden';
}

Try / catch

try {
  await page.locator(sel).tap();
} catch (e) {
  if (/intercepts pointer events|timeout/i.test(e.message)) {
    await page.locator(sel).tap({ force: true });
  } else throw e;
}

Prevention

When it happens

Trigger: locator.tap() where the selector matches 0 or >1 elements; an element with pointer-events: none or covered by an overlay; element not visible or still animating past the timeout.

Common situations: Mobile-viewport tests tapping buttons under fixed footers or banners; tapping inside unexpanded panels; tests that assume touch works on desktop-like pages where the target is tiny or off-screen.

Related errors


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