Bug 1445944 - [mozrunner] Create a base BlinkRuntimeRunner and add a ChromeRunner to the runners list r=rwood

This allows consumers to bootstrap Chrome with mozrunner. For now the profile implementation
is just an empty class but this will be expanded in a future commit.

MozReview-Commit-ID: 1Z14FudH0JJ

--HG--
extra : rebase_source : b593965a6bd725b133adf42ff31d61726bcff520
This commit is contained in:
Andrew Halberstadt 2018-04-12 22:29:17 -04:00
Родитель 07297de09a
Коммит 3d3df5c730
7 изменённых файлов: 78 добавлений и 22 удалений

Просмотреть файл

@ -153,6 +153,12 @@ GeckoRuntimeRunner
:show-inheritance: :show-inheritance:
:members: :members:
BlinkRuntimeRunner
~~~~~~~~~~~~~~~~~~
.. autoclass:: mozrunner.base.BlinkRuntimeRunner
:show-inheritance:
:members:
DeviceRunner DeviceRunner
~~~~~~~~~~~~ ~~~~~~~~~~~~
.. autoclass:: mozrunner.base.DeviceRunner .. autoclass:: mozrunner.base.DeviceRunner

Просмотреть файл

@ -20,10 +20,13 @@ here = os.path.abspath(os.path.dirname(__file__))
def get_app_context(appname): def get_app_context(appname):
context_map = {'default': DefaultContext, context_map = {
'firefox': FirefoxContext, 'chrome': ChromeContext,
'thunderbird': ThunderbirdContext, 'default': DefaultContext,
'fennec': FennecContext} 'fennec': FennecContext,
'firefox': FirefoxContext,
'thunderbird': ThunderbirdContext,
}
if appname not in context_map: if appname not in context_map:
raise KeyError("Application '%s' not supported!" % appname) raise KeyError("Application '%s' not supported!" % appname)
return context_map[appname] return context_map[appname]
@ -131,3 +134,11 @@ class FirefoxContext(object):
class ThunderbirdContext(object): class ThunderbirdContext(object):
profile_class = ThunderbirdProfile profile_class = ThunderbirdProfile
class ChromeProfile(object):
"""Dummy profile class until a proper one is implemented in mozprofile"""
class ChromeContext(object):
profile_class = ChromeProfile

Просмотреть файл

@ -1,7 +1,6 @@
# flake8: noqa
from __future__ import absolute_import from __future__ import absolute_import
from .runner import BaseRunner from .runner import BaseRunner
from .device import DeviceRunner, FennecRunner from .device import DeviceRunner, FennecRunner
from .browser import GeckoRuntimeRunner from .browser import GeckoRuntimeRunner, BlinkRuntimeRunner
__all__ = ['BaseRunner', 'DeviceRunner', 'FennecRunner', 'GeckoRuntimeRunner']

Просмотреть файл

@ -77,3 +77,19 @@ class GeckoRuntimeRunner(BaseRunner):
self.env["MOZ_CRASHREPORTER"] = "1" self.env["MOZ_CRASHREPORTER"] = "1"
BaseRunner.start(self, *args, **kwargs) BaseRunner.start(self, *args, **kwargs)
class BlinkRuntimeRunner(BaseRunner):
"""A base runner class for running apps like Google Chrome or Chromium."""
def __init__(self, binary, cmdargs=None, **runner_args):
super(BlinkRuntimeRunner, self).__init__(**runner_args)
self.binary = binary
self.cmdargs = cmdargs or []
@property
def command(self):
cmd = self.cmdargs[:]
return [self.binary] + cmd
def check_for_crashes(self, *args, **kwargs):
raise NotImplementedError

Просмотреть файл

