зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1384517 - Add "marionette doc" subcommand to generate docs; r=automatedtester
This patch introduces a new top-level mach command "marionette" that can be invoked as `./mach marionette`. It offers two subcommands, "test" and "doc". The "test" subcommand is functionally equivalent to the existing "marionette-test" command, which this patch deprecates. The "doc" subcommand generates the Marionette server API documentation using jsdoc, which it is presumed is already installed on the system. A future patch will make this subcommand more sophisticated, but this should work for now. It also comes with an --http <host>:<port> flag which spins up an HTTPD serving the documentation. MozReview-Commit-ID: DAoHC8tHJQF --HG-- extra : rebase_source : b1c65c67a55b9bbbf5ef4724f2db57f720443fff
This commit is contained in:
Родитель
dd7a57fd22
Коммит
7bcd574c92
|
@ -4,32 +4,36 @@
|
|||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
from mach.decorators import (
|
||||
CommandArgument,
|
||||
CommandProvider,
|
||||
Command,
|
||||
SubCommand,
|
||||
)
|
||||
|
||||
from mozbuild.base import (
|
||||
MachCommandBase,
|
||||
MachCommandConditions as conditions,
|
||||
)
|
||||
|
||||
from mach.decorators import (
|
||||
CommandArgument,
|
||||
CommandProvider,
|
||||
Command,
|
||||
)
|
||||
|
||||
def is_firefox_or_android(cls):
|
||||
"""Must have Firefox build or Android build."""
|
||||
return conditions.is_firefox(cls) or conditions.is_android(cls)
|
||||
|
||||
def setup_marionette_argument_parser():
|
||||
|
||||
def create_parser_tests():
|
||||
from marionette_harness.runtests import MarionetteArguments
|
||||
from mozlog.structured import commandline
|
||||
parser = MarionetteArguments()
|
||||
commandline.add_logging_group(parser)
|
||||
return parser
|
||||
|
||||
|
||||
def run_marionette(tests, binary=None, topsrcdir=None, **kwargs):
|
||||
from mozlog.structured import commandline
|
||||
|
||||
|
@ -38,11 +42,11 @@ def run_marionette(tests, binary=None, topsrcdir=None, **kwargs):
|
|||
MarionetteHarness
|
||||
)
|
||||
|
||||
parser = setup_marionette_argument_parser()
|
||||
parser = create_parser_tests()
|
||||
|
||||
if not tests:
|
||||
tests = [os.path.join(topsrcdir,
|
||||
'testing/marionette/harness/marionette_harness/tests/unit-tests.ini')]
|
||||
"testing/marionette/harness/marionette_harness/tests/unit-tests.ini")]
|
||||
|
||||
args = argparse.Namespace(tests=tests)
|
||||
|
||||
|
@ -62,20 +66,96 @@ def run_marionette(tests, binary=None, topsrcdir=None, **kwargs):
|
|||
else:
|
||||
return 0
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class MachCommands(MachCommandBase):
|
||||
@Command('marionette-test', category='testing',
|
||||
description='Run a Marionette test (Check UI or the internal JavaScript using marionette).',
|
||||
conditions=[is_firefox_or_android],
|
||||
parser=setup_marionette_argument_parser,
|
||||
)
|
||||
def run_marionette_test(self, tests, **kwargs):
|
||||
if 'test_objects' in kwargs:
|
||||
tests = []
|
||||
for obj in kwargs['test_objects']:
|
||||
tests.append(obj['file_relpath'])
|
||||
del kwargs['test_objects']
|
||||
|
||||
if not kwargs.get('binary') and conditions.is_firefox(self):
|
||||
kwargs['binary'] = self.get_binary_path('app')
|
||||
"""Deprecated in favour of ./mach marionette <subcommand>."""
|
||||
|
||||
@Command("marionette-test",
|
||||
category="testing",
|
||||
description="Remote control protocol to Gecko, used for functional UI tests and browser automation.",
|
||||
conditions=[is_firefox_or_android],
|
||||
parser=create_parser_tests,
|
||||
)
|
||||
def run_marionette_test(self, tests, **kwargs):
|
||||
print >>sys.stderr, ("warning: ./mach marionette-test is deprecated; "
|
||||
"please use ./mach marionette test")
|
||||
|
||||
if "test_objects" in kwargs:
|
||||
tests = []
|
||||
for obj in kwargs["test_objects"]:
|
||||
tests.append(obj["file_relpath"])
|
||||
del kwargs["test_objects"]
|
||||
|
||||
if not kwargs.get("binary") and conditions.is_firefox(self):
|
||||
kwargs["binary"] = self.get_binary_path("app")
|
||||
return run_marionette(tests, topsrcdir=self.topsrcdir, **kwargs)
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class Marionette(MachCommandBase):
|
||||
|
||||
@property
|
||||
def srcdir(self):
|
||||
return os.path.join(self.topsrcdir, "testing/marionette")
|
||||
|
||||
@Command("marionette",
|
||||
category="misc",
|
||||
description="Remote control protocol to Gecko, used for functional UI tests and browser automation.",
|
||||
conditions=[is_firefox_or_android],
|
||||
)
|
||||
def marionette(self):
|
||||
self.parser.print_usage()
|
||||
return 1
|
||||
|
||||
@SubCommand("marionette", "test",
|
||||
description="Run browser automation tests based on Marionette harness.",
|
||||
parser=create_parser_tests,
|
||||
)
|
||||
def marionette_test(self, tests, **kwargs):
|
||||
if "test_objects" in kwargs:
|
||||
tests = []
|
||||
for obj in kwargs["test_objects"]:
|
||||
tests.append(obj["file_relpath"])
|
||||
del kwargs["test_objects"]
|
||||
|
||||
if not kwargs.get("binary") and conditions.is_firefox(self):
|
||||
kwargs["binary"] = self.get_binary_path("app")
|
||||
return run_marionette(tests, topsrcdir=self.topsrcdir, **kwargs)
|
||||
|
||||
@SubCommand("marionette", "doc",
|
||||
description="Generate Marionette server API documentation in testing/marionette/doc.")
|
||||
@CommandArgument("--http",
|
||||
help='HTTP service address (e.g. "127.0.0.1:6060" or just ":6060".'
|
||||
)
|
||||
def marionette_doc(self, http, **kwargs):
|
||||
import subprocess
|
||||
|
||||
def is_marionette_source_file(filename):
|
||||
path = os.path.join(self.srcdir, filename)
|
||||
return (os.path.isfile(path)
|
||||
and filename.endswith(".js")
|
||||
and not filename.startswith("test_"))
|
||||
|
||||
srcs = [f for f in os.listdir(
|
||||
self.srcdir) if is_marionette_source_file(f)]
|
||||
|
||||
proc = subprocess.Popen(
|
||||
["jsdoc", "-c", ".jsdoc.js"] + srcs, cwd=self.srcdir)
|
||||
proc.wait()
|
||||
|
||||
if http:
|
||||
import SimpleHTTPServer
|
||||
import SocketServer
|
||||
|
||||
host, port = http.split(":")
|
||||
host = host or "127.0.0.1"
|
||||
port = int(port)
|
||||
|
||||
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
|
||||
httpd = SocketServer.TCPServer((host, int(port)), handler)
|
||||
|
||||
print "serving at %s:%s" % (host, port)
|
||||
os.chdir(os.path.join(self.srcdir, "doc"))
|
||||
httpd.serve_forever()
|
||||
|
|
Загрузка…
Ссылка в новой задаче