Path: blob/trunk/py/selenium/webdriver/common/options.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.1617import warnings18from abc import ABCMeta, abstractmethod19from enum import Enum20from typing import Optional2122from selenium.common.exceptions import InvalidArgumentException23from selenium.webdriver.common.proxy import Proxy242526class PageLoadStrategy(str, Enum):27"""Enum of possible page load strategies.2829Selenium support following strategies:30* normal (default) - waits for all resources to download31* eager - DOM access is ready, but other resources like images may still be loading32* none - does not block `WebDriver` at all3334Docs: https://www.selenium.dev/documentation/webdriver/drivers/options/#pageloadstrategy.35"""3637normal = "normal"38eager = "eager"39none = "none"404142class _BaseOptionsDescriptor:43def __init__(self, name):44self.name = name4546def __get__(self, obj, cls):47if self.name == "enableBidi":48# whether BiDi is or will be enabled49value = obj._caps.get("webSocketUrl")50return value is True or isinstance(value, str)51if self.name == "webSocketUrl":52# Return socket url or None if not created yet53value = obj._caps.get(self.name)54return None if not isinstance(value, str) else value55if self.name in ("acceptInsecureCerts", "strictFileInteractability", "setWindowRect", "se:downloadsEnabled"):56return obj._caps.get(self.name, False)57return obj._caps.get(self.name)5859def __set__(self, obj, value):60if self.name == "enableBidi":61obj.set_capability("webSocketUrl", value)62else:63obj.set_capability(self.name, value)646566class _PageLoadStrategyDescriptor:67"""Determines the point at which a navigation command is returned:68https://w3c.github.io/webdriver/#dfn-table-of-page-load-strategies.6970:param strategy: the strategy corresponding to a document readiness state71"""7273def __init__(self, name):74self.name = name7576def __get__(self, obj, cls):77return obj._caps.get(self.name)7879def __set__(self, obj, value):80if value in ("normal", "eager", "none"):81obj.set_capability(self.name, value)82else:83raise ValueError("Strategy can only be one of the following: normal, eager, none")848586class _UnHandledPromptBehaviorDescriptor:87"""How the driver should respond when an alert is present and the:88command sent is not handling the alert:89https://w3c.github.io/webdriver/#dfn-table-of-page-load-strategies:9091:param behavior: behavior to use when an alert is encountered9293:returns: Values for implicit timeout, pageLoad timeout and script timeout if set (in milliseconds)94"""9596def __init__(self, name):97self.name = name9899def __get__(self, obj, cls):100return obj._caps.get(self.name)101102def __set__(self, obj, value):103if value in ("dismiss", "accept", "dismiss and notify", "accept and notify", "ignore"):104obj.set_capability(self.name, value)105else:106raise ValueError(107"Behavior can only be one of the following: dismiss, accept, dismiss and notify, "108"accept and notify, ignore"109)110111112class _TimeoutsDescriptor:113"""How long the driver should wait for actions to complete before:114returning an error https://w3c.github.io/webdriver/#timeouts:115116:param timeouts: values in milliseconds for implicit wait, page load and script timeout117118:returns: Values for implicit timeout, pageLoad timeout and script timeout if set (in milliseconds)119"""120121def __init__(self, name):122self.name = name123124def __get__(self, obj, cls):125return obj._caps.get(self.name)126127def __set__(self, obj, value):128if all(x in ("implicit", "pageLoad", "script") for x in value.keys()):129obj.set_capability(self.name, value)130else:131raise ValueError("Timeout keys can only be one of the following: implicit, pageLoad, script")132133134class _ProxyDescriptor:135""":Returns: Proxy if set, otherwise None."""136137def __init__(self, name):138self.name = name139140def __get__(self, obj, cls):141return obj._proxy142143def __set__(self, obj, value):144if not isinstance(value, Proxy):145raise InvalidArgumentException("Only Proxy objects can be passed in.")146obj._proxy = value147obj._caps[self.name] = value.to_capabilities()148149150class BaseOptions(metaclass=ABCMeta):151"""Base class for individual browser options."""152153browser_version = _BaseOptionsDescriptor("browserVersion")154"""Gets and Sets the version of the browser.155156Usage:157------158- Get159- `self.browser_version`160- Set161- `self.browser_version` = `value`162163Parameters:164-----------165`value`: `str`166167Returns:168--------169- Get170- `str`171- Set172- `None`173"""174175platform_name = _BaseOptionsDescriptor("platformName")176"""Gets and Sets name of the platform.177178Usage:179------180- Get181- `self.platform_name`182- Set183- `self.platform_name` = `value`184185Parameters:186-----------187`value`: `str`188189Returns:190--------191- Get192- `str`193- Set194- `None`195"""196197accept_insecure_certs = _BaseOptionsDescriptor("acceptInsecureCerts")198"""Gets and Set whether the session accepts insecure certificates.199200Usage:201------202- Get203- `self.accept_insecure_certs`204- Set205- `self.accept_insecure_certs` = `value`206207Parameters:208-----------209`value`: `bool`210211Returns:212--------213- Get214- `bool`215- Set216- `None`217"""218219strict_file_interactability = _BaseOptionsDescriptor("strictFileInteractability")220"""Gets and Sets whether session is about file interactability.221222Usage:223------224- Get225- `self.strict_file_interactability`226- Set227- `self.strict_file_interactability` = `value`228229Parameters:230-----------231`value`: `bool`232233Returns:234--------235- Get236- `bool`237- Set238- `None`239"""240241set_window_rect = _BaseOptionsDescriptor("setWindowRect")242"""Gets and Sets window size and position.243244Usage:245------246- Get247- `self.set_window_rect`248- Set249- `self.set_window_rect` = `value`250251Parameters:252-----------253`value`: `bool`254255Returns:256--------257- Get258- `bool`259- Set260- `None`261"""262263enable_bidi = _BaseOptionsDescriptor("enableBidi")264"""Gets and Set whether the session has WebDriverBiDi enabled.265266Usage:267------268- Get269- `self.enable_bidi`270- Set271- `self.enable_bidi` = `value`272273Parameters:274-----------275`value`: `bool`276277Returns:278--------279- Get280- `bool`281- Set282- `None`283"""284285page_load_strategy = _PageLoadStrategyDescriptor("pageLoadStrategy")286""":Gets and Sets page load strategy, the default is "normal".287288Usage:289------290- Get291- `self.page_load_strategy`292- Set293- `self.page_load_strategy` = `value`294295Parameters:296-----------297`value`: `str`298299Returns:300--------301- Get302- `str`303- Set304- `None`305"""306307unhandled_prompt_behavior = _UnHandledPromptBehaviorDescriptor("unhandledPromptBehavior")308""":Gets and Sets unhandled prompt behavior, the default is "dismiss and309notify".310311Usage:312------313- Get314- `self.unhandled_prompt_behavior`315- Set316- `self.unhandled_prompt_behavior` = `value`317318Parameters:319-----------320`value`: `str`321322Returns:323--------324- Get325- `str`326- Set327- `None`328"""329330timeouts = _TimeoutsDescriptor("timeouts")331""":Gets and Sets implicit timeout, pageLoad timeout and script timeout if332set (in milliseconds)333334Usage:335------336- Get337- `self.timeouts`338- Set339- `self.timeouts` = `value`340341Parameters:342-----------343`value`: `dict`344345Returns:346--------347- Get348- `dict`349- Set350- `None`351"""352353proxy = _ProxyDescriptor("proxy")354"""Sets and Gets Proxy.355356Usage:357------358- Get359- `self.proxy`360- Set361- `self.proxy` = `value`362363Parameters:364-----------365`value`: `Proxy`366367Returns:368--------369- Get370- `Proxy`371- Set372- `None`373"""374375enable_downloads = _BaseOptionsDescriptor("se:downloadsEnabled")376"""Gets and Sets whether session can download files.377378Usage:379------380- Get381- `self.enable_downloads`382- Set383- `self.enable_downloads` = `value`384385Parameters:386-----------387`value`: `bool`388389Returns:390--------391- Get392- `bool`393- Set394- `None`395"""396397web_socket_url = _BaseOptionsDescriptor("webSocketUrl")398"""Gets and Sets WebSocket URL.399400Usage:401------402- Get403- `self.web_socket_url`404- Set405- `self.web_socket_url` = `value`406407Parameters:408-----------409`value`: `str`410411Returns:412--------413- Get414- `bool`415- Set416- `None`417"""418419def __init__(self) -> None:420super().__init__()421self._caps = self.default_capabilities422self._proxy = None423self.set_capability("pageLoadStrategy", PageLoadStrategy.normal)424self.mobile_options: Optional[dict[str, str]] = None425self._ignore_local_proxy = False426427@property428def capabilities(self):429return self._caps430431def set_capability(self, name, value) -> None:432"""Sets a capability."""433self._caps[name] = value434435def enable_mobile(436self,437android_package: Optional[str] = None,438android_activity: Optional[str] = None,439device_serial: Optional[str] = None,440) -> None:441"""Enables mobile browser use for browsers that support it.442443:Args:444android_activity: The name of the android package to start445"""446if not android_package:447raise AttributeError("android_package must be passed in")448self.mobile_options = {"androidPackage": android_package}449if android_activity:450self.mobile_options["androidActivity"] = android_activity451if device_serial:452self.mobile_options["androidDeviceSerial"] = device_serial453454@abstractmethod455def to_capabilities(self):456"""Convert options into capabilities dictionary."""457458@property459@abstractmethod460def default_capabilities(self):461"""Return minimal capabilities necessary as a dictionary."""462463def ignore_local_proxy_environment_variables(self) -> None:464"""By calling this you will ignore HTTP_PROXY and HTTPS_PROXY from465being picked up and used."""466self._ignore_local_proxy = True467468469class ArgOptions(BaseOptions):470BINARY_LOCATION_ERROR = "Binary Location Must be a String"471# FedCM capability key472FEDCM_CAPABILITY = "fedcm:accounts"473474def __init__(self) -> None:475super().__init__()476self._arguments: list[str] = []477478@property479def arguments(self):480""":Returns: A list of arguments needed for the browser."""481return self._arguments482483def add_argument(self, argument: str) -> None:484"""Adds an argument to the list.485486:Args:487- Sets the arguments488"""489if argument:490self._arguments.append(argument)491else:492raise ValueError("argument can not be null")493494def ignore_local_proxy_environment_variables(self) -> None:495"""By calling this you will ignore HTTP_PROXY and HTTPS_PROXY from496being picked up and used."""497warnings.warn(498"using ignore_local_proxy_environment_variables in Options has been deprecated, "499"instead, create a Proxy instance with ProxyType.DIRECT to ignore proxy settings, "500"pass the proxy instance into a ClientConfig constructor, "501"pass the client config instance into the Webdriver constructor",502DeprecationWarning,503stacklevel=2,504)505506super().ignore_local_proxy_environment_variables()507508def to_capabilities(self):509return self._caps510511@property512def default_capabilities(self):513return {}514515516