From 2b329a9ea602160a13dde6a1d35fdec2c940d050 Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 01:51:51 +0700 Subject: [PATCH 1/7] Refactor docstrings for consistency and clarity across WebDriver and ChromiumOptions classes --- py/selenium/webdriver/chrome/webdriver.py | 13 ++-- py/selenium/webdriver/chromium/options.py | 77 ++++++++++--------- .../webdriver/firefox/firefox_binary.py | 10 +-- py/selenium/webdriver/firefox/webdriver.py | 24 +++--- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/py/selenium/webdriver/chrome/webdriver.py b/py/selenium/webdriver/chrome/webdriver.py index dc38bdc8dbafc..44882bcf4cae0 100644 --- a/py/selenium/webdriver/chrome/webdriver.py +++ b/py/selenium/webdriver/chrome/webdriver.py @@ -32,13 +32,14 @@ def __init__( service: Optional[Service] = None, keep_alive: bool = True, ) -> None: - """Creates a new instance of the chrome driver. Starts the service and - then creates new instance of chrome driver. + """Creates a new instance of the chrome driver. - :Args: - - options - this takes an instance of ChromeOptions - - service - Service object for handling the browser driver if you need to pass extra details - - keep_alive - Whether to configure ChromeRemoteConnection to use HTTP keep-alive. + Starts the service and then creates new instance of chrome driver. + + Args: + options: This takes an instance of ChromeOptions. + service: Service object for handling the browser driver if you need to pass extra details. + keep_alive: Whether to configure ChromeRemoteConnection to use HTTP keep-alive. """ service = service if service else Service() options = options if options else Options() diff --git a/py/selenium/webdriver/chromium/options.py b/py/selenium/webdriver/chromium/options.py index c7b35d612ee7e..d11baf5a91ded 100644 --- a/py/selenium/webdriver/chromium/options.py +++ b/py/selenium/webdriver/chromium/options.py @@ -27,6 +27,7 @@ class ChromiumOptions(ArgOptions): KEY = "goog:chromeOptions" def __init__(self) -> None: + """Initialize ChromiumOptions with default settings.""" super().__init__() self._binary_location: str = "" self._extension_files: list[str] = [] @@ -37,16 +38,17 @@ def __init__(self) -> None: @property def binary_location(self) -> str: - """:Returns: The location of the binary, otherwise an empty string.""" + """Returns: + The location of the binary, otherwise an empty string. + """ return self._binary_location @binary_location.setter def binary_location(self, value: str) -> None: """Allows you to set where the chromium binary lives. - Parameters: - ---------- - value: path to the Chromium binary + Args: + value: Path to the Chromium binary. """ if not isinstance(value, str): raise TypeError(self.BINARY_LOCATION_ERROR) @@ -54,7 +56,9 @@ def binary_location(self, value: str) -> None: @property def debugger_address(self) -> Optional[str]: - """:Returns: The address of the remote devtools instance.""" + """Returns: + The address of the remote devtools instance. + """ return self._debugger_address @debugger_address.setter @@ -62,9 +66,8 @@ def debugger_address(self, value: str) -> None: """Allows you to set the address of the remote devtools instance that the ChromeDriver instance will try to connect to during an active wait. - Parameters: - ---------- - value: address of remote devtools instance if any (hostname[:port]) + Args: + value: Address of remote devtools instance if any (hostname[:port]). """ if not isinstance(value, str): raise TypeError("Debugger Address must be a string") @@ -72,7 +75,9 @@ def debugger_address(self, value: str) -> None: @property def extensions(self) -> list[str]: - """:Returns: A list of encoded extensions that will be loaded.""" + """Returns: + A list of encoded extensions that will be loaded. + """ def _decode(file_data: BinaryIO) -> str: # Should not use base64.encodestring() which inserts newlines every @@ -91,9 +96,8 @@ def add_extension(self, extension: str) -> None: """Adds the path to the extension to a list that will be used to extract it to the ChromeDriver. - Parameters: - ---------- - extension: path to the \\*.crx file + Args: + extension: Path to the \\*.crx file. """ if extension: extension_to_add = os.path.abspath(os.path.expanduser(extension)) @@ -108,9 +112,8 @@ def add_encoded_extension(self, extension: str) -> None: """Adds Base64 encoded string with extension data to a list that will be used to extract it to the ChromeDriver. - Parameters: - ---------- - extension: Base64 encoded string with extension data + Args: + extension: Base64 encoded string with extension data. """ if extension: self._extensions.append(extension) @@ -119,23 +122,25 @@ def add_encoded_extension(self, extension: str) -> None: @property def experimental_options(self) -> dict: - """:Returns: A dictionary of experimental options for chromium.""" + """Returns: + A dictionary of experimental options for chromium. + """ return self._experimental_options def add_experimental_option(self, name: str, value: Union[str, int, dict, list[str]]) -> None: """Adds an experimental option which is passed to chromium. - Parameters: - ---------- - name: The experimental option name. - value: The option value. + Args: + name: The experimental option name. + value: The option value. """ self._experimental_options[name] = value @property def enable_webextensions(self) -> bool: - """:Returns: Whether webextension support is enabled for Chromium-based browsers. - True if webextension support is enabled, False otherwise. + """Returns: + Whether webextension support is enabled for Chromium-based browsers. + True if webextension support is enabled, False otherwise. """ return self._enable_webextensions @@ -143,21 +148,18 @@ def enable_webextensions(self) -> bool: def enable_webextensions(self, value: bool) -> None: """Enables or disables webextension support for Chromium-based browsers. - Parameters: - ---------- - value : bool - True to enable webextension support, False to disable. + Args: + value: True to enable webextension support, False to disable. Notes: - ----- - - When enabled, this automatically adds the required Chromium flags: - - --enable-unsafe-extension-debugging - - --remote-debugging-pipe - - When disabled, this removes BOTH flags listed above, even if they were manually added via add_argument() - before enabling webextensions. - - Enabling --remote-debugging-pipe makes the connection b/w chromedriver - and the browser use a pipe instead of a port, disabling many CDP functionalities - like devtools + - When enabled, this automatically adds the required Chromium flags: + - --enable-unsafe-extension-debugging + - --remote-debugging-pipe + - When disabled, this removes BOTH flags listed above, even if they were manually added via add_argument() + before enabling webextensions. + - Enabling --remote-debugging-pipe makes the connection b/w chromedriver + and the browser use a pipe instead of a port, disabling many CDP functionalities + like devtools """ self._enable_webextensions = value if value: @@ -174,11 +176,10 @@ def enable_webextensions(self, value: bool) -> None: self._arguments.remove(flag) def to_capabilities(self) -> dict: - """Creates a capabilities with all the options that have been set + """Creates a capabilities with all the options that have been set. Returns: - ------- - dict : a dictionary with all set options + A dictionary with all set options. """ caps = self._caps chrome_options = self.experimental_options.copy() diff --git a/py/selenium/webdriver/firefox/firefox_binary.py b/py/selenium/webdriver/firefox/firefox_binary.py index 0932fa11e4176..a3efc036318bc 100644 --- a/py/selenium/webdriver/firefox/firefox_binary.py +++ b/py/selenium/webdriver/firefox/firefox_binary.py @@ -34,11 +34,11 @@ class FirefoxBinary: def __init__(self, firefox_path=None, log_file=None): """Creates a new instance of Firefox binary. - :Args: - - firefox_path - Path to the Firefox executable. By default, it will be detected from the standard locations. - - log_file - A file object to redirect the firefox process output to. It can be sys.stdout. - Please note that with parallel run the output won't be synchronous. - By default, it will be redirected to /dev/null. + Args: + firefox_path: Path to the Firefox executable. By default, it will be detected from the standard locations. + log_file: A file object to redirect the firefox process output to. It can be sys.stdout. + Please note that with parallel run the output won't be synchronous. + By default, it will be redirected to /dev/null. """ self._start_cmd = firefox_path # We used to default to subprocess.PIPE instead of /dev/null, but after diff --git a/py/selenium/webdriver/firefox/webdriver.py b/py/selenium/webdriver/firefox/webdriver.py index f8cc1418ee38b..e69456a97adc1 100644 --- a/py/selenium/webdriver/firefox/webdriver.py +++ b/py/selenium/webdriver/firefox/webdriver.py @@ -44,10 +44,10 @@ def __init__( """Creates a new instance of the Firefox driver. Starts the service and then creates new instance of Firefox driver. - :Args: - - options - Instance of ``options.Options``. - - service - (Optional) service instance for managing the starting and stopping of the driver. - - keep_alive - Whether to configure remote_connection.RemoteConnection to use HTTP keep-alive. + Args: + options: Instance of ``options.Options``. + service: (Optional) service instance for managing the starting and stopping of the driver. + keep_alive: Whether to configure remote_connection.RemoteConnection to use HTTP keep-alive. """ self.service = service if service else Service() @@ -159,11 +159,11 @@ def get_full_page_screenshot_as_file(self, filename) -> bool: image file. Returns False if there is any IOError, else returns True. Use full paths in your filename. - :Args: - - filename: The full path you wish to save your screenshot to. This - should end with a `.png` extension. + Args: + filename: The full path you wish to save your screenshot to. This + should end with a `.png` extension. - :Usage: + Usage: :: driver.get_full_page_screenshot_as_file("/Screenshots/foo.png") @@ -188,11 +188,11 @@ def save_full_page_screenshot(self, filename) -> bool: image file. Returns False if there is any IOError, else returns True. Use full paths in your filename. - :Args: - - filename: The full path you wish to save your screenshot to. This - should end with a `.png` extension. + Args: + filename: The full path you wish to save your screenshot to. This + should end with a `.png` extension. - :Usage: + Usage: :: driver.save_full_page_screenshot("/Screenshots/foo.png") From d3af98d08bfe5509b4a1d8110360ab49949456bf Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 01:59:37 +0700 Subject: [PATCH 2/7] Refactor docstrings in ChromiumDriver for consistency and clarity --- py/selenium/webdriver/chromium/webdriver.py | 107 ++++++++++---------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/py/selenium/webdriver/chromium/webdriver.py b/py/selenium/webdriver/chromium/webdriver.py index 59700c1a24803..f99ddd82173cc 100644 --- a/py/selenium/webdriver/chromium/webdriver.py +++ b/py/selenium/webdriver/chromium/webdriver.py @@ -40,12 +40,12 @@ def __init__( """Creates a new WebDriver instance of the ChromiumDriver. Starts the service and then creates new WebDriver instance of ChromiumDriver. - :Args: - - browser_name - Browser name used when matching capabilities. - - vendor_prefix - Company prefix to apply to vendor-specific WebDriver extension commands. - - options - this takes an instance of ChromiumOptions - - service - Service object for handling the browser driver if you need to pass extra details - - keep_alive - Whether to configure ChromiumRemoteConnection to use HTTP keep-alive. + Args: + browser_name: Browser name used when matching capabilities. + vendor_prefix: Company prefix to apply to vendor-specific WebDriver extension commands. + options: This takes an instance of ChromiumOptions. + service: Service object for handling the browser driver if you need to pass extra details. + keep_alive: Whether to configure ChromiumRemoteConnection to use HTTP keep-alive. """ self.service = service if service else ChromiumService() @@ -76,33 +76,34 @@ def __init__( self._is_remote = False def launch_app(self, id): - """Launches Chromium app specified by id.""" + """Launches Chromium app specified by id. + + Args: + id: The id of the Chromium app to launch. + """ return self.execute("launchApp", {"id": id}) def get_network_conditions(self): """Gets Chromium network emulation settings. - :Returns: - A dict. - For example: {'latency': 4, 'download_throughput': 2, 'upload_throughput': 2, 'offline': False} + Returns: + A dict. For example: {'latency': 4, 'download_throughput': 2, 'upload_throughput': 2} """ return self.execute("getNetworkConditions")["value"] def set_network_conditions(self, **network_conditions) -> None: """Sets Chromium network emulation settings. - :Args: - - network_conditions: A dict with conditions specification. - - :Usage: - :: + Args: + **network_conditions: A dict with conditions specification. - driver.set_network_conditions( - offline=False, - latency=5, # additional latency (ms) - download_throughput=500 * 1024, # maximal throughput - upload_throughput=500 * 1024, - ) # maximal throughput + Example: + driver.set_network_conditions( + offline=False, + latency=5, # additional latency (ms) + download_throughput=500 * 1024, # maximal throughput + upload_throughput=500 * 1024, + ) # maximal throughput Note: 'throughput' can be used to set both (for download and upload). """ @@ -115,14 +116,12 @@ def delete_network_conditions(self) -> None: def set_permissions(self, name: str, value: str) -> None: """Sets Applicable Permission. - :Args: - - name: The item to set the permission on. - - value: The value to set on the item - - :Usage: - :: + Args: + name: The item to set the permission on. + value: The value to set on the item - driver.set_permissions("clipboard-read", "denied") + Example: + driver.set_permissions("clipboard-read", "denied") """ self.execute("setPermissions", {"descriptor": {"name": name}, "state": value}) @@ -132,14 +131,14 @@ def execute_cdp_cmd(self, cmd: str, cmd_args: dict): domains/commands, refer to link https://chromedevtools.github.io/devtools-protocol/ - :Args: - - cmd: A str, command name - - cmd_args: A dict, command args. empty dict {} if there is no command args - :Usage: - :: + Args: + cmd: A str, command name + cmd_args: A dict, command args. empty dict {} if there is no command args + + Example: + driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}) - driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId}) - :Returns: + Returns: A dict, empty dict {} if there is no result to return. For example to getResponseBody: {'base64Encoded': False, 'body': 'response body string'} @@ -147,11 +146,11 @@ def execute_cdp_cmd(self, cmd: str, cmd_args: dict): return super().execute_cdp_cmd(cmd, cmd_args) def get_sinks(self) -> list: - """:Returns: A list of sinks available for Cast.""" + """Returns: A list of sinks available for Cast.""" return self.execute("getSinks")["value"] def get_issue_message(self): - """:Returns: An error message when there is any issue in a Cast + """Returns: An error message when there is any issue in a Cast session.""" return self.execute("getIssueMessage")["value"] @@ -168,17 +167,14 @@ def log_types(self): def get_log(self, log_type): """Gets the log for a given log type. - Parameters: - ----------- - log_type : str - - Type of log that which will be returned + Args: + log_type: Type of log that which will be returned Example: - -------- - >>> driver.get_log("browser") - >>> driver.get_log("driver") - >>> driver.get_log("client") - >>> driver.get_log("server") + >>> driver.get_log("browser") + >>> driver.get_log("driver") + >>> driver.get_log("client") + >>> driver.get_log("server") """ return self.execute(Command.GET_LOG, {"type": log_type})["value"] @@ -186,32 +182,32 @@ def set_sink_to_use(self, sink_name: str) -> dict: """Sets a specific sink, using its name, as a Cast session receiver target. - :Args: - - sink_name: Name of the sink to use as the target. + Args: + sink_name: Name of the sink to use as the target. """ return self.execute("setSinkToUse", {"sinkName": sink_name}) def start_desktop_mirroring(self, sink_name: str) -> dict: """Starts a desktop mirroring session on a specific receiver target. - :Args: - - sink_name: Name of the sink to use as the target. + Args: + sink_name: Name of the sink to use as the target. """ return self.execute("startDesktopMirroring", {"sinkName": sink_name}) def start_tab_mirroring(self, sink_name: str) -> dict: """Starts a tab mirroring session on a specific receiver target. - :Args: - - sink_name: Name of the sink to use as the target. + Args: + sink_name: Name of the sink to use as the target. """ return self.execute("startTabMirroring", {"sinkName": sink_name}) def stop_casting(self, sink_name: str) -> dict: """Stops the existing Cast session on a specific receiver target. - :Args: - - sink_name: Name of the sink to stop the Cast session. + Args: + sink_name: Name of the sink to stop the Cast session. """ return self.execute("stopCasting", {"sinkName": sink_name}) @@ -226,10 +222,13 @@ def quit(self) -> None: self.service.stop() def download_file(self, *args, **kwargs): + """Download file functionality is not implemented for Chromium driver.""" raise NotImplementedError def get_downloadable_files(self, *args, **kwargs): + """Get downloadable files functionality is not implemented for Chromium driver.""" raise NotImplementedError def delete_downloadable_files(self, *args, **kwargs): + """Delete downloadable files functionality is not implemented for Chromium driver.""" raise NotImplementedError From 1727e34d309cd46bc3b28127af8bfa91859b7c85 Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 02:06:16 +0700 Subject: [PATCH 3/7] Refactor docstrings in EdgeOptions and Service classes for clarity and consistency --- py/selenium/webdriver/edge/options.py | 19 +++++++++++++++++-- py/selenium/webdriver/edge/service.py | 25 +++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/py/selenium/webdriver/edge/options.py b/py/selenium/webdriver/edge/options.py index bb4fe42df6e89..3cc5a50ac0529 100644 --- a/py/selenium/webdriver/edge/options.py +++ b/py/selenium/webdriver/edge/options.py @@ -23,20 +23,32 @@ class Options(ChromiumOptions): KEY = "ms:edgeOptions" def __init__(self) -> None: + """Initialize EdgeOptions with default settings.""" super().__init__() self._use_webview = False @property def use_webview(self) -> bool: + """Returns: + Whether WebView2 is enabled for Edge browser. + """ return self._use_webview @use_webview.setter def use_webview(self, value: bool) -> None: + """Enables or disables WebView2 support for Edge browser. + + Args: + value: True to enable WebView2 support, False to disable. + """ self._use_webview = bool(value) def to_capabilities(self) -> dict: - """Creates a capabilities with all the options that have been set and - :Returns: A dictionary with everything.""" + """Creates a capabilities with all the options that have been set. + + Returns: + A dictionary with all set options for Edge browser. + """ caps = super().to_capabilities() if self._use_webview: caps["browserName"] = "webview2" @@ -45,4 +57,7 @@ def to_capabilities(self) -> dict: @property def default_capabilities(self) -> dict: + """Returns: + The default capabilities for Edge browser. + """ return DesiredCapabilities.EDGE.copy() diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index ef53f24d8f86b..ea957cd960afb 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -26,12 +26,13 @@ class Service(service.ChromiumService): """A Service class that is responsible for the starting and stopping of `msedgedriver`. - :param executable_path: install path of the msedgedriver executable, defaults to `msedgedriver`. - :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. - :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. - :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. - :param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. + Args: + executable_path: Install path of the msedgedriver executable, defaults to `msedgedriver`. + port: Port for the service to run on, defaults to 0 where the operating system will decide. + log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. + service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. + env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. + driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. """ def __init__( @@ -44,6 +45,7 @@ def __init__( driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: + """Initialize Edge service with the specified parameters.""" self._service_args = list(service_args or []) driver_path_env_key = driver_path_env_key or "SE_EDGEDRIVER" @@ -59,10 +61,21 @@ def __init__( @property def service_args(self) -> Sequence[str]: + """Returns: + The sequence of service arguments. + """ return self._service_args @service_args.setter def service_args(self, value: Sequence[str]): + """Sets the service arguments for the Edge driver. + + Args: + value: A sequence of strings representing service arguments. + + Raises: + TypeError: If value is not a sequence or is a string. + """ if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) From 9f33617237b975da6647eba3826a010a2b3b2aa7 Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 02:08:47 +0700 Subject: [PATCH 4/7] applied format.sh --- py/selenium/webdriver/chromium/options.py | 12 ++++++------ py/selenium/webdriver/edge/options.py | 4 ++-- py/selenium/webdriver/edge/service.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/py/selenium/webdriver/chromium/options.py b/py/selenium/webdriver/chromium/options.py index d11baf5a91ded..fa94c8f571054 100644 --- a/py/selenium/webdriver/chromium/options.py +++ b/py/selenium/webdriver/chromium/options.py @@ -39,7 +39,7 @@ def __init__(self) -> None: @property def binary_location(self) -> str: """Returns: - The location of the binary, otherwise an empty string. + The location of the binary, otherwise an empty string. """ return self._binary_location @@ -57,7 +57,7 @@ def binary_location(self, value: str) -> None: @property def debugger_address(self) -> Optional[str]: """Returns: - The address of the remote devtools instance. + The address of the remote devtools instance. """ return self._debugger_address @@ -76,7 +76,7 @@ def debugger_address(self, value: str) -> None: @property def extensions(self) -> list[str]: """Returns: - A list of encoded extensions that will be loaded. + A list of encoded extensions that will be loaded. """ def _decode(file_data: BinaryIO) -> str: @@ -123,7 +123,7 @@ def add_encoded_extension(self, extension: str) -> None: @property def experimental_options(self) -> dict: """Returns: - A dictionary of experimental options for chromium. + A dictionary of experimental options for chromium. """ return self._experimental_options @@ -139,8 +139,8 @@ def add_experimental_option(self, name: str, value: Union[str, int, dict, list[s @property def enable_webextensions(self) -> bool: """Returns: - Whether webextension support is enabled for Chromium-based browsers. - True if webextension support is enabled, False otherwise. + Whether webextension support is enabled for Chromium-based browsers. + True if webextension support is enabled, False otherwise. """ return self._enable_webextensions diff --git a/py/selenium/webdriver/edge/options.py b/py/selenium/webdriver/edge/options.py index 3cc5a50ac0529..52fe81fca0531 100644 --- a/py/selenium/webdriver/edge/options.py +++ b/py/selenium/webdriver/edge/options.py @@ -30,7 +30,7 @@ def __init__(self) -> None: @property def use_webview(self) -> bool: """Returns: - Whether WebView2 is enabled for Edge browser. + Whether WebView2 is enabled for Edge browser. """ return self._use_webview @@ -58,6 +58,6 @@ def to_capabilities(self) -> dict: @property def default_capabilities(self) -> dict: """Returns: - The default capabilities for Edge browser. + The default capabilities for Edge browser. """ return DesiredCapabilities.EDGE.copy() diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index ea957cd960afb..1ce05b6b2d99c 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -62,7 +62,7 @@ def __init__( @property def service_args(self) -> Sequence[str]: """Returns: - The sequence of service arguments. + The sequence of service arguments. """ return self._service_args From 64c759929d4abf0a5d6dcd33262969e8096ce17d Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 02:18:45 +0700 Subject: [PATCH 5/7] replacing unformatted leftovers --- py/selenium/webdriver/firefox/webdriver.py | 61 +++++++++++++--------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/py/selenium/webdriver/firefox/webdriver.py b/py/selenium/webdriver/firefox/webdriver.py index e69456a97adc1..5b3078fe8f2da 100644 --- a/py/selenium/webdriver/firefox/webdriver.py +++ b/py/selenium/webdriver/firefox/webdriver.py @@ -86,6 +86,11 @@ def quit(self) -> None: self.service.stop() def set_context(self, context) -> None: + """Sets the context that Selenium commands are running in. + + Args: + context: Context to set, should be one of CONTEXT_CHROME or CONTEXT_CONTENT. + """ self.execute("SET_CONTEXT", {"context": context}) @contextmanager @@ -94,11 +99,11 @@ def context(self, context): `with` statement. The state of the context on the server is saved before entering the block, and restored upon exiting it. - :param context: Context, may be one of the class properties - `CONTEXT_CHROME` or `CONTEXT_CONTENT`. - - Usage example:: + Args: + context: Context, may be one of the class properties + `CONTEXT_CHROME` or `CONTEXT_CONTENT`. + Example: with selenium.context(selenium.CONTEXT_CHROME): # chrome scope ... do stuff ... @@ -116,13 +121,15 @@ def install_addon(self, path, temporary=False) -> str: Returns identifier of installed addon. This identifier can later be used to uninstall addon. - :param temporary: allows you to load browser extensions temporarily during a session - :param path: Absolute path to the addon that will be installed. + Args: + path: Absolute path to the addon that will be installed. + temporary: Allows you to load browser extensions temporarily during a session. - :Usage: - :: + Returns: + Identifier of installed addon. - driver.install_addon("/path/to/firebug.xpi") + Example: + driver.install_addon("/path/to/firebug.xpi") """ if os.path.isdir(path): @@ -147,10 +154,11 @@ def install_addon(self, path, temporary=False) -> str: def uninstall_addon(self, identifier) -> None: """Uninstalls Firefox addon using its identifier. - :Usage: - :: + Args: + identifier: The addon identifier to uninstall. - driver.uninstall_addon("addon@foo.com") + Example: + driver.uninstall_addon("addon@foo.com") """ self.execute("UNINSTALL_ADDON", {"id": identifier}) @@ -163,10 +171,8 @@ def get_full_page_screenshot_as_file(self, filename) -> bool: filename: The full path you wish to save your screenshot to. This should end with a `.png` extension. - Usage: - :: - - driver.get_full_page_screenshot_as_file("/Screenshots/foo.png") + Example: + driver.get_full_page_screenshot_as_file("/Screenshots/foo.png") """ if not filename.lower().endswith(".png"): warnings.warn( @@ -192,10 +198,8 @@ def save_full_page_screenshot(self, filename) -> bool: filename: The full path you wish to save your screenshot to. This should end with a `.png` extension. - Usage: - :: - - driver.save_full_page_screenshot("/Screenshots/foo.png") + Example: + driver.save_full_page_screenshot("/Screenshots/foo.png") """ return self.get_full_page_screenshot_as_file(filename) @@ -203,10 +207,11 @@ def get_full_page_screenshot_as_png(self) -> bytes: """Gets the full document screenshot of the current window as a binary data. - :Usage: - :: + Returns: + Binary data of the screenshot. - driver.get_full_page_screenshot_as_png() + Example: + driver.get_full_page_screenshot_as_png() """ return base64.b64decode(self.get_full_page_screenshot_as_base64().encode("ascii")) @@ -214,18 +219,22 @@ def get_full_page_screenshot_as_base64(self) -> str: """Gets the full document screenshot of the current window as a base64 encoded string which is useful in embedded images in HTML. - :Usage: - :: + Returns: + Base64 encoded string of the screenshot. - driver.get_full_page_screenshot_as_base64() + Example: + driver.get_full_page_screenshot_as_base64() """ return self.execute("FULL_PAGE_SCREENSHOT")["value"] def download_file(self, *args, **kwargs): + """Download file functionality is not implemented for Firefox driver.""" raise NotImplementedError def get_downloadable_files(self, *args, **kwargs): + """Get downloadable files functionality is not implemented for Firefox driver.""" raise NotImplementedError def delete_downloadable_files(self, *args, **kwargs): + """Delete downloadable files functionality is not implemented for Firefox driver.""" raise NotImplementedError From f44a9ac2852cb2d55a88ef4f865b6539f234214f Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 21:58:21 +0700 Subject: [PATCH 6/7] prettyfy docstrings in ChromiumOptions, Edge Options, and Service classes for clarity and consistency --- py/selenium/webdriver/chromium/options.py | 27 ++++++++++++++--------- py/selenium/webdriver/edge/options.py | 10 +++++---- py/selenium/webdriver/edge/service.py | 5 +++-- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/py/selenium/webdriver/chromium/options.py b/py/selenium/webdriver/chromium/options.py index fa94c8f571054..9c6104a487f6c 100644 --- a/py/selenium/webdriver/chromium/options.py +++ b/py/selenium/webdriver/chromium/options.py @@ -38,8 +38,9 @@ def __init__(self) -> None: @property def binary_location(self) -> str: - """Returns: - The location of the binary, otherwise an empty string. + """ + Returns: + The location of the binary, otherwise an empty string. """ return self._binary_location @@ -56,8 +57,9 @@ def binary_location(self, value: str) -> None: @property def debugger_address(self) -> Optional[str]: - """Returns: - The address of the remote devtools instance. + """ + Returns: + The address of the remote devtools instance. """ return self._debugger_address @@ -75,8 +77,9 @@ def debugger_address(self, value: str) -> None: @property def extensions(self) -> list[str]: - """Returns: - A list of encoded extensions that will be loaded. + """ + Returns: + A list of encoded extensions that will be loaded. """ def _decode(file_data: BinaryIO) -> str: @@ -122,8 +125,9 @@ def add_encoded_extension(self, extension: str) -> None: @property def experimental_options(self) -> dict: - """Returns: - A dictionary of experimental options for chromium. + """ + Returns: + A dictionary of experimental options for chromium. """ return self._experimental_options @@ -138,9 +142,10 @@ def add_experimental_option(self, name: str, value: Union[str, int, dict, list[s @property def enable_webextensions(self) -> bool: - """Returns: - Whether webextension support is enabled for Chromium-based browsers. - True if webextension support is enabled, False otherwise. + """ + Returns: + Whether webextension support is enabled for Chromium-based browsers. + True if webextension support is enabled, False otherwise. """ return self._enable_webextensions diff --git a/py/selenium/webdriver/edge/options.py b/py/selenium/webdriver/edge/options.py index 52fe81fca0531..659b19ce8819d 100644 --- a/py/selenium/webdriver/edge/options.py +++ b/py/selenium/webdriver/edge/options.py @@ -29,8 +29,9 @@ def __init__(self) -> None: @property def use_webview(self) -> bool: - """Returns: - Whether WebView2 is enabled for Edge browser. + """ + Returns: + Whether WebView2 is enabled for Edge browser. """ return self._use_webview @@ -57,7 +58,8 @@ def to_capabilities(self) -> dict: @property def default_capabilities(self) -> dict: - """Returns: - The default capabilities for Edge browser. + """ + Returns: + The default capabilities for Edge browser. """ return DesiredCapabilities.EDGE.copy() diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index 1ce05b6b2d99c..1d2146a4b13ba 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -61,8 +61,9 @@ def __init__( @property def service_args(self) -> Sequence[str]: - """Returns: - The sequence of service arguments. + """ + Returns: + The sequence of service arguments. """ return self._service_args From ac7c4d0e08796a645d41d1e94eba672c6d58d2c1 Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Thu, 16 Oct 2025 22:36:48 +0700 Subject: [PATCH 7/7] Improve docstring formatting in get_sinks and get_issue_message methods for clarity --- py/selenium/webdriver/chromium/webdriver.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/py/selenium/webdriver/chromium/webdriver.py b/py/selenium/webdriver/chromium/webdriver.py index f99ddd82173cc..77b04c70db0ad 100644 --- a/py/selenium/webdriver/chromium/webdriver.py +++ b/py/selenium/webdriver/chromium/webdriver.py @@ -146,12 +146,17 @@ def execute_cdp_cmd(self, cmd: str, cmd_args: dict): return super().execute_cdp_cmd(cmd, cmd_args) def get_sinks(self) -> list: - """Returns: A list of sinks available for Cast.""" + """ + Returns: + A list of sinks available for Cast. + """ return self.execute("getSinks")["value"] def get_issue_message(self): - """Returns: An error message when there is any issue in a Cast - session.""" + """ + Returns: + An error message when there is any issue in a Cast session. + """ return self.execute("getIssueMessage")["value"] @property