Path: blob/trunk/py/selenium/webdriver/chromium/webdriver.py
1864 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 typing import Optional1819from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection20from selenium.webdriver.common.driver_finder import DriverFinder21from selenium.webdriver.common.options import ArgOptions22from selenium.webdriver.common.service import Service23from selenium.webdriver.remote.command import Command24from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver252627class ChromiumDriver(RemoteWebDriver):28"""Controls the WebDriver instance of ChromiumDriver and allows you to29drive the browser."""3031def __init__(32self,33browser_name: Optional[str] = None,34vendor_prefix: Optional[str] = None,35options: ArgOptions = ArgOptions(),36service: Optional[Service] = None,37keep_alive: bool = True,38) -> None:39"""Creates a new WebDriver instance of the ChromiumDriver. Starts the40service and then creates new WebDriver instance of ChromiumDriver.4142:Args:43- browser_name - Browser name used when matching capabilities.44- vendor_prefix - Company prefix to apply to vendor-specific WebDriver extension commands.45- options - this takes an instance of ChromiumOptions46- service - Service object for handling the browser driver if you need to pass extra details47- keep_alive - Whether to configure ChromiumRemoteConnection to use HTTP keep-alive.48"""49self.service = service5051finder = DriverFinder(self.service, options)52if finder.get_browser_path():53options.binary_location = finder.get_browser_path()54options.browser_version = None5556self.service.path = self.service.env_path() or finder.get_driver_path()57self.service.start()5859executor = ChromiumRemoteConnection(60remote_server_addr=self.service.service_url,61browser_name=browser_name,62vendor_prefix=vendor_prefix,63keep_alive=keep_alive,64ignore_proxy=options._ignore_local_proxy,65)6667try:68super().__init__(command_executor=executor, options=options)69except Exception:70self.quit()71raise7273self._is_remote = False7475def launch_app(self, id):76"""Launches Chromium app specified by id."""77return self.execute("launchApp", {"id": id})7879def get_network_conditions(self):80"""Gets Chromium network emulation settings.8182:Returns:83A dict.84For example: {'latency': 4, 'download_throughput': 2, 'upload_throughput': 2, 'offline': False}85"""86return self.execute("getNetworkConditions")["value"]8788def set_network_conditions(self, **network_conditions) -> None:89"""Sets Chromium network emulation settings.9091:Args:92- network_conditions: A dict with conditions specification.9394:Usage:95::9697driver.set_network_conditions(98offline=False,99latency=5, # additional latency (ms)100download_throughput=500 * 1024, # maximal throughput101upload_throughput=500 * 1024,102) # maximal throughput103104Note: 'throughput' can be used to set both (for download and upload).105"""106self.execute("setNetworkConditions", {"network_conditions": network_conditions})107108def delete_network_conditions(self) -> None:109"""Resets Chromium network emulation settings."""110self.execute("deleteNetworkConditions")111112def set_permissions(self, name: str, value: str) -> None:113"""Sets Applicable Permission.114115:Args:116- name: The item to set the permission on.117- value: The value to set on the item118119:Usage:120::121122driver.set_permissions("clipboard-read", "denied")123"""124self.execute("setPermissions", {"descriptor": {"name": name}, "state": value})125126def execute_cdp_cmd(self, cmd: str, cmd_args: dict):127"""Execute Chrome Devtools Protocol command and get returned result The128command and command args should follow chrome devtools protocol129domains/commands, refer to link130https://chromedevtools.github.io/devtools-protocol/131132:Args:133- cmd: A str, command name134- cmd_args: A dict, command args. empty dict {} if there is no command args135:Usage:136::137138driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})139:Returns:140A dict, empty dict {} if there is no result to return.141For example to getResponseBody:142{'base64Encoded': False, 'body': 'response body string'}143"""144return super().execute_cdp_cmd(cmd, cmd_args)145146def get_sinks(self) -> list:147""":Returns: A list of sinks available for Cast."""148return self.execute("getSinks")["value"]149150def get_issue_message(self):151""":Returns: An error message when there is any issue in a Cast152session."""153return self.execute("getIssueMessage")["value"]154155@property156def log_types(self):157"""Gets a list of the available log types.158159Example:160--------161>>> driver.log_types162"""163return self.execute(Command.GET_AVAILABLE_LOG_TYPES)["value"]164165def get_log(self, log_type):166"""Gets the log for a given log type.167168Parameters:169-----------170log_type : str171- Type of log that which will be returned172173Example:174--------175>>> driver.get_log("browser")176>>> driver.get_log("driver")177>>> driver.get_log("client")178>>> driver.get_log("server")179"""180return self.execute(Command.GET_LOG, {"type": log_type})["value"]181182def set_sink_to_use(self, sink_name: str) -> dict:183"""Sets a specific sink, using its name, as a Cast session receiver184target.185186:Args:187- sink_name: Name of the sink to use as the target.188"""189return self.execute("setSinkToUse", {"sinkName": sink_name})190191def start_desktop_mirroring(self, sink_name: str) -> dict:192"""Starts a desktop mirroring session on a specific receiver target.193194:Args:195- sink_name: Name of the sink to use as the target.196"""197return self.execute("startDesktopMirroring", {"sinkName": sink_name})198199def start_tab_mirroring(self, sink_name: str) -> dict:200"""Starts a tab mirroring session on a specific receiver target.201202:Args:203- sink_name: Name of the sink to use as the target.204"""205return self.execute("startTabMirroring", {"sinkName": sink_name})206207def stop_casting(self, sink_name: str) -> dict:208"""Stops the existing Cast session on a specific receiver target.209210:Args:211- sink_name: Name of the sink to stop the Cast session.212"""213return self.execute("stopCasting", {"sinkName": sink_name})214215def quit(self) -> None:216"""Closes the browser and shuts down the ChromiumDriver executable."""217try:218super().quit()219except Exception:220# We don't care about the message because something probably has gone wrong221pass222finally:223self.service.stop()224225def download_file(self, *args, **kwargs):226raise NotImplementedError227228def get_downloadable_files(self, *args, **kwargs):229raise NotImplementedError230231232