Skip to content

Documentation for the browser module

Browser is the module handling the different browser logic and their implementation in order to be used with selenium.

BrowserFactory

Factory class to create browser instances based on the user's default browser.

This class is designed to abstract the process of detecting the default web browser on the user's system and instantiating a corresponding browser object that can be used within the application.

Source code in src/speed_sleuth/browser/__init__.py
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
class BrowserFactory:
    """Factory class to create browser instances based on the user's default
    browser.

    This class is designed to abstract the process of detecting the
    default web browser on the user's system and instantiating a
    corresponding browser object that can be used within the
    application.

    """

    @staticmethod
    def get_browser() -> BrowserInterface:
        """Retrieves an instance of a browser object based on the user's
        default browser.

        The method first detects the default browser and its executable
        path by calling the `detect_default_browser` static method.
        Depending on the detected browser, it then dynamically imports
        and returns an instance of the corresponding browser class.

        Returns:
            browser: An instance of a browser object corresponding to
                the user's default browser and conforming to BrowserInterface.

        Raises:
            ValueError: If the detected default browser is not supported by the
                factory.

        """
        default_browser, path = BrowserFactory.detect_default_browser()

        match default_browser:
            case "MSEdgeHTM":
                from speed_sleuth.browser.ms_edge import MSEdgeBrowser

                return MSEdgeBrowser(path)
            case "google-chrome":
                from speed_sleuth.browser.chromium import ChromiumBrowser

                return ChromiumBrowser(path)
            case _:
                raise ValueError(
                    f"No supported browser found for {default_browser}"
                )

    @staticmethod
    def detect_default_browser() -> tuple[str, str]:
        """Detects the user's default web browser and its executable path.

        This method attempts to identify the default browser set on the
        user's system. It utilizes the platform module to determine the
        operating system and then uses OS-specific methods to find the
        default browser and its path. For Windows, it accesses the
        system registry.

        Returns:
            tuple: A tuple containing the identifier of the default browser and
                its executable path.

        Raises:
            OsNotFoundException: If the operating system is not recognized or
                supported by this method.

        """
        # selenium is able to cope without.
        os_platform = platform.system().lower()

        match os_platform:
            case "windows":  # TODO FIX THIS MESS and use webbrowser
                browser = ""
                path = None
                try:
                    from winreg import (
                        HKEY_CLASSES_ROOT,
                        HKEY_CURRENT_USER,
                        OpenKey,
                        QueryValueEx,
                    )

                    reg_key = OpenKey(
                        HKEY_CURRENT_USER,
                        r"SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice",  # noqa: E501
                    )
                    browser = QueryValueEx(reg_key, "ProgId")[0]

                    reg_key = OpenKey(
                        HKEY_CLASSES_ROOT,
                        r"{}\shell\open\command".format(browser),
                    )
                    browser_path_tuple = QueryValueEx(reg_key, None)
                    path = browser_path_tuple[0].split('"')[1]

                    return browser, path
                except ImportError:
                    pass
                except Exception as e:
                    print(
                        "Failed to look up default browser in system registry: ",  # noqa: E501
                        e,
                    )

            case "linux":
                try:
                    import gc
                    import webbrowser

                    browser_instance = webbrowser.get()
                    browser = browser_instance.basename
                    browser_instance = (
                        None  # Manually free to avoid calling GC
                    )
                    del browser_instance
                    gc.collect()
                    print(f"browser: {browser}")

                    return browser, None
                except ImportError as e:
                    print("Unable to import webbrowser library: ", str(e))

            case _:
                raise OsNotFoundException(
                    f"Your OS {os_platform} is not yet implement."
                )

detect_default_browser() staticmethod

Detects the user's default web browser and its executable path.

This method attempts to identify the default browser set on the user's system. It utilizes the platform module to determine the operating system and then uses OS-specific methods to find the default browser and its path. For Windows, it accesses the system registry.

Returns:

Name Type Description
tuple tuple[str, str]

A tuple containing the identifier of the default browser and its executable path.

Raises:

Type Description
OsNotFoundException

If the operating system is not recognized or supported by this method.

