tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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        )