зеркало из 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 channel: Browser channel to download
|
||||||
:param rename: Optional name for the downloaded package; the original
|
:param rename: Optional name for the downloaded package; the original
|
||||||
extension is preserved.
|
extension is preserved.
|
||||||
|
:return: The path to the downloaded package/installer
|
||||||
"""
|
"""
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def install(self, dest=None):
|
def install(self, dest=None, channel=None):
|
||||||
"""Install the browser."""
|
"""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
|
return NotImplemented
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def install_webdriver(self, dest=None, channel=None, browser_binary=None):
|
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
|
return NotImplemented
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -470,11 +484,14 @@ class FirefoxAndroid(Browser):
|
||||||
product = "firefox_android"
|
product = "firefox_android"
|
||||||
requirements = "requirements_firefox.txt"
|
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):
|
def download(self, dest=None, channel=None, rename=None):
|
||||||
if dest is None:
|
if dest is None:
|
||||||
dest = os.pwd
|
dest = os.pwd
|
||||||
|
|
||||||
|
|
||||||
resp = get_taskcluster_artifact(
|
resp = get_taskcluster_artifact(
|
||||||
"gecko.v2.mozilla-central.latest.mobile.android-x86_64-opt",
|
"gecko.v2.mozilla-central.latest.mobile.android-x86_64-opt",
|
||||||
"public/build/geckoview-androidTest.apk")
|
"public/build/geckoview-androidTest.apk")
|
||||||
|
@ -482,12 +499,12 @@ class FirefoxAndroid(Browser):
|
||||||
filename = "geckoview-androidTest.apk"
|
filename = "geckoview-androidTest.apk"
|
||||||
if rename:
|
if rename:
|
||||||
filename = "%s%s" % (rename, get_ext(filename)[1])
|
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)
|
f.write(resp.content)
|
||||||
|
|
||||||
return apk_path
|
return self.apk_path
|
||||||
|
|
||||||
def install(self, dest=None, channel=None):
|
def install(self, dest=None, channel=None):
|
||||||
return self.download(dest, channel)
|
return self.download(dest, channel)
|
||||||
|
@ -497,7 +514,7 @@ class FirefoxAndroid(Browser):
|
||||||
return fx_browser.install_prefs(binary, dest, channel)
|
return fx_browser.install_prefs(binary, dest, channel)
|
||||||
|
|
||||||
def find_binary(self, venv_path=None, channel=None):
|
def find_binary(self, venv_path=None, channel=None):
|
||||||
raise NotImplementedError
|
return self.apk_path
|
||||||
|
|
||||||
def find_webdriver(self, channel=None):
|
def find_webdriver(self, channel=None):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -731,8 +748,8 @@ class ChromeAndroid(ChromeAndroidBase):
|
||||||
|
|
||||||
|
|
||||||
# TODO(aluo): This is largely copied from the AndroidWebView implementation.
|
# TODO(aluo): This is largely copied from the AndroidWebView implementation.
|
||||||
# Tests are not running for weblayer yet (crbug/1019521), this
|
# Tests are not running for weblayer yet (crbug/1019521), this initial
|
||||||
# initial implementation will help to reproduce and debug any issues.
|
# implementation will help to reproduce and debug any issues.
|
||||||
class AndroidWeblayer(ChromeAndroidBase):
|
class AndroidWeblayer(ChromeAndroidBase):
|
||||||
"""Weblayer-specific interface for Android."""
|
"""Weblayer-specific interface for Android."""
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
|
||||||
from . import browser
|
from . import browser
|
||||||
|
|
||||||
latest_channels = {
|
latest_channels = {
|
||||||
|
@ -22,25 +21,27 @@ channel_by_name = {
|
||||||
'canary': 'canary',
|
'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():
|
def get_parser():
|
||||||
parser = argparse.ArgumentParser(description="""Install a given browser or webdriver frontend.
|
parser = argparse.ArgumentParser(
|
||||||
|
parents=[channel_args],
|
||||||
For convenience the release channel of the browser accepts various spellings,
|
description="Install a given browser or webdriver frontend.")
|
||||||
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.add_argument('browser', choices=['firefox', 'chrome', 'servo'],
|
parser.add_argument('browser', choices=['firefox', 'chrome', 'servo'],
|
||||||
help='name of web browser product')
|
help='name of web browser product')
|
||||||
parser.add_argument('component', choices=['browser', 'webdriver'],
|
parser.add_argument('component', choices=['browser', 'webdriver'],
|
||||||
help='name of component')
|
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",
|
parser.add_argument('--download-only', action="store_true",
|
||||||
help="Download the selected component but don't install it")
|
help="Download the selected component but don't install it")
|
||||||
parser.add_argument('--rename', action="store", default=None,
|
parser.add_argument('--rename', action="store", default=None,
|
||||||
|
@ -59,13 +60,15 @@ def get_channel(browser, channel):
|
||||||
|
|
||||||
|
|
||||||
def run(venv, **kwargs):
|
def run(venv, **kwargs):
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger("install")
|
||||||
|
|
||||||
browser = kwargs["browser"]
|
browser = kwargs["browser"]
|
||||||
destination = kwargs["destination"]
|
destination = kwargs["destination"]
|
||||||
channel = get_channel(browser, kwargs["channel"])
|
channel = get_channel(browser, kwargs["channel"])
|
||||||
|
|
||||||
if channel != kwargs["channel"]:
|
if channel != kwargs["channel"]:
|
||||||
print("Interpreting channel '%s' as '%s'" % (kwargs["channel"],
|
logger.info("Interpreting channel '%s' as '%s'", kwargs["channel"], channel)
|
||||||
channel))
|
|
||||||
|
|
||||||
if destination is None:
|
if destination is None:
|
||||||
if venv:
|
if venv:
|
||||||
|
@ -77,7 +80,7 @@ def run(venv, **kwargs):
|
||||||
raise argparse.ArgumentError(None,
|
raise argparse.ArgumentError(None,
|
||||||
"No --destination argument, and no default for the environment")
|
"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"])
|
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
|
method = prefix + suffix
|
||||||
|
|
||||||
subclass = getattr(browser, name.title())
|
browser_cls = getattr(browser, name.title())
|
||||||
sys.stdout.write('Now installing %s %s...\n' % (name, component))
|
logger.info('Now installing %s %s...', name, component)
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if download_only and rename:
|
if download_only and rename:
|
||||||
kwargs["rename"] = 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:
|
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():
|
def create_parser():
|
||||||
from wptrunner import wptcommandline
|
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",
|
parser.add_argument("product", action="store",
|
||||||
help="Browser to run tests in")
|
help="Browser to run tests in")
|
||||||
parser.add_argument("--affected", action="store", default=None,
|
parser.add_argument("--affected", action="store", default=None,
|
||||||
|
@ -52,15 +52,6 @@ def create_parser():
|
||||||
parser.add_argument("--install-browser", action="store_true",
|
parser.add_argument("--install-browser", action="store_true",
|
||||||
help="Install the browser from the release channel specified by --channel "
|
help="Install the browser from the release channel specified by --channel "
|
||||||
"(or the nightly channel by default).")
|
"(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())
|
parser._add_container_actions(wptcommandline.create_parser())
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
@ -182,6 +173,7 @@ class BrowserSetup(object):
|
||||||
def setup(self, kwargs):
|
def setup(self, kwargs):
|
||||||
self.setup_kwargs(kwargs)
|
self.setup_kwargs(kwargs)
|
||||||
|
|
||||||
|
|
||||||
def safe_unsetenv(env_var):
|
def safe_unsetenv(env_var):
|
||||||
"""Safely remove an environment variable.
|
"""Safely remove an environment variable.
|
||||||
|
|
||||||
|
@ -193,6 +185,7 @@ def safe_unsetenv(env_var):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Firefox(BrowserSetup):
|
class Firefox(BrowserSetup):
|
||||||
name = "firefox"
|
name = "firefox"
|
||||||
browser_cls = browser.Firefox
|
browser_cls = browser.Firefox
|
||||||
|
@ -264,11 +257,6 @@ class FirefoxAndroid(BrowserSetup):
|
||||||
name = "firefox_android"
|
name = "firefox_android"
|
||||||
browser_cls = browser.FirefoxAndroid
|
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):
|
def setup_kwargs(self, kwargs):
|
||||||
from . import android
|
from . import android
|
||||||
import mozdevice
|
import mozdevice
|
||||||
|
@ -295,13 +283,6 @@ class FirefoxAndroid(BrowserSetup):
|
||||||
emulator = android.install(logger, reinstall=False, no_prompt=not self.prompt)
|
emulator = android.install(logger, reinstall=False, no_prompt=not self.prompt)
|
||||||
android.start(logger, emulator=emulator, reinstall=False)
|
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:
|
if "ADB_PATH" not in os.environ:
|
||||||
adb_path = os.path.join(android.get_sdk_path(None),
|
adb_path = os.path.join(android.get_sdk_path(None),
|
||||||
"platform-tools",
|
"platform-tools",
|
||||||
|
@ -312,9 +293,9 @@ class FirefoxAndroid(BrowserSetup):
|
||||||
device = mozdevice.ADBDeviceFactory(adb=adb_path,
|
device = mozdevice.ADBDeviceFactory(adb=adb_path,
|
||||||
device=kwargs["device_serial"])
|
device=kwargs["device_serial"])
|
||||||
|
|
||||||
if install:
|
if self.browser.apk_path:
|
||||||
device.uninstall_app(app)
|
device.uninstall_app(app)
|
||||||
device.install_app(apk_path)
|
device.install_app(self.browser.apk_path)
|
||||||
elif not device.is_app_installed(app):
|
elif not device.is_app_installed(app):
|
||||||
raise WptrunError("app %s not installed on device %s" %
|
raise WptrunError("app %s not installed on device %s" %
|
||||||
(app, kwargs["device_serial"]))
|
(app, kwargs["device_serial"]))
|
||||||
|
|
|
@ -3,6 +3,7 @@ import subprocess
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
|
import inspect
|
||||||
|
|
||||||
from tools.wpt import browser
|
from tools.wpt import browser
|
||||||
|
|
||||||
|
@ -10,6 +11,19 @@ from tools.wpt import browser
|
||||||
logger = logging.getLogger()
|
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')
|
@mock.patch('subprocess.check_output')
|
||||||
def test_safari_version(mocked_check_output):
|
def test_safari_version(mocked_check_output):
|
||||||
safari = browser.Safari(logger)
|
safari = browser.Safari(logger)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче