Bug 1570756 [wpt PR 18239] - [tools] Various Chrome for Android improvements, a=testonly

Automatic update from web-platform-tests
[wpt] Support detecting Chrome for Android version

Consequently, we can now install the correct ChromeDriver version.

* The change also includes some drive-by whitespace fixes in the file.

--
Allow custom package names for Chrome Android

1. [wptrunner] chrome_android now honours (and requires) the
   --package-name flag instead of hardcoding the package name.
2. [wpt] chrome_android now chooses the correct official package name
   depending on the channel.
3. [wpt] chrome_android correctly sets browser_version.
4. [wpt] drive-by change: update the logic for adding --binary-arg &
   --webdriver-arg in chrome & chrome_android (now they both add
   --enable-experimental... to binary_arg and --disable-build-check to
   webdriver_arg when running dev or canary channel).

--

wpt-commits: cc864ad313dafdaefa90b483818ed5a603803a41, 2a4e78b2c66b7a6589c50c44dda31e5cf215421f
wpt-pr: 18239
This commit is contained in:
Robert Ma 2019-08-06 17:27:19 +00:00 committed by moz-wptsync-bot
parent 9ad90874ea
commit ef1dbe597e
5 changed files with 78 additions and 38 deletions

View File

@ -7,17 +7,16 @@ connect to the device. Run `adb devices` to verify.
Currently, Android support is a prototype with some known issues:
* We install ChromeDriver corresponding to the Chrome version on your *host*,
so you will need a special flag to bypass ChromeDriver's version check if the
test device runs a different version of Chrome from your host.
* The package name is hard coded. If you are testing a custom build, you will
need to search and replace `com.android.chrome` in `tools/`.
* If you have previously run `./wpt run` against Chrome, you might need to
remove `_venv/bin/chromedriver` so that we can install the correct
ChromeDriver corresponding to your Chrome for Android version.
* We do not support reftests at the moment.
* You will need to manually kill Chrome (all channels) before running tests.
Note: rooting the device or installing a root CA is no longer required.
Example:
Example (assuming you have Chrome Canary installed on your phone):
```bash
./wpt run --webdriver-arg=--disable-build-check --test-type=testharness chrome_android TESTS
./wpt run --test-type=testharness --channel=canary chrome_android TESTS
```

View File