@ -11,7 +11,7 @@ used Mozilla applications, such as Firefox, Firefox for Android or Thunderbird.
from __future__ import absolute_import from __future__ import absolute_import
from .application import get_app_context from .application import get_app_context
from .base import GeckoRuntimeRunner, FennecRunner from .base import GeckoRuntimeRunner, FennecRunner, BlinkRuntimeRunner
from .devices import EmulatorAVD from .devices import EmulatorAVD
@ -74,6 +74,17 @@ def ThunderbirdRunner(*args, **kwargs):
return GeckoRuntimeRunner(*args, **kwargs) return GeckoRuntimeRunner(*args, **kwargs)
def ChromeRunner(*args, **kwargs):
"""
Create a desktop Google Chrome runner.
:param binary: Path to Chrome binary.
:param cmdargs: Arguments to pass into the binary.
"""
kwargs['app_ctx'] = get_app_context('chrome')()
return BlinkRuntimeRunner(*args, **kwargs)
def FennecEmulatorRunner(avd='mozemulator-4.3', def FennecEmulatorRunner(avd='mozemulator-4.3',
adb_path=None, adb_path=None,
avd_home=None, avd_home=None,
@ -113,8 +124,9 @@ def FennecEmulatorRunner(avd='mozemulator-4.3',
runners = { runners = {
'chrome': ChromeRunner,
'default': Runner, 'default': Runner,
'firefox': FirefoxRunner, 'firefox': FirefoxRunner,
'fennec': FennecEmulatorRunner,
'thunderbird': ThunderbirdRunner, 'thunderbird': ThunderbirdRunner,
'fennec': FennecEmulatorRunner
} }

Просмотреть файл

@ -8,37 +8,46 @@ import os
import threading import threading
from time import sleep from time import sleep
import mozprofile
import mozrunner import mozrunner
import pytest import pytest
from moztest.selftest import fixtures from moztest.selftest import fixtures
@pytest.fixture @pytest.fixture(scope='session')
def profile():
return mozprofile.FirefoxProfile()
@pytest.fixture
def get_binary(): def get_binary():
if 'BROWSER_PATH' in os.environ: if 'BROWSER_PATH' in os.environ:
os.environ['GECKO_BINARY_PATH'] = os.environ['BROWSER_PATH'] os.environ['GECKO_BINARY_PATH'] = os.environ['BROWSER_PATH']
def inner(app): def inner(app):
if app != 'firefox': if app not in ('chrome', 'firefox'):
pytest.xfail(reason="{} support not implemented".format(app)) pytest.xfail(reason="{} support not implemented".format(app))
binary = fixtures.binary() if app == 'firefox':
binary = fixtures.binary()
elif app == 'chrome':
binary = os.environ.get('CHROME_BINARY_PATH')
if not binary: if not binary:
pytest.skip("could not find a {} binary".format(app)) pytest.skip("could not find a {} binary".format(app))
return binary return binary
return inner return inner
@pytest.fixture @pytest.fixture(params=['firefox', 'chrome'])
def runner(profile, get_binary): def runner(request, get_binary):
binary = get_binary('firefox') app = request.param
return mozrunner.FirefoxRunner(binary, profile=profile) binary = get_binary(app)
cmdargs = ['--headless']
if app == 'chrome':
# prevents headless chrome from exiting after loading the page
cmdargs.append('--remote-debugging-port=9222')
# only needed on Windows, but no harm in specifying it everywhere
cmdargs.append('--disable-gpu')
runner = mozrunner.runners[app](binary, cmdargs=cmdargs)
runner.app = app
yield runner
runner.stop()
class RunnerThread(threading.Thread): class RunnerThread(threading.Thread):

Просмотреть файл

@ -13,6 +13,9 @@ import pytest
@pytest.mark.parametrize('logger', [True, False]) @pytest.mark.parametrize('logger', [True, False])
def test_crash_count_with_or_without_logger(runner, logger): def test_crash_count_with_or_without_logger(runner, logger):
if runner.app == 'chrome':
pytest.xfail("crash checking not implemented for ChromeRunner")
if not logger: if not logger:
runner.logger = None runner.logger = None
fn = 'check_for_crashes' fn = 'check_for_crashes'