brizental pushed to branch tor-browser-149.0a1-16.0-2 at The Tor Project / Applications / Tor Browser

Commits:

6 changed files:

Changes:

  • testing/marionette/harness/marionette_harness/__init__.py
    ... ... @@ -28,5 +28,6 @@ from .runner import (
    28 28
         TestManifest,
    
    29 29
         TestResult,
    
    30 30
         TestResultCollection,
    
    31
    +    TorBrowserMixin,
    
    31 32
         WindowManagerMixin,
    
    32 33
     )

  • testing/marionette/harness/marionette_harness/runner/__init__.py
    ... ... @@ -13,4 +13,7 @@ from .base import (
    13 13
         TestResult,
    
    14 14
         TestResultCollection,
    
    15 15
     )
    
    16
    -from .mixins import WindowManagerMixin
    16
    +from .mixins import (
    
    17
    +    TorBrowserMixin,
    
    18
    +    WindowManagerMixin,
    
    19
    +)

  • testing/marionette/harness/marionette_harness/runner/mixins/__init__.py
    ... ... @@ -3,3 +3,4 @@
    3 3
     # file, You can obtain one at http://mozilla.org/MPL/2.0/.
    
    4 4
     
    
    5 5
     from .window_manager import WindowManagerMixin
    
    6
    +from .tor_browser import TorBrowserMixin

  • testing/marionette/harness/marionette_harness/runner/mixins/tor_browser.py
    1
    +from marionette_driver.errors import ScriptTimeoutException
    
    2
    +
    
    3
    +DEFAULT_BOOTSTRAP_TIMEOUT_MS = 60 * 1000
    
    4
    +DEFAULT_BOOTSTRAP_MAX_RETRIES = 3
    
    5
    +
    
    6
    +class TorBrowserMixin:
    
    7
    +    def bootstrap(
    
    8
    +        self,
    
    9
    +        max_retries=DEFAULT_BOOTSTRAP_MAX_RETRIES,
    
    10
    +    ):
    
    11
    +        """Bootstrap the Tor connection.
    
    12
    +
    
    13
    +        This doesn't fail if already bootstrapped, but will retry a few times if
    
    14
    +        a script timeout is hit.
    
    15
    +
    
    16
    +        This function is UI-agnostic, meaning it can be used both on Desktop and Android.
    
    17
    +        """
    
    18
    +
    
    19
    +        attempt = 0
    
    20
    +        while attempt < max_retries:
    
    21
    +            try:
    
    22
    +                with self.marionette.using_context("chrome"):
    
    23
    +                    self.marionette.execute_async_script(
    
    24
    +                        """
    
    25
    +                        const { TorConnect, TorConnectStage, TorConnectTopics } = ChromeUtils.importESModule(
    
    26
    +                            "resource://gre/modules/TorConnect.sys.mjs"
    
    27
    +                        );
    
    28
    +                        const [resolve] = arguments;
    
    29
    +
    
    30
    +                        // Only the first test of a suite will need to bootstrap.
    
    31
    +                        if (TorConnect.stage.name === TorConnectStage.Bootstrapped) {
    
    32
    +                            resolve();
    
    33
    +                            return;
    
    34
    +                        }
    
    35
    +
    
    36
    +                        function waitForBootstrap() {
    
    37
    +                            const topic = TorConnectTopics.BootstrapComplete;
    
    38
    +                            Services.obs.addObserver(function observer() {
    
    39
    +                                Services.obs.removeObserver(observer, topic);
    
    40
    +                                resolve();
    
    41
    +                            }, topic);
    
    42
    +                            TorConnect.beginBootstrapping();
    
    43
    +                        }
    
    44
    +
    
    45
    +                        const stageTopic = TorConnectTopics.StageChange;
    
    46
    +                        function stageObserver() {
    
    47
    +                            if (TorConnect.canBeginNormalBootstrap) {
    
    48
    +                                Services.obs.removeObserver(stageObserver, stageTopic);
    
    49
    +                                waitForBootstrap();
    
    50
    +                            }
    
    51
    +                        }
    
    52
    +                        Services.obs.addObserver(stageObserver, stageTopic);
    
    53
    +                        stageObserver();
    
    54
    +                        """,
    
    55
    +                        script_timeout=DEFAULT_BOOTSTRAP_TIMEOUT_MS,
    
    56
    +                    )
    
    57
    +
    
    58
    +                return
    
    59
    +            except ScriptTimeoutException:
    
    60
    +                attempt += 1
    
    61
    +                with self.marionette.using_context("chrome"):
    
    62
    +                    self.marionette.execute_script(
    
    63
    +                        """
    
    64
    +                        const { TorConnect } = ChromeUtils.importESModule(
    
    65
    +                            "resource://gre/modules/TorConnect.sys.mjs"
    
    66
    +                        );
    
    67
    +
    
    68
    +                        TorConnect._makeStageRequest(TorConnectStage.Start, true);
    
    69
    +                        """
    
    70
    +                    )
    
    71
    +
    
    72
    +
    
    73
    +        raise RuntimeError("Unable to connect to Tor Network")

  • testing/tor/test_circuit_isolation.py
    ... ... @@ -2,47 +2,13 @@ from ipaddress import ip_address
    2 2
     
    
    3 3
     from marionette_driver import By
    
    4 4
     from marionette_driver.errors import NoSuchElementException
    
    5
    -from marionette_harness import MarionetteTestCase
    
    5
    +from marionette_harness import MarionetteTestCase, TorBrowserMixin
    
    6 6
     
    
    7
    -TOR_BOOTSTRAP_TIMEOUT = 30000  # 30s
    
    8 7
     
    
    9
    -
    
    10
    -class TestCircuitIsolation(MarionetteTestCase):
    
    8
    +class TestCircuitIsolation(MarionetteTestCase, TorBrowserMixin):
    
    11 9
         def tearDown(self):
    
    12
    -        self.marionette.restart(in_app=False, clean=True)
    
    13 10
             super().tearDown()
    
    14 11
     
    
    15
    -    def bootstrap(self):
    
    16
    -        with self.marionette.using_context("chrome"):
    
    17
    -            self.marionette.execute_async_script(
    
    18
    -                """
    
    19
    -                const { TorConnect, TorConnectTopics } = ChromeUtils.importESModule(
    
    20
    -                    "resource://gre/modules/TorConnect.sys.mjs"
    
    21
    -                );
    
    22
    -                const [resolve] = arguments;
    
    23
    -
    
    24
    -                function waitForBootstrap() {
    
    25
    -                    const topic = TorConnectTopics.BootstrapComplete;
    
    26
    -                    Services.obs.addObserver(function observer() {
    
    27
    -                        Services.obs.removeObserver(observer, topic);
    
    28
    -                        resolve();
    
    29
    -                    }, topic);
    
    30
    -                    TorConnect.beginBootstrapping();
    
    31
    -                }
    
    32
    -
    
    33
    -                const stageTopic = TorConnectTopics.StageChange;
    
    34
    -                function stageObserver() {
    
    35
    -                    if (TorConnect.canBeginNormalBootstrap) {
    
    36
    -                        Services.obs.removeObserver(stageObserver, stageTopic);
    
    37
    -                        waitForBootstrap();
    
    38
    -                    }
    
    39
    -                }
    
    40
    -                Services.obs.addObserver(stageObserver, stageTopic);
    
    41
    -                stageObserver();
    
    42
    -                """,
    
    43
    -                script_timeout=TOR_BOOTSTRAP_TIMEOUT,
    
    44
    -            )
    
    45
    -
    
    46 12
         def extract_from_check_tpo(self):
    
    47 13
             # Fetch the IP from check.torproject.org.
    
    48 14
             # In addition to that, since we are loading this page, we
    

  • testing/tor/test_network_check.py
    1
    -from marionette_driver import By, Wait, errors
    
    2
    -from marionette_driver.localization import L10n
    
    3
    -from marionette_harness import MarionetteTestCase
    
    1
    +from marionette_harness import MarionetteTestCase, TorBrowserMixin
    
    4 2
     
    
    5 3
     NETWORK_CHECK_URL = "https://check.torproject.org/"
    
    6
    -TOR_BOOTSTRAP_TIMEOUT = 30  # 30s
    
    7 4
     
    
    8
    -STRINGS_LOCATION = "chrome://torbutton/locale/torConnect.properties"
    
    9
    -
    
    10
    -
    
    11
    -class TestNetworkCheck(MarionetteTestCase):
    
    12
    -    def setUp(self):
    
    13
    -        MarionetteTestCase.setUp(self)
    
    14
    -
    
    15
    -        self.l10n = L10n(self.marionette)
    
    16
    -
    
    17
    -    def tearDown(self):
    
    18
    -        self.marionette.restart(in_app=False, clean=True)
    
    19
    -        super().tearDown()
    
    20
    -
    
    21
    -    def attemptConnection(self, tries=1):
    
    22
    -        if tries > 3:
    
    23
    -            self.assertTrue(False, "Failed to connect to Tor after 3 attempts")
    
    24
    -
    
    25
    -        connectBtn = self.marionette.find_element(By.ID, "connectButton")
    
    26
    -        Wait(self.marionette, timeout=10).until(
    
    27
    -            lambda _: connectBtn.is_displayed(),
    
    28
    -            message="Timed out waiting for tor connect button to show up.",
    
    29
    -        )
    
    30
    -        connectBtn.click()
    
    31
    -
    
    32
    -        try:
    
    33
    -
    
    34
    -            def check(m):
    
    35
    -                if not m.get_url().startswith("about:torconnect"):
    
    36
    -                    # We have finished connecting and have been redirected.
    
    37
    -                    return True
    
    38
    -
    
    39
    -                try:
    
    40
    -                    heading = self.marionette.find_element(By.ID, "tor-connect-heading")
    
    41
    -                except errors.NoSuchElementException:
    
    42
    -                    # Page is probably redirecting.
    
    43
    -                    return False
    
    44
    -
    
    45
    -                if heading.text not in [
    
    46
    -                    self.l10n.localize_property(
    
    47
    -                        [STRINGS_LOCATION], "torConnect.torConnecting"
    
    48
    -                    ),
    
    49
    -                    self.l10n.localize_property(
    
    50
    -                        [STRINGS_LOCATION], "torConnect.torConnected"
    
    51
    -                    ),
    
    52
    -                ]:
    
    53
    -                    raise ValueError("Tor connect page is not connecting or connected")
    
    54
    -
    
    55
    -                return False
    
    56
    -
    
    57
    -            Wait(self.marionette, timeout=TOR_BOOTSTRAP_TIMEOUT).until(check)
    
    58
    -        except (errors.TimeoutException, ValueError):
    
    59
    -            cancelBtn = self.marionette.find_element(By.ID, "cancelButton")
    
    60
    -            if cancelBtn.is_displayed():
    
    61
    -                cancelBtn.click()
    
    62
    -
    
    63
    -            self.attemptConnection(tries + 1)
    
    64 5
     
    
    6
    +class TestNetworkCheck(MarionetteTestCase, TorBrowserMixin):
    
    65 7
         def test_network_check(self):
    
    66
    -        self.attemptConnection()
    
    8
    +        self.bootstrap()
    
    67 9
             self.marionette.navigate(NETWORK_CHECK_URL)
    
    68 10
             self.assertRegex(
    
    69 11
                 self.marionette.title,