Bug 1487358 - [marionette] "Accept Alert" and "Dismiss Alert" should check for remaining user prompts. r=webdriver-reviewers,maja_zf
authorHenrik Skupin <mail@hskupin.info>
Fri, 14 Jun 2019 11:17:30 +0000
changeset 479082 9c28135106d340f316c993001643507b47b39f75
parent 479081 ffde7e3218fb941ac17bd3a9b154965635f863dd
child 479083 64f906609a52251f39b6c6d0202f7ad47fe5a37e
push id113460
push userbtara@mozilla.com
push dateMon, 17 Jun 2019 21:43:26 +0000
treeherdermozilla-inbound@40c99f4752f9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswebdriver-reviewers, maja_zf
bugs1487358, 1477977
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 1487358 - [marionette] "Accept Alert" and "Dismiss Alert" should check for remaining user prompts. r=webdriver-reviewers,maja_zf Workaround until we have a sane dynamic user prompt implementation (see bug 1477977). At least for now this patch will give us the opportunity to handle multiple open user prompts. Differential Revision: https://phabricator.services.mozilla.com/D32666
testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
@@ -1,234 +1,198 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
 from __future__ import absolute_import
 
 from marionette_driver.by import By
 from marionette_driver.expected import element_present
 from marionette_driver import errors
 from marionette_driver.marionette import Alert
 from marionette_driver.wait import Wait
 
-from marionette_harness import MarionetteTestCase, WindowManagerMixin
+from marionette_harness import MarionetteTestCase, parameterized, WindowManagerMixin
 
 
 class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
 
+    def setUp(self):
+        super(BaseAlertTestCase, self).setUp()
+        self.new_tab = self.open_tab()
+        self.marionette.switch_to_window(self.new_tab)
+
+    def tearDown(self):
+        self.close_all_tabs()
+        super(BaseAlertTestCase, self).tearDown()
+
     @property
     def alert_present(self):
         try:
             Alert(self.marionette).text
             return True
         except errors.NoAlertPresentException:
             return False
 
     def wait_for_alert(self, timeout=None):
         Wait(self.marionette, timeout=timeout).until(
             lambda _: self.alert_present)
 
-    def wait_for_alert_closed(self, timeout=None):
-        Wait(self.marionette, timeout=timeout).until(
-            lambda _: not self.alert_present)
-
 
 class TestTabModalAlerts(BaseAlertTestCase):
 
     def setUp(self):
         super(TestTabModalAlerts, self).setUp()
         self.assertTrue(self.marionette.get_pref("prompts.tab_modal.enabled",
                         "Tab modal alerts should be enabled by default."))
 
         self.test_page = self.marionette.absolute_url("test_tab_modal_dialogs.html")
         self.marionette.navigate(self.test_page)
 
     def tearDown(self):
-        # Ensure to close a possible remaining tab modal dialog
+        # Ensure to close all possible remaining tab modal dialogs
         try:
-            alert = self.marionette.switch_to_alert()
-            alert.dismiss()
-
-            self.wait_for_alert_closed()
-        except:
+            while True:
+                alert = self.marionette.switch_to_alert()
+                alert.dismiss()
+        except errors.NoAlertPresentException:
             pass
 
         super(TestTabModalAlerts, self).tearDown()
 
     def test_no_alert_raises(self):
         with self.assertRaises(errors.NoAlertPresentException):
             Alert(self.marionette).accept()
         with self.assertRaises(errors.NoAlertPresentException):
             Alert(self.marionette).dismiss()
 
-    def test_alert_accept(self):
-        self.marionette.find_element(By.ID, "tab-modal-alert").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        alert.accept()
-
-    def test_alert_dismiss(self):
-        self.marionette.find_element(By.ID, "tab-modal-alert").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        alert.dismiss()
-
-    def test_confirm_accept(self):
-        self.marionette.find_element(By.ID, "tab-modal-confirm").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        alert.accept()
-        self.wait_for_condition(
-            lambda mn: mn.find_element(By.ID, "confirm-result").text == "true")
-
-    def test_confirm_dismiss(self):
-        self.marionette.find_element(By.ID, "tab-modal-confirm").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        alert.dismiss()
-        self.wait_for_condition(
-            lambda mn: mn.find_element(By.ID, "confirm-result").text == "false")
-
-    def test_prompt_accept(self):
-        self.marionette.find_element(By.ID, "tab-modal-prompt").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        alert.accept()
-        self.wait_for_condition(
-            lambda mn: mn.find_element(By.ID, "prompt-result").text == "")
-
-    def test_prompt_dismiss(self):
-        self.marionette.find_element(By.ID, "tab-modal-prompt").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        alert.dismiss()
-        self.wait_for_condition(
-            lambda mn: mn.find_element(By.ID, "prompt-result").text == "null")
-
     def test_alert_opened_before_session_starts(self):
         self.marionette.find_element(By.ID, "tab-modal-alert").click()
         self.wait_for_alert()
 
         # Restart the session to ensure we still find the formerly left-open dialog.
         self.marionette.delete_session()
         self.marionette.start_session()
 
         alert = self.marionette.switch_to_alert()
         alert.dismiss()
 
