зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1653696 [wpt PR 24651] - [wpt] Refactor tools.wpt (part 1), a=testonly
Automatic update from web-platform-tests [wpt] Clean up --channel flag Unify the two definitions of the --channel flag into one. Drive-by: use logger in wpt.install isntead of print or sys.stdout.write -- Remove the special case for FirefoxAndroid There is no need to delay FirefoxAndroid.install() now that channel is available to install(). Fix the definition of the Browser base class and update some docs. Also add a test to make sure all subclasses are not abstract. -- Update tools/wpt/tests/test_browser.py Co-authored-by: Robert Ma <robertma@chromium.org> -- wpt-commits: 9ddfd3cfc4239d82a429aed9c8aff6afb6035d36, 11787031d1257d4aea42d6506e90573298ab6b70, f85bd5cce97f04d357a361395750b3ce9149656d wpt-pr: 24651
This commit is contained in:
Родитель
3c66428304
Коммит
a7cd55a1da
|
@ -70,17 +70,31 @@ class Browser(object):
|
|||
:param channel: Browser channel to download
|
||||
:param rename: Optional name for the downloaded package; the original
|
||||
extension is preserved.
|
||||
:return: The path to the downloaded package/installer
|
||||
"""
|
||||
return NotImplemented
|
||||
|
||||
@abstractmethod
|
||||
def install(self, dest=None):
|
||||
"""Install the browser."""
|
||||
def install(self, dest=None, channel=None):
|
||||
"""Download and install the browser.
|
||||
|
||||
This method usually calls download().
|
||||
|
||||
:param dest: Directory in which to install the browser
|
||||
:param channel: Browser channel to install
|
||||
:return: The path to the installed browser
|
||||
"""
|
||||
return NotImplemented
|
||||
|
||||
@abstractmethod
|
||||
def install_webdriver(self, dest=None, channel=None, browser_binary=None):
|
||||
"""Install the WebDriver implementation for this browser."""
|
||||
"""Download and install the WebDriver implementation for this browser.
|
||||
|
||||
:param dest: Directory in which to install the WebDriver
|
||||
:param channel: Browser channel to install
|
||||
:param browser_binary: The path to the browser binary
|
||||
:return: The path to the installed WebDriver
|
||||
"""
|
||||
return NotImplemented
|
||||
|
||||
@abstractmethod
|
||||
|
@ -387,14 +401,14 @@ class Firefox(Browser):
|
|||
tags = call("git", "ls-remote", "--tags", "--refs",
|
||||
"https://github.com/mozilla/geckodriver.git")
|
||||
release_re = re.compile(r".*refs/tags/v(\d+)\.(\d+)\.(\d+)")
|
||||
latest_release = (0,0,0)
|
||||
latest_release = (0, 0, 0)
|
||||
for item in tags.split("\n"):
|
||||
m = release_re.match(item)
|
||||
if m:
|
||||
version = tuple(int(item) for item in m.groups())
|
||||
if version > latest_release:
|
||||
latest_release = version
|
||||
assert latest_release != (0,0,0)
|
||||
assert latest_release != (0, 0, 0)
|
||||
return "v%s.%s.%s" % tuple(str(item) for item in latest_release)
|
||||
|
||||
def install_webdriver(self, dest=None, channel=None, browser_binary=None):
|
||||
|
@ -470,11 +484,14 @@ class FirefoxAndroid(Browser):
|
|||
product = "firefox_android"
|
||||
requirements = "requirements_firefox.txt"
|
||||
|
||||
def __init__(self, logger):
|
||||
super(FirefoxAndroid, self).__init__(logger)
|
||||
self.apk_path = None
|
||||
|
||||
def download(self, dest=None, channel=None, rename=None):
|
||||
if dest is None:
|
||||
dest = os.pwd
|
||||
|
||||
|
||||
resp = get_taskcluster_artifact(
|
||||
"gecko.v2.mozilla-central.latest.mobile.android-x86_64-opt",
|
||||
"public/build/geckoview-androidTest.apk")
|
||||
|
@ -482,12 +499,12 @@ class FirefoxAndroid(Browser):
|
|||
filename = "geckoview-androidTest.apk"
|
||||
if rename:
|
||||
filename = "%s%s" % (rename, get_ext(filename)[1])
|
||||
apk_path = os.path.join(dest, filename)
|
||||
self.apk_path = os.path.join(dest, filename)
|
||||
|
||||
with open(apk_path, "wb") as f:
|
||||
with open(self.apk_path, "wb") as f:
|
||||
f.write(resp.content)
|
||||
|
||||
return apk_path
|
||||
return self.apk_path
|
||||
|
||||
def install(self, dest=None, channel=None):
|
||||
return self.download(dest, channel)
|
||||
|
@ -497,7 +514,7 @@ class FirefoxAndroid(Browser):
|
|||
return fx_browser.install_prefs(binary, dest, channel)
|
||||
|
||||
def find_binary(self, venv_path=None, channel=None):
|
||||
raise NotImplementedError
|
||||
return self.apk_path
|
||||
|
||||
def find_webdriver(self, channel=None):
|
||||
raise NotImplementedError
|
||||
|
@ -730,9 +747,9 @@ class ChromeAndroid(ChromeAndroidBase):
|
|||
return "com.android.chrome"
|
||||
|
||||
|
||||
#TODO(aluo): This is largely copied from the AndroidWebView implementation.
|
||||
# Tests are not running for weblayer yet (crbug/1019521), this
|
||||
# initial implementation will help to reproduce and debug any issues.
|
||||
# TODO(aluo): This is largely copied from the AndroidWebView implementation.
|
||||
# Tests are not running for weblayer yet (crbug/1019521), this initial
|
||||
# implementation will help to reproduce and debug any issues.
|
||||
class AndroidWeblayer(ChromeAndroidBase):
|
||||
"""Weblayer-specific interface for Android."""
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import argparse
|
||||
import sys
|
||||
from . import browser
|
||||
|
||||
latest_channels = {
|
||||
|
@ -22,25 +21,27 @@ channel_by_name = {
|
|||
'canary': 'canary',
|
||||
}
|
||||
|
||||
channel_args = argparse.ArgumentParser(add_help=False)
|
||||
channel_args.add_argument('--channel', choices=channel_by_name.keys(),
|
||||
default='nightly', action='store',
|
||||
help='''
|
||||
Name of browser release channel (default: nightly). "stable" and "release" are
|
||||
synonyms for the latest browser stable release; "beta" is the beta release;
|
||||
"dev" is only meaningful for Chrome (i.e. Chrome Dev); "nightly",
|
||||
"experimental", and "preview" are all synonyms for the latest available
|
||||
development or trunk release. (For WebDriver installs, we attempt to select an
|
||||
appropriate, compatible version for the latest browser release on the selected
|
||||
channel.) This flag overrides --browser-channel.''')
|
||||
|
||||
|
||||
def get_parser():
|
||||
parser = argparse.ArgumentParser(description="""Install a given browser or webdriver frontend.
|
||||
|
||||
For convenience the release channel of the browser accepts various spellings,
|
||||
but we actually support at most three variants; whatever the latest development
|
||||
release is (e.g. Firefox nightly or Chrome dev), the latest beta release, and
|
||||
the most recent stable release.""")
|
||||
parser = argparse.ArgumentParser(
|
||||
parents=[channel_args],
|
||||
description="Install a given browser or webdriver frontend.")
|
||||
parser.add_argument('browser', choices=['firefox', 'chrome', 'servo'],
|
||||
help='name of web browser product')
|
||||
parser.add_argument('component', choices=['browser', 'webdriver'],
|
||||
help='name of component')
|
||||
parser.add_argument('--channel', choices=channel_by_name.keys(),
|
||||
default="nightly", help='Name of browser release channel. '
|
||||
'"stable" and "release" are synonyms for the latest browser stable release,'
|
||||
'"nightly", "dev", "experimental", and "preview" are all synonyms for '
|
||||
'the latest available development release. For WebDriver installs, '
|
||||
'we attempt to select an appropriate, compatible, version for the '
|
||||
'latest browser release on the selected channel.')
|
||||
parser.add_argument('--download-only', action="store_true",
|
||||
help="Download the selected component but don't install it")
|
||||
parser.add_argument('--rename', action="store", default=None,
|
||||
|
@ -59,13 +60,15 @@ def get_channel(browser, channel):
|
|||
|
||||
|
||||
def run(venv, **kwargs):
|
||||
import logging
|
||||
logger = logging.getLogger("install")
|
||||
|
||||
browser = kwargs["browser"]
|
||||
destination = kwargs["destination"]
|
||||
channel = get_channel(browser, kwargs["channel"])
|
||||
|
||||
if channel != kwargs["channel"]:
|
||||
print("Interpreting channel '%s' as '%s'" % (kwargs["channel"],
|
||||
channel))
|
||||
logger.info("Interpreting channel '%s' as '%s'", kwargs["channel"], channel)
|
||||
|
||||
if destination is None:
|
||||
if venv:
|
||||
|
@ -77,7 +80,7 @@ def run(venv, **kwargs):
|
|||
raise argparse.ArgumentError(None,
|
||||
"No --destination argument, and no default for the environment")
|
||||
|
||||
install(browser, kwargs["component"], destination, channel,
|
||||
install(browser, kwargs["component"], destination, channel, logger=logger,
|
||||
download_only=kwargs["download_only"], rename=kwargs["rename"])
|
||||
|
||||
|
||||
|
@ -92,11 +95,11 @@ def install(name, component, destination, channel="nightly", logger=None, downlo
|
|||
|
||||
method = prefix + suffix
|
||||
|
||||
subclass = getattr(browser, name.title())
|
||||
sys.stdout.write('Now installing %s %s...\n' % (name, component))
|
||||
browser_cls = getattr(browser, name.title())
|
||||
logger.info('Now installing %s %s...', name, component)
|
||||
kwargs = {}
|
||||
if download_only and rename:
|
||||
kwargs["rename"] = rename
|
||||
path = getattr(subclass(logger), method)(dest=destination, channel=channel, **kwargs)
|
||||
path = getattr(browser_cls(logger), method)(dest=destination, channel=channel, **kwargs)
|
||||
if path:
|
||||
sys.stdout.write('Binary %s as %s\n' % ("downloaded" if download_only else "installed", path,))
|
||||
logger.info('Binary %s as %s', "downloaded" if download_only else "installed", path)
|
||||
|
|
|
@ -42,7 +42,7 @@ class WptrunnerHelpAction(argparse.Action):
|
|||
def create_parser():
|
||||
from wptrunner import wptcommandline
|
||||
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser = argparse.ArgumentParser(add_help=False, parents=[install.channel_args])
|
||||
parser.add_argument("product", action="store",
|
||||
help="Browser to run tests in")
|
||||
parser.add_argument("--affected", action="store", default=None,
|
||||
|
@ -52,15 +52,6 @@ def create_parser():
|
|||
parser.add_argument("--install-browser", action="store_true",
|
||||
help="Install the browser from the release channel specified by --channel "
|
||||
"(or the nightly channel by default).")
|
||||
parser.add_argument("--channel", action="store",
|
||||
choices=install.channel_by_name.keys(),
|
||||
default=None, help='Name of browser release channel. '
|
||||
'"stable" and "release" are synonyms for the latest browser stable '
|
||||
'release, "nightly", "dev", "experimental", and "preview" are all '
|
||||
'synonyms for the latest available development release. (For WebDriver '
|
||||
'installs, we attempt to select an appropriate, compatible version for '
|
||||
'the latest browser release on the selected channel.) '
|
||||
'This flag overrides --browser-channel.')
|
||||
parser._add_container_actions(wptcommandline.create_parser())
|
||||
return parser
|
||||
|
||||
|
@ -182,6 +173,7 @@ class BrowserSetup(object):
|
|||
def setup(self, kwargs):
|
||||
self.setup_kwargs(kwargs)
|
||||
|
||||
|
||||
def safe_unsetenv(env_var):
|
||||
"""Safely remove an environment variable.
|
||||
|
||||
|
@ -193,6 +185,7 @@ def safe_unsetenv(env_var):
|
|||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
class Firefox(BrowserSetup):
|
||||
name = "firefox"
|
||||
browser_cls = browser.Firefox
|
||||
|
@ -264,11 +257,6 @@ class FirefoxAndroid(BrowserSetup):
|
|||
name = "firefox_android"
|
||||
browser_cls = browser.FirefoxAndroid
|
||||
|
||||
def install(self, channel):
|
||||
# The install needs to happen in setup so that we have access to all the kwargs
|
||||
self._install_browser = True
|
||||
return None
|
||||
|
||||
def setup_kwargs(self, kwargs):
|
||||
from . import android
|
||||
import mozdevice
|
||||
|
@ -295,13 +283,6 @@ class FirefoxAndroid(BrowserSetup):
|
|||
emulator = android.install(logger, reinstall=False, no_prompt=not self.prompt)
|
||||
android.start(logger, emulator=emulator, reinstall=False)
|
||||
|
||||
install = False
|
||||
if hasattr(self, "_install_browser"):
|
||||
if self.prompt_install("geckoview-test"):
|
||||
install = True
|
||||
apk_path = self.browser.install(self.venv.path,
|
||||
channel=kwargs["browser_channel"])
|
||||
|
||||
if "ADB_PATH" not in os.environ:
|
||||
adb_path = os.path.join(android.get_sdk_path(None),
|
||||
"platform-tools",
|
||||
|
@ -312,9 +293,9 @@ class FirefoxAndroid(BrowserSetup):
|
|||
device = mozdevice.ADBDeviceFactory(adb=adb_path,
|
||||
device=kwargs["device_serial"])
|
||||
|
||||
if install:
|
||||
if self.browser.apk_path:
|
||||
device.uninstall_app(app)
|
||||
device.install_app(apk_path)
|
||||
device.install_app(self.browser.apk_path)
|
||||
elif not device.is_app_installed(app):
|
||||
raise WptrunError("app %s not installed on device %s" %
|
||||
(app, kwargs["device_serial"]))
|
||||
|
|
|
@ -3,6 +3,7 @@ import subprocess
|
|||
import logging
|
||||
import sys
|
||||
import pytest
|
||||
import inspect
|
||||
|
||||
from tools.wpt import browser
|
||||
|
||||
|
@ -10,6 +11,19 @@ from tools.wpt import browser
|
|||
logger = logging.getLogger()
|
||||
|
||||
|
||||
def test_all_browser_abc():
|
||||
# Make sure all subclasses of Browser implement all abstract methods
|
||||
# (except some known base classes). This is a basic sanity test in case
|
||||
# we change the ABC interface of Browser as we only instantiate some
|
||||
# products in unit tests.
|
||||
classes = inspect.getmembers(browser)
|
||||
for name, cls in classes:
|
||||
if cls in (browser.Browser, browser.ChromeAndroidBase):
|
||||
continue
|
||||
if inspect.isclass(cls) and issubclass(cls, browser.Browser):
|
||||
assert not inspect.isabstract(cls), "%s is abstract" % name
|
||||
|
||||
|
||||
@mock.patch('subprocess.check_output')
|
||||
def test_safari_version(mocked_check_output):
|
||||
safari = browser.Safari(logger)
|
||||
|
|
Загрузка…
Ссылка в новой задаче