{"record":{"id":"ad0b41a2bb231f08","repo":"grafana/k6","slug":"finding-position-in-frame-w","errorCode":null,"errorMessage":"finding position in frame: %w","messagePattern":"finding position in frame: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/frame.go","lineNumber":388,"sourceCode":"\t//       website never stops performing network requests.\n}\n\nfunc (f *Frame) position() (*Position, error) {\n\tframe, ok := f.manager.getFrameByID(cdp.FrameID(f.page.targetID))\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"could not find frame with id %s\", f.page.targetID)\n\t}\n\tif frame == f.page.frameManager.MainFrame() {\n\t\treturn &Position{X: 0, Y: 0}, nil\n\t}\n\telement, err := frame.FrameElement()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbox, err := element.BoundingBox()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"finding position in frame: %w\", err)\n\t}\n\n\treturn &Position{X: box.X, Y: box.Y}, nil\n}\n\nfunc (f *Frame) removeChildFrame(child *Frame) {\n\tf.log.Debugf(\"Frame:removeChildFrame\", \"fid:%s furl:%q cfid:%s curl:%q\",\n\t\tf.ID(), f.URL(), child.ID(), child.URL())\n\n\tf.childFramesMu.Lock()\n\tdefer f.childFramesMu.Unlock()\n\n\tdelete(f.childFrames, child)\n}\n\nfunc (f *Frame) setContext(world executionWorld, execCtx frameExecutionContext) {\n\tf.executionContextMu.Lock()\n\tdefer f.executionContextMu.Unlock()","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/frame.go#L370-L406","documentation":"After resolving the frame, Frame.position obtains the frame element (the <iframe> in the parent document) and asks for its bounding box; a failure there is wrapped as 'finding position in frame'. It occurs while computing coordinates for pointer actions on elements inside child frames, and means the iframe's box could not be determined.","triggerScenarios":"Clicking/hovering elements inside an iframe that is hidden (display:none) or zero-sized; the iframe removed from the parent DOM between action start and box calculation; collapsed or scrolled-out iframes where Chrome cannot produce a box.","commonSituations":"Lazy-loaded iframes not yet visible; ad/consent iframes that get removed mid-action; responsive layouts collapsing the iframe at small viewports.","solutions":["Ensure the iframe is visible and non-zero-sized before interacting inside it (waitForSelector with state:'visible' on the iframe element)","Scroll the iframe into view first","Set a realistic viewport if responsive CSS hides the frame","Retry after the frame becomes visible"],"exampleFix":"// before\nconst frame = page.frames().find(f => f.name() === 'widget');\nawait frame.click('#inside');\n\n// after\nawait page.waitForSelector('iframe[name=widget]', { state: 'visible' });\nconst frame = page.frames().find(f => f.name() === 'widget');\nawait frame.click('#inside');","handlingStrategy":"validation","validationCode":"const fh = await page.waitForSelector('iframe[name=widget]', { state: 'visible' });\nconst box = await fh.boundingBox();\nif (!box || box.width === 0 || box.height === 0) throw new Error('iframe not visible or zero-size');\nawait frame.click('#inside');","typeGuard":null,"tryCatchPattern":"try {\n  await frame.click('#inside');\n} catch (e) {\n  if (/finding position in frame/.test(e.message)) {\n    // make the iframe visible/attached, then retry\n  } else throw e;\n}","preventionTips":["Wait for iframes to be visible before acting inside them","Check boundingBox is non-zero for frames used in pointer actions","Keep viewport sizes realistic so responsive CSS does not collapse frames"],"tags":["browser","iframe","frame","visibility"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}