Bug 1477977 - [marionette] Handle "tabmodal-dialog-loaded" to observe new tab modal dialogs. r=maja_zf
authorHenrik Skupin <mail@hskupin.info>
Fri, 07 Jun 2019 18:36:48 +0000
changeset 541573 e9e20d087e338275a4ceae79e91d7a8e2f882f91
parent 541572 09614cb3a896ab3be71ccc44d7663eb5454cf5cf
child 541574 5d6397e990cbc374be49baaa4fc6622dfed18119
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmaja_zf
bugs1477977
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1477977 - [marionette] Handle "tabmodal-dialog-loaded" to observe new tab modal dialogs. r=maja_zf Differential Revision: https://phabricator.services.mozilla.com/D34138
testing/marionette/driver.js
testing/marionette/proxy.js
testing/web-platform/tests/webdriver/tests/accept_alert/accept.py
testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py
testing/web-platform/tests/webdriver/tests/get_alert_text/get.py
testing/web-platform/tests/webdriver/tests/send_alert_text/send.py
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -146,17 +146,17 @@ this.GeckoDriver = function(server) {
   this.capabilities = new Capabilities();
 
   this.mm = globalMessageManager;
   this.listener = proxy.toListener(
       this.sendAsync.bind(this), () => this.curBrowser);
 
   // points to an alert instance if a modal dialog is present
   this.dialog = null;
-  this.dialogHandler = this.globalModalDialogHandler.bind(this);
+  this.dialogHandler = this.modalDialogHandler.bind(this);
 };
 
 Object.defineProperty(GeckoDriver.prototype, "a11yChecks", {
   get() {
     return this.capabilities.get("moz:accessibilityChecks");
   },
 });
 
@@ -299,23 +299,27 @@ GeckoDriver.prototype.uninit = function(
   this.mm.removeMessageListener("Marionette:Register", this);
   this.mm.removeMessageListener("Marionette:switchedToFrame", this);
 };
 
 /**
  * Callback used to observe the creation of new modal or tab modal dialogs
  * during the session's lifetime.
  */
