test_execute_async_script.py (7664B)
1 import os 2 3 from marionette_driver.errors import ( 4 JavascriptException, 5 NoAlertPresentException, 6 ScriptTimeoutException, 7 ) 8 from marionette_driver.marionette import Alert 9 from marionette_driver.wait import Wait 10 11 from marionette_harness import MarionetteTestCase 12 13 14 class TestExecuteAsyncContent(MarionetteTestCase): 15 def setUp(self): 16 super(TestExecuteAsyncContent, self).setUp() 17 self.marionette.timeout.script = 1 18 19 def tearDown(self): 20 if self.alert_present(): 21 alert = self.marionette.switch_to_alert() 22 alert.dismiss() 23 self.wait_for_alert_closed() 24 25 def alert_present(self): 26 try: 27 Alert(self.marionette).text 28 return True 29 except NoAlertPresentException: 30 return False 31 32 def wait_for_alert_closed(self, timeout=None): 33 Wait(self.marionette, timeout=timeout).until(lambda _: not self.alert_present()) 34 35 def test_execute_async_simple(self): 36 self.assertEqual( 37 1, self.marionette.execute_async_script("arguments[arguments.length-1](1);") 38 ) 39 40 def test_execute_async_ours(self): 41 self.assertEqual(1, self.marionette.execute_async_script("arguments[0](1);")) 42 43 def test_script_timeout_error(self): 44 with self.assertRaisesRegex(ScriptTimeoutException, "Timed out after 100 ms"): 45 self.marionette.execute_async_script("var x = 1;", script_timeout=100) 46 47 def test_script_timeout_reset_after_timeout_error(self): 48 script_timeout = self.marionette.timeout.script 49 with self.assertRaises(ScriptTimeoutException): 50 self.marionette.execute_async_script("var x = 1;", script_timeout=100) 51 self.assertEqual(self.marionette.timeout.script, script_timeout) 52 53 def test_script_timeout_no_timeout_error(self): 54 self.assertTrue( 55 self.marionette.execute_async_script( 56 """ 57 var callback = arguments[arguments.length - 1]; 58 setTimeout(function() { callback(true); }, 500); 59 """, 60 script_timeout=1000, 61 ) 62 ) 63 64 def test_no_timeout(self): 65 self.marionette.timeout.script = 10 66 self.assertTrue( 67 self.marionette.execute_async_script( 68 """ 69 var callback = arguments[arguments.length - 1]; 70 setTimeout(function() { callback(true); }, 500); 71 """ 72 ) 73 ) 74 75 def test_execute_async_unload(self): 76 self.marionette.timeout.script = 5 77 unload = """ 78 window.location.href = "about:blank"; 79 """ 80 self.assertRaises( 81 JavascriptException, self.marionette.execute_async_script, unload 82 ) 83 84 def test_check_window(self): 85 self.assertTrue( 86 self.marionette.execute_async_script( 87 "arguments[0](window != null && window != undefined);" 88 ) 89 ) 90 91 def test_same_context(self): 92 var1 = "testing" 93 self.assertEqual( 94 self.marionette.execute_script( 95 """ 96 this.testvar = '{}'; 97 return this.testvar; 98 """.format( 99 var1 100 ) 101 ), 102 var1, 103 ) 104 self.assertEqual( 105 self.marionette.execute_async_script( 106 "arguments[0](this.testvar);", new_sandbox=False 107 ), 108 var1, 109 ) 110 111 def test_execute_no_return(self): 112 self.assertEqual(self.marionette.execute_async_script("arguments[0]()"), None) 113 114 def test_execute_js_exception(self): 115 try: 116 self.marionette.execute_async_script( 117 """ 118 let a = 1; 119 foo(bar); 120 """ 121 ) 122 self.fail() 123 except JavascriptException as e: 124 self.assertIsNotNone(e.stacktrace) 125 self.assertIn( 126 os.path.relpath(__file__.replace(".pyc", ".py")), e.stacktrace 127 ) 128 129 def test_execute_async_js_exception(self): 130 try: 131 self.marionette.execute_async_script( 132 """ 133 let [resolve] = arguments; 134 resolve(foo()); 135 """ 136 ) 137 self.fail() 138 except JavascriptException as e: 139 self.assertIsNotNone(e.stacktrace) 140 self.assertIn( 141 os.path.relpath(__file__.replace(".pyc", ".py")), e.stacktrace 142 ) 143 144 def test_script_finished(self): 145 self.assertTrue( 146 self.marionette.execute_async_script( 147 """ 148 arguments[0](true); 149 """ 150 ) 151 ) 152 153 def test_execute_permission(self): 154 self.assertRaises( 155 JavascriptException, 156 self.marionette.execute_async_script, 157 """ 158 let prefs = Components.classes["@mozilla.org/preferences-service;1"] 159 .getService(Components.interfaces.nsIPrefBranch); 160 arguments[0](4); 161 """, 162 ) 163 164 def test_sandbox_reuse(self): 165 # Sandboxes between `execute_script()` invocations are shared. 166 self.marionette.execute_async_script( 167 "this.foobar = [23, 42];" "arguments[0]();" 168 ) 169 self.assertEqual( 170 self.marionette.execute_async_script( 171 "arguments[0](this.foobar);", new_sandbox=False 172 ), 173 [23, 42], 174 ) 175 176 def test_sandbox_refresh_arguments(self): 177 self.marionette.execute_async_script( 178 "this.foobar = [arguments[0], arguments[1]];" 179 "let resolve = " 180 "arguments[arguments.length - 1];" 181 "resolve();", 182 script_args=[23, 42], 183 ) 184 self.assertEqual( 185 self.marionette.execute_async_script( 186 "arguments[0](this.foobar);", new_sandbox=False 187 ), 188 [23, 42], 189 ) 190 191 # Functions defined in higher privilege scopes, such as the privileged 192 # JSWindowActor child runs in, cannot be accessed from 193 # content. This tests that it is possible to introspect the objects on 194 # `arguments` without getting permission defined errors. This is made 195 # possible because the last argument is always the callback/complete 196 # function. 197 # 198 # See bug 1290966. 199 def test_introspection_of_arguments(self): 200 self.marionette.execute_async_script( 201 "arguments[0].cheese; __webDriverCallback();", script_args=[], sandbox=None 202 ) 203 204 def test_return_value_on_alert(self): 205 res = self.marionette.execute_async_script("alert()") 206 self.assertIsNone(res) 207 208 209 class TestExecuteAsyncChrome(TestExecuteAsyncContent): 210 def setUp(self): 211 super(TestExecuteAsyncChrome, self).setUp() 212 self.marionette.set_context("chrome") 213 214 def test_execute_async_unload(self): 215 pass 216 217 def test_execute_permission(self): 218 self.assertEqual( 219 5, 220 self.marionette.execute_async_script( 221 """ 222 var c = Components.classes; 223 arguments[0](5); 224 """ 225 ), 226 ) 227 228 def test_execute_async_js_exception(self): 229 # Javascript exceptions are not propagated in chrome code 230 self.marionette.timeout.script = 0.2 231 with self.assertRaises(ScriptTimeoutException): 232 self.marionette.execute_async_script( 233 """ 234 var callback = arguments[arguments.length - 1]; 235 setTimeout(function() { callback(foo()); }, 50); 236 """ 237 ) 238 239 def test_return_value_on_alert(self): 240 pass