Skip to content

Commit

Permalink
Merge branch 'master' of github.com:SeleniumHQ/selenium
Browse files Browse the repository at this point in the history
  • Loading branch information
AutomatedTester committed Mar 10, 2020
2 parents 8b2bab5 + 617f16f commit 264ed97
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 93 deletions.
46 changes: 46 additions & 0 deletions py/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,52 @@ py_test_suite(
],
)

py_test_suite(
name = "test-edge",
size = "large",
srcs = glob([
"test/selenium/webdriver/edge/**/*.py",
"test/selenium/webdriver/common/**/*.py",
"test/selenium/webdriver/support/**/*.py",
]),
args = [
"--instafail",
"--driver=Edge",
],
tags = [
"no-sandbox",
],
deps = [
":init-tree",
":selenium",
":webserver",
"//third_party/py:pytest",
],
)

py_test_suite(
name = "test-edge-chromium",
size = "large",
srcs = glob([
"test/selenium/webdriver/edge/**/*.py",
"test/selenium/webdriver/common/**/*.py",
"test/selenium/webdriver/support/**/*.py",
]),
args = [
"--instafail",
"--driver=ChromiumEdge",
],
tags = [
"no-sandbox",
],
deps = [
":init-tree",
":selenium",
":webserver",
"//third_party/py:pytest",
],
)