-GeckoDriver.prototype.globalModalDialogHandler = function(subject, topic) {
-  let winr;
-  if (topic === modal.COMMON_DIALOG_LOADED) {
-    // Always keep a weak reference to the current dialog
-    winr = Cu.getWeakReference(subject);
+GeckoDriver.prototype.modalDialogHandler = function(subject, topic) {
+  logger.trace(`Received observer notification ${topic}`);
+
+  switch (topic) {
+    case modal.COMMON_DIALOG_LOADED:
+    case modal.TABMODAL_DIALOG_LOADED:
+      // Always keep a weak reference to the current dialog
+      let winRef = Cu.getWeakReference(subject);
+      this.dialog = new modal.Dialog(() => this.curBrowser, winRef);
+      break;
   }
-  this.dialog = new modal.Dialog(() => this.curBrowser, winr);
 };
 
 /**
  * Helper method to send async messages to the content listener.
  * Correct usage is to pass in the name of a function in listener.js,
  * a serialisable object, and optionally the current command's ID
  * when not using the modern dispatching technique.
  *
--- a/testing/marionette/proxy.js
+++ b/testing/marionette/proxy.js
@@ -160,18 +160,16 @@ proxy.AsyncMessageChannel = class {
         this.removeHandlers();
         resolve();
       };
 
       // A modal or tab modal dialog has been opened. To be able to handle it,
       // the active command has to be aborted. Therefore remove all handlers,
       // and cancel any ongoing requests in the listener.
       this.dialogueObserver_ = (subject, topic) => {
-        log.trace(`Received observer notification ${topic}`);
-
         this.removeAllListeners_();
         // TODO(ato): It's not ideal to have listener specific behaviour here:
         this.sendAsync("cancelRequest");
 
         this.removeHandlers();
         resolve();
       };
 
--- a/testing/web-platform/tests/webdriver/tests/accept_alert/accept.py
+++ b/testing/web-platform/tests/webdriver/tests/accept_alert/accept.py
@@ -1,10 +1,13 @@
+from webdriver.error import NoSuchAlertException
+
 from tests.support.asserts import assert_error, assert_success
 from tests.support.inline import inline
+from tests.support.sync import Poll
 
 
 def accept_alert(session):
     return session.transport.send(
         "POST", "session/{session_id}/alert/accept".format(**vars(session)))
 
 
 def test_null_response_value(session, url):
@@ -38,8 +41,21 @@ def test_accept_confirm(session):
     assert session.execute_script("return window.result") is True
 
 
 def test_accept_prompt(session):
     session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Federer');</script>")
     response = accept_alert(session)
     assert_success(response)
     assert session.execute_script("return window.result") == "Federer"
+
+
+def test_unexpected_alert(session):
+    session.execute_script("window.setTimeout(function() { window.alert('Hello'); }, 100);")
+    wait = Poll(
+        session,
+        timeout=5,
+        ignored_exceptions=NoSuchAlertException,
+        message="No user prompt with text 'Hello' detected")
+    wait.until(lambda s: s.alert.text == "Hello")
+
+    response = accept_alert(session)
+    assert_success(response)
--- a/testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py
+++ b/testing/web-platform/tests/webdriver/tests/dismiss_alert/dismiss.py
@@ -1,10 +1,13 @@
+from webdriver.error import NoSuchAlertException
+
 from tests.support.asserts import assert_error, assert_success
 from tests.support.inline import inline
+from tests.support.sync import Poll
 
 
 def dismiss_alert(session):
     return session.transport.send(
         "POST", "session/{session_id}/alert/dismiss".format(**vars(session)))
 
 
 def test_null_response_value(session, url):
@@ -38,8 +41,21 @@ def test_dismiss_confirm(session):
     assert session.execute_script("return window.result;") is False
 
 
 def test_dismiss_prompt(session):
     session.url = inline("<script>window.result = window.prompt('Enter Your Name: ', 'Federer');</script>")
     response = dismiss_alert(session)
     assert_success(response)
     assert session.execute_script("return window.result") is None
+
+
+def test_unexpected_alert(session):
+    session.execute_script("setTimeout(function() { alert('Hello'); }, 100);")
+    wait = Poll(
+        session,
+        timeout=5,
+        ignored_exceptions=NoSuchAlertException,
+        message="No user prompt with text 'Hello' detected")
+    wait.until(lambda s: s.alert.text == "Hello")
+
+    response = dismiss_alert(session)
+    assert_success(response)
--- a/testing/web-platform/tests/webdriver/tests/get_alert_text/get.py
+++ b/testing/web-platform/tests/webdriver/tests/get_alert_text/get.py
@@ -1,10 +1,13 @@
+from webdriver.error import NoSuchAlertException
+
 from tests.support.asserts import assert_error, assert_success
 from tests.support.inline import inline
+from tests.support.sync import Poll
 
 
 def get_alert_text(session):
     return session.transport.send(
         "GET", "session/{session_id}/alert/text".format(**vars(session)))
 
 
 def test_no_browsing_context(session, closed_window):
@@ -43,8 +46,21 @@ def test_get_prompt_text(session):
     session.url = inline("<script>window.prompt('Enter Your Name: ', 'Federer');</script>")
     response = get_alert_text(session)
     assert_success(response)
     assert isinstance(response.body, dict)
     assert "value" in response.body
     prompt_text = response.body["value"]
     assert isinstance(prompt_text, basestring)
     assert prompt_text == "Enter Your Name: "
+
+
+def test_unexpected_alert(session):
+    session.execute_script("setTimeout(function() { alert('Hello'); }, 100);")
+    wait = Poll(
+        session,
+        timeout=5,
+        ignored_exceptions=NoSuchAlertException,
+        message="No user prompt with text 'Hello' detected")
+    wait.until(lambda s: s.alert.text == "Hello")
+
+    response = get_alert_text(session)
+    assert_success(response)
--- a/testing/web-platform/tests/webdriver/tests/send_alert_text/send.py
+++ b/testing/web-platform/tests/webdriver/tests/send_alert_text/send.py
@@ -1,15 +1,17 @@
 import pytest
 
+from webdriver.error import NoSuchAlertException
 from webdriver.transport import Response
 
 from tests.support.asserts import assert_error, assert_success
 from tests.support.authentication import basic_authentication
 from tests.support.inline import inline
+from tests.support.sync import Poll
 
 
 @pytest.fixture
 def page(session):
     session.url = inline("""
         <script>window.result = window.prompt('Enter Your Name: ', 'Name');</script>
     """)
 
@@ -66,8 +68,21 @@ def test_alert_unsupported_operation(ses
 @pytest.mark.parametrize("text", ["", "Federer", " Fed erer ", "Fed\terer"])
 def test_send_alert_text(session, page, text):
     send_response = send_alert_text(session, text)
     assert_success(send_response)
 
     session.alert.accept()
 
     assert session.execute_script("return window.result") == text
+
+
+def test_unexpected_alert(session):
+    session.execute_script("setTimeout(function() { prompt('Hello'); }, 100);")
+    wait = Poll(
+        session,
+        timeout=5,
+        ignored_exceptions=NoSuchAlertException,
+        message="No user prompt with text 'Hello' detected")
+    wait.until(lambda s: s.alert.text == "Hello")
+
+    response = send_alert_text(session, "Federer")
+    assert_success(response)