diff --git a/common/frame_session.go b/common/frame_session.go index 32eac456d..f7cef7037 100644 --- a/common/frame_session.go +++ b/common/frame_session.go @@ -259,12 +259,34 @@ func (fs *FrameSession) initEvents() { fs.onAttachedToTarget(ev) case *target.EventDetachedFromTarget: fs.onDetachedFromTarget(ev) + case *cdppage.EventJavascriptDialogOpening: + fs.onEventJavascriptDialogOpening(ev) } } } }() } +func (fs *FrameSession) onEventJavascriptDialogOpening(event *cdppage.EventJavascriptDialogOpening) { + fs.logger.Debugf("FrameSession:onEventJavascriptDialogOpening", + "sid:%v tid:%v url:%v dialogType:%s", + fs.session.ID(), fs.targetID, event.URL, event.Type) + + // Dialog type of beforeunload needs to accept the + // dialog, instead of dismissing it. We're unable to + // dismiss beforeunload dialog boxes at the moment as + // it seems to pause the exec of any other action on + // the page. I believe this is an issue in Chromium. + action := cdppage.HandleJavaScriptDialog(false) + if event.Type == cdppage.DialogTypeBeforeunload { + action = cdppage.HandleJavaScriptDialog(true) + } + + if err := action.Do(cdp.WithExecutor(fs.ctx, fs.session)); err != nil { + fs.logger.Errorf("FrameSession:onEventJavascriptDialogOpening", "failed to dismiss dialog box: %v", err) + } +} + func (fs *FrameSession) initFrameTree() error { fs.logger.Debugf("NewFrameSession:initFrameTree", "sid:%v tid:%v", fs.session.ID(), fs.targetID) diff --git a/tests/frame_test.go b/tests/frame_test.go index 7741feaf7..5de752323 100644 --- a/tests/frame_test.go +++ b/tests/frame_test.go @@ -3,6 +3,8 @@ package tests import ( "testing" + "github.com/dop251/goja" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -21,3 +23,52 @@ func TestFramePress(t *testing.T) { require.Equal(t, "AbC", f.InputValue("#text1", nil)) } + +func TestFrameDismissDialogBox(t *testing.T) { + t.Parallel() + + tests := []string{ + "alert", + "confirm", + "prompt", + "beforeunload", + } + + for _, test := range tests { + t.Run(test, func(t *testing.T) { + t.Parallel() + + b := newTestBrowser(t, withFileServer()) + + p := b.NewPage(nil) + + err := b.await(func() error { + opts := b.toGojaValue(struct { + WaitUntil string `js:"waitUntil"` + }{ + WaitUntil: "networkidle", + }) + pageGoto := p.Goto( + b.staticURL("dialog.html?dialogType="+test), + opts, + ) + b.promise(pageGoto).then(func() *goja.Promise { + if test == "beforeunload" { + return p.Click("#clickHere", nil) + } + + result := p.TextContent("#textField", nil) + assert.EqualValues(t, test+" dismissed", result) + + return nil + }).then(func() { + result := p.TextContent("#textField", nil) + assert.EqualValues(t, test+" dismissed", result) + }) + + return nil + }) + require.NoError(t, err) + }) + } +} diff --git a/tests/static/dialog.html b/tests/static/dialog.html new file mode 100644 index 000000000..24042e6f8 --- /dev/null +++ b/tests/static/dialog.html @@ -0,0 +1,36 @@ + + + +
Hello World
+
+ + + + + \ No newline at end of file