py_test_suite(
name = "test-firefox",
size = "large",
Expand Down
9 changes: 5 additions & 4 deletions py/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ def fin():
options = get_options(driver_class, request.config)
if driver_class == 'ChromiumEdge':
options = get_options(driver_class, request.config)
kwargs.update({'is_legacy': False})
if driver_path is not None:
kwargs['executable_path'] = driver_path
if options is not None:
Expand All @@ -136,10 +135,12 @@ def get_options(driver_class, config):
browser_args = config.option.args
options = None

if driver_class == 'ChromiumEdge':
options = getattr(webdriver, 'EdgeOptions')()
options.use_chromium = True

if browser_path or browser_args:
if driver_class == 'ChromiumEdge':
options = getattr(webdriver, 'EdgeOptions')(False)
else:
if not options:
options = getattr(webdriver, '{}Options'.format(driver_class))()
if driver_class == 'WebKitGTK':
options.overlay_scrollbars_enabled = False
Expand Down
7 changes: 6 additions & 1 deletion py/selenium/webdriver/chrome/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from selenium.webdriver.chromium.webdriver import ChromiumDriver
from .options import Options
from .service import Service
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities


DEFAULT_PORT = 0
Expand Down Expand Up @@ -49,6 +50,9 @@ def __init__(self, executable_path="chromedriver", port=DEFAULT_PORT,
- 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 chrome_options:
warnings.warn('use options instead of chrome_options',
DeprecationWarning, stacklevel=2)
Expand All @@ -57,7 +61,8 @@ def __init__(self, executable_path="chromedriver", port=DEFAULT_PORT,
if service is None:
service = Service(executable_path, port, service_args, service_log_path)

super(WebDriver, self).__init__(executable_path, port, options,
super(WebDriver, self).__init__(DesiredCapabilities.CHROME['browserName'], "goog",
port, options,
service_args, desired_capabilities,
service_log_path, service, keep_alive)

Expand Down
18 changes: 8 additions & 10 deletions py/selenium/webdriver/chromium/remote_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@


class ChromiumRemoteConnection(RemoteConnection):

browser_name = DesiredCapabilities.CHROME['browserName']

def __init__(self, remote_server_addr, keep_alive=True):
def __init__(self, remote_server_addr, vendor_prefix, browser_name, keep_alive=True):
RemoteConnection.__init__(self, remote_server_addr, keep_alive)
self.browser_name = browser_name
self._commands["launchApp"] = ('POST', '/session/$sessionId/chromium/launch_app')
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')
self._commands['executeCdpCommand'] = ('POST', '/session/$sessionId/{}/cdp/execute'.format(vendor_prefix))
self._commands['getSinks'] = ('GET', '/session/$sessionId/{}/cast/get_sinks'.format(vendor_prefix))
self._commands['getIssueMessage'] = ('GET', '/session/$sessionId/{}/cast/get_issue_message'.format(vendor_prefix))
self._commands['setSinkToUse'] = ('POST', '/session/$sessionId/{}/cast/set_sink_to_use'.format(vendor_prefix))
self._commands['startTabMirroring'] = ('POST', '/session/$sessionId/{}/cast/start_tab_mirroring'.format(vendor_prefix))
self._commands['stopCasting'] = ('POST', '/session/$sessionId/{}/cast/stop_casting'.format(vendor_prefix))
11 changes: 5 additions & 6 deletions py/selenium/webdriver/chromium/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,17 @@ class ChromiumDriver(RemoteWebDriver):
Controls the WebDriver instance of ChromiumDriver and allows you to drive the browser.
"""

def __init__(self, executable_path="chromedriver", port=DEFAULT_PORT,
options=None, service_args=None,
def __init__(self, browser_name, vendor_prefix,
port=DEFAULT_PORT, options=None, service_args=None,
desired_capabilities=None, service_log_path=DEFAULT_SERVICE_LOG_PATH,
service=None, keep_alive=True):
"""
Creates a new WebDriver instance of the ChromiumDriver.
Starts the service and then creates new WebDriver instance of ChromiumDriver.
:Args:
- executable_path - Deprecated: path to the executable. If the default is used it assumes the executable is in the $PATH
browser_name - Browser name used when matching capabilities.
vendor_prefix - Company prefix to apply to vendor-specific WebDriver extension commands.
- 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 ChromiumOptions
- service_args - Deprecated: List of args to pass to the driver service
Expand All @@ -46,9 +47,6 @@ def __init__(self, executable_path="chromedriver", port=DEFAULT_PORT,
- service_log_path - Deprecated: Where to log information from the driver.
- keep_alive - Whether to configure ChromiumRemoteConnection 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)
Expand Down Expand Up @@ -81,6 +79,7 @@ def __init__(self, executable_path="chromedriver", port=DEFAULT_PORT,
self,
command_executor=ChromiumRemoteConnection(
remote_server_addr=self.service.service_url,
browser_name=browser_name, vendor_prefix=vendor_prefix,
keep_alive=keep_alive),
desired_capabilities=desired_capabilities)
except Exception:
Expand Down
52 changes: 21 additions & 31 deletions py/selenium/webdriver/edge/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,52 +22,42 @@
class Options(ChromiumOptions):
KEY = "ms:edgeOptions"

def __init__(self, is_legacy=True):
def __init__(self):
super(Options, self).__init__()
self._is_legacy = is_legacy
self._custom_browser_name = None

if is_legacy:
self._page_load_strategy = "normal"
self._use_chromium = False
self._use_webview = False

@property
def custom_browser_name(self):
return self._custom_browser_name
def use_chromium(self):
return self._use_chromium

@custom_browser_name.setter
def custom_browser_name(self, value):
self._custom_browser_name = value
@use_chromium.setter
def use_chromium(self, value):
self._use_chromium = bool(value)

@property
def page_load_strategy(self):
if not self._is_legacy:
raise AttributeError("Page Load Strategy only exists in Legacy Mode")

return self._page_load_strategy

@page_load_strategy.setter
def page_load_strategy(self, value):
if not self._is_legacy:
raise AttributeError("Page Load Strategy only exists in Legacy Mode")
def use_webview(self):
return self._use_webview

if value not in ['normal', 'eager', 'none']:
raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
self._page_load_strategy = value
@use_webview.setter
def use_webview(self, value):
self._use_webview = bool(value)

def to_capabilities(self):
"""
Creates a capabilities with all the options that have been set and
:Returns: A dictionary with everything
"""
if not self._is_legacy:
return_caps = super(Options, self).to_capabilities()
if self._custom_browser_name:
return_caps['browserName'] = self._custom_browser_name
return return_caps

caps = self._caps
caps['pageLoadStrategy'] = self._page_load_strategy

if self._use_chromium:
caps = super(Options, self).to_capabilities()
if self._use_webview:
caps['browserName'] = 'WebView2'
else:
caps['platform'] = 'windows'

caps['ms:edgeChromium'] = self._use_chromium
return caps

@property
Expand Down
13 changes: 5 additions & 8 deletions py/selenium/webdriver/edge/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
class Service(service.ChromiumService):

def __init__(self, executable_path, port=0, verbose=False, log_path=None,
is_legacy=True, service_args=None, env=None):
service_args=None, env=None):
"""
Creates a new instance of the EdgeDriver service.
EdgeDriver provides an interface for Microsoft WebDriver to use
Expand All @@ -32,19 +32,16 @@ def __init__(self, executable_path, port=0, verbose=False, log_path=None,
- port : Run the remote service on a specified port. Defaults to 0, which binds to a random open port
of the system's choosing.
- verbose : Whether to make the webdriver more verbose (passes the --verbose option to the binary).
Defaults to False. Should be only used for legacy mode.
Defaults to False.
- log_path : Optional path for the webdriver binary to log to. Defaults to None which disables logging.
- is_legacy : Whether to use MicrosoftWebDriver.exe (legacy) or MSEdgeDriver.exe (chromium-based). Defaults to True.
- service_args : List of args to pass to the WebDriver service.
"""
self.service_args = service_args or []

if is_legacy:
if verbose:
self.service_args.append("--verbose")
if verbose:
self.service_args.append("--verbose")

service.ChromiumService.__init__(
self,
super(Service, self).__init__(
executable_path,
port,
service_args,
Expand Down
60 changes: 33 additions & 27 deletions py/selenium/webdriver/edge/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,58 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.edge.service import Service
import warnings
from selenium.webdriver.chromium.webdriver import ChromiumDriver
from .options import Options
from .service import Service
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities


DEFAULT_PORT = 0
DEFAULT_SERVICE_LOG_PATH = None


class WebDriver(ChromiumDriver):
"""
Controls the Microsoft Edge driver and allows you to drive the browser.
You will need to download either the MicrosoftWebDriver (Legacy)
or MSEdgeDriver (Chromium) executable from
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
"""

def __init__(self, executable_path='MicrosoftWebDriver.exe',
capabilities=None, port=DEFAULT_PORT, verbose=False,
service_log_path=None, log_path=DEFAULT_SERVICE_LOG_PATH,
service=None, options=None, keep_alive=False, is_legacy=True,
service_args=None):
def __init__(self, executable_path='MicrosoftWebDriver.exe', port=DEFAULT_PORT,
options=None, service_args=None,
capabilities=None, service_log_path=DEFAULT_SERVICE_LOG_PATH,
service=None, keep_alive=False, verbose=False):
"""
Creates a new instance of the edge driver.
Starts the service and then creates new instance of edge driver.
:Args:
- executable_path - Deprecated: path to the executable. If the default is used it assumes the executable is in the $PATH
- capabilities - Dictionary object with non-browser specific capabilities only, such as "proxy" or "loggingPref".
Only available in Legacy mode
- port - Deprecated: port you would like the service to run, if left as 0, a free port will be found.
- verbose - whether to set verbose logging in the service. Only available in Legacy Mode
- options - this takes an instance of EdgeOptions
- service_args - Deprecated: List of args to pass to the driver service
- capabilities - Deprecated: Dictionary object with non-browser specific
capabilities only, such as "proxy" or "loggingPref".
- service_log_path - Deprecated: Where to log information from the driver.
- keep_alive - Whether to configure EdgeRemoteConnection to use HTTP keep-alive.
- service_args - Deprecated: List of args to pass to the driver service
- is_legacy: Whether to use MicrosoftWebDriver.exe (legacy) or MSEdgeDriver.exe (chromium-based). Defaults to True.
- verbose - whether to set verbose logging in the service.
"""
if not is_legacy:
if executable_path != 'MicrosoftWebDriver.exe':
warnings.warn('executable_path has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)

if options is not None and options.use_chromium:
executable_path = "msedgedriver"

service = service or Service(executable_path,
port=port,
verbose=verbose,
log_path=service_log_path,
is_legacy=is_legacy)
if service is None:
service = Service(executable_path, port, service_args, service_log_path)

super(WebDriver, self).__init__(DesiredCapabilities.EDGE['browserName'], "ms",
port, options,
service_args, capabilities,
service_log_path, service, keep_alive)

super(WebDriver, self).__init__(
executable_path,
port,
options,
service_args,
DesiredCapabilities.EDGE,
service_log_path,
service,
keep_alive)
def create_options(self):
return Options()
21 changes: 15 additions & 6 deletions py/test/unit/selenium/webdriver/edge/edge_options_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ def test_raises_exception_with_invalid_page_load_strategy(options):

def test_set_page_load_strategy(options):
options.page_load_strategy = 'normal'
assert options._page_load_strategy == 'normal'
caps = options.to_capabilities()
assert caps['pageLoadStrategy'] == 'normal'


def test_get_page_load_strategy(options):
options._page_load_strategy = 'normal'
options._caps['pageLoadStrategy'] = 'normal'
assert options.page_load_strategy == 'normal'


Expand All @@ -58,8 +59,16 @@ def test_is_a_baseoptions(options):
assert isinstance(options, BaseOptions)


def test_custom_browser_name():
options = Options(is_legacy=False)
options.custom_browser_name = "testbrowsername"
def test_use_chromium():
options = Options()
options.use_chromium = True
caps = options.to_capabilities()
assert caps['ms:edgeChromium'] == True


def test_use_webview():
options = Options()
options.use_chromium = True
options.use_webview = True
caps = options.to_capabilities()
assert caps['browserName'] == "testbrowsername"
assert caps['browserName'] == "WebView2"

0 comments on commit 264ed97

Please sign in to comment.