-    def test_alert_text(self):
-        with self.assertRaises(errors.NoAlertPresentException):
-            alert = self.marionette.switch_to_alert()
-            alert.text
-        self.marionette.find_element(By.ID, "tab-modal-alert").click()
+    @parameterized("alert", "alert", "undefined")
+    @parameterized("confirm", "confirm", "true")
+    @parameterized("prompt", "prompt", "")
+    def test_accept(self, value, result):
+        self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
-        self.assertEqual(alert.text, "Marionette alert")
         alert.accept()
+        self.assertEqual(self.marionette.find_element(By.ID, "text").text, result)
 
-    def test_prompt_text(self):
+    @parameterized("alert", "alert", "undefined")
+    @parameterized("confirm", "confirm", "false")
+    @parameterized("prompt", "prompt", "null")
+    def test_dismiss(self, value, result):
+        self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
+        self.wait_for_alert()
+        alert = self.marionette.switch_to_alert()
+        alert.dismiss()
+        self.assertEqual(self.marionette.find_element(By.ID, "text").text, result)
+
+    @parameterized("alert", "alert", "Marionette alert")
+    @parameterized("confirm", "confirm", "Marionette confirm")
+    @parameterized("prompt", "prompt", "Marionette prompt")
+    def test_text(self, value, text):
         with self.assertRaises(errors.NoAlertPresentException):
             alert = self.marionette.switch_to_alert()
             alert.text
-        self.marionette.find_element(By.ID, "tab-modal-prompt").click()
+        self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
-        self.assertEqual(alert.text, "Marionette prompt")
+        self.assertEqual(alert.text, text)
         alert.accept()
 
-    def test_confirm_text(self):
-        with self.assertRaises(errors.NoAlertPresentException):
-            alert = self.marionette.switch_to_alert()
-            alert.text
-        self.marionette.find_element(By.ID, "tab-modal-confirm").click()
-        self.wait_for_alert()
-        alert = self.marionette.switch_to_alert()
-        self.assertEqual(alert.text, "Marionette confirm")
-        alert.accept()
-
-    def test_set_text_throws(self):
+    @parameterized("alert", "alert")
+    @parameterized("confirm", "confirm")
+    def test_set_text_throws(self, value):
         with self.assertRaises(errors.NoAlertPresentException):
             Alert(self.marionette).send_keys("Foo")
-        self.marionette.find_element(By.ID, "tab-modal-alert").click()
+        self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
         with self.assertRaises(errors.ElementNotInteractableException):
             alert.send_keys("Foo")
         alert.accept()
 
     def test_set_text_accept(self):
         self.marionette.find_element(By.ID, "tab-modal-prompt").click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
-        alert.send_keys("Some text!")
+        alert.send_keys("Foo bar")
         alert.accept()
-        self.wait_for_condition(
-            lambda mn: mn.find_element(By.ID, "prompt-result").text == "Some text!")
+        self.assertEqual(self.marionette.find_element(By.ID, "text").text, "Foo bar")
 
     def test_set_text_dismiss(self):
         self.marionette.find_element(By.ID, "tab-modal-prompt").click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
         alert.send_keys("Some text!")
         alert.dismiss()
-        self.wait_for_condition(
-            lambda mn: mn.find_element(By.ID, "prompt-result").text == "null")
+        self.assertEqual(self.marionette.find_element(By.ID, "text").text, "null")
 
     def test_unrelated_command_when_alert_present(self):
         self.marionette.find_element(By.ID, "tab-modal-alert").click()
         self.wait_for_alert()
         with self.assertRaises(errors.UnexpectedAlertOpen):
-            self.marionette.find_element(By.ID, "click-result")
+            self.marionette.find_element(By.ID, "text")
 
     def test_modal_is_dismissed_after_unexpected_alert(self):
         self.marionette.find_element(By.ID, "tab-modal-alert").click()
         self.wait_for_alert()
         with self.assertRaises(errors.UnexpectedAlertOpen):
-            self.marionette.find_element(By.ID, "click-result")
+            self.marionette.find_element(By.ID, "text")
 
         assert not self.alert_present
 
