1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5from marionette_driver.by import By
6from marionette_driver.errors import NoAlertPresentException, ElementNotInteractableException
7from marionette_driver.marionette import Alert
8from marionette_driver.wait import Wait
9
10from marionette_harness import MarionetteTestCase, skip_if_e10s
11
12
13class TestTabModals(MarionetteTestCase):
14
15    def setUp(self):
16        super(TestTabModals, self).setUp()
17        self.marionette.set_pref("prompts.tab_modal.enabled", True)
18        self.marionette.navigate(self.marionette.absolute_url('modal_dialogs.html'))
19
20    def tearDown(self):
21        # Ensure an alert is absent before proceeding past this test.
22        Wait(self.marionette).until(lambda _: not self.alert_present())
23        self.marionette.execute_script("window.onbeforeunload = null;")
24        self.marionette.clear_pref("prompts.tab_modal.enabled")
25        super(TestTabModals, self).tearDown()
26
27    def alert_present(self):
28        try:
29            Alert(self.marionette).text
30            return True
31        except NoAlertPresentException:
32            return False
33
34    def wait_for_alert(self):
35        Wait(self.marionette).until(lambda _: self.alert_present())
36
37    def test_no_alert_raises(self):
38        self.assertRaises(NoAlertPresentException, Alert(self.marionette).accept)
39        self.assertRaises(NoAlertPresentException, Alert(self.marionette).dismiss)
40
41    def test_alert_accept(self):
42        self.marionette.find_element(By.ID, 'modal-alert').click()
43        self.wait_for_alert()
44        alert = self.marionette.switch_to_alert()
45        alert.accept()
46
47    def test_alert_dismiss(self):
48        self.marionette.find_element(By.ID, 'modal-alert').click()
49        self.wait_for_alert()
50        alert = self.marionette.switch_to_alert()
51        alert.dismiss()
52
53    def test_confirm_accept(self):
54        self.marionette.find_element(By.ID, 'modal-confirm').click()
55        self.wait_for_alert()
56        alert = self.marionette.switch_to_alert()
57        alert.accept()
58        self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'confirm-result').text == 'true')
59
60    def test_confirm_dismiss(self):
61        self.marionette.find_element(By.ID, 'modal-confirm').click()
62        self.wait_for_alert()
63        alert = self.marionette.switch_to_alert()
64        alert.dismiss()
65        self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'confirm-result').text == 'false')
66
67    def test_prompt_accept(self):
68        self.marionette.find_element(By.ID, 'modal-prompt').click()
69        self.wait_for_alert()
70        alert = self.marionette.switch_to_alert()
71        alert.accept()
72        self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == '')
73
74    def test_prompt_dismiss(self):
75        self.marionette.find_element(By.ID, 'modal-prompt').click()
76        self.wait_for_alert()
77        alert = self.marionette.switch_to_alert()
78        alert.dismiss()
79        self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == 'null')
80
81    def test_alert_text(self):
82        with self.assertRaises(NoAlertPresentException):
83            alert = self.marionette.switch_to_alert()
84            alert.text
85        self.marionette.find_element(By.ID, 'modal-alert').click()
86        self.wait_for_alert()
87        alert = self.marionette.switch_to_alert()
88        self.assertEqual(alert.text, 'Marionette alert')
89        alert.accept()
90
91    def test_prompt_text(self):
92        with self.assertRaises(NoAlertPresentException):
93            alert = self.marionette.switch_to_alert()
94            alert.text
95        self.marionette.find_element(By.ID, 'modal-prompt').click()
96        self.wait_for_alert()
97        alert = self.marionette.switch_to_alert()
98        self.assertEqual(alert.text, 'Marionette prompt')
99        alert.accept()
100
101    def test_confirm_text(self):
102        with self.assertRaises(NoAlertPresentException):
103            alert = self.marionette.switch_to_alert()
104            alert.text
105        self.marionette.find_element(By.ID, 'modal-confirm').click()
106        self.wait_for_alert()
107        alert = self.marionette.switch_to_alert()
108        self.assertEqual(alert.text, 'Marionette confirm')
109        alert.accept()
110
111    def test_set_text_throws(self):
112        self.assertRaises(NoAlertPresentException, Alert(self.marionette).send_keys, "Foo")
113        self.marionette.find_element(By.ID, 'modal-alert').click()
114        self.wait_for_alert()
115        alert = self.marionette.switch_to_alert()
116        self.assertRaises(ElementNotInteractableException, alert.send_keys, "Foo")
117        alert.accept()
118
119    def test_set_text_accept(self):
120        self.marionette.find_element(By.ID, 'modal-prompt').click()
121        self.wait_for_alert()
122        alert = self.marionette.switch_to_alert()
123        alert.send_keys("Some text!");
124        alert.accept()
125        self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == 'Some text!')
126
127    def test_set_text_dismiss(self):
128        self.marionette.find_element(By.ID, 'modal-prompt').click()
129        self.wait_for_alert()
130        alert = self.marionette.switch_to_alert()
131        alert.send_keys("Some text!");
132        alert.dismiss()
133        self.wait_for_condition(lambda mn: mn.find_element(By.ID, 'prompt-result').text == 'null')
134
135    def test_onbeforeunload_dismiss(self):
136        start_url = self.marionette.get_url()
137        self.marionette.find_element(By.ID, 'onbeforeunload-handler').click()
138        self.wait_for_condition(
139            lambda mn: mn.execute_script("""
140              return window.onbeforeunload !== null;
141            """))
142        self.marionette.navigate("about:blank")
143        self.wait_for_alert()
144        alert = self.marionette.switch_to_alert()
145        self.assertTrue(alert.text.startswith("This page is asking you to confirm"))
146        alert.dismiss()
147        self.assertTrue(self.marionette.get_url().startswith(start_url))
148
149    def test_onbeforeunload_accept(self):
150        self.marionette.find_element(By.ID, 'onbeforeunload-handler').click()
151        self.wait_for_condition(
152            lambda mn: mn.execute_script("""
153              return window.onbeforeunload !== null;
154            """))
155        self.marionette.navigate("about:blank")
156        self.wait_for_alert()
157        alert = self.marionette.switch_to_alert()
158        self.assertTrue(alert.text.startswith("This page is asking you to confirm"))
159        alert.accept()
160        self.wait_for_condition(lambda mn: mn.get_url() == "about:blank")
161
162    @skip_if_e10s("Bug 1325044")
163    def test_unrelated_command_when_alert_present(self):
164        click_handler = self.marionette.find_element(By.ID, 'click-handler')
165        text = self.marionette.find_element(By.ID, 'click-result').text
166        self.assertEqual(text, '')
167
168        self.marionette.find_element(By.ID, 'modal-alert').click()
169        self.wait_for_alert()
170
171        # Commands succeed, but because the dialog blocks the event loop,
172        # our actions aren't reflected on the page.
173        text = self.marionette.find_element(By.ID, 'click-result').text
174        self.assertEqual(text, '')
175        click_handler.click()
176        text = self.marionette.find_element(By.ID, 'click-result').text
177        self.assertEqual(text, '')
178
179        alert = self.marionette.switch_to_alert()
180        alert.accept()
181
182        Wait(self.marionette).until(lambda _: not self.alert_present())
183
184        click_handler.click()
185        text = self.marionette.find_element(By.ID, 'click-result').text
186        self.assertEqual(text, 'result')
187
188
189class TestGlobalModals(TestTabModals):
190
191    def setUp(self):
192        super(TestGlobalModals, self).setUp()
193        self.marionette.set_pref("prompts.tab_modal.enabled", False)
194
195    def test_unrelated_command_when_alert_present(self):
196        # The assumptions in this test do not hold on certain platforms, and not when
197        # e10s is enabled.
198        pass
199