From bc1ac57af96075f506a0f6515fd6ab4046b938f6 Mon Sep 17 00:00:00 2001 From: Paul Cento Date: Wed, 11 Jan 2023 14:04:24 -0500 Subject: [PATCH 1/4] Element.ShadowRoot returns an error when ShadowRoots slice is empty --- element.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/element.go b/element.go index f6d6e684..f5920682 100644 --- a/element.go +++ b/element.go @@ -17,6 +17,10 @@ import ( "github.com/go-rod/rod/lib/utils" ) +var ( + ErrNoShadowRoot = errors.New("element has no shadow root") +) + // Element implements these interfaces var _ proto.Client = &Element{} var _ proto.Contextable = &Element{} @@ -402,6 +406,9 @@ func (el *Element) ShadowRoot() (*Element, error) { } // though now it's an array, w3c changed the spec of it to be a single. + if len(node.ShadowRoots) == 0 { + return nil, ErrNoShadowRoot + } id := node.ShadowRoots[0].BackendNodeID shadowNode, err := proto.DOMResolveNode{BackendNodeID: id}.Call(el) From 384b638bd16b2c0afed51027fa4d4628d6283558 Mon Sep 17 00:00:00 2001 From: Paul Cento Date: Wed, 11 Jan 2023 14:24:33 -0500 Subject: [PATCH 2/4] comment exported ErrNoShadowRoot --- element.go | 1 + 1 file changed, 1 insertion(+) diff --git a/element.go b/element.go index f5920682..420e32c5 100644 --- a/element.go +++ b/element.go @@ -18,6 +18,7 @@ import ( ) var ( + // ErrNoShadowRoot is calling ShadowRoot on an Element with no shadow root ErrNoShadowRoot = errors.New("element has no shadow root") ) From 618facbab14c116e87e257751615f095b0f850c7 Mon Sep 17 00:00:00 2001 From: Paul Cento Date: Thu, 12 Jan 2023 12:06:07 -0500 Subject: [PATCH 3/4] unit test shadow root error --- element.go | 7 +------ element_test.go | 4 ++++ error.go | 13 +++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/element.go b/element.go index 420e32c5..7d1e7da0 100644 --- a/element.go +++ b/element.go @@ -17,11 +17,6 @@ import ( "github.com/go-rod/rod/lib/utils" ) -var ( - // ErrNoShadowRoot is calling ShadowRoot on an Element with no shadow root - ErrNoShadowRoot = errors.New("element has no shadow root") -) - // Element implements these interfaces var _ proto.Client = &Element{} var _ proto.Contextable = &Element{} @@ -408,7 +403,7 @@ func (el *Element) ShadowRoot() (*Element, error) { // though now it's an array, w3c changed the spec of it to be a single. if len(node.ShadowRoots) == 0 { - return nil, ErrNoShadowRoot + return nil, &ErrNoShadowRoot{el} } id := node.ShadowRoots[0].BackendNodeID diff --git a/element_test.go b/element_test.go index d560eec0..6cd28d89 100644 --- a/element_test.go +++ b/element_test.go @@ -284,6 +284,10 @@ func TestShadowDOM(t *testing.T) { g.mc.stubErr(1, proto.DOMResolveNode{}) el.MustShadowRoot() }) + + elNoShadow := p.MustElement("script") + _, err := elNoShadow.ShadowRoot() + g.True((&rod.ErrNoShadowRoot{}).Is(err)) } func TestInputTime(t *testing.T) { diff --git a/error.go b/error.go index 400e0f1a..ec926551 100644 --- a/error.go +++ b/error.go @@ -181,3 +181,16 @@ type ErrPageNotFound struct { func (e *ErrPageNotFound) Error() string { return "cannot find page" } + +// ErrNoShadowRoot error +type ErrNoShadowRoot struct { + *Element +} + +// Error ... +func (e *ErrNoShadowRoot) Error() string { + return fmt.Sprintf("element has no shadow root: %s", e.String()) +} + +// Is interface +func (e *ErrNoShadowRoot) Is(err error) bool { _, ok := err.(*ErrNoShadowRoot); return ok } From 9fb3b5df2fa1622876b06566def1ad4043200456 Mon Sep 17 00:00:00 2001 From: Paul Cento Date: Fri, 13 Jan 2023 17:32:35 -0500 Subject: [PATCH 4/4] test shadow root error contains correct error message --- element_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/element_test.go b/element_test.go index 6cd28d89..7dff62bd 100644 --- a/element_test.go +++ b/element_test.go @@ -288,6 +288,7 @@ func TestShadowDOM(t *testing.T) { elNoShadow := p.MustElement("script") _, err := elNoShadow.ShadowRoot() g.True((&rod.ErrNoShadowRoot{}).Is(err)) + g.Has(err.Error(), "element has no shadow root:") } func TestInputTime(t *testing.T) {