grafana/k6 · error
translating point to page
Error message
translating point to page: %w
What it means
Stage of the k6 browser module's pointer-action pipeline for elements inside iframes: translatePointToPage converts the click/tap point from frame-relative to page-relative coordinates when the owning frame has a parent. This error wraps failure of that translation: resolving the owner frame, getting the iframe's FrameElement, or reading that frame element's BoundingBox failed (frame navigated/closed, cross-origin frame access limits, or detached frame element).
Solutions
- Re-acquire the frame chain before acting: page.frame(...) or waitForSelector inside the frame, so owner frames are live.
- Wait for the iframe itself to be visible and settled: ensure the iframe element has a bounding box before acting on its content.
- Retry the action once — iframe navigation races are often transient.
- If the widget navigates predictably (e.g., after an inner click), pair the trigger with waitForNavigation on the frame.
Example fix
// before
const frame = page.frames().find(f => f.name() === 'widget');
const el = await frame.$('#pay');
await el.click(); // widget iframe reloaded mid-action -> translation fails
// after
await page.waitForSelector('iframe[name="widget"]', { state: 'visible' });
const frame = page.frames().find(f => f.name() === 'widget');
const el = await frame.waitForSelector('#pay', { state: 'visible' });
await el.click(); Defensive patterns
Strategy: retry
Validate before calling
const frameEl = await page.waitForSelector('iframe[name="widget"]', { state: 'visible', timeout: '30s' });
const box = await frameEl.boundingBox();
if (!box) { throw new Error('iframe has no bounding box; skip in-frame action'); }
const frame = page.frames().find(f => f.name() === 'widget');
const el = await frame.waitForSelector(sel, { state: 'visible' });
await el.click(); Try / catch
for (let i = 0; i < 2; i++) {
try { await el.click(); break; }
catch (e) {
if (i === 1 || !String(e).includes('translating point to page')) throw e;
// iframe may have navigated: rebuild the frame chain and handle
const frame = page.frames().find(f => f.name() === frameName);
el = await frame.waitForSelector(sel, { state: 'visible' });
}
} Prevention
- Verify the iframe element itself is visible and has a box before acting inside it.
- Rebuild frame references after any in-frame navigation; never cache frames across reloads.
When it happens
Trigger: click()/tap() on elements inside an iframe whose document navigates or is removed between the state checks and the translation; iframes whose bounding box cannot be resolved (hidden iframe, display:none container); nested iframe hierarchies where an intermediate frame detaches.
Common situations: Payment/ad/auth widgets embedded in iframes that reload on their own schedule; tests acting in an iframe right as the host page rerenders the iframe element; iframes hidden via CSS until user action.
Related errors
- checking hit target
- getting element position
- pointer action
- waiting for element state
- Error while parsing selector
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/d1fe663e297e7c13.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:1759
// Get the clickable point
if p != nil {
p, err = h.offsetPosition(apiCtx, opts.Position)
if err != nil {
return nil, fmt.Errorf("getting element position: %w", err)
}
} else {
p, err = h.clickablePoint()
if err != nil {
return nil, fmt.Errorf("pointer action: %w", err)
}
}
// Further translation of the point might be necessary if the point
// is still relative to the parent frame it is in and not the page.
*p, err = h.translatePointToPage(apiCtx, *p)
if err != nil {
return nil, fmt.Errorf("translating point to page: %w", err)
}
// Do a final actionability check to see if element can receive events
// at mouse position in question
if !opts.Force {
if ok, err := h.checkHitTargetAt(apiCtx, *p); !ok {
return nil, fmt.Errorf("checking hit target: %w", err)
}
}
// Are we only "trialing" the action but not actually performing
// it (ie. running the actionability checks).
if opts.Trial {
return nil, nil //nolint:nilnil
}
b := NewBarrier()
h.frame.manager.addBarrier(b)
defer h.frame.manager.removeBarrier(b)View on GitHub (pinned to 3fcf5388d7)