test_capabilities.py (14029B)
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 5 import os 6 import sys 7 import unittest 8 9 import marionette_driver.errors as errors 10 from marionette_harness import MarionetteTestCase 11 12 13 PROMPT_HANDLERS = [ 14 "accept", 15 "accept and notify", 16 "dismiss", 17 "dismiss and notify", 18 "ignore", 19 ] 20 21 PROMPT_TYPES = [ 22 "alert", 23 "beforeUnload", 24 "confirm", 25 "prompt", 26 ] 27 28 29 class TestCapabilities(MarionetteTestCase): 30 def setUp(self): 31 super(TestCapabilities, self).setUp() 32 self.caps = self.marionette.session_capabilities 33 with self.marionette.using_context("chrome"): 34 self.appinfo = self.marionette.execute_script( 35 """ 36 return { 37 name: Services.appinfo.name, 38 version: Services.appinfo.version, 39 processID: Services.appinfo.processID, 40 buildID: Services.appinfo.appBuildID, 41 } 42 """ 43 ) 44 self.os_name = self.marionette.execute_script( 45 """ 46 let name = Services.sysinfo.getProperty("name"); 47 switch (name) { 48 case "Windows_NT": 49 return "windows"; 50 case "Darwin": 51 return "mac"; 52 default: 53 return name.toLowerCase(); 54 } 55 """ 56 ) 57 self.os_version = self.marionette.execute_script( 58 "return Services.sysinfo.getProperty('version')" 59 ) 60 61 def test_mandated_capabilities(self): 62 self.assertIn("acceptInsecureCerts", self.caps) 63 self.assertIn("browserName", self.caps) 64 self.assertIn("browserVersion", self.caps) 65 self.assertIn("platformName", self.caps) 66 self.assertIn("proxy", self.caps) 67 self.assertIn("setWindowRect", self.caps) 68 self.assertIn("strictFileInteractability", self.caps) 69 self.assertIn("timeouts", self.caps) 70 71 self.assertFalse(self.caps["acceptInsecureCerts"]) 72 self.assertEqual(self.caps["browserName"], self.appinfo["name"].lower()) 73 self.assertEqual(self.caps["browserVersion"], self.appinfo["version"]) 74 self.assertEqual(self.caps["platformName"], self.os_name) 75 self.assertEqual(self.caps["proxy"], {}) 76 77 if self.appinfo["name"] == "Firefox": 78 self.assertTrue(self.caps["setWindowRect"]) 79 else: 80 self.assertFalse(self.caps["setWindowRect"]) 81 self.assertTrue(self.caps["strictFileInteractability"]) 82 self.assertDictEqual( 83 self.caps["timeouts"], {"implicit": 0, "pageLoad": 300000, "script": 30000} 84 ) 85 86 def test_additional_capabilities(self): 87 self.assertIn("moz:processID", self.caps) 88 self.assertEqual(self.caps["moz:processID"], self.appinfo["processID"]) 89 self.assertEqual(self.marionette.process_id, self.appinfo["processID"]) 90 91 self.assertIn("moz:profile", self.caps) 92 if self.marionette.instance is not None: 93 if self.caps["browserName"] == "fennec": 94 current_profile = ( 95 self.marionette.instance.runner.device.app_ctx.remote_profile 96 ) 97 else: 98 current_profile = self.marionette.profile_path 99 # Bug 1438461 - mozprofile uses lower-case letters even on case-sensitive filesystems 100 # Bug 1533221 - paths may differ due to file system links or aliases 101 self.assertEqual( 102 os.path.basename(self.caps["moz:profile"]).lower(), 103 os.path.basename(current_profile).lower(), 104 ) 105 106 self.assertIn("moz:accessibilityChecks", self.caps) 107 self.assertFalse(self.caps["moz:accessibilityChecks"]) 108 109 self.assertIn("moz:buildID", self.caps) 110 self.assertEqual(self.caps["moz:buildID"], self.appinfo["buildID"]) 111 112 self.assertNotIn("moz:debuggerAddress", self.caps) 113 114 self.assertIn("moz:platformVersion", self.caps) 115 self.assertEqual(self.caps["moz:platformVersion"], self.os_version) 116 117 self.assertIn("moz:webdriverClick", self.caps) 118 self.assertTrue(self.caps["moz:webdriverClick"]) 119 120 self.assertIn("moz:windowless", self.caps) 121 self.assertFalse(self.caps["moz:windowless"]) 122 123 def test_disable_webdriver_click(self): 124 self.marionette.delete_session() 125 self.marionette.start_session({"moz:webdriverClick": False}) 126 caps = self.marionette.session_capabilities 127 self.assertFalse(caps["moz:webdriverClick"]) 128 129 def test_valid_uuid4_when_creating_a_session(self): 130 self.assertNotIn( 131 "{", 132 self.marionette.session_id, 133 "Session ID has {{}} in it: {}".format(self.marionette.session_id), 134 ) 135 136 def test_windowless_false(self): 137 self.marionette.delete_session() 138 self.marionette.start_session({"moz:windowless": False}) 139 caps = self.marionette.session_capabilities 140 self.assertFalse(caps["moz:windowless"]) 141 142 @unittest.skipUnless(sys.platform.startswith("darwin"), "Only supported on MacOS") 143 def test_windowless_true(self): 144 self.marionette.delete_session() 145 self.marionette.start_session({"moz:windowless": True}) 146 caps = self.marionette.session_capabilities 147 self.assertTrue(caps["moz:windowless"]) 148 149 150 class TestCapabilityMatching(MarionetteTestCase): 151 def setUp(self): 152 MarionetteTestCase.setUp(self) 153 self.browser_name = self.marionette.session_capabilities["browserName"] 154 self.delete_session() 155 156 def delete_session(self): 157 if self.marionette.session is not None: 158 self.marionette.delete_session() 159 160 def test_accept_insecure_certs(self): 161 for value in ["", 42, {}, []]: 162 print(f" type {type(value)}") 163 with self.assertRaises(errors.SessionNotCreatedException): 164 self.marionette.start_session({"acceptInsecureCerts": value}) 165 166 self.delete_session() 167 self.marionette.start_session({"acceptInsecureCerts": True}) 168 self.assertTrue(self.marionette.session_capabilities["acceptInsecureCerts"]) 169 170 def test_page_load_strategy(self): 171 for strategy in ["none", "eager", "normal"]: 172 print(f"valid strategy {strategy}") 173 self.delete_session() 174 self.marionette.start_session({"pageLoadStrategy": strategy}) 175 self.assertEqual( 176 self.marionette.session_capabilities["pageLoadStrategy"], strategy 177 ) 178 179 self.delete_session() 180 181 for value in ["", "EAGER", True, 42, {}, []]: 182 print(f"invalid strategy {value}") 183 with self.assertRaisesRegex( 184 errors.SessionNotCreatedException, "InvalidArgumentError" 185 ): 186 self.marionette.start_session({"pageLoadStrategy": value}) 187 188 def test_set_window_rect(self): 189 with self.assertRaisesRegex( 190 errors.SessionNotCreatedException, "InvalidArgumentError" 191 ): 192 self.marionette.start_session({"setWindowRect": False}) 193 194 def test_timeouts(self): 195 for value in ["", 2.5, {}, []]: 196 print(f" type {type(value)}") 197 with self.assertRaises(errors.SessionNotCreatedException): 198 self.marionette.start_session({"timeouts": {"pageLoad": value}}) 199 200 self.delete_session() 201 202 timeouts = {"implicit": 0, "pageLoad": 2.0, "script": 2**53 - 1} 203 self.marionette.start_session({"timeouts": timeouts}) 204 self.assertIn("timeouts", self.marionette.session_capabilities) 205 self.assertDictEqual(self.marionette.session_capabilities["timeouts"], timeouts) 206 self.assertDictEqual( 207 self.marionette._send_message("WebDriver:GetTimeouts"), timeouts 208 ) 209 210 def test_strict_file_interactability(self): 211 for value in ["", 2.5, {}, []]: 212 print(f" type {type(value)}") 213 with self.assertRaises(errors.SessionNotCreatedException): 214 self.marionette.start_session({"strictFileInteractability": value}) 215 216 self.delete_session() 217 218 self.marionette.start_session({"strictFileInteractability": True}) 219 self.assertIn("strictFileInteractability", self.marionette.session_capabilities) 220 self.assertTrue( 221 self.marionette.session_capabilities["strictFileInteractability"] 222 ) 223 224 self.delete_session() 225 226 self.marionette.start_session({"strictFileInteractability": False}) 227 self.assertIn("strictFileInteractability", self.marionette.session_capabilities) 228 self.assertFalse( 229 self.marionette.session_capabilities["strictFileInteractability"] 230 ) 231 232 def test_unhandled_prompt_behavior_as_string(self): 233 """WebDriver Classic (HTTP) style""" 234 235 # Invalid values 236 self.delete_session() 237 for handler in ["", "ACCEPT", True, 42, []]: 238 print(f"invalid unhandled prompt behavior {handler}") 239 with self.assertRaisesRegex( 240 errors.SessionNotCreatedException, "InvalidArgumentError" 241 ): 242 self.marionette.start_session({"unhandledPromptBehavior": handler}) 243 244 # Default value if capability is not requested when creating a new session. 245 self.delete_session() 246 self.marionette.start_session() 247 self.assertEqual( 248 self.marionette.session_capabilities["unhandledPromptBehavior"], 249 "dismiss and notify", 250 ) 251 252 for handler in PROMPT_HANDLERS: 253 print(f" value {handler}") 254 self.delete_session() 255 self.marionette.start_session({"unhandledPromptBehavior": handler}) 256 self.assertEqual( 257 self.marionette.session_capabilities["unhandledPromptBehavior"], 258 handler, 259 ) 260 261 def test_unhandled_prompt_behavior_as_object(self): 262 """WebDriver BiDi style""" 263 264 # Invalid values 265 self.delete_session() 266 for handler in [{"foo": "accept"}, {"alert": "bar"}]: 267 print(f"invalid unhandled prompt behavior {handler}") 268 with self.assertRaisesRegex( 269 errors.SessionNotCreatedException, "InvalidArgumentError" 270 ): 271 self.marionette.start_session({"unhandledPromptBehavior": handler}) 272 273 # Default value if capability is not requested when creating a new session. 274 self.delete_session() 275 self.marionette.start_session({"unhandledPromptBehavior": {}}) 276 self.assertEqual( 277 self.marionette.session_capabilities["unhandledPromptBehavior"], 278 {}, 279 ) 280 281 for prompt_type in PROMPT_TYPES: 282 for handler in PROMPT_HANDLERS: 283 value = {prompt_type: handler} 284 print(f" value {value}") 285 self.delete_session() 286 self.marionette.start_session({"unhandledPromptBehavior": value}) 287 self.assertEqual( 288 self.marionette.session_capabilities["unhandledPromptBehavior"], 289 value, 290 ) 291 292 def test_web_socket_url(self): 293 self.marionette.start_session({"webSocketUrl": True}) 294 # Remote Agent is not active by default 295 self.assertNotIn("webSocketUrl", self.marionette.session_capabilities) 296 297 def test_webauthn_extension_cred_blob(self): 298 for value in ["", 42, {}, []]: 299 print(f" type {type(value)}") 300 with self.assertRaises(errors.SessionNotCreatedException): 301 self.marionette.start_session({"webauthn:extension:credBlob": value}) 302 303 self.delete_session() 304 self.marionette.start_session({"webauthn:extension:credBlob": True}) 305 self.assertTrue( 306 self.marionette.session_capabilities["webauthn:extension:credBlob"] 307 ) 308 309 def test_webauthn_extension_large_blob(self): 310 for value in ["", 42, {}, []]: 311 print(f" type {type(value)}") 312 with self.assertRaises(errors.SessionNotCreatedException): 313 self.marionette.start_session({"webauthn:extension:largeBlob": value}) 314 315 self.delete_session() 316 self.marionette.start_session({"webauthn:extension:largeBlob": True}) 317 self.assertTrue( 318 self.marionette.session_capabilities["webauthn:extension:largeBlob"] 319 ) 320 321 def test_webauthn_extension_prf(self): 322 for value in ["", 42, {}, []]: 323 print(f" type {type(value)}") 324 with self.assertRaises(errors.SessionNotCreatedException): 325 self.marionette.start_session({"webauthn:extension:prf": value}) 326 327 self.delete_session() 328 self.marionette.start_session({"webauthn:extension:prf": True}) 329 self.assertTrue(self.marionette.session_capabilities["webauthn:extension:prf"]) 330 331 def test_webauthn_extension_uvm(self): 332 for value in ["", 42, {}, []]: 333 print(f" type {type(value)}") 334 with self.assertRaises(errors.SessionNotCreatedException): 335 self.marionette.start_session({"webauthn:extension:uvm": value}) 336 337 self.delete_session() 338 self.marionette.start_session({"webauthn:extension:uvm": True}) 339 self.assertTrue(self.marionette.session_capabilities["webauthn:extension:uvm"]) 340 341 def test_webauthn_virtual_authenticators(self): 342 for value in ["", 42, {}, []]: 343 print(f" type {type(value)}") 344 with self.assertRaises(errors.SessionNotCreatedException): 345 self.marionette.start_session({"webauthn:virtualAuthenticators": value}) 346 347 self.delete_session() 348 self.marionette.start_session({"webauthn:virtualAuthenticators": True}) 349 self.assertTrue( 350 self.marionette.session_capabilities["webauthn:virtualAuthenticators"] 351 )