0

[build] Set up python for pinned browsers

This allows people to pass in  --//common:pin_browsers to python tests
and bazel will setup the browsers and use them.

Work from pairing session with Simon Stewart

NOKEYCHECK=True
GitOrigin-RevId: 958724989003cfcc422b3f433cde2a7da37865c9
This commit is contained in:
AutomatedTester
2021-03-10 10:50:12 +00:00
committed by Josip Sokcevic
parent 7cf40723ae
commit 21d61a31d0
5 changed files with 153 additions and 18 deletions

@@ -3,6 +3,7 @@ load("@rules_python//experimental/python:wheel.bzl", "py_package", "py_wheel")
load("@dev_requirements//:requirements.bzl", "requirement")
load("//common:defs.bzl", "copy_file")
load("//py:defs.bzl", "py_test_suite", "pytest_test")
load("//py/private:browsers.bzl", "BROWSERS")
BROWSER_VERSIONS = [
"v85",
@@ -143,7 +144,7 @@ py_library(
data = [
"pytest.ini",
"setup.cfg",
"test/selenium/webdriver/common/test_file.txt"
"test/selenium/webdriver/common/test_file.txt",
],
imports = ["."],
deps = [
@@ -216,6 +217,50 @@ py_library(
deps = [],
)
[
py_test_suite(
name = "auto-%s" % browser,
size = "large",
srcs = glob(
[
"test/selenium/webdriver/common/**/*.py",
"test/selenium/webdriver/support/**/*.py",
],
exclude = ["test/selenium/webdriver/common/print_pdf_tests.py"],
),
args = [
"--instafail",
] + BROWSERS[browser]["args"],
data = BROWSERS[browser]["data"],
tags = [
"no-sandbox",
] + BROWSERS[browser]["tags"],
deps = [
":init-tree",
":selenium",
":webserver",
requirement("attrs"),
requirement("debugpy"),
requirement("idna"),
requirement("iniconfig"),
requirement("importlib_metadata"),
requirement("h11"),
requirement("more_itertools"),
requirement("multidict"),
requirement("outcome"),
requirement("pluggy"),
requirement("py"),
requirement("pytest"),
requirement("pytest-instafail"),
requirement("pytest-trio"),
requirement("sortedcontainers"),
requirement("sniffio"),
requirement("zipp"),
],
)
for browser in BROWSERS.keys()
]
py_test_suite(
name = "test-chrome",
size = "large",

@@ -31,15 +31,15 @@ from test.selenium.webdriver.common.network import get_lan_ip
from urllib.request import urlopen
drivers = (
'Chrome',
'Edge',
'Firefox',
'Ie',
'Remote',
'Safari',
'WebKitGTK',
'ChromiumEdge',
'WPEWebKit',
'chrome',
'edge',
'firefox',
'ie',
'remote',
'safari',
'webkitgtk',
'chromiumedge',
'wpewebkit',
)
@@ -74,7 +74,7 @@ def driver(request):
kwargs = {}
try:
driver_class = request.param
driver_class = request.param.capitalize()
except AttributeError:
raise Exception('This test requires a --driver to be specified.')
@@ -122,7 +122,7 @@ def driver(request):
options = get_options('Firefox', request.config)
if driver_class == 'WebKitGTK':
options = get_options(driver_class, request.config)
if driver_class == 'ChromiumEdge':
if driver_class == 'Edge':
options = get_options(driver_class, request.config)
if driver_class == 'WPEWebKit':
options = get_options(driver_class, request.config)
@@ -130,6 +130,7 @@ def driver(request):
kwargs['executable_path'] = driver_path
if options is not None:
kwargs['options'] = options
driver_instance = getattr(webdriver, driver_class)(**kwargs)
yield driver_instance

84
private/browsers.bzl Normal file

@@ -0,0 +1,84 @@
load(
"//common:browsers.bzl",
"COMMON_TAGS",
"chrome_data",
"edge_data",
"firefox_data",
)
headless_args = select({
"@selenium//common:use_headless_browser": [
"--headless=true",
],
"//conditions:default": [],
})
chrome_args = select({
"@selenium//common:use_pinned_linux_chrome": [
"--driver-binary=$(location @linux_chromedriver//:chromedriver)",
"--browser-binary=$(location @linux_chrome//:chrome-linux)/linux-chrome/chrome",
],
"@selenium//common:use_pinned_macos_chrome": [
"--driver-binary=$(location @mac_chromedriver//:chromedriver)",
"--browser-binary=$(location @mac_chrome//:Chromium.app)/Contents/MacOS/Chromium",
],
"@selenium//common:use_local_chromedriver": [
"--driver-binary=$(location @selenium//common:chromedriver)",
],
"//conditions:default": []
}) + headless_args
edge_args = select({
"@selenium//common:use_pinned_macos_edge": [
"--driver-binary=$(location @mac_edgedriver//:msedgedriver)",
"--browser-binary",
"$(location @mac_edge//:Edge.app)/Contents/MacOS/Microsoft Edge",
],
"@selenium//common:use_local_msedgedriver": [
"-Dwebdriver.edge.driver=$(location @selenium//common:msedgedriver)",
],
"//conditions:default": []
}) + headless_args
firefox_args = select({
"@selenium//common:use_pinned_linux_firefox": [
"--driver-binary=$(location @linux_geckodriver//:geckodriver)",
"--browser-binary=$(location @linux_firefox//:firefox)/firefox",
],
"@selenium//common:use_pinned_macos_firefox": [
"--driver-binary=$(location @mac_geckodriver//:geckodriver)",
"--browser-binary=$(location @mac_firefox//:Firefox.app)/Contents/MacOS/firefox",
],
"@selenium//common:use_local_geckodriver": [
"--driver-binary=$(location @selenium//common:geckodriver)",
],
"//conditions:default": [],
}) + headless_args
BROWSERS = {
"chrome": {
"args": ["--driver=chrome"] + chrome_args,
"data": chrome_data,
"tags": COMMON_TAGS + ["chrome"],
},
"edge": {
"args": ["--driver=edge"] + edge_args,
"data": edge_data,
"tags": COMMON_TAGS + ["edge"],
},
"firefox": {
"args": ["--driver=firefox"] + firefox_args,
"data": firefox_data,
"tags": COMMON_TAGS + ["firefox"],
},
"ie": {
"args": ["--driver=ie"],
"data": [],
"tags": COMMON_TAGS + ["ie"],
},
"safari": {
"args": ["--driver=safari"],
"data": [],
"tags": COMMON_TAGS + ["safari"],
}
}

@@ -1,12 +1,14 @@
load("@rules_python//python:defs.bzl", "PyInfo", "py_test")
def _stringify(paths):
return "[%s]" % (", ".join(["\"%s\"" % path for path in paths]))
return repr(paths)
def _pytest_runner_impl(ctx):
if len(ctx.attr.srcs) == 0:
fail("No test files specified.")
expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]
runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(
runner,
@@ -17,13 +19,14 @@ if __name__ == "__main__":
args = ["-ra"] + %s + sys.argv[1:] + %s
sys.exit(pytest.main(args))""" % (_stringify(ctx.attr.args), _stringify([src.path for src in ctx.files.srcs])),
sys.exit(pytest.main(args))""" % (_stringify(expanded_args), _stringify([src.path for src in ctx.files.srcs])),
is_executable = True,
)
return [
DefaultInfo(
files = depset([runner]),
runfiles = ctx.runfiles(ctx.files.data),
executable = runner,
),
]
@@ -42,6 +45,10 @@ _pytest_runner = rule(
"args": attr.string_list(
default = [],
),
"data": attr.label_list(
allow_empty = True,
allow_files = True,
),
"python_version": attr.string(
values = ["PY2", "PY3"],
default = "PY3",
@@ -49,7 +56,7 @@ _pytest_runner = rule(
},
)
def pytest_test(name, srcs, deps = None, args = None, python_version = None, **kwargs):
def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name
_pytest_runner(
@@ -58,6 +65,7 @@ def pytest_test(name, srcs, deps = None, args = None, python_version = None, **k
srcs = srcs,
deps = deps,
args = args,
data = data,
python_version = python_version,
)

@@ -56,9 +56,6 @@ class WebDriver(ChromiumDriver):
warnings.warn('executable_path has been deprecated, please pass in a Service object',
DeprecationWarning, stacklevel=2)
if options and options.use_chromium:
executable_path = "msedgedriver"
if not service:
service = Service(executable_path, port, service_args, service_log_path)