@ -36,6 +36,7 @@ def handle_remove_readonly(func, path, exc):
else:
raise
class Browser(object):
__metaclass__ = ABCMeta
@ -534,28 +535,32 @@ class Chrome(Browser):
self.chromium_platform_string(), revision, self.platform_string())
return url
def _latest_chromedriver_url(self, browser_binary=None):
chrome_version = self.version(browser_binary)
assert chrome_version, "Cannot detect the version of Chrome"
def _latest_chromedriver_url(self, chrome_version):
# Remove channel suffixes (e.g. " dev").
chrome_version = chrome_version.split(' ')[0]
return (self._official_chromedriver_url(chrome_version) or
self._chromium_chromedriver_url(chrome_version))
def install_webdriver(self, dest=None, channel=None, browser_binary=None):
def install_webdriver_by_version(self, version, dest=None):
assert version, "Cannot install ChromeDriver without Chrome version"
if dest is None:
dest = os.pwd
if browser_binary is None:
browser_binary = self.find_binary(channel)
url = self._latest_chromedriver_url(browser_binary)
url = self._latest_chromedriver_url(version)
self.logger.info("Downloading ChromeDriver from %s" % url)
unzip(get(url).raw, dest)
chromedriver_dir = os.path.join(dest, 'chromedriver_%s' % self.platform_string())
chromedriver_dir = os.path.join(
dest, 'chromedriver_%s' % self.platform_string())
if os.path.isfile(os.path.join(chromedriver_dir, "chromedriver")):
shutil.move(os.path.join(chromedriver_dir, "chromedriver"), dest)
shutil.rmtree(chromedriver_dir)
return find_executable("chromedriver", dest)
def install_webdriver(self, dest=None, channel=None, browser_binary=None):
if browser_binary is None:
browser_binary = self.find_binary(channel)
return self.install_webdriver_by_version(
self.version(browser_binary), dest)
def version(self, binary=None, webdriver_binary=None):
if not binary:
self.logger.warning("No browser binary provided.")
@ -585,21 +590,43 @@ class ChromeAndroid(Browser):
product = "chrome_android"
requirements = "requirements_chrome_android.txt"
def __init__(self, logger):
super(ChromeAndroid, self).__init__(logger)
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
if channel in ("beta", "dev", "canary"):
return "com.chrome." + channel
return "com.android.chrome"
def find_webdriver(self, channel=None):
return find_executable("chromedriver")
def install_webdriver(self, dest=None, channel=None, browser_binary=None):
if browser_binary is None:
browser_binary = self.find_binary(channel)
chrome = Chrome(self.logger)
return chrome.install_webdriver(dest, channel)
return chrome.install_webdriver_by_version(
self.version(browser_binary), dest)
def version(self, binary=None, webdriver_binary=None):
return None
if not binary:
self.logger.warning("No package name provided.")
return None
command = ['adb', 'shell', 'dumpsys', 'package', binary]
try:
output = call(*command)
except (subprocess.CalledProcessError, OSError):
self.logger.warning("Failed to call %s" % " ".join(command))
return None
match = re.search(r'versionName=(.*)', output)
if not match:
self.logger.warning("Failed to find versionName")
return None
return match.group(1)
class ChromeiOS(Browser):
@ -699,6 +726,7 @@ class Opera(Browser):
if m:
return m.group(0)
class EdgeChromium(Browser):
"""MicrosoftEdge-specific interface."""
platform = {
@ -725,16 +753,16 @@ class EdgeChromium(Browser):
os.path.expandvars("$SYSTEMDRIVE\\Program Files\\Microsoft\\Edge Dev\\Application"),
os.path.expandvars("$SYSTEMDRIVE\\Program Files (x86)\\Microsoft\\Edge Beta\\Application"),
os.path.expandvars("$SYSTEMDRIVE\\Program Files (x86)\\Microsoft\\Edge Dev\\Application"),
os.path.expanduser("~\\AppData\Local\\Microsoft\\Edge SxS\\Application"),]
os.path.expanduser("~\\AppData\Local\\Microsoft\\Edge SxS\\Application")]
return find_executable(binaryname, os.pathsep.join(winpaths))
if self.platform == "macos":
binaryname = "Microsoft Edge Canary"
binary = find_executable(binaryname)
if not binary:
macpaths = ["/Applications/Microsoft Edge.app/Contents/MacOS",
os.path.expanduser("~/Applications/Microsoft Edge.app/Contents/MacOS"),
"/Applications/Microsoft Edge Canary.app/Contents/MacOS",
os.path.expanduser("~/Applications/Microsoft Edge Canary.app/Contents/MacOS")]
os.path.expanduser("~/Applications/Microsoft Edge.app/Contents/MacOS"),
"/Applications/Microsoft Edge Canary.app/Contents/MacOS",
os.path.expanduser("~/Applications/Microsoft Edge Canary.app/Contents/MacOS")]
return find_executable("Microsoft Edge Canary", os.pathsep.join(macpaths))
return binary
@ -797,6 +825,7 @@ class EdgeChromium(Browser):
self.logger.warning("Failed to find Edge binary.")
return None
class Edge(Browser):
"""Edge-specific interface."""

View File

