Path: blob/trunk/py/selenium/webdriver/chromium/webdriver.py
3987 views
# Licensed to the Software Freedom Conservancy (SFC) under one1# or more contributor license agreements. See the NOTICE file2# distributed with this work for additional information3# regarding copyright ownership. The SFC licenses this file4# to you under the Apache License, Version 2.0 (the5# "License"); you may not use this file except in compliance6# with the License. You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing,11# software distributed under the License is distributed on an12# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13# KIND, either express or implied. See the License for the14# specific language governing permissions and limitations15# under the License.1617from selenium.webdriver.chromium.options import ChromiumOptions18from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection19from selenium.webdriver.chromium.service import ChromiumService20from selenium.webdriver.common.driver_finder import DriverFinder21from selenium.webdriver.common.webdriver import LocalWebDriver22from selenium.webdriver.remote.command import Command232425class ChromiumDriver(LocalWebDriver):26"""Control the WebDriver instance of ChromiumDriver and drive the browser."""2728def __init__(29self,30browser_name: str,31vendor_prefix: str,32options: ChromiumOptions | None = None,33service: ChromiumService | None = None,34keep_alive: bool = True,35) -> None:36"""Create a new WebDriver instance, start the service, and create new ChromiumDriver instance.3738Args:39browser_name: Browser name used when matching capabilities.40vendor_prefix: Company prefix to apply to vendor-specific WebDriver extension commands.41options: Instance of ChromiumOptions.42service: Service object for handling the browser driver if you need to pass extra details.43keep_alive: Whether to configure ChromiumRemoteConnection to use HTTP keep-alive.44"""45self.service = service if service else ChromiumService()46self.options = options if options else ChromiumOptions()4748finder = DriverFinder(self.service, self.options)49if finder.get_browser_path():50self.options.binary_location = finder.get_browser_path()51self.options.browser_version = None5253self.service.path = self.service.env_path() or finder.get_driver_path()54self.service.start()5556executor = ChromiumRemoteConnection(57remote_server_addr=self.service.service_url,58browser_name=browser_name,59vendor_prefix=vendor_prefix,60keep_alive=keep_alive,61ignore_proxy=self.options._ignore_local_proxy,62)6364try:65super().__init__(command_executor=executor, options=self.options)66except Exception:67self.quit()68raise6970def launch_app(self, id):71"""Launches Chromium app specified by id.7273Args:74id: The id of the Chromium app to launch.75"""76return self.execute("launchApp", {"id": id})7778def get_network_conditions(self):79"""Gets Chromium network emulation settings.8081Returns:82A dict. For example: {'latency': 4, 'download_throughput': 2, 'upload_throughput': 2}83"""84return self.execute("getNetworkConditions")["value"]8586def set_network_conditions(self, **network_conditions) -> None:87"""Sets Chromium network emulation settings.8889Args:90**network_conditions: A dict with conditions specification.9192Example:93driver.set_network_conditions(94offline=False,95latency=5, # additional latency (ms)96download_throughput=500 * 1024, # maximal throughput97upload_throughput=500 * 1024,98) # maximal throughput99100Note: `throughput` can be used to set both (for download and upload).101"""102self.execute("setNetworkConditions", {"network_conditions": network_conditions})103104def delete_network_conditions(self) -> None:105"""Resets Chromium network emulation settings."""106self.execute("deleteNetworkConditions")107108def set_permissions(self, name: str, value: str) -> None:109"""Sets Applicable Permission.110111Args:112name: The item to set the permission on.113value: The value to set on the item114115Example:116driver.set_permissions("clipboard-read", "denied")117"""118self.execute("setPermissions", {"descriptor": {"name": name}, "state": value})119120def execute_cdp_cmd(self, cmd: str, cmd_args: dict):121"""Execute Chrome Devtools Protocol command and get returned result.122123The command and command args should follow chrome devtools protocol domains/commands124125See:126- https://chromedevtools.github.io/devtools-protocol/127128Args:129cmd: A str, command name130cmd_args: A dict, command args. empty dict {} if there is no command args131132Example:133`driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})`134135Returns:136A dict, empty dict {} if there is no result to return.137For example to getResponseBody:138{'base64Encoded': False, 'body': 'response body string'}139"""140return super().execute_cdp_cmd(cmd, cmd_args)141142def get_sinks(self) -> list:143"""Get a list of sinks available for Cast."""144return self.execute("getSinks")["value"]145146def get_issue_message(self):147"""Returns an error message when there is any issue in a Cast session."""148return self.execute("getIssueMessage")["value"]149150@property151def log_types(self):152"""Gets a list of the available log types.153154Example:155--------156>>> driver.log_types157"""158return self.execute(Command.GET_AVAILABLE_LOG_TYPES)["value"]159160def get_log(self, log_type):161"""Gets the log for a given log type.162163Args:164log_type: Type of log that which will be returned165166Example:167>>> driver.get_log("browser")168>>> driver.get_log("driver")169>>> driver.get_log("client")170>>> driver.get_log("server")171"""172return self.execute(Command.GET_LOG, {"type": log_type})["value"]173174def set_sink_to_use(self, sink_name: str) -> dict:175"""Set a specific sink as a Cast session receiver target.176177Args:178sink_name: Name of the sink to use as the target.179"""180return self.execute("setSinkToUse", {"sinkName": sink_name})181182def start_desktop_mirroring(self, sink_name: str) -> dict:183"""Starts a desktop mirroring session on a specific receiver target.184185Args:186sink_name: Name of the sink to use as the target.187"""188return self.execute("startDesktopMirroring", {"sinkName": sink_name})189190def start_tab_mirroring(self, sink_name: str) -> dict:191"""Starts a tab mirroring session on a specific receiver target.192193Args:194sink_name: Name of the sink to use as the target.195"""196return self.execute("startTabMirroring", {"sinkName": sink_name})197198def stop_casting(self, sink_name: str) -> dict:199"""Stops the existing Cast session on a specific receiver target.200201Args:202sink_name: Name of the sink to stop the Cast session.203"""204return self.execute("stopCasting", {"sinkName": sink_name})205206207