0

Roll wpt tooling

This rolls wpt to latest commit at
https://github.com/web-platform-tests/wpt.
REMOTE-WPT-HEAD: a50aec6c90d6ce28629fa4eb5cbeba0d1d65c53b

Cq-Include-Trybots: luci.chromium.try:linux-blink-rel
Change-Id: Iadb5743da93ee3ebdb8cdffcec7b055f6ec3442d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5114401
Commit-Queue: Weizhong Xia <weizhong@google.com>
Auto-Submit: Jonathan Lee <jonathanjlee@google.com>
Reviewed-by: Weizhong Xia <weizhong@google.com>
Cr-Commit-Position: refs/heads/main@{#1236466}
This commit is contained in:
Jonathan Lee
2023-12-12 18:54:42 +00:00
committed by Chromium LUCI CQ
parent 33b441e83b
commit 076fbac136
31 changed files with 233 additions and 66 deletions

@ -1,3 +1,4 @@
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = TypeError: test_driver.set_rph_registration_mode is not a function
Harness Error. harness_status.status = 1 , harness_status.message = error: Action set_rph_registration_mode not implemented
[NOTRUN] registerProtocolHandler() and a handler with %s in the fragment (does not use a service worker)
Harness: the test ran to completion.

@ -1,3 +1,4 @@
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = TypeError: test_driver.set_rph_registration_mode is not a function
Harness Error. harness_status.status = 1 , harness_status.message = error: Action set_rph_registration_mode not implemented
[NOTRUN] registerProtocolHandler() and a handler with %s in the fragment
Harness: the test ran to completion.

@ -1,3 +1,4 @@
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = TypeError: test_driver.set_rph_registration_mode is not a function
Harness Error. harness_status.status = 1 , harness_status.message = error: Action set_rph_registration_mode not implemented
[NOTRUN] registerProtocolHandler() and a handler with %s in the path
Harness: the test ran to completion.

@ -1,3 +1,4 @@
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = TypeError: test_driver.set_rph_registration_mode is not a function
Harness Error. harness_status.status = 1 , harness_status.message = error: Action set_rph_registration_mode not implemented
[NOTRUN] registerProtocolHandler() and a handler with %s in the query (does not use a service worker)
Harness: the test ran to completion.

@ -1,3 +1,4 @@
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = TypeError: test_driver.set_rph_registration_mode is not a function
Harness Error. harness_status.status = 1 , harness_status.message = error: Action set_rph_registration_mode not implemented
[NOTRUN] registerProtocolHandler() and a handler with %s in the query
Harness: the test ran to completion.

@ -1,7 +1,7 @@
Name: web-platform-tests - Test Suites for Web Platform specifications
Short Name: wpt
URL: https://github.com/web-platform-tests/wpt/
Version: c359284745e2a2f6c44af320d1d6c43ce51f25bc
Version: a50aec6c90d6ce28629fa4eb5cbeba0d1d65c53b
License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
Security Critical: no
Shipped: no

@ -283,6 +283,7 @@
./tools/webdriver/webdriver/bidi/modules/script.py
./tools/webdriver/webdriver/bidi/modules/session.py
./tools/webdriver/webdriver/bidi/transport.py
./tools/webdriver/webdriver/bidi/undefined.py
./tools/webdriver/webdriver/client.py
./tools/webdriver/webdriver/error.py
./tools/webdriver/webdriver/protocol.py

@ -647,7 +647,7 @@
*
* This function places `Secure Payment
* Confirmation <https://w3c.github.io/secure-payment-confirmation>`_ into
* an automated 'autoaccept' or 'autoreject' mode, to allow testing
* an automated 'autoAccept' or 'autoReject' mode, to allow testing
* without user interaction with the transaction UX prompt.
*
* Matches the `Set SPC Transaction Mode
@ -667,8 +667,8 @@
* @param {String} mode - The `transaction mode
* <https://w3c.github.io/secure-payment-confirmation/#enumdef-transactionautomationmode>`_
* to set. Must be one of "``none``",
* "``autoaccept``", or
* "``autoreject``".
* "``autoAccept``", or
* "``autoReject``".
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
@ -680,6 +680,42 @@
return window.test_driver_internal.set_spc_transaction_mode(mode, context);
},
/**
* Sets the current registration automation mode for Register Protocol Handlers.
*
* This function places `Register Protocol Handlers
* <https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers>`_ into
* an automated 'autoAccept' or 'autoReject' mode, to allow testing
* without user interaction with the transaction UX prompt.
*
* Matches the `Set Register Protocol Handler Mode
* <https://html.spec.whatwg.org/multipage/system-state.html#set-rph-registration-mode>`_
* WebDriver command.
*
* @example
* await test_driver.set_rph_registration_mode("autoAccept");
* test.add_cleanup(() => {
* return test_driver.set_rph_registration_mode("none");
* });
*
* navigator.registerProtocolHandler('web+soup', 'soup?url=%s');
*
* @param {String} mode - The `registration mode
* <https://html.spec.whatwg.org/multipage/system-state.html#registerprotocolhandler()-automation-mode>`_
* to set. Must be one of "``none``",
* "``autoAccept``", or
* "``autoReject``".
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} Fulfilled after the transaction mode has been set,
* or rejected if setting the mode fails.
*/
set_rph_registration_mode: function(mode, context=null) {
return window.test_driver_internal.set_rph_registration_mode(mode, context);
},
/**
* Cancels the Federated Credential Management dialog
*
@ -699,21 +735,22 @@
},
/**
* Accepts a FedCM "Confirm IDP login" dialog.
* Clicks a button on the Federated Credential Management dialog
*
* Matches the `Confirm IDP Login
* <https://fedidcg.github.io/FedCM/#webdriver-confirmidplogin>`_
* Matches the `Click dialog button
* <https://fedidcg.github.io/FedCM/#webdriver-clickdialogbutton>`_
* WebDriver command.
*
* @param {String} dialog_button - String enum representing the dialog button to click.
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
*
* @returns {Promise} Fulfilled after the IDP login has started,
* @returns {Promise} Fulfilled after the button is clicked,
* or rejected in case the WebDriver command errors
*/
confirm_idp_login: function(context=null) {
return window.test_driver_internal.confirm_idp_login(context);
click_fedcm_dialog_button: function(dialog_button, context=null) {
return window.test_driver_internal.click_fedcm_dialog_button(dialog_button, context);
},
/**
@ -1093,12 +1130,16 @@
throw new Error("set_spc_transaction_mode() is not implemented by testdriver-vendor.js");
},
set_rph_registration_mode: function(mode, context=null) {
return Promise.reject(new Error("unimplemented"));
},
async cancel_fedcm_dialog(context=null) {
throw new Error("cancel_fedcm_dialog() is not implemented by testdriver-vendor.js");
},
async confirm_idp_login(context=null) {
throw new Error("confirm_idp_login() is not implemented by testdriver-vendor.js");
async click_fedcm_dialog_button(dialog_button, context=null) {
throw new Error("click_fedcm_dialog_button() is not implemented by testdriver-vendor.js");
},
async select_fedcm_account(account_index, context=null) {

@ -63,6 +63,10 @@ class NoSuchHandleException(BidiException):
error_code = "no such handle"
class NoSuchHistoryEntryException(BidiException):
error_code = "no such history entry"
class NoSuchNodeException(BidiException):
error_code = "no such node"

@ -9,6 +9,8 @@ from typing import (
TYPE_CHECKING,
)
from ..undefined import UNDEFINED
if TYPE_CHECKING:
from ..client import BidiSession
@ -49,7 +51,8 @@ class command:
self.params_fn = fn
self.result_fn: Optional[Callable[..., Any]] = None
def result(self, fn: Callable[[Any, MutableMapping[str, Any]], Any]) -> None:
def result(self, fn: Callable[[Any, MutableMapping[str, Any]],
Any]) -> None:
self.result_fn = fn
def __set_name__(self, owner: Any, name: str) -> None:
@ -61,7 +64,7 @@ class command:
@functools.wraps(params_fn)
async def inner(self: Any, **kwargs: Any) -> Any:
raw_result = kwargs.pop("raw_result", False)
params = params_fn(self, **kwargs)
params = remove_undefined(params_fn(self, **kwargs))
# Convert the classname and the method name to a bidi command name
mod_name = owner.__name__[0].lower() + owner.__name__[1:]
@ -85,6 +88,7 @@ class command:
class BidiModule:
def __init__(self, session: "BidiSession"):
self.session = session
@ -96,3 +100,7 @@ def to_camelcase(name: str) -> str:
for i in range(1, len(parts)):
parts[i] = parts[i].title()
return "".join(parts)
def remove_undefined(obj: Mapping[str, Any]) -> Mapping[str, Any]:
return {key: value for key, value in obj.items() if value != UNDEFINED}

@ -1,19 +1,16 @@
import base64
from enum import Enum
from typing import Any, Dict, List, Mapping, MutableMapping, Optional, Union
from ._module import BidiModule, command
from ..undefined import UNDEFINED, Undefined
class ElementOptions(Dict[str, Any]):
def __init__(
self, element: Mapping[str, Any], scroll_into_view: Optional[bool] = None
):
def __init__(self, element: Mapping[str, Any]):
self["type"] = "element"
self["element"] = element
if scroll_into_view is not None:
self["scrollIntoView"] = scroll_into_view
class BoxOptions(Dict[str, Any]):
def __init__(self, x: float, y: float, width: float, height: float):
@ -27,6 +24,19 @@ class BoxOptions(Dict[str, Any]):
ClipOptions = Union[ElementOptions, BoxOptions]
class OriginOptions(Enum):
DOCUMENT = "document"
VIEWPORT = "viewport"
class FormatOptions(Dict[str, Any]):
def __init__(self, type: str, quality: Optional[float] = None):
dict.__init__(self, type=type)
if quality is not None:
self["quality"] = quality
class BrowsingContext(BidiModule):
@command
def activate(self, context: str) -> Mapping[str, Any]:
@ -34,12 +44,20 @@ class BrowsingContext(BidiModule):
@command
def capture_screenshot(
self, context: str, clip: Optional[ClipOptions] = None
self,
context: str,
clip: Optional[ClipOptions] = None,
origin: Optional[OriginOptions] = None,
format: Optional[FormatOptions] = None,
) -> Mapping[str, Any]:
params: MutableMapping[str, Any] = {"context": context}
if format is not None:
params["format"] = format
if clip is not None:
params["clip"] = clip
if origin is not None:
params["origin"] = origin
return params
@ -180,16 +198,20 @@ class BrowsingContext(BidiModule):
@command
def set_viewport(self,
context: str,
viewport: Optional[Mapping[str, Any]] = None,
device_pixel_ratio: Optional[float] = None) -> Mapping[str, Any]:
viewport: Union[Optional[Mapping[str, Any]], Undefined] = UNDEFINED,
device_pixel_ratio: Union[Optional[float], Undefined] = UNDEFINED) -> Mapping[str, Any]:
params: MutableMapping[str, Any] = {
"context": context,
}
if viewport is not None:
if viewport is not UNDEFINED:
params["viewport"] = viewport
if device_pixel_ratio is not None:
if device_pixel_ratio is not UNDEFINED:
params["devicePixelRatio"] = device_pixel_ratio
return params
@command
def traverse_history(self, context: str, delta: int) -> Mapping[str, Any]:
return {"context": context, "delta": delta}

@ -0,0 +1,6 @@
class Undefined:
def __init__(self) -> None:
raise RuntimeError('Import UNDEFINED instead.')
UNDEFINED = Undefined.__new__(Undefined)

@ -15,7 +15,7 @@ here = os.path.abspath(os.path.dirname(__file__))
wpt_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
NDK_VERSION = "r23c"
NDK_VERSION = "r25c"
CMDLINE_TOOLS_VERSION_STRING = "11.0"
CMDLINE_TOOLS_VERSION = "9644228"

@ -395,22 +395,23 @@ class FirefoxAndroid(BrowserSetup):
device_serial=device_serial,
prompt=kwargs["prompt"])
if "ADB_PATH" not in os.environ:
adb_path = os.path.join(android.get_paths(None)["sdk"],
"platform-tools",
"adb")
os.environ["ADB_PATH"] = adb_path
adb_path = os.environ["ADB_PATH"]
if kwargs["adb_binary"] is None:
if "ADB_PATH" not in os.environ:
adb_path = os.path.join(android.get_paths(None)["sdk"],
"platform-tools",
"adb")
os.environ["ADB_PATH"] = adb_path
kwargs["adb_binary"] = os.environ["ADB_PATH"]
self._logcat = AndroidLogcat(adb_path, base_path=kwargs["logcat_dir"])
self._logcat = AndroidLogcat(kwargs["adb_binary"], base_path=kwargs["logcat_dir"])
for device_serial in kwargs["device_serial"]:
device = mozdevice.ADBDeviceFactory(adb=adb_path,
device = mozdevice.ADBDeviceFactory(adb=kwargs["adb_binary"],
device=device_serial)
self._logcat.start(device_serial)
if self.browser.apk_path:
device.uninstall_app(app)
device.install_app(self.browser.apk_path)
device.install_app(self.browser.apk_path, timeout=600)
elif not device.is_app_installed(app):
raise WptrunError("app %s not installed on device %s" %
(app, device_serial))

@ -95,7 +95,7 @@ class EdgeBrowser(WebDriverBrowser):
return [self.webdriver_binary, f"--port={self.port}"] + self.webdriver_args
def run_info_extras(**kwargs):
def run_info_extras(logger, **kwargs):
osReleaseCommand = r"(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion').ReleaseId"
osBuildCommand = r"(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion').BuildLabEx"
try:

@ -71,5 +71,5 @@ def env_options():
return {}
def run_info_extras(**kwargs):
def run_info_extras(logger, **kwargs):
return {"webkit_port": "gtk"}

@ -193,7 +193,7 @@ def env_options():
"supports_debugger": True}
def run_info_extras(**kwargs):
def run_info_extras(logger, **kwargs):
def get_bool_pref_if_exists(pref):
for key, value in kwargs.get('extra_prefs', []):
@ -213,7 +213,8 @@ def run_info_extras(**kwargs):
"fission": not kwargs.get("disable_fission"),
"sessionHistoryInParent": (not kwargs.get("disable_fission") or
not get_bool_pref("fission.disableSessionHistoryInParent")),
"swgl": get_bool_pref("gfx.webrender.software")}
"swgl": get_bool_pref("gfx.webrender.software"),
"privateBrowsing": (kwargs["tags"] is not None and ("privatebrowsing" in kwargs["tags"]))}
rv.update(run_info_browser_version(**kwargs))
@ -567,6 +568,7 @@ class FirefoxOutputHandler(OutputHandler):
if self.lsan_handler:
self.lsan_handler.process()
if self.leak_report_file is not None:
processed_files = None
if not clean_shutdown:
# If we didn't get a clean shutdown there probably isn't a leak report file
self.logger.warning("Firefox didn't exit cleanly, not processing leak logs")
@ -575,7 +577,7 @@ class FirefoxOutputHandler(OutputHandler):
# content process crashed and in that case we don't want the test to fail.
# Ideally we would record which content process crashed and just skip those.
self.logger.info("PROCESS LEAKS %s" % self.leak_report_file)
mozleak.process_leak_log(
processed_files = mozleak.process_leak_log(
self.leak_report_file,
leak_thresholds=self.mozleak_thresholds,
ignore_missing_leaks=["tab", "gmplugin"],
@ -583,6 +585,11 @@ class FirefoxOutputHandler(OutputHandler):
stack_fixer=self.stack_fixer,
scope=self.group_metadata.get("scope"),
allowed=self.mozleak_allowed)
if processed_files:
for path in processed_files:
if os.path.exists(path):
os.unlink(path)
# Fallback for older versions of mozleak, or if we didn't shutdown cleanly
if os.path.exists(self.leak_report_file):
os.unlink(self.leak_report_file)

@ -1,6 +1,8 @@
# mypy: allow-untyped-defs
import os
import subprocess
import re
from mozrunner import FennecEmulatorRunner, get_app_context
@ -14,6 +16,7 @@ from ..executors.executormarionette import (MarionetteTestharnessExecutor, # no
from .base import (Browser,
ExecutorBrowser)
from .firefox import (get_timeout_multiplier, # noqa: F401
run_info_browser_version,
run_info_extras as fx_run_info_extras,
update_properties, # noqa: F401
executor_kwargs as fx_executor_kwargs, # noqa: F401
@ -87,14 +90,45 @@ def env_extras(**kwargs):
return []
def run_info_extras(**kwargs):
rv = fx_run_info_extras(**kwargs)
def run_info_extras(logger, **kwargs):
rv = fx_run_info_extras(logger, **kwargs)
package = kwargs["package_name"]
rv.update({"e10s": True if package is not None and "geckoview" in package else False,
"headless": False})
if kwargs["browser_version"] is None:
rv.update(run_info_browser_version(**kwargs))
if rv.get("browser_version") is None:
# If we didn't get the browser version from the apk, try to get it from adb dumpsys
rv["browser_version"] = get_package_browser_version(logger,
kwargs["adb_binary"],
kwargs["package_name"])
return rv
def get_package_browser_version(logger, adb_binary, package_name):
if adb_binary is None:
logger.warning("Couldn't run adb to get Firefox Android version number")
return None
try:
completed = subprocess.run([adb_binary, "shell", "dumpsys", "package", package_name],
check=True,
capture_output=True,
encoding="utf8")
except subprocess.CalledProcessError as e:
logger.warning(f"adb failed with return code {e.returncode}\nCaptured stderr:\n{e.stderr}")
return None
version_name_re = re.compile(r"^\s+versionName=(.*)")
for line in completed.stdout.splitlines():
m = version_name_re.match(line)
if m is not None:
return m.group(1)
logger.warning("Failed to find versionName property in dumpsys output")
def env_options():
return {"server_host": "127.0.0.1",
"supports_debugger": True}

@ -69,7 +69,7 @@ def env_options():
return {}
def run_info_extras(**kwargs):
def run_info_extras(logger, **kwargs):
webdriver_binary = kwargs["webdriver_binary"]
rv = {}

@ -72,7 +72,7 @@ def env_options():
return {}
def run_info_extras(**kwargs):
def run_info_extras(logger, **kwargs):
return {"webkit_port": kwargs["webkit_port"]}

@ -76,7 +76,7 @@ def env_options():
return {}
def run_info_extras(**kwargs):
def run_info_extras(logger, **kwargs):
return {"webkit_port": "gtk"}

@ -277,6 +277,18 @@ class SetSPCTransactionModeAction:
self.logger.debug("Setting SPC transaction mode to %s" % mode)
return self.protocol.spc_transactions.set_spc_transaction_mode(mode)
class SetRPHRegistrationModeAction:
name = "set_rph_registration_mode"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
mode = payload["mode"]
self.logger.debug("Setting RPH registration mode to %s" % mode)
return self.protocol.rph_registrations.set_rph_registration_mode(mode)
class CancelFedCMDialogAction:
name = "cancel_fedcm_dialog"
@ -442,6 +454,7 @@ actions = [ClickAction,
RemoveAllCredentialsAction,
SetUserVerifiedAction,
SetSPCTransactionModeAction,
SetRPHRegistrationModeAction,
CancelFedCMDialogAction,
ConfirmIDPLoginAction,
SelectFedCMAccountAction,

@ -760,7 +760,10 @@ class CallbackHandler:
except AttributeError as e:
# If we fail to get an attribute from the protocol presumably that's a
# ProtocolPart we don't implement
if getattr(e, "obj") == self.protocol:
# AttributeError got an obj property in Python 3.10, for older versions we
# fall back to looking at the error message.
if ((hasattr(e, "obj") and getattr(e, "obj") == self.protocol) or
"'{self.protocol.__class__.__name__}' has no attribute" in str(e)):
raise NotImplementedError from e
except self.unimplemented_exc:
self.logger.warning("Action %s not implemented" % action)

@ -1037,8 +1037,14 @@ class MarionetteRefTestExecutor(RefTestExecutor):
self.implementation_kwargs = {}
if reftest_internal:
self.implementation_kwargs["screenshot"] = reftest_screenshot
self.implementation_kwargs["chrome_scope"] = (browser_version is not None and
int(browser_version.split(".")[0]) < 82)
self.implementation_kwargs["chrome_scope"] = False
# Older versions of Gecko require switching to chrome scope to run refests
if browser_version is not None:
try:
major_version = int(browser_version.split(".")[0])
self.implementation_kwargs["chrome_scope"] = major_version < 82
except ValueError:
pass
self.close_after_done = close_after_done
self.has_window = False
self.original_pref_values = {}

@ -32,6 +32,7 @@ from .protocol import (BaseProtocolPart,
WindowProtocolPart,
DebugProtocolPart,
SPCTransactionsProtocolPart,
RPHRegistrationsProtocolPart,
FedCMProtocolPart,
VirtualSensorProtocolPart,
merge_dicts)
@ -363,6 +364,13 @@ class WebDriverSPCTransactionsProtocolPart(SPCTransactionsProtocolPart):
body = {"mode": mode}
return self.webdriver.send_session_command("POST", "secure-payment-confirmation/set-mode", body)
class WebDriverRPHRegistrationsProtocolPart(RPHRegistrationsProtocolPart):
def setup(self):
self.webdriver = self.parent.webdriver
def set_rph_registration_mode(self, mode):
body = {"mode": mode}
return self.webdriver.send_session_command("POST", "custom-handlers/set-mode", body)
class WebDriverFedCMProtocolPart(FedCMProtocolPart):
def setup(self):
@ -432,6 +440,7 @@ class WebDriverProtocol(Protocol):
WebDriverSetPermissionProtocolPart,
WebDriverVirtualAuthenticatorProtocolPart,
WebDriverSPCTransactionsProtocolPart,
WebDriverRPHRegistrationsProtocolPart,
WebDriverFedCMProtocolPart,
WebDriverDebugProtocolPart,
WebDriverVirtualSensorPart]

@ -616,6 +616,18 @@ class SPCTransactionsProtocolPart(ProtocolPart):
:param str mode: The automation mode to set"""
pass
class RPHRegistrationsProtocolPart(ProtocolPart):
"""Protocol part for Custom Handlers registrations"""
__metaclass__ = ABCMeta
name = "rph_registrations"
@abstractmethod
def set_rph_registration_mode(self, mode):
"""Set the RPH registration automation mode
:param str mode: The automation mode to set"""
pass
class FedCMProtocolPart(ProtocolPart):
"""Protocol part for Federated Credential Management"""

@ -31,7 +31,7 @@ class Product:
self.env_options = getattr(module, data["env_options"])()
self.get_env_extras = getattr(module, data["env_extras"])
self.run_info_extras = (getattr(module, data["run_info_extras"])
if "run_info_extras" in data else lambda **kwargs:{})
if "run_info_extras" in data else lambda product, **kwargs:{})
self.get_timeout_multiplier = getattr(module, data["timeout_multiplier"])
self.executor_classes = {}

@ -269,6 +269,10 @@
return create_action("set_spc_transaction_mode", {mode, context});
};
window.test_driver_internal.set_rph_registration_mode = function(mode, context = null) {
return create_action("set_rph_registration_mode", {mode, context});
};
window.test_driver_internal.cancel_fedcm_dialog = function(context = null) {
return create_action("cancel_fedcm_dialog", {context});
};

@ -640,7 +640,7 @@ class TestRunnerManager(threading.Thread):
self.recording.set(["testrunner", "test"] + self.state.test.id.split("/")[1:])
self.logger.test_start(self.state.test.id, subsuite=self.state.subsuite)
if self.rerun > 1:
self.logger.info("Run %d/%d" % (self.run_count, self.rerun))
self.logger.info(f"Run {self.run_count + 1}/{self.rerun}")
self.send_message("reset")
self.run_count += 1
if self.debug_info is None:

@ -52,7 +52,7 @@ def setup_logging(*args, **kwargs):
def get_loader(test_paths: wptcommandline.TestPaths,
product: products.Product,
**kwargs: Any) -> Tuple[testloader.TestQueueBuilder, testloader.TestLoader]:
run_info_extras = product.run_info_extras(**kwargs)
run_info_extras = product.run_info_extras(logger, **kwargs)
base_run_info = wpttest.get_run_info(kwargs["run_info"],
product.name,
browser_version=kwargs.get("browser_version"),

@ -4,16 +4,7 @@ import sys, urllib, time
from mod_pywebsocket import msgutil
def web_socket_do_extra_handshake(request):
request.connection.write(b'x')
time.sleep(2)
request.connection.write(b'x')
time.sleep(2)
request.connection.write(b'x')
time.sleep(2)
request.connection.write(b'x')
time.sleep(2)
request.connection.write(b'x')
time.sleep(2)
time.sleep(10)
return
def web_socket_transfer_data(request):