File: options.py

package info (click to toggle)
python-selenium 4.24.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,404 kB
  • sloc: python: 14,901; javascript: 2,347; makefile: 124; sh: 52
file content (131 lines) | stat: -rw-r--r-- 4,835 bytes parent folder | download
1
2
3
4
5
6
7
8
9
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
44
45
46
47
48
49
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
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
from typing import Union

from typing_extensions import deprecated

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.options import ArgOptions
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile


class Log:
    def __init__(self) -> None:
        self.level = None

    def to_capabilities(self) -> dict:
        if self.level:
            return {"log": {"level": self.level}}
        return {}


class Options(ArgOptions):
    KEY = "moz:firefoxOptions"

    def __init__(self) -> None:
        super().__init__()
        self._binary_location = ""
        self._preferences: dict = {}
        # Firefox 129 onwards the CDP protocol will not be enabled by default. Setting this preference will enable it.
        # https://fxdx.dev/deprecating-cdp-support-in-firefox-embracing-the-future-with-webdriver-bidi/.
        self._preferences["remote.active-protocols"] = 3
        self._profile = None
        self.log = Log()

    @property
    @deprecated("use binary_location instead")
    def binary(self) -> FirefoxBinary:
        """Returns the FirefoxBinary instance."""
        return FirefoxBinary(self._binary_location)

    @binary.setter
    @deprecated("use binary_location instead")
    def binary(self, new_binary: Union[str, FirefoxBinary]) -> None:
        """Sets location of the browser binary, either by string or
        ``FirefoxBinary`` instance."""
        if isinstance(new_binary, FirefoxBinary):
            new_binary = new_binary._start_cmd
        self.binary_location = new_binary

    @property
    def binary_location(self) -> str:
        """:Returns: The location of the binary."""
        return self._binary_location

    @binary_location.setter  # noqa
    def binary_location(self, value: str) -> None:
        """Sets the location of the browser binary by string."""
        if not isinstance(value, str):
            raise TypeError(self.BINARY_LOCATION_ERROR)
        self._binary_location = value

    @property
    def preferences(self) -> dict:
        """:Returns: A dict of preferences."""
        return self._preferences

    def set_preference(self, name: str, value: Union[str, int, bool]):
        """Sets a preference."""
        self._preferences[name] = value

    @property
    def profile(self) -> FirefoxProfile:
        """:Returns: The Firefox profile to use."""
        return self._profile

    @profile.setter
    def profile(self, new_profile: Union[str, FirefoxProfile]) -> None:
        """Sets location of the browser profile to use, either by string or
        ``FirefoxProfile``."""
        if not isinstance(new_profile, FirefoxProfile):
            new_profile = FirefoxProfile(new_profile)
        self._profile = new_profile

    def enable_mobile(self, android_package: str = "org.mozilla.firefox", android_activity=None, device_serial=None):
        super().enable_mobile(android_package, android_activity, device_serial)

    def to_capabilities(self) -> dict:
        """Marshals the Firefox options to a `moz:firefoxOptions` object."""
        # This intentionally looks at the internal properties
        # so if a binary or profile has _not_ been set,
        # it will defer to geckodriver to find the system Firefox
        # and generate a fresh profile.
        caps = self._caps
        opts = {}

        if self._binary_location:
            opts["binary"] = self._binary_location
        if self._preferences:
            opts["prefs"] = self._preferences
        if self._profile:
            opts["profile"] = self._profile.encoded
        if self._arguments:
            opts["args"] = self._arguments
        if self.mobile_options:
            opts.update(self.mobile_options)

        opts.update(self.log.to_capabilities())

        if opts:
            caps[Options.KEY] = opts

        return caps

    @property
    def default_capabilities(self) -> dict:
        return DesiredCapabilities.FIREFOX.copy()