Commit e42a311f authored by Sascha Girrulat's avatar Sascha Girrulat

New upstream version 4.0.0~a1+dfsg1

parent 23be9c48
Selenium 4.0 Alpha 1
* Update driver initialisation to use service and option objects
* turn on keep-alive by default for remote connections (#7072)
* Fix ConnectionResetError
* Add new Cast commands
* Suggest download Microsoft Webdriver over HTTPS
* Clear PoolManager in ‘remote_connection’ to ensure sockets are closed
* remove --disable-gpu option for headless Chrome
* Add support for the New Window command (#6873)
* Update docstrings in Options classes to allow documentation to highlight Return values
* Fix typos in select.py (#6925)
* Remove native events handling code
* Deleting unused imports, fixing flake8 issues
* Remove unused port selection in IE Driver
* Enabling tests xpassed in Chrome
* Pretty-printing code samples
* remove all deprecated methods and args from Python bindings
* Fix DeprecationWarning: invalid escape sequence
* Don't override browser options with desired capabilities by default in WebKitGTK (#6814)
* Add WebKitGTK to API docs (#6815)
* Subclass options classes from a common base class (#6522)
* Update Sphinx (#6728)
* WebDriverWait: update documentation for until and until_not (#6711)
* Fix typo in description of WebDriver class (#6724)
* add strictFileInteractability to acceptable W3C capabilities
* Deprecate Blackberry Driver support
* Fixing/tidying docstring.
Selenium 3.141.0
* Bump version to a better approximation of Π
* Improved Test build targets
* fix os path in test for Windows
* use 'NUL' for /dev/null on Windows
* Update ctor docstrings to explain that a directory passed in is cloned. Fixes #6542
* Allow passing of service_args to Safari. Fixes #6459
* Remove element equals url
* Improved WebExtension support
Selenium 3.14.1
* Fix ability to set timeout for urllib3 (#6286)
* get_cookie uses w3c endpoint when compliant
......
......@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 Software Freedom Conservancy (SFC)
Copyright 2019 Software Freedom Conservancy (SFC)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
......
......@@ -8,8 +8,6 @@ recursive-include selenium/webdriver/chrome *.py
recursive-include selenium/webdriver/opera *.py
recursive-include selenium/webdriver/phantomjs *.py
recursive-include selenium/webdriver/firefox *.py *.xpi *.json
recursive-include selenium/webdriver/firefox/x86 *.so
recursive-include selenium/webdriver/firefox/amd64 *.so
recursive-include selenium/webdriver/ie *.py
recursive-include selenium/webdriver/edge *.py
recursive-include selenium/webdriver/remote *.py *.js
......
Metadata-Version: 1.1
Name: selenium
Version: 3.14.1
Version: 4.0.0a1
Summary: Python bindings for Selenium
Home-page: https://github.com/SeleniumHQ/selenium/
Author: UNKNOWN
Author-email: UNKNOWN
License: Apache 2.0
Description-Content-Type: UNKNOWN
Description: ======================
Selenium Client Driver
======================
......@@ -44,7 +43,7 @@ Description: ======================
pip install -U selenium
Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-3.14.0.tar.gz), unarchive it, and run::
Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.0.0a1.tar.gz), unarchive it, and run::
python setup.py install
......@@ -136,11 +135,11 @@ Description: ======================
However, to use Selenium Webdriver Remote or the legacy Selenium API (Selenium-RC), you need to also run the Selenium server. The server requires a Java Runtime Environment (JRE).
Download the server separately, from: http://selenium-release.storage.googleapis.com/3.14/selenium-server-standalone-3.14.0.jar
Download the server separately, from: http://selenium-release.storage.googleapis.com/4.0/selenium-server-standalone-4.0.0.jar
Run the server from the command line::
java -jar selenium-server-standalone-3.14.0.jar
java -jar selenium-server-standalone-3.141.0.jar
Then run your Python client scripts.
......
......@@ -35,7 +35,7 @@ If you have `pip <https://pip.pypa.io/>`_ on your system, you can simply install
pip install -U selenium
Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-3.14.0.tar.gz), unarchive it, and run::
Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.0.0a1.tar.gz), unarchive it, and run::
python setup.py install
......@@ -127,11 +127,11 @@ For normal WebDriver scripts (non-Remote), the Java server is not needed.
However, to use Selenium Webdriver Remote or the legacy Selenium API (Selenium-RC), you need to also run the Selenium server. The server requires a Java Runtime Environment (JRE).
Download the server separately, from: http://selenium-release.storage.googleapis.com/3.14/selenium-server-standalone-3.14.0.jar
Download the server separately, from: http://selenium-release.storage.googleapis.com/4.0/selenium-server-standalone-4.0.0.jar
Run the server from the command line::
java -jar selenium-server-standalone-3.14.0.jar
java -jar selenium-server-standalone-3.141.0.jar
Then run your Python client scripts.
......
Metadata-Version: 1.1
Name: selenium
Version: 3.14.1
Version: 4.0.0a1
Summary: Python bindings for Selenium
Home-page: https://github.com/SeleniumHQ/selenium/
Author: UNKNOWN
Author-email: UNKNOWN
License: Apache 2.0
Description-Content-Type: UNKNOWN
Description: ======================
Selenium Client Driver
======================
......@@ -44,7 +43,7 @@ Description: ======================
pip install -U selenium
Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-3.14.0.tar.gz), unarchive it, and run::
Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.0.0a1.tar.gz), unarchive it, and run::
python setup.py install
......@@ -136,11 +135,11 @@ Description: ======================
However, to use Selenium Webdriver Remote or the legacy Selenium API (Selenium-RC), you need to also run the Selenium server. The server requires a Java Runtime Environment (JRE).
Download the server separately, from: http://selenium-release.storage.googleapis.com/3.14/selenium-server-standalone-3.14.0.jar
Download the server separately, from: http://selenium-release.storage.googleapis.com/4.0/selenium-server-standalone-4.0.0.jar
Run the server from the command line::
java -jar selenium-server-standalone-3.14.0.jar
java -jar selenium-server-standalone-3.141.0.jar
Then run your Python client scripts.
......
......@@ -29,10 +29,12 @@ selenium/webdriver/common/alert.py
selenium/webdriver/common/by.py
selenium/webdriver/common/desired_capabilities.py
selenium/webdriver/common/keys.py
selenium/webdriver/common/options.py
selenium/webdriver/common/proxy.py
selenium/webdriver/common/service.py
selenium/webdriver/common/touch_actions.py
selenium/webdriver/common/utils.py
selenium/webdriver/common/window.py
selenium/webdriver/common/actions/__init__.py
selenium/webdriver/common/actions/action_builder.py
selenium/webdriver/common/actions/input_device.py
......@@ -59,8 +61,6 @@ selenium/webdriver/firefox/webdriver.py
selenium/webdriver/firefox/webdriver.xpi
selenium/webdriver/firefox/webdriver_prefs.json
selenium/webdriver/firefox/webelement.py
selenium/webdriver/firefox/amd64/x_ignore_nofocus.so
selenium/webdriver/firefox/x86/x_ignore_nofocus.so
selenium/webdriver/ie/__init__.py
selenium/webdriver/ie/options.py
selenium/webdriver/ie/service.py
......
......@@ -16,4 +16,4 @@
# under the License.
__version__ = "3.14.1"
__version__ = "4.0.0a1"
......@@ -133,10 +133,10 @@ class InvalidElementStateException(WebDriverException):
class UnexpectedAlertPresentException(WebDriverException):
"""
Thrown when an unexpected alert is appeared.
Thrown when an unexpected alert has appeared.
Usually raised when when an expected modal is blocking webdriver form executing any
more commands.
Usually raised when an unexpected modal is blocking the webdriver from executing
commands.
"""
def __init__(self, msg=None, screen=None, stacktrace=None, alert_text=None):
super(UnexpectedAlertPresentException, self).__init__(msg, screen, stacktrace)
......
......@@ -36,4 +36,4 @@ from .common.action_chains import ActionChains # noqa
from .common.touch_actions import TouchActions # noqa
from .common.proxy import Proxy # noqa
__version__ = '3.14.1'
__version__ = '4.0.0a1'
......@@ -52,6 +52,11 @@ class WebDriver(RemoteWebDriver):
"""
def __init__(self, device_password, bb_tools_dir=None,
hostip='169.254.0.1', port=1338, desired_capabilities={}):
import warnings
warnings.warn('BlackBerry Driver is no longer supported and will be '
'removed in future versions',
DeprecationWarning, stacklevel=2)
remote_addr = 'http://{}:{}'.format(hostip, port)
filename = 'blackberry-deploy'
......
......@@ -17,28 +17,26 @@
import base64
import os
import platform
import warnings
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.options import ArgOptions
class Options(object):
class Options(ArgOptions):
KEY = "goog:chromeOptions"
def __init__(self):
super(Options, self).__init__()
self._binary_location = ''
self._arguments = []
self._extension_files = []
self._extensions = []
self._experimental_options = {}
self._debugger_address = None
self._caps = DesiredCapabilities.CHROME.copy()
@property
def binary_location(self):
"""
Returns the location of the binary otherwise an empty string
:Returns: The location of the binary, otherwise an empty string
"""
return self._binary_location
......@@ -52,18 +50,10 @@ class Options(object):
"""
self._binary_location = value
@property
def capabilities(self):
return self._caps
def set_capability(self, name, value):
"""Sets a capability."""
self._caps[name] = value
@property
def debugger_address(self):
"""
Returns the address of the remote devtools instance
:Returns: The address of the remote devtools instance
"""
return self._debugger_address
......@@ -79,30 +69,10 @@ class Options(object):
"""
self._debugger_address = value
@property
def arguments(self):
"""
Returns a list of arguments needed for the browser
"""
return self._arguments
def add_argument(self, argument):
"""
Adds an argument to the list
:Args:
- Sets the arguments
"""
if argument:
self._arguments.append(argument)
else:
raise ValueError("argument can not be null")
@property
def extensions(self):
"""
Returns a list of encoded extensions that will be loaded into chrome
:Returns: A list of encoded extensions that will be loaded into chrome
"""
encoded_extensions = []
for ext in self._extension_files:
......@@ -121,7 +91,7 @@ class Options(object):
to the ChromeDriver
:Args:
- extension: path to the \*.crx file
- extension: path to the \\*.crx file
"""
if extension:
extension_to_add = os.path.abspath(os.path.expanduser(extension))
......@@ -148,7 +118,7 @@ class Options(object):
@property
def experimental_options(self):
"""
Returns a dictionary of experimental options for chrome.
:Returns: A dictionary of experimental options for chrome
"""
return self._experimental_options
......@@ -156,7 +126,7 @@ class Options(object):
"""
Adds an experimental option which is passed to chrome.
Args:
:Args:
name: The experimental option name.
value: The option value.
"""
......@@ -165,7 +135,7 @@ class Options(object):
@property
def headless(self):
"""
Returns whether or not the headless argument is set
:Returns: True if the headless argument is set, else False
"""
return '--headless' in self._arguments
......@@ -174,28 +144,20 @@ class Options(object):
"""
Sets the headless argument
Args:
:Args:
value: boolean value indicating to set the headless option
"""
args = {'--headless'}
if platform.system().lower() == 'windows':
args.add('--disable-gpu')
if value is True:
self._arguments.extend(args)
else:
self._arguments = list(set(self._arguments) - args)
def set_headless(self, headless=True):
""" Deprecated, options.headless = True """
warnings.warn('use setter for headless property instead of set_headless',
DeprecationWarning, stacklevel=2)
self.headless = headless
def to_capabilities(self):
"""
Creates a capabilities with all the options that have been set and
Creates a capabilities with all the options that have been set
returns a dictionary with everything
:Returns: A dictionary with everything
"""
caps = self._caps
chrome_options = self.experimental_options.copy()
......@@ -209,3 +171,7 @@ class Options(object):
caps[self.KEY] = chrome_options
return caps
@property
def default_capabilities(self):
return DesiredCapabilities.CHROME.copy()
......@@ -26,3 +26,8 @@ class ChromeRemoteConnection(RemoteConnection):
self._commands["setNetworkConditions"] = ('POST', '/session/$sessionId/chromium/network_conditions')
self._commands["getNetworkConditions"] = ('GET', '/session/$sessionId/chromium/network_conditions')
self._commands['executeCdpCommand'] = ('POST', '/session/$sessionId/goog/cdp/execute')
self._commands['getSinks'] = ('GET', '/session/$sessionId/goog/cast/get_sinks')
self._commands['getIssueMessage'] = ('GET', '/session/$sessionId/goog/cast/get_issue_message')
self._commands['setSinkToUse'] = ('POST', '/session/$sessionId/goog/cast/set_sink_to_use')
self._commands['startTabMirroring'] = ('POST', '/session/$sessionId/goog/cast/start_tab_mirroring')
self._commands['stopCasting'] = ('POST', '/session/$sessionId/goog/cast/stop_casting')
......@@ -15,13 +15,15 @@
# specific language governing permissions and limitations
# under the License.
import warnings
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from .remote_connection import ChromeRemoteConnection
from .service import Service
from .options import Options
DEFAULT_PORT = 0
DEFAULT_SERVICE_LOG_PATH = None
class WebDriver(RemoteWebDriver):
"""
Controls the ChromeDriver and allows you to drive the browser.
......@@ -30,26 +32,40 @@ class WebDriver(RemoteWebDriver):
http://chromedriver.storage.googleapis.com/index.html
"""
def __init__(self, executable_path="chromedriver", port=0,
def __init__(self, executable_path="chromedriver", port=DEFAULT_PORT,
options=None, service_args=None,
desired_capabilities=None, service_log_path=None,
chrome_options=None, keep_alive=True):
desired_capabilities=None, service_log_path=DEFAULT_SERVICE_LOG_PATH,
chrome_options=None, service=None, keep_alive=True):
"""
Creates a new instance of the chrome driver.
Starts the service and then creates new instance of chrome driver.
:Args:
- executable_path - path to the executable. If the default is used it assumes the executable is in the $PATH
- port - port you would like the service to run, if left as 0, a free port will be found.
- executable_path - Deprecated: path to the executable. If the default is used it assumes the executable is in the $PATH
- port - Deprecated: port you would like the service to run, if left as 0, a free port will be found.
- options - this takes an instance of ChromeOptions
- service_args - List of args to pass to the driver service
- desired_capabilities - Dictionary object with non-browser specific
- service_args - Deprecated: List of args to pass to the driver service
- desired_capabilities - Deprecated: Dictionary object with non-browser specific
capabilities only, such as "proxy" or "loggingPref".
- service_log_path - Where to log information from the driver.
- chrome_options - Deprecated argument for options
- service_log_path - Deprecated: Where to log information from the driver.
- keep_alive - Whether to configure ChromeRemoteConnection to use HTTP keep-alive.
"""
if executable_path != 'chromedriver':
warnings.warn('executable_path has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if desired_capabilities is not None:
warnings.warn('desired_capabilities has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if port != DEFAULT_PORT:
warnings.warn('port has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
self.port = port
if service_log_path != DEFAULT_SERVICE_LOG_PATH:
warnings.warn('service_log_path has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if chrome_options:
warnings.warn('use options instead of chrome_options',
DeprecationWarning, stacklevel=2)
......@@ -65,11 +81,14 @@ class WebDriver(RemoteWebDriver):
else:
desired_capabilities.update(options.to_capabilities())
self.service = Service(
executable_path,
port=port,
service_args=service_args,
log_path=service_log_path)
if service:
self.service = service
else:
self.service = Service(
executable_path,
port=port,
service_args=service_args,
log_path=service_log_path)
self.service.start()
try:
......@@ -109,11 +128,13 @@ class WebDriver(RemoteWebDriver):
- network_conditions: A dict with conditions specification.
:Usage:
driver.set_network_conditions(
offline=False,
latency=5, # additional latency (ms)
download_throughput=500 * 1024, # maximal throughput
upload_throughput=500 * 1024) # maximal throughput
::
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).
"""
......@@ -133,7 +154,9 @@ class WebDriver(RemoteWebDriver):
- cmd_args: A dict, command args. empty dict {} if there is no command args
:Usage:
driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})
::
driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})
:Returns:
A dict, empty dict {} if there is no result to return.
......@@ -144,6 +167,45 @@ class WebDriver(RemoteWebDriver):
"""
return self.execute("executeCdpCommand", {'cmd': cmd, 'params': cmd_args})['value']
def get_sinks(self):
"""
:Returns: A list of sinks avaliable 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.
"""
return self.execute('getIssueMessage')['value']
def set_sink_to_use(self, sink_name):
"""
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.
"""
return self.execute('setSinkToUse', {'sinkName': sink_name})
def start_tab_mirroring(self, sink_name):
"""
Starts a tab mirroring session on a specific receiver 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):
"""
Stops the existing Cast session on a specific receiver target.
:Args:
- sink_name: Name of the sink to stop the Cast session.
"""
return self.execute('stopCasting', {'sinkName': sink_name})
def quit(self):
"""
Closes the browser and shuts down the ChromeDriver executable
......
# 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.
class MouseButton(object):
LEFT = 0
......
......@@ -49,7 +49,6 @@ class DesiredCapabilities(object):
FIREFOX = {
"browserName": "firefox",
"marionette": True,
"acceptInsecureCerts": True,
}
......
# 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 abc import ABCMeta, abstractmethod
class BaseOptions(object):
"""
Base class for individual browser options
"""
__metaclass__ = ABCMeta
def __init__(self):
self._caps = self.default_capabilities
@property
def capabilities(self):
return self._caps
def set_capability(self, name, value):
""" Sets a capability """
self._caps[name] = value
@abstractmethod
def to_capabilities(self):
return
@property
@abstractmethod
def default_capabilities(self):
return {}
class ArgOptions(BaseOptions):
def __init__(self):
super(ArgOptions, self).__init__()
self._arguments = []
@property
def arguments(self):
"""
:Returns: A list of arguments needed for the browser
"""
return self._arguments
def add_argument(self, argument):
"""
Adds an argument to the list
:Args:
- Sets the arguments
"""
if argument:
self._arguments.append(argument)
else:
raise ValueError('argument can not be null')
def to_capabilities(self):
return self._caps
......@@ -22,10 +22,13 @@ import socket
from selenium.webdriver.common.keys import Keys
try:
# Python 2
basestring
_is_connectable_exceptions = (socket.error,)
except NameError:
# Python 3
basestring = str
_is_connectable_exceptions = (socket.error, ConnectionResetError)
def free_port():
......@@ -105,7 +108,7 @@ def is_connectable(port, host="localhost"):
try:
socket_ = socket.create_connection((host, port), 1)
result = True
except socket.error:
except _is_connectable_exceptions:
result = False
finally:
if socket_:
......
# 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.
"""
The WindowTypes implementation.
"""
from __future__ import unicode_literals
class WindowTypes(object):
"""Set of supported window types."""
TAB = 'tab'
WINDOW = 'window'
......@@ -16,13 +16,14 @@
# under the License.
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.options import BaseOptions
class Options(object):
class Options(BaseOptions):
def __init__(self):
super(Options, self).__init__()
self._page_load_strategy = "normal"
self._caps = DesiredCapabilities.EDGE.copy()
@property
def page_load_strategy(self):
......@@ -34,21 +35,17 @@ class Options(object):
raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
self._page_load_strategy = value
@property
def capabilities(self):
return self._caps
def set_capability(self, name, value):
"""Sets a capability."""
self._caps[name] = value
def to_capabilities(self):
"""