+    def test_handle_two_dialogs(self):
+        self.marionette.find_element(By.ID, "open-two-dialogs").click()
+
+        alert1 = self.marionette.switch_to_alert()
+        alert1.send_keys("foo")
+        alert1.accept()
+
+        alert2 = self.marionette.switch_to_alert()
+        alert2.send_keys("bar")
+        alert2.accept()
+
+        self.assertEqual(self.marionette.find_element(By.ID, "text1").text, "foo")
+        self.assertEqual(self.marionette.find_element(By.ID, "text2").text, "bar")
+
 
 class TestModalAlerts(BaseAlertTestCase):
 
     def setUp(self):
         super(TestModalAlerts, self).setUp()
         self.marionette.set_pref(
             "network.auth.non-web-content-triggered-resources-http-auth-allow",
             True,
         )
 
-        self.new_tab = self.open_tab()
-        self.marionette.switch_to_window(self.new_tab)
-
     def tearDown(self):
-        self.close_all_tabs()
         self.marionette.clear_pref(
             "network.auth.non-web-content-triggered-resources-http-auth-allow")
-
         super(TestModalAlerts, self).tearDown()
 
     def test_http_auth_dismiss(self):
         self.marionette.navigate(self.marionette.absolute_url("http_auth"))
         self.wait_for_alert(timeout=self.marionette.timeout.page_load)
         alert = self.marionette.switch_to_alert()
         alert.dismiss()
 
-        self.wait_for_alert_closed()
-
         status = Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
             element_present(By.ID, "status")
         )
         self.assertEqual(status.text, "restricted")
 
     def test_alert_opened_before_session_starts(self):
         self.marionette.navigate(self.marionette.absolute_url("http_auth"))
         self.wait_for_alert(timeout=self.marionette.timeout.page_load)
 
         # Restart the session to ensure we still find the formerly left-open dialog.
         self.marionette.delete_session()
         self.marionette.start_session()
 
         alert = self.marionette.switch_to_alert()
         alert.dismiss()
-
-        self.wait_for_alert_closed()
--- a/testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html
+++ b/testing/marionette/harness/marionette_harness/www/test_tab_modal_dialogs.html
@@ -2,33 +2,42 @@
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!DOCTYPE html>
 <html>
 <head>
   <title>Dialog Test</title>
   <script type="text/javascript">
+    function setInnerText(id, value) {
+      document.getElementById(id).innerHTML = "<p>" + value + "</p>";
+    }
+
     function handleAlert () {
-      window.alert('Marionette alert');
+      setInnerText("text", alert("Marionette alert"));
     }
 
     function handleConfirm () {
-      var alertAccepted = window.confirm('Marionette confirm');
-      document.getElementById('confirm-result').innerHTML = alertAccepted;
+      setInnerText("text", confirm("Marionette confirm"));
     }
 
     function handlePrompt () {
-      var promptText = window.prompt('Marionette prompt');
-      document.getElementById('prompt-result').innerHTML = promptText === null ? 'null' : promptText;
+      setInnerText("text", prompt("Marionette prompt"));
+    }
+
+    function handleTwoDialogs() {
+      setInnerText("text1", prompt("First"));
+      setInnerText("text2", prompt("Second"));
     }
   </script>
 </head>
 <body>
-   <a href="#" id="tab-modal-alert" onclick="handleAlert()">Open an alert dialog.</a>
-   <a href="#" id="tab-modal-confirm" onclick="handleConfirm()">Open a confirm dialog.</a>
-   <a href="#" id="tab-modal-prompt" onclick="handlePrompt()">Open a prompt dialog.</a>
-   <a href="#" id="click-handler" onclick="document.getElementById('click-result').innerHTML='result';">Make text appear.</a>
-   <div id="confirm-result"></div>
-   <div id="prompt-result"></div>
-   <div id="click-result"></div>
+  <a href="#" id="tab-modal-alert" onclick="handleAlert()">Open an alert dialog.</a>
+  <a href="#" id="tab-modal-confirm" onclick="handleConfirm()">Open a confirm dialog.</a>
+  <a href="#" id="tab-modal-prompt" onclick="handlePrompt()">Open a prompt dialog.</a>
+  <a href="#" id="open-two-dialogs" onclick="handleTwoDialogs()">Open two prompts.</a>
+  <a href="#" id="click-handler" onclick="document.getElementById('text').innerHTML='result';">Make text appear.</a>
+
+  <div id="text"></div>
+  <div id="text1"></div>
+  <div id="text2"></div>
 </body>
 </html>