Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic executor that uses WebDriver protocol directly #10197

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tools/webdriver/webdriver/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ def _set(self, key, secs):
timeouts = self.session.send_session_command("POST", "timeouts", body)
return None

def set_w3c(self, timeout, secs):
body = {"type": timeout, "ms": secs * 1000}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this into the webdriver client rather than here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean, this is in tools/webdriver/webdriver/client.py which is the webdriver client?

timeouts = self.session.send_session_command("POST", "timeouts", body)
return None

@property
def script(self):
return self._get("script")
Expand Down
25 changes: 25 additions & 0 deletions tools/wpt/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,31 @@ def install_webdriver(self, dest=None):
def version(self, root):
raise NotImplementedError

class ChromeWebdriver(Browser):
"""Chrome-specific interface for chrome without using selenium.

Includes webdriver installation.
"""

product = "chrome_webdriver"
requirements = "requirements_chrome.txt"

def install(self, dest=None):
raise NotImplementedError

def find_binary(self):
raise NotImplementedError

def find_webdriver(self):
return find_executable("chromedriver")

def install_webdriver(self, dest=None):
chrome = Chrome()
return chrome.install_webdriver(dest)

def version(self, root):
raise NotImplementedError


class Opera(Browser):
"""Opera-specific interface.
Expand Down
23 changes: 23 additions & 0 deletions tools/wpt/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,28 @@ def setup_kwargs(self, kwargs):
else:
raise WptrunError("Unable to locate or install chromedriver binary")

class ChromeWebdriver(BrowserSetup):
name = "chrome_webdriver"
browser_cls = browser.ChromeWebdriver

def setup_kwargs(self, kwargs):
if kwargs["webdriver_binary"] is None:
webdriver_binary = self.browser.find_webdriver()

if webdriver_binary is None:
install = self.prompt_install("chromedriver")

if install:
print("Downloading chromedriver")
webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path)
else:
print("Using webdriver binary %s" % webdriver_binary)

if webdriver_binary:
kwargs["webdriver_binary"] = webdriver_binary
else:
raise WptrunError("Unable to locate or install chromedriver binary")


class Opera(BrowserSetup):
name = "opera"
Expand Down Expand Up @@ -380,6 +402,7 @@ def setup_kwargs(self, kwargs):
"firefox": Firefox,
"chrome": Chrome,
"chrome_android": ChromeAndroid,
"chrome_webdriver": ChromeWebdriver,
"edge": Edge,
"ie": InternetExplorer,
"safari": Safari,
Expand Down
1 change: 1 addition & 0 deletions tools/wptrunner/wptrunner/browsers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

product_list = ["chrome",
"chrome_android",
"chrome_webdriver",
"edge",
"firefox",
"ie",
Expand Down
11 changes: 10 additions & 1 deletion tools/wptrunner/wptrunner/browsers/chrome.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from ..executors import executor_kwargs as base_executor_kwargs
from ..executors.executorselenium import (SeleniumTestharnessExecutor,
SeleniumRefTestExecutor)
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor,
WebDriverRefTestExecutor)
from ..executors.executorchrome import ChromeDriverWdspecExecutor


Expand Down Expand Up @@ -51,7 +53,14 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
capabilities["chromeOptions"]["excludeSwitches"] = ["enable-automation"]
if test_type == "wdspec":
capabilities["chromeOptions"]["w3c"] = True
executor_kwargs["capabilities"] = capabilities

if __wptrunner__["executor"]["testharness"] == ("WebDriverTestharnessExecutor"
or __wptrunner__["executor"]["reftest"] == "WebDriverRefTestExecutor"):
capabilities["chromeOptions"]["w3c"] = True
always_match = {"alwaysMatch": capabilities}
executor_kwargs["capabilities"] = always_match
else:
executor_kwargs["capabilities"] = capabilities
return executor_kwargs


Expand Down
104 changes: 104 additions & 0 deletions tools/wptrunner/wptrunner/browsers/chrome_webdriver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from .base import Browser, ExecutorBrowser, require_arg
from ..webdriver_server import ChromeDriverServer
from ..executors import executor_kwargs as base_executor_kwargs
from ..executors.executorselenium import (SeleniumTestharnessExecutor,
SeleniumRefTestExecutor)
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor,
WebDriverRefTestExecutor)
from ..executors.executorchrome import ChromeDriverWdspecExecutor


__wptrunner__ = {"product": "chrome_webdriver",
"check_args": "check_args",
"browser": "ChromeWebdriverBrowser",
"executor": {"testharness": "WebDriverTestharnessExecutor",
"reftest": "WebDriverRefTestExecutor",
"wdspec": "ChromeDriverWdspecExecutor"},
"browser_kwargs": "browser_kwargs",
"executor_kwargs": "executor_kwargs",
"env_extras": "env_extras",
"env_options": "env_options"}

def check_args(**kwargs):
require_arg(kwargs, "webdriver_binary")


def browser_kwargs(test_type, run_info_data, **kwargs):
return {"binary": kwargs["binary"],
"webdriver_binary": kwargs["webdriver_binary"],
"webdriver_args": kwargs.get("webdriver_args")}


def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
**kwargs):
from selenium.webdriver import DesiredCapabilities

executor_kwargs = base_executor_kwargs(test_type, server_config,
cache_manager, **kwargs)
executor_kwargs["close_after_done"] = True
capabilities = dict(DesiredCapabilities.CHROME.items())
capabilities.setdefault("chromeOptions", {})["prefs"] = {
"profile": {
"default_content_setting_values": {
"popups": 1
}
}
}
for (kwarg, capability) in [("binary", "binary"), ("binary_args", "args")]:
if kwargs[kwarg] is not None:
capabilities["chromeOptions"][capability] = kwargs[kwarg]
if test_type == "testharness":
capabilities["chromeOptions"]["useAutomationExtension"] = False
capabilities["chromeOptions"]["excludeSwitches"] = ["enable-automation"]
if test_type == "wdspec":
capabilities["chromeOptions"]["w3c"] = True

capabilities["chromeOptions"]["w3c"] = True
always_match = {"alwaysMatch": capabilities}
executor_kwargs["capabilities"] = always_match
return executor_kwargs


def env_extras(**kwargs):
return []


def env_options():
return {}


class ChromeWebdriverBrowser(Browser):
"""Chrome is backed by chromedriver, which is supplied through
``wptrunner.webdriver.ChromeDriverServer``.
"""

def __init__(self, logger, binary, webdriver_binary="chromedriver",
webdriver_args=None):
"""Creates a new representation of Chrome. The `binary` argument gives
the browser binary to use for testing."""
Browser.__init__(self, logger)
self.binary = binary
self.server = ChromeDriverServer(self.logger,
binary=webdriver_binary,
args=webdriver_args)

def start(self, **kwargs):
self.server.start(block=False)

def stop(self, force=False):
self.server.stop(force=force)

def pid(self):
return self.server.pid

def is_alive(self):
# TODO(ato): This only indicates the driver is alive,
# and doesn't say anything about whether a browser session
# is active.
return self.server.is_alive()

def cleanup(self):
self.stop()

def executor_browser(self):
return ExecutorBrowser, {"webdriver_url": self.server.url}
Loading