Source code in src/speed_sleuth/browser/__init__.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
@staticmethod
def detect_default_browser() -> tuple[str, str]:
    """Detects the user's default web browser and its executable path.

    This method attempts to identify the default browser set on the
    user's system. It utilizes the platform module to determine the
    operating system and then uses OS-specific methods to find the
    default browser and its path. For Windows, it accesses the
    system registry.

    Returns:
        tuple: A tuple containing the identifier of the default browser and
            its executable path.

    Raises:
        OsNotFoundException: If the operating system is not recognized or
            supported by this method.

    """
    # selenium is able to cope without.
    os_platform = platform.system().lower()

    match os_platform:
        case "windows":  # TODO FIX THIS MESS and use webbrowser
            browser = ""
            path = None
            try:
                from winreg import (
                    HKEY_CLASSES_ROOT,
                    HKEY_CURRENT_USER,
                    OpenKey,
                    QueryValueEx,
                )

                reg_key = OpenKey(
                    HKEY_CURRENT_USER,
                    r"SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice",  # noqa: E501
                )
                browser = QueryValueEx(reg_key, "ProgId")[0]

                reg_key = OpenKey(
                    HKEY_CLASSES_ROOT,
                    r"{}\shell\open\command".format(browser),
                )
                browser_path_tuple = QueryValueEx(reg_key, None)
                path = browser_path_tuple[0].split('"')[1]

                return browser, path
            except ImportError:
                pass
            except Exception as e:
                print(
                    "Failed to look up default browser in system registry: ",  # noqa: E501
                    e,
                )

        case "linux":
            try:
                import gc
                import webbrowser

                browser_instance = webbrowser.get()
                browser = browser_instance.basename
                browser_instance = (
                    None  # Manually free to avoid calling GC
                )
                del browser_instance
                gc.collect()
                print(f"browser: {browser}")

                return browser, None
            except ImportError as e:
                print("Unable to import webbrowser library: ", str(e))

        case _:
            raise OsNotFoundException(
                f"Your OS {os_platform} is not yet implement."
            )

get_browser() staticmethod

Retrieves an instance of a browser object based on the user's default browser.

The method first detects the default browser and its executable path by calling the detect_default_browser static method. Depending on the detected browser, it then dynamically imports and returns an instance of the corresponding browser class.

Returns:

Name Type Description
browser BrowserInterface

An instance of a browser object corresponding to the user's default browser and conforming to BrowserInterface.

Raises:

Type Description
ValueError

If the detected default browser is not supported by the factory.

Source code in src/speed_sleuth/browser/__init__.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@staticmethod
def get_browser() -> BrowserInterface:
    """Retrieves an instance of a browser object based on the user's
    default browser.

    The method first detects the default browser and its executable
    path by calling the `detect_default_browser` static method.
    Depending on the detected browser, it then dynamically imports
    and returns an instance of the corresponding browser class.

    Returns:
        browser: An instance of a browser object corresponding to
            the user's default browser and conforming to BrowserInterface.

    Raises:
        ValueError: If the detected default browser is not supported by the
            factory.

    """
    default_browser, path = BrowserFactory.detect_default_browser()

    match default_browser:
        case "MSEdgeHTM":
            from speed_sleuth.browser.ms_edge import MSEdgeBrowser

            return MSEdgeBrowser(path)
        case "google-chrome":
            from speed_sleuth.browser.chromium import ChromiumBrowser

            return ChromiumBrowser(path)
        case _:
            raise ValueError(
                f"No supported browser found for {default_browser}"
            )

BrowserInterface

BrowserInterface is a generic interface each browser subclass will need to implement in order to correctly configure the selenium webdriver.

This interface ensures that all subclasses provide a specific method to load and configure a Selenium WebDriver instance appropriate for the browser they represent.

Source code in src/speed_sleuth/browser/__init__.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class BrowserInterface(metaclass=abc.ABCMeta):
    """BrowserInterface is a generic interface each browser subclass will need
    to implement in order to correctly configure the selenium webdriver.

    This interface ensures that all subclasses provide a specific method
    to load and configure a Selenium WebDriver instance appropriate for
    the browser they represent.

    """

    @classmethod
    def __subclasshook__(cls, subclass):
        return hasattr(subclass, "load_driver") and callable(
            subclass.load_driver
        )

    @classmethod
    @abc.abstractmethod
    def load_driver(cls) -> WebDriver:
        """Loads and returns a configured instance of Selenium WebDriver
        specific to the browser.

        This method must be implemented by subclasses to provide a
        ready-to-use WebDriver instance that is appropriately configured
        for the browser the subclass represents. The configuration may
        include setting browser options, capabilities, and webdriver
        paths.

        Returns:
            WebDriver: An instance of a Selenium WebDriver ready for browser
                automation tasks.

        """
        pass

load_driver() abstractmethod classmethod

Loads and returns a configured instance of Selenium WebDriver specific to the browser.

This method must be implemented by subclasses to provide a ready-to-use WebDriver instance that is appropriately configured for the browser the subclass represents. The configuration may include setting browser options, capabilities, and webdriver paths.

Returns:

Name Type Description
WebDriver WebDriver

An instance of a Selenium WebDriver ready for browser automation tasks.

Source code in src/speed_sleuth/browser/__init__.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@classmethod
@abc.abstractmethod
def load_driver(cls) -> WebDriver:
    """Loads and returns a configured instance of Selenium WebDriver
    specific to the browser.

    This method must be implemented by subclasses to provide a
    ready-to-use WebDriver instance that is appropriately configured
    for the browser the subclass represents. The configuration may
    include setting browser options, capabilities, and webdriver
    paths.

    Returns:
        WebDriver: An instance of a Selenium WebDriver ready for browser
            automation tasks.

    """
    pass

OsNotFoundException

Bases: Exception

Raised when OS cannot be detected.

Source code in src/speed_sleuth/browser/__init__.py
46
47
class OsNotFoundException(Exception):
    """Raised when OS cannot be detected."""