don't crash when loading pages with iframes

We broke this in the refactor because of a nil pointer dereference, but
we didn't catch that as none of the tests loaded a page with an iframe.
That is, a page with multiple frames.

Add such a test, and fix the bug by creating an almost-empty frame when
we start receiving events about a new frame before it's navigated to.
This commit is contained in:
Daniel Martí 2019-03-28 21:21:52 +00:00
parent 8ff2971fc5
commit 661ef78880
4 changed files with 36 additions and 6 deletions

View File

@ -211,10 +211,7 @@ func (t *Target) pageEvent(ev interface{}) {
id, op = e.FrameID, frameDetached id, op = e.FrameID, frameDetached
case *page.EventFrameStartedLoading: case *page.EventFrameStartedLoading:
// TODO: this happens before EventFrameNavigated, so the frame id, op = e.FrameID, frameStartedLoading
// isn't in t.frames yet.
//id, op = e.FrameID, frameStartedLoading
return
case *page.EventFrameStoppedLoading: case *page.EventFrameStoppedLoading:
id, op = e.FrameID, frameStoppedLoading id, op = e.FrameID, frameStoppedLoading
@ -237,6 +234,13 @@ func (t *Target) pageEvent(ev interface{}) {
} }
f := t.frames[id] f := t.frames[id]
if f == nil {
// This can happen if a frame is attached or starts loading
// before it's ever navigated to. We won't have all the frame
// details just yet, but that's okay.
f = &cdp.Frame{ID: id}
t.frames[id] = f
}
f.Lock() f.Lock()
defer f.Unlock() defer f.Unlock()

View File

@ -9,6 +9,7 @@ import (
"net/http/httptest" "net/http/httptest"
"strings" "strings"
"testing" "testing"
"time"
"github.com/chromedp/cdproto/emulation" "github.com/chromedp/cdproto/emulation"
"github.com/chromedp/cdproto/page" "github.com/chromedp/cdproto/page"
@ -345,3 +346,19 @@ func TestTitle(t *testing.T) {
t.Fatalf("expected title to be %s, got: %s", exptitle, title) t.Fatalf("expected title to be %s, got: %s", exptitle, title)
} }
} }
func TestLoadIframe(t *testing.T) {
t.Parallel()
ctx, cancel := testAllocate(t, "iframe.html")
defer cancel()
if err := Run(ctx, Tasks{
// TODO: remove the sleep once we have better support for
// iframes.
Sleep(10 * time.Millisecond),
//WaitVisible(`#form`, ByID), // for the nested form.html
}); err != nil {
t.Fatal(err)
}
}

9
testdata/iframe.html vendored Normal file
View File

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<title>page with an iframe</title>
</head>
<body>
<iframe src="form.html"></iframe>
</body>
</html>

View File

@ -37,9 +37,9 @@ func frameDetached(f *cdp.Frame) {
clearFrameState(f, cdp.FrameAttached) clearFrameState(f, cdp.FrameAttached)
} }
/*func frameStartedLoading(f *cdp.Frame) { func frameStartedLoading(f *cdp.Frame) {
setFrameState(f, cdp.FrameLoading) setFrameState(f, cdp.FrameLoading)
}*/ }
func frameStoppedLoading(f *cdp.Frame) { func frameStoppedLoading(f *cdp.Frame) {
clearFrameState(f, cdp.FrameLoading) clearFrameState(f, cdp.FrameLoading)