diff --git a/api/frame.go b/api/frame.go index f24a394bb..a8e44acb9 100644 --- a/api/frame.go +++ b/api/frame.go @@ -16,7 +16,7 @@ type Frame interface { EvaluateHandle(pageFunc goja.Value, args ...goja.Value) (JSHandle, error) Fill(selector string, value string, opts goja.Value) Focus(selector string, opts goja.Value) - FrameElement() ElementHandle + FrameElement() (ElementHandle, error) GetAttribute(selector string, name string, opts goja.Value) goja.Value Goto(url string, opts goja.Value) (Response, error) Hover(selector string, opts goja.Value) diff --git a/browser/mapping.go b/browser/mapping.go index b25df0d8e..fb2234080 100644 --- a/browser/mapping.go +++ b/browser/mapping.go @@ -322,9 +322,12 @@ func mapFrame(vu moduleVU, f api.Frame) mapping { }, "fill": f.Fill, "focus": f.Focus, - "frameElement": func() *goja.Object { - eh := mapElementHandle(vu, f.FrameElement()) - return rt.ToValue(eh).ToObject(rt) + "frameElement": func() (mapping, error) { + fe, err := f.FrameElement() + if err != nil { + return nil, err //nolint:wrapcheck + } + return mapElementHandle(vu, fe), nil }, "getAttribute": f.GetAttribute, "goto": func(url string, opts goja.Value) *goja.Promise { diff --git a/common/element_handle.go b/common/element_handle.go index 922ba1ad5..76b456fdc 100644 --- a/common/element_handle.go +++ b/common/element_handle.go @@ -55,7 +55,11 @@ func (h *ElementHandle) boundingBox() (*Rect, error) { y := math.Min(quad[1], math.Min(quad[3], math.Min(quad[5], quad[7]))) width := math.Max(quad[0], math.Max(quad[2], math.Max(quad[4], quad[6]))) - x height := math.Max(quad[1], math.Max(quad[3], math.Max(quad[5], quad[7]))) - y - position := h.frame.position() + + position, err := h.frame.position() + if err != nil { + return nil, err + } return &Rect{X: x + position.X, Y: y + position.Y, Width: width, Height: height}, nil } @@ -63,10 +67,11 @@ func (h *ElementHandle) boundingBox() (*Rect, error) { func (h *ElementHandle) checkHitTargetAt(apiCtx context.Context, point Position) (bool, error) { frame := h.ownerFrame(apiCtx) if frame != nil && frame.parentFrame != nil { - var ( - el = h.frame.FrameElement() - element, ok = el.(*ElementHandle) - ) + el, err := h.frame.FrameElement() + if err != nil { + return false, err + } + element, ok := el.(*ElementHandle) if !ok { return false, fmt.Errorf("unexpected type %T", el) } diff --git a/common/frame.go b/common/frame.go index a4044832f..e16d0d266 100644 --- a/common/frame.go +++ b/common/frame.go @@ -358,17 +358,22 @@ func (f *Frame) onLoadingStopped() { // website never stops performing network requests. } -func (f *Frame) position() *Position { +func (f *Frame) position() (*Position, error) { frame := f.manager.getFrameByID(cdp.FrameID(f.page.targetID)) if frame == nil { - return nil + return nil, fmt.Errorf("could not find frame with id %s", f.page.targetID) } if frame == f.page.frameManager.MainFrame() { - return &Position{X: 0, Y: 0} + return &Position{X: 0, Y: 0}, nil + } + element, err := frame.FrameElement() + if err != nil { + return nil, err } - element := frame.FrameElement() + box := element.BoundingBox() - return &Position{X: box.X, Y: box.Y} + + return &Position{X: box.X, Y: box.Y}, nil } func (f *Frame) removeChildFrame(child *Frame) { @@ -825,14 +830,15 @@ func (f *Frame) focus(selector string, opts *FrameBaseOptions) error { return nil } -func (f *Frame) FrameElement() api.ElementHandle { +// FrameElement returns the element handle for the frame. +func (f *Frame) FrameElement() (api.ElementHandle, error) { f.log.Debugf("Frame:FrameElement", "fid:%s furl:%q", f.ID(), f.URL()) element, err := f.page.getFrameElement(f) if err != nil { - k6ext.Panic(f.ctx, "getting frame element: %w", err) + return nil, fmt.Errorf("getting frame element: %w", err) } - return element + return element, nil } // GetAttribute of the first element found that matches the selector.