mirror of
https://github.com/lexmount/moli.git
synced 2026-10-06 08:00:59 +00:00
refactor(wpt): unify fixture dispatch and preserve raw response headers
Reconcile the shared HTTP handlers and discovery rules from the split PRs with the complete fixture surface in wpt-misc-fix. Share stash namespaces and XHR dispatch, retain the existing testdriver bridge, preserve raw header values, and carry forward the remaining pipe, template, and dynamic-import regressions. Validation: 742 Python tests across 74 modules pass; focused Ruff checks and git diff --check pass. With fixed Moli and Chromium binaries, a 27-case WPT comparison against main improves whole-case passes from 7 to 26 and 6 to 23 respectively, with no previously passing case regressing.
This commit is contained in:
@@ -751,6 +751,37 @@ def _common_echo_handler_reference_patterns(directory: str) -> tuple[re.Pattern[
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _remote_context_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
for resource in (
|
||||
"common/dispatcher/dispatcher.py",
|
||||
"html/browsers/browsing-the-web/remote-context-helper/resources/executor-window.py",
|
||||
):
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _iframe_stash_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
resource = "html/semantics/embedded-content/the-iframe-element/stash.py"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in ("/" + resource, relative, "./" + relative)
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _script_content_type_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
resource = "html/semantics/scripting-1/the-script-element/serve-with-content-type.py"
|
||||
@@ -764,6 +795,68 @@ def _script_content_type_handler_reference_patterns(directory: str) -> tuple[re.
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _document_charset_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
for name in ("bogus-charset-http.py", "bogus-charset-http-valid-meta.py"):
|
||||
resource = f"html/syntax/charset/resources/{name}"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _fetch_content_type_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
resource = "fetch/content-type/resources/content-type.py"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in ("/" + resource, relative, "./" + relative)
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _fetch_resource_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
names = (
|
||||
"preflight.py", "clean-stash.py", "inspect-headers.py", "redirect.py",
|
||||
"redirect-empty-location.py",
|
||||
)
|
||||
references = []
|
||||
for name in names:
|
||||
resource = "fetch/api/resources/" + name
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
patterns = [
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
]
|
||||
# The Fetch API's shared utils.js defines RESOURCES_DIR. Keep the
|
||||
# concatenation intact in this match; a bare filename is not sufficient.
|
||||
patterns.append(re.compile(
|
||||
r"(?<![\w$.])RESOURCES_DIR\s*\+\s*['\"](?:"
|
||||
+ "|".join(re.escape(name) for name in names)
|
||||
+ rf"){WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
))
|
||||
patterns.append(re.compile(
|
||||
r"`\$\{\s*RESOURCES_DIR\s*\}(?:"
|
||||
+ "|".join(re.escape(name) for name in names)
|
||||
+ rf"){WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
))
|
||||
return tuple(patterns)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _navigation_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
resource = (
|
||||
@@ -829,28 +922,17 @@ def _empty_location_handler_reference_patterns(directory: str) -> tuple[re.Patte
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _remote_context_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
def _xhr_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
for resource in (
|
||||
"common/dispatcher/dispatcher.py",
|
||||
"html/browsers/browsing-the-web/remote-context-helper/resources/executor-window.py",
|
||||
for name in (
|
||||
"requri.py", "redirect.py", "headers.py", "inspect-headers.py", "echo-headers.py", "content.py",
|
||||
"echo-content-type.py", "corsenabled.py", "win-1252-xml.py", "win-1252-html.py",
|
||||
"access-control-basic-put-allow.py",
|
||||
"access-control-preflight-request-allow-headers-returns-star.py",
|
||||
"invalid-utf8-html.py", "shift-jis-html.py", "img-utf8-html.py",
|
||||
"empty-div-utf8-html.py", "status.py", "last-modified.py",
|
||||
"bad-chunk-encoding.py", "infinite-redirects.py",
|
||||
):
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _xhr_url_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
for name in ("requri.py", "redirect.py"):
|
||||
resource = f"xhr/resources/{name}"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
@@ -863,38 +945,82 @@ def _xhr_url_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str]
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _script_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
for name in (
|
||||
"serve-with-content-type.py", "resources/load-error-events.py",
|
||||
"json-module/load-error-events.py", "serve-json-then-js.py",
|
||||
):
|
||||
resource = "html/semantics/scripting-1/the-script-element/" + name
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _service_worker_script_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
resources = tuple(
|
||||
"service-workers/service-worker/resources/" + name
|
||||
for name in (
|
||||
"redirect.py", "update-worker.py", "update-worker-from-file.py",
|
||||
"mime-type-worker.py", "import-mime-type-worker.py", "malformed-worker.py",
|
||||
"invalid-chunked-encoding.py", "invalid-chunked-encoding-with-flush.py",
|
||||
"update-during-installation-worker.py",
|
||||
"import-scripts-version.py", "import-scripts-get.py", "import-scripts-echo.py",
|
||||
"subdir/import-scripts-echo.py", "scope2/import-scripts-echo.py",
|
||||
)
|
||||
) + ("service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py",)
|
||||
for resource in resources:
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
def _supported_wptserve_handler_references(
|
||||
rel: str | None,
|
||||
) -> tuple[re.Pattern[str], ...]:
|
||||
supported: tuple[re.Pattern[str], ...] = ()
|
||||
if rel is not None:
|
||||
supported += _service_worker_script_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _fetch_resource_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
if rel is not None and rel.startswith("fetch/api/"):
|
||||
supported += _empty_location_handler_reference_patterns(posixpath.dirname(rel))
|
||||
if rel is not None:
|
||||
supported += _common_echo_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _remote_context_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _fetch_content_type_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _document_charset_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _iframe_stash_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _remote_context_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _preload_count_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _navigation_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _json_module_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
if rel is not None:
|
||||
supported += _script_content_type_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _script_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
supported += _service_worker_script_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
if rel is not None and rel.rsplit("/", 1)[0] == "fetch/api/abort":
|
||||
supported += SUPPORTED_FETCH_ABORT_WPTSERVE_HANDLER_PATTERNS
|
||||
if rel is not None and rel.rsplit("/", 1)[0] == "fetch/range":
|
||||
supported += SUPPORTED_FETCH_RANGE_WPTSERVE_HANDLER_PATTERNS
|
||||
if rel is not None and rel.startswith("fetch/api/"):
|
||||
supported += _fetch_resource_handler_reference_patterns(posixpath.dirname(rel))
|
||||
if rel is not None and rel.startswith("wasm/webapi/"):
|
||||
supported += SUPPORTED_WASM_WEBAPI_WPTSERVE_HANDLER_PATTERNS
|
||||
if rel is not None:
|
||||
supported += _script_load_error_handler_reference_patterns(posixpath.dirname(rel) or ".")
|
||||
if rel is not None and rel.startswith("xhr/"):
|
||||
supported += SUPPORTED_XHR_DELAY_WPTSERVE_HANDLER_PATTERNS
|
||||
supported += _xhr_url_handler_reference_patterns(rel.rsplit("/", 1)[0])
|
||||
supported += _xhr_handler_reference_patterns(rel.rsplit("/", 1)[0])
|
||||
if rel is not None and rel.startswith(
|
||||
"html/semantics/scripting-1/the-script-element/module/"
|
||||
):
|
||||
@@ -911,9 +1037,7 @@ def _xhr_response_handler_reference_patterns(directory: str) -> tuple[re.Pattern
|
||||
"inspect-headers.py", "echo-headers.py", "content.py",
|
||||
"echo-content-type.py", "win-1252-xml.py", "win-1252-html.py",
|
||||
"invalid-utf8-html.py", "shift-jis-html.py", "img-utf8-html.py",
|
||||
"empty-div-utf8-html.py", "headers.py", "bad-chunk-encoding.py", "infinite-redirects.py",
|
||||
"access-control-basic-put-allow.py",
|
||||
"access-control-preflight-request-allow-headers-returns-star.py"):
|
||||
"empty-div-utf8-html.py"):
|
||||
resource = f"xhr/resources/{name}"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
@@ -1670,109 +1794,3 @@ def explicit_case(wpt_root: Path, case_path: str) -> WptCase:
|
||||
timeout_multiplier=timeout_multiplier,
|
||||
test_type="crashtest" if _is_crashtest_path(source_case_path) else "testharness",
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _service_worker_script_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
resources = tuple(
|
||||
"service-workers/service-worker/resources/" + name
|
||||
for name in (
|
||||
"redirect.py", "update-worker.py", "update-worker-from-file.py",
|
||||
"mime-type-worker.py", "import-mime-type-worker.py", "malformed-worker.py",
|
||||
"invalid-chunked-encoding.py", "invalid-chunked-encoding-with-flush.py",
|
||||
"update-during-installation-worker.py",
|
||||
"import-scripts-version.py", "import-scripts-get.py", "import-scripts-echo.py",
|
||||
"subdir/import-scripts-echo.py", "scope2/import-scripts-echo.py",
|
||||
)
|
||||
) + ("service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py",)
|
||||
for resource in resources:
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _fetch_resource_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
names = (
|
||||
"preflight.py", "clean-stash.py", "inspect-headers.py", "redirect.py",
|
||||
"redirect-empty-location.py",
|
||||
)
|
||||
references = []
|
||||
for name in names:
|
||||
resource = "fetch/api/resources/" + name
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
patterns = [
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
]
|
||||
# The Fetch API's shared utils.js defines RESOURCES_DIR. Keep the
|
||||
# concatenation intact in this match; a bare filename is not sufficient.
|
||||
patterns.append(re.compile(
|
||||
r"(?<![\w$.])RESOURCES_DIR\s*\+\s*['\"](?:"
|
||||
+ "|".join(re.escape(name) for name in names)
|
||||
+ rf"){WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
))
|
||||
patterns.append(re.compile(
|
||||
r"`\$\{\s*RESOURCES_DIR\s*\}(?:"
|
||||
+ "|".join(re.escape(name) for name in names)
|
||||
+ rf"){WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
))
|
||||
return tuple(patterns)
|
||||
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _fetch_content_type_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
resource = "fetch/content-type/resources/content-type.py"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in ("/" + resource, relative, "./" + relative)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _document_charset_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
references = []
|
||||
for name in ("bogus-charset-http.py", "bogus-charset-http-valid-meta.py"):
|
||||
resource = f"html/syntax/charset/resources/{name}"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
references.extend(("/" + resource, relative, "./" + relative))
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in references
|
||||
)
|
||||
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _iframe_stash_handler_reference_patterns(directory: str) -> tuple[re.Pattern[str], ...]:
|
||||
resource = "html/semantics/embedded-content/the-iframe-element/stash.py"
|
||||
relative = posixpath.relpath(resource, directory)
|
||||
return tuple(
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z0-9_./-]){re.escape(reference)}"
|
||||
rf"{WPTSERVE_HANDLER_TRAILING_BOUNDARY}"
|
||||
)
|
||||
for reference in ("/" + resource, relative, "./" + relative)
|
||||
)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
reports[0]["metadata"]["content_type"],
|
||||
"application/csp-report",
|
||||
)
|
||||
|
||||
def test_fixture_server_accepts_standard_websocket_echo_endpoint(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -80,6 +81,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
while len(echoed) < 6:
|
||||
echoed += connection.recv(6 - len(echoed))
|
||||
self.assertEqual(echoed, b"\x81\x04ping")
|
||||
|
||||
def test_fixture_server_serves_raw_asis_header_bytes(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -101,6 +103,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
header = response.headers["X-Custom-Header-Bytes"]
|
||||
|
||||
self.assertEqual(header.encode("latin-1"), b"\xe2\x80\xa6")
|
||||
|
||||
def test_fixture_server_serves_raw_sidecar_header_bytes(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -122,6 +125,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
header = response.headers["Content-Type"]
|
||||
|
||||
self.assertEqual(header.encode("latin-1"), b"\xc3\x97\xc2\xba invalid")
|
||||
|
||||
def test_fixture_server_uses_explicit_content_type_header_as_override(self) -> None:
|
||||
self.assertEqual(
|
||||
_static_response_header_block(
|
||||
@@ -134,6 +138,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
_static_response_header_block("application/javascript", [("X-Test", "ok")]),
|
||||
[("Content-Type", "application/javascript"), ("X-Test", "ok")],
|
||||
)
|
||||
|
||||
def test_fixture_server_detects_explicit_content_length_header(self) -> None:
|
||||
header_block = _static_response_header_block(
|
||||
"text/html",
|
||||
@@ -141,6 +146,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
)
|
||||
|
||||
self.assertTrue(_headers_include(header_block, "content-length"))
|
||||
|
||||
def test_fixture_server_preserves_explicit_content_length_body_boundary(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -172,12 +178,14 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
|
||||
self.assertEqual(served, body)
|
||||
self.assertNotIn(BENCH_TIMEOUT_MULTIPLIER_QUERY.encode("ascii"), served)
|
||||
|
||||
def test_fixture_server_maps_legacy_webidl_parser_resource(self) -> None:
|
||||
self.assertEqual(
|
||||
_legacy_wpt_resource_alias("/resources/WebIDLParser.js"),
|
||||
"resources/webidl2/lib/webidl2.js",
|
||||
)
|
||||
self.assertIsNone(_legacy_wpt_resource_alias("/resources/testharness.js"))
|
||||
|
||||
def test_fixture_server_builds_any_js_window_wrapper(self) -> None:
|
||||
body = _any_js_window_wrapper(
|
||||
"/WebCryptoAPI/sign_verify/hmac.https.any.html",
|
||||
@@ -197,6 +205,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
self.assertIn(b'<script src="hmac_vectors.js"></script>', body)
|
||||
self.assertIn(b'<div id="log"></div>', body)
|
||||
self.assertIn(b'<script src="hmac.https.any.js"></script>', body)
|
||||
|
||||
def test_fixture_server_builds_window_js_wrapper_without_any_global(self) -> None:
|
||||
body = _window_js_window_wrapper(
|
||||
"/WebCryptoAPI/algorithm-discards-context.https.window.html",
|
||||
@@ -211,6 +220,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
self.assertIn(b'<script src="helper.js"></script>', body)
|
||||
self.assertIn(b'<script src="algorithm-discards-context.https.window.js"></script>', body)
|
||||
self.assertNotIn(b"self.GLOBAL", body)
|
||||
|
||||
def test_fixture_server_builds_wpt_any_js_query_wrapper(self) -> None:
|
||||
html = _wpt_any_window_wrapper_html(
|
||||
"wasm/jsapi/feature.any.js",
|
||||
@@ -227,6 +237,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
html,
|
||||
)
|
||||
self.assertNotIn("moli-wpt-any", html)
|
||||
|
||||
def test_fixture_server_builds_any_js_dedicated_worker_wrapper(self) -> None:
|
||||
html = _wpt_any_dedicated_worker_wrapper_html(
|
||||
"wasm/jsapi/feature.any.js",
|
||||
@@ -240,6 +251,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
html,
|
||||
)
|
||||
self.assertNotIn("moli-wpt-any", html)
|
||||
|
||||
def test_fixture_server_builds_any_js_dedicated_worker_script(self) -> None:
|
||||
js = _wpt_any_dedicated_worker_wrapper_js(
|
||||
"wasm/jsapi/feature.any.js",
|
||||
@@ -255,6 +267,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
self.assertIn('importScripts("/wasm/jsapi/feature.any.js?variant=1");', js)
|
||||
self.assertTrue(js.rstrip().endswith("done();"))
|
||||
self.assertNotIn("moli-wpt-any", js)
|
||||
|
||||
def test_fixture_server_builds_window_js_wrapper(self) -> None:
|
||||
html = _wpt_window_js_wrapper_html(
|
||||
"wasm/serialization/transfer.window.js",
|
||||
@@ -271,6 +284,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
html,
|
||||
)
|
||||
self.assertNotIn("moli-wpt-script", html)
|
||||
|
||||
def test_fixture_server_builds_worker_js_wrapper(self) -> None:
|
||||
html = _wpt_dedicated_worker_js_wrapper_html(
|
||||
"wasm/create_multiple_memory.worker.js",
|
||||
@@ -284,6 +298,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
html,
|
||||
)
|
||||
self.assertNotIn("moli-wpt-script", html)
|
||||
|
||||
def test_any_js_worker_script_path_round_trips_to_source_path(self) -> None:
|
||||
worker_path = any_js_worker_script_path(
|
||||
"wasm/jsapi/feature.any.js?variant=1"
|
||||
@@ -297,6 +312,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
any_js_source_script_path(worker_path),
|
||||
"wasm/jsapi/feature.any.js?variant=1",
|
||||
)
|
||||
|
||||
def test_any_js_case_path_for_global_replaces_existing_wrapper_query(self) -> None:
|
||||
self.assertEqual(
|
||||
any_js_case_path_for_global(
|
||||
@@ -305,6 +321,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
),
|
||||
"wasm/jsapi/feature.any.js?variant=1&moli-wpt-any=dedicatedworker",
|
||||
)
|
||||
|
||||
def test_fixture_server_resolves_any_js_meta_scripts_within_wpt_root(self) -> None:
|
||||
self.assertEqual(
|
||||
_resolve_wpt_static_script_url(
|
||||
@@ -326,6 +343,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
"../../../escape.js",
|
||||
)
|
||||
)
|
||||
|
||||
def test_fixture_server_substitutes_core_sub_template_variables(self) -> None:
|
||||
body = (
|
||||
b"http://{{domains[www2]}}:{{ports[http][0]}}/"
|
||||
@@ -372,6 +390,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
b" ws-url=ws://example.test:12345/socket"
|
||||
b" wss-url=ws://example.test:12345/socket",
|
||||
)
|
||||
|
||||
def test_fixture_server_substitutes_idna_domain_aliases(self) -> None:
|
||||
cases = [
|
||||
("{{domains[天気の良い日]}}", b"xn--n8j6ds53lwwkrqhv28a.localhost"),
|
||||
@@ -455,6 +474,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
"",
|
||||
)
|
||||
)
|
||||
|
||||
def test_fixture_server_maps_external_ipv6_domain_location_port_to_remote_port(
|
||||
self,
|
||||
) -> None:
|
||||
@@ -480,6 +500,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
b" http://[2001:db8::1]:34567/d"
|
||||
b" http://[2001:db8::1]:23456/e",
|
||||
)
|
||||
|
||||
def test_fixture_server_substitutes_get_query_template_variables(self) -> None:
|
||||
body = (
|
||||
b"var expected_logs = {{GET[logs]}};"
|
||||
@@ -497,6 +518,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
b' var timeout = "2";'
|
||||
b' var missing = "";',
|
||||
)
|
||||
|
||||
def test_fixture_server_substitutes_template_variables_in_sidecar_headers(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
fixture = Path(root) / "frame-ancestors.sub.html"
|
||||
@@ -521,6 +543,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_substitution_preserves_non_utf8_bytes(self) -> None:
|
||||
body = b"\xff{{host}}\xfe{{ports[http][0]}}"
|
||||
|
||||
@@ -528,6 +551,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
_substitute_wpt_template_variables(body, port=12345),
|
||||
b"\xfflocalhost\xfe12345",
|
||||
)
|
||||
|
||||
def test_fixture_server_distinguishes_primary_host_from_request_hostname(
|
||||
self,
|
||||
) -> None:
|
||||
@@ -547,10 +571,12 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
b"host=localhost domain=localhost location=www1.localhost "
|
||||
b"HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + HTTP_PORT_ELIDED,",
|
||||
)
|
||||
|
||||
def test_host_header_hostname_preserves_ipv6_brackets(self) -> None:
|
||||
self.assertEqual(_host_header_hostname("[2001:db8::1]:1234"), "[2001:db8::1]")
|
||||
self.assertEqual(_host_header_hostname("localhost:1234"), "localhost")
|
||||
self.assertEqual(_host_header_hostname("example.test"), "example.test")
|
||||
|
||||
def test_fixture_server_substitutes_ipv6_websocket_template_urls(self) -> None:
|
||||
body = (
|
||||
b"ws=ws://{{host}}:{{ports[ws][0]}}/echo"
|
||||
@@ -566,6 +592,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
b"ws=ws://[2001:db8::1]:12345/echo"
|
||||
b" wss=ws://[2001:db8::1]:12345/echo",
|
||||
)
|
||||
|
||||
def test_fixture_server_wasm_status_handler_normalizes_status_codes(self) -> None:
|
||||
self.assertEqual(_wasm_webapi_status_code("status=404"), 404)
|
||||
self.assertEqual(_wasm_webapi_status_code("status=300"), 300)
|
||||
@@ -573,6 +600,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
self.assertEqual(_wasm_webapi_status_code("status=700"), 599)
|
||||
self.assertEqual(_wasm_webapi_status_code("status=not-a-number"), 400)
|
||||
self.assertEqual(_wasm_webapi_status_code(""), 200)
|
||||
|
||||
def test_fixture_server_redirect_handler_models_wasm_origin_probe(self) -> None:
|
||||
self.assertEqual(
|
||||
_redirect_fixture_response(
|
||||
@@ -589,17 +617,20 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
_redirect_fixture_response("status=307&location=/target"),
|
||||
(307, "/target"),
|
||||
)
|
||||
|
||||
def test_fixture_server_models_csp_resource_py(self) -> None:
|
||||
body, headers = _content_security_policy_resource_response()
|
||||
|
||||
self.assertIn(b"success", body)
|
||||
self.assertIn(("Access-Control-Allow-Origin", "*"), headers)
|
||||
|
||||
def test_fixture_server_models_workers_modules_export_on_load_script_py(self) -> None:
|
||||
body, headers = _workers_modules_export_on_load_script_response()
|
||||
|
||||
self.assertIn(b"export const importedModules", body)
|
||||
self.assertIn(("Content-Type", "text/javascript"), headers)
|
||||
self.assertIn(("Access-Control-Allow-Origin", "*"), headers)
|
||||
|
||||
def test_fixture_server_preserves_raw_sidecar_header_bytes(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
@@ -614,6 +645,7 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
self.assertEqual(headers, [("Content-Type", "\xc3\x97\xc2\xba invalid")])
|
||||
for _name, value in headers:
|
||||
value.encode("latin-1")
|
||||
|
||||
def test_fixture_server_substitutes_get_host_info_remote_host_for_loopback(self) -> None:
|
||||
body = (
|
||||
b"var REMOTE_HOST = (ORIGINAL_HOST === 'localhost') ? "
|
||||
@@ -724,4 +756,21 @@ class WptCrossFixtureResourcesTests(WptCrossTestCase):
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_substitutes_request_header_or_default(self) -> None:
|
||||
body = (
|
||||
b"present={{header_or_default(Referer, missing)}}"
|
||||
b" absent={{header_or_default(X-Absent, <missing>)}}"
|
||||
b" empty={{header_or_default(X-Empty, )}}"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_substitute_wpt_template_variables(
|
||||
body,
|
||||
port=12345,
|
||||
request_headers={
|
||||
"referer": "https://example.test/path?a=1&b=2",
|
||||
},
|
||||
),
|
||||
b"present=https://example.test/path?a=1&b=2"
|
||||
b" absent=<missing> empty=",
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
)
|
||||
self.assertEqual(_pipe_trickle_delay_seconds("pipe=trickle(d999)"), 10.0)
|
||||
self.assertEqual(_pipe_trickle_delay_seconds("notpipe=trickle(d1)"), 0.0)
|
||||
|
||||
def test_fixture_server_parses_delay_handler_duration(self) -> None:
|
||||
self.assertEqual(_wpt_delay_seconds("ms=3000"), 3.0)
|
||||
self.assertEqual(_wpt_delay_seconds("ms=2.5"), 0.0025)
|
||||
@@ -21,6 +22,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
self.assertIsNone(_wpt_delay_seconds("ms=invalid"))
|
||||
self.assertIsNone(_wpt_delay_seconds("ms=-1"))
|
||||
self.assertIsNone(_wpt_delay_seconds("ms=nan"))
|
||||
|
||||
def test_fixture_server_models_xhr_delay_py_methods(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -66,6 +68,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
("YO", 200, b"TEST_DELAY", "text/plain", "*", "YO"),
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_models_delayed_module_script_handler(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -111,6 +114,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
("HEAD", 200, b"", "text/javascript"),
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_models_common_redirect_opt_in_handler(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -129,6 +133,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
self.assertEqual(response.headers.get("Location"), "/target")
|
||||
self.assertEqual(response.headers.get("Timing-Allow-Origin"), "*")
|
||||
connection.close()
|
||||
|
||||
def test_fixture_server_drains_xhr_delay_yo_body_before_next_request(
|
||||
self,
|
||||
) -> None:
|
||||
@@ -163,6 +168,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
self.assertIs(connection.sock, first_socket)
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def test_fixture_server_drains_chunked_xhr_delay_body_before_next_request(
|
||||
self,
|
||||
) -> None:
|
||||
@@ -202,6 +208,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
self.assertIs(connection.sock, first_socket)
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def test_fixture_server_parses_wpt_header_pipe(self) -> None:
|
||||
def applied_pipe_headers(query: str) -> list[tuple[str, str]]:
|
||||
return _apply_header_operations(
|
||||
@@ -237,6 +244,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
[("X-Test", "bad Injected: x")],
|
||||
)
|
||||
self.assertEqual(applied_pipe_headers("notpipe=header(X,Y)"), [])
|
||||
|
||||
def test_fixture_server_parses_wpt_status_pipe(self) -> None:
|
||||
self.assertEqual(_pipe_response_status("pipe=status(204)&cachebust=1"), 204)
|
||||
self.assertEqual(
|
||||
@@ -250,6 +258,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
self.assertIsNone(_pipe_response_status("pipe=status(099)"))
|
||||
self.assertIsNone(_pipe_response_status("pipe=status(600)"))
|
||||
self.assertIsNone(_pipe_response_status("notpipe=status(204)"))
|
||||
|
||||
def test_fixture_server_parses_wpt_headers_sidecar(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
fixture = Path(root) / "case.html"
|
||||
@@ -265,6 +274,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
_sidecar_response_headers(fixture),
|
||||
[("Referrer-Policy", "no-referrer"), ("X-Test", "ok")],
|
||||
)
|
||||
|
||||
def test_fixture_server_parses_sub_headers_sidecar_for_sub_files(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
fixture = Path(root) / "worker.sub.js"
|
||||
@@ -278,6 +288,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
_sidecar_response_headers(fixture),
|
||||
[("Content-Security-Policy", "connect-src 'none'")],
|
||||
)
|
||||
|
||||
def test_fixture_server_combines_immediate_directory_and_file_headers(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -306,6 +317,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
("X-File", "exact"),
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_prefers_file_sub_headers_when_both_exist(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
fixture = Path(root) / "case.sub.html"
|
||||
@@ -323,6 +335,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
_sidecar_response_headers(fixture),
|
||||
[("X-Source", "substituted")],
|
||||
)
|
||||
|
||||
def test_fixture_server_prefers_directory_sub_headers_when_both_exist(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
@@ -341,6 +354,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
_sidecar_response_headers(fixture),
|
||||
[("X-Source", "substituted")],
|
||||
)
|
||||
|
||||
def test_fixture_server_content_type_sidecar_overrides_static_guess(self) -> None:
|
||||
content_type, headers = _response_content_type_and_extra_headers(
|
||||
"application/octet-stream",
|
||||
@@ -352,6 +366,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
|
||||
self.assertEqual(content_type, "text/javascript; charset=utf-8")
|
||||
self.assertEqual(headers, [("X-Test", "ok")])
|
||||
|
||||
def test_fixture_server_combines_sidecar_and_pipe_headers_for_static_responses(
|
||||
self,
|
||||
) -> None:
|
||||
@@ -390,6 +405,7 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_reads_sub_headers_for_plain_static_resource(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
fixture = Path(root) / "policy.html"
|
||||
@@ -692,3 +708,44 @@ class WptCrossFixtureResponsesTests(WptCrossTestCase):
|
||||
("text/javascript", "nosniff", b"// nothing to see here\np()"),
|
||||
],
|
||||
)
|
||||
|
||||
def test_fixture_server_models_dynamic_import_redirect_without_cors(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as root:
|
||||
root_path = Path(root)
|
||||
(root_path / "resources").mkdir()
|
||||
(root_path / "resources" / "testharness.js").write_text(
|
||||
"// testharness", encoding="utf-8"
|
||||
)
|
||||
with WptFixtureServer(root_path) as server:
|
||||
for method in ("GET", "HEAD"):
|
||||
for query, status, location in (
|
||||
("location=%2Ftarget", 302, "/target"),
|
||||
(
|
||||
"status=307&location=https%3A%2F%2Fexample.test%2Fx",
|
||||
307,
|
||||
"https://example.test/x",
|
||||
),
|
||||
("status=invalid&location=%2Ftarget", 302, "/target"),
|
||||
(
|
||||
"status=302&status=307&location=%2Fa&location=%2Fb",
|
||||
302,
|
||||
"/a",
|
||||
),
|
||||
):
|
||||
with self.subTest(method=method, query=query):
|
||||
connection = HTTPConnection("127.0.0.1", server.port, timeout=2)
|
||||
try:
|
||||
connection.request(
|
||||
method,
|
||||
"/html/semantics/scripting-1/the-script-element/module/"
|
||||
f"dynamic-import/beta/redirect.py?{query}",
|
||||
)
|
||||
response = connection.getresponse()
|
||||
self.assertEqual(response.status, status)
|
||||
self.assertEqual(response.headers.get("Location"), location)
|
||||
self.assertIsNone(
|
||||
response.headers.get("Access-Control-Allow-Origin")
|
||||
)
|
||||
self.assertEqual(response.read(), b"")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
@@ -231,7 +231,7 @@ class FetchPreflightFixtureTests(unittest.TestCase):
|
||||
}
|
||||
utils = self.root / "fetch/api/resources/utils.js"
|
||||
utils.parent.mkdir(parents=True)
|
||||
utils.write_text('var RESOURCES_DIR = "../resources/";')
|
||||
utils.write_text('var RESOURCES_DIR = "../resources/"; fetch(RESOURCES_DIR + "inspect-headers.py");')
|
||||
for name, source in cases.items():
|
||||
path = self.root / f"fetch/api/cors/{name}.any.js"
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -119,6 +119,29 @@ class WptPipeFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(headers.get_all("X-Test"), expected)
|
||||
|
||||
def test_explicit_cache_control_is_not_overridden_by_the_fixture_default(self) -> None:
|
||||
for method in ("GET", "HEAD"):
|
||||
with self.subTest(method=method, source="default"):
|
||||
status, headers, _ = self.request("", method=method)
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(headers.get_all("Cache-Control"), ["no-store"])
|
||||
(self.root / "module.json.headers").write_text("cAcHe-CoNtRoL: max-age=600\n")
|
||||
for pipe, expected in (
|
||||
("", ["max-age=600"]),
|
||||
("header(Cache-Control,max-age=30)", ["max-age=30"]),
|
||||
("header(cache-control,public,true)", ["max-age=600", "public"]),
|
||||
("header(Cache-Control,)", [""]),
|
||||
):
|
||||
for method in ("GET", "HEAD"):
|
||||
with self.subTest(method=method, pipe=pipe):
|
||||
status, headers, body = self.request(urlencode({"pipe": pipe}), method=method)
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(headers.get_all("Cache-Control"), expected)
|
||||
self.assertEqual(body, b"" if method == "HEAD" else b'{"value": 1}')
|
||||
(self.root / "module.json.headers").unlink()
|
||||
_, headers, _ = self.request(urlencode({"pipe": "header(Cache-Control,max-age=60)"}))
|
||||
self.assertEqual(headers.get_all("Cache-Control"), ["max-age=60"])
|
||||
|
||||
def test_only_last_nonempty_pipe_parameter_is_applied(self) -> None:
|
||||
cases = (
|
||||
(["unknown", "header(X-Test,last)"], 200, "last"),
|
||||
@@ -156,6 +179,22 @@ class WptPipeFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(headers["X-Test"], "before Injected: value")
|
||||
self.assertIsNone(headers["Injected"])
|
||||
|
||||
def test_status_conversion_and_errors_also_work_for_inspection_methods(self) -> None:
|
||||
for method in ("GET", "HEAD", "POST", "OPTIONS", "CUSTOM"):
|
||||
for command, expected_status in (
|
||||
("status(00201)", 201),
|
||||
("status( +201 )", 201),
|
||||
("status(invalid)", 500),
|
||||
("status(201)|unknown", 500),
|
||||
):
|
||||
with self.subTest(method=method, command=command):
|
||||
status, _, body = self.request(
|
||||
urlencode({"pipe": command}), method=method,
|
||||
path="/fetch/api/resources/inspect-headers.py",
|
||||
)
|
||||
self.assertEqual(status, expected_status)
|
||||
if method == "HEAD":
|
||||
self.assertEqual(body, b"")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -12,11 +12,10 @@ from moli_benchmark.wpt_cross.server import WptFixtureServer
|
||||
|
||||
|
||||
RESOURCE = "/xhr/resources/corsenabled.py"
|
||||
|
||||
|
||||
PUT_RESOURCE = "/xhr/resources/access-control-basic-put-allow.py"
|
||||
STAR_RESOURCE = "/xhr/resources/access-control-preflight-request-allow-headers-returns-star.py"
|
||||
|
||||
|
||||
class XhrCorsFixtureTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.stack = ExitStack()
|
||||
@@ -100,24 +99,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
status, _, _ = self.request(server, resource=resource)
|
||||
self.assertEqual(status, 404)
|
||||
|
||||
def test_case_selection_recognizes_relative_and_absolute_references(self) -> None:
|
||||
sources = {
|
||||
"xhr/absolute.html": f"fetch('{RESOURCE}');",
|
||||
"xhr/relative.html": "fetch('resources/corsenabled.py');",
|
||||
"xhr/nested/relative.html": "fetch('../resources/corsenabled.py?delay=0');",
|
||||
"xhr/unknown.html": "fetch('resources/corsenabled.py'); fetch('unknown.py');",
|
||||
"xhr/wrong-relative.html": "fetch('corsenabled.py');",
|
||||
}
|
||||
for name, script in sources.items():
|
||||
path = self.root / name
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text('<script src="/resources/testharness.js"></script><script>'
|
||||
+ script + '</script>')
|
||||
selected = enumerate_cases(self.root, dir_prefixes=("xhr",))
|
||||
self.assertEqual([case.case_path for case in selected], [
|
||||
"xhr/absolute.html", "xhr/nested/relative.html", "xhr/relative.html",
|
||||
])
|
||||
|
||||
def test_put_preflight_and_upload_preserve_origin_and_bytes(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
for origin in ("https://caller.test", "null", ""):
|
||||
@@ -143,7 +124,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(headers["Access-Control-Allow-Credentials"], "true")
|
||||
self.assertIsNone(headers["Access-Control-Allow-Methods"])
|
||||
|
||||
|
||||
def test_put_fixture_missing_origin_matches_upstream_failure(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
for method in ("OPTIONS", "PUT"):
|
||||
@@ -152,7 +132,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(status, 500)
|
||||
self.assertIsNone(headers["Access-Control-Allow-Origin"])
|
||||
|
||||
|
||||
def test_put_fixture_reports_other_methods_without_cors_headers(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
for method in ("GET", "HEAD", "POST", "DELETE", "FOO"):
|
||||
@@ -164,7 +143,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(headers["Content-Length"], str(len(expected)))
|
||||
self.assertIsNone(headers["Access-Control-Allow-Origin"])
|
||||
|
||||
|
||||
def test_wildcard_preflight_and_actual_request_have_distinct_headers(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
status, headers, body = self.request(server, "OPTIONS", resource=STAR_RESOURCE)
|
||||
@@ -184,7 +162,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(headers["Content-Type"], "text/plain")
|
||||
self.assertIsNone(headers["Access-Control-Allow-Headers"])
|
||||
|
||||
|
||||
def test_wildcard_fixture_rejects_missing_or_empty_test_header(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
for request_headers in ({}, {"X-Test": ""}):
|
||||
@@ -196,7 +173,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
self.assertEqual(headers["Access-Control-Allow-Origin"], "*")
|
||||
self.assertIsNone(headers["Content-Type"])
|
||||
|
||||
|
||||
def test_wildcard_fixture_other_methods_have_no_cors_grants(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
for method in ("HEAD", "POST", "PUT", "DELETE", "FOO"):
|
||||
@@ -208,7 +184,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
self.assertIsNone(headers["Access-Control-Allow-Origin"])
|
||||
self.assertIsNone(headers["Content-Type"])
|
||||
|
||||
|
||||
def test_preflight_fixtures_require_exact_resource_paths(self) -> None:
|
||||
server = self.stack.enter_context(WptFixtureServer(self.root))
|
||||
for resource in (PUT_RESOURCE, STAR_RESOURCE):
|
||||
@@ -217,7 +192,6 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
status, _, _ = self.request(server, resource=wrong)
|
||||
self.assertEqual(status, 404)
|
||||
|
||||
|
||||
def test_preflight_case_selection_rejects_unsupported_dependencies(self) -> None:
|
||||
for resource in (PUT_RESOURCE, STAR_RESOURCE):
|
||||
name = Path(resource).name
|
||||
@@ -240,3 +214,21 @@ class XhrCorsFixtureTests(unittest.TestCase):
|
||||
for prefix in ("absolute-", "relative-", "nested/relative-")
|
||||
)
|
||||
self.assertEqual([case.case_path for case in selected], expected)
|
||||
|
||||
def test_case_selection_recognizes_relative_and_absolute_references(self) -> None:
|
||||
sources = {
|
||||
"xhr/absolute.html": f"fetch('{RESOURCE}');",
|
||||
"xhr/relative.html": "fetch('resources/corsenabled.py');",
|
||||
"xhr/nested/relative.html": "fetch('../resources/corsenabled.py?delay=0');",
|
||||
"xhr/unknown.html": "fetch('resources/corsenabled.py'); fetch('unknown.py');",
|
||||
"xhr/wrong-relative.html": "fetch('corsenabled.py');",
|
||||
}
|
||||
for name, script in sources.items():
|
||||
path = self.root / name
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text('<script src="/resources/testharness.js"></script><script>'
|
||||
+ script + '</script>')
|
||||
selected = enumerate_cases(self.root, dir_prefixes=("xhr",))
|
||||
self.assertEqual([case.case_path for case in selected], [
|
||||
"xhr/absolute.html", "xhr/nested/relative.html", "xhr/relative.html",
|
||||
])
|
||||
|
||||
@@ -110,9 +110,6 @@ from moli_benchmark.wpt_cross.scheduler import (
|
||||
build_run_schedule,
|
||||
)
|
||||
from moli_benchmark.wpt_cross.server import (
|
||||
_nosniff_javascript_response,
|
||||
_workers_url_encoding_response,
|
||||
_fetch_status_response,
|
||||
BENCH_REPORT_BRIDGE,
|
||||
BENCH_TESTDRIVER_VENDOR_BRIDGE,
|
||||
BENCH_TIMEOUT_MULTIPLIER_QUERY,
|
||||
@@ -126,8 +123,10 @@ from moli_benchmark.wpt_cross.server import (
|
||||
_inject_bench_report_bridge_config,
|
||||
_host_header_hostname,
|
||||
_headers_include,
|
||||
_normalize_harness_case_key,
|
||||
_inspect_headers_response_headers,
|
||||
_fetch_status_response,
|
||||
_normalize_harness_case_key,
|
||||
_nosniff_javascript_response,
|
||||
_needs_wpt_template_substitution,
|
||||
_legacy_wpt_resource_alias,
|
||||
_pipe_response_header_operations,
|
||||
@@ -142,6 +141,7 @@ from moli_benchmark.wpt_cross.server import (
|
||||
_substitute_wpt_template_variables,
|
||||
_window_js_window_wrapper,
|
||||
_wasm_webapi_status_code,
|
||||
_workers_url_encoding_response,
|
||||
_wpt_delay_seconds,
|
||||
_wpt_dedicated_worker_js_wrapper_html,
|
||||
_wpt_any_dedicated_worker_wrapper_html,
|
||||
@@ -156,8 +156,6 @@ from moli_benchmark.wpt_cross.server import (
|
||||
clear_current_proxy_env()
|
||||
|
||||
|
||||
|
||||
|
||||
class WptCrossTestCase(unittest.TestCase):
|
||||
def _run_wpt_cross_with_fake_moli(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user