@ -6,6 +6,7 @@ import sys
latest_channels = {
'firefox': 'nightly',
'chrome': 'dev',
'chrome_android': 'dev',
'edgechromium': 'dev',
'safari': 'preview',
'servo': 'nightly'

View File

@ -281,7 +281,7 @@ class Chrome(BrowserSetup):
logger.info("Downloading chromedriver")
webdriver_binary = self.browser.install_webdriver(
dest=self.venv.bin_path,
browser_binary=kwargs["binary"]
browser_binary=kwargs["binary"],
)
else:
logger.info("Using webdriver binary %s" % webdriver_binary)
@ -290,8 +290,8 @@ class Chrome(BrowserSetup):
kwargs["webdriver_binary"] = webdriver_binary
else:
raise WptrunError("Unable to locate or install chromedriver binary")
if kwargs["browser_channel"] == "dev":
logger.info("Automatically turning on experimental features for Chrome Dev")
if browser_channel in ("dev", "canary"):
logger.info("Automatically turning on experimental features for Chrome Dev/Canary")
kwargs["binary_args"].append("--enable-experimental-web-platform-features")
# HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448
kwargs["webdriver_args"].append("--disable-build-check")
@ -302,6 +302,10 @@ class ChromeAndroid(BrowserSetup):
browser_cls = browser.ChromeAndroid
def setup_kwargs(self, kwargs):
browser_channel = kwargs["browser_channel"]
if kwargs["package_name"] is None:
kwargs["package_name"] = self.browser.find_binary(
channel=browser_channel)
if kwargs["webdriver_binary"] is None:
webdriver_binary = self.browser.find_webdriver()
@ -310,7 +314,10 @@ class ChromeAndroid(BrowserSetup):
if install:
logger.info("Downloading chromedriver")
webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path)
webdriver_binary = self.browser.install_webdriver(
dest=self.venv.bin_path,
browser_binary=kwargs["package_name"],
)
else:
logger.info("Using webdriver binary %s" % webdriver_binary)
@ -318,6 +325,11 @@ class ChromeAndroid(BrowserSetup):
kwargs["webdriver_binary"] = webdriver_binary
else:
raise WptrunError("Unable to locate or install chromedriver binary")
if browser_channel in ("dev", "canary"):
logger.info("Automatically turning on experimental features for Chrome Dev/Canary")
kwargs["binary_args"].append("--enable-experimental-web-platform-features")
# HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448
kwargs["webdriver_args"].append("--disable-build-check")
class ChromeiOS(BrowserSetup):
@ -626,8 +638,10 @@ def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs):
# Only update browser_version if it was not given as a command line
# argument, so that it can be overridden on the command line.
if not kwargs["browser_version"]:
kwargs["browser_version"] = setup_cls.browser.version(binary=kwargs.get("binary"),
webdriver_binary=kwargs.get("webdriver_binary"))
kwargs["browser_version"] = setup_cls.browser.version(
binary=kwargs.get("binary") or kwargs.get("package_name"),
webdriver_binary=kwargs.get("webdriver_binary"),
)
return kwargs

View File

@ -25,11 +25,12 @@ _wptserve_ports = set()
def check_args(**kwargs):
require_arg(kwargs, "package_name")
require_arg(kwargs, "webdriver_binary")
def browser_kwargs(test_type, run_info_data, config, **kwargs):
return {"binary": kwargs["binary"],
return {"package_name": kwargs["package_name"],
"webdriver_binary": kwargs["webdriver_binary"],
"webdriver_args": kwargs.get("webdriver_args")}
@ -45,15 +46,13 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
executor_kwargs = chrome_executor_kwargs(test_type, server_config,
cache_manager, run_info_data,
**kwargs)
# Remove unsupported options on mobile.
del executor_kwargs["capabilities"]["goog:chromeOptions"]["prefs"]
del executor_kwargs["capabilities"]["goog:chromeOptions"]["useAutomationExtension"]
# TODO(Hexcles): browser_channel should be properly supported.
package_name = "com.android.chrome" # stable channel
# Required to start on mobile
assert kwargs["package_name"], "missing --package-name"
executor_kwargs["capabilities"]["goog:chromeOptions"]["androidPackage"] = \
package_name
# Map wptrunner args to chromeOptions.
kwargs["package_name"]
return executor_kwargs
@ -71,12 +70,10 @@ class ChromeAndroidBrowser(Browser):
``wptrunner.webdriver.ChromeDriverServer``.
"""
def __init__(self, logger, binary, webdriver_binary="chromedriver",
def __init__(self, logger, package_name, 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.package_name = package_name
self.server = ChromeDriverServer(self.logger,
binary=webdriver_binary,
args=webdriver_args)