# mypy: allow-untyped-defs
import builtins
import io
import logging
import os
import pickle
import platform
from unittest.mock import MagicMock, patch
from typing import Generator, Tuple
import pytest
import localpaths # type: ignore
from . import serve
from .serve import (
ConfigBuilder,
Test262WindowHandler,
Test262WindowTestHandler,
Test262WindowModuleHandler,
Test262WindowModuleTestHandler,
Test262StrictWindowHandler,
Test262StrictWindowTestHandler,
Test262StrictHandler,
inject_script)
logger = logging.getLogger()
@pytest.mark.skipif(platform.uname()[0 ] == "Windows" ,
reason="Expected contents are platform-dependent" )
def test_make_hosts_file_nix():
with ConfigBuilder(logger,
ports={"http" : [8000 ]},
browser_host="foo.bar" ,
alternate_hosts={"alt" : "foo2.bar" },
subdomains={"a" , "b" },
not_subdomains={"x, y" }) as c:
hosts = serve.make_hosts_file(c, "192.168.42.42" )
lines = hosts.split("\n" )
assert lines == [
"# Start web-platform-tests hosts",
"192.168.42.42\tfoo.bar" ,
"192.168.42.42\ta.foo.bar" ,
"192.168.42.42\tb.foo.bar" ,
"192.168.42.42\tfoo2.bar" ,
"192.168.42.42\ta.foo2.bar" ,
"192.168.42.42\tb.foo2.bar" ,
"# End web-platform-tests hosts",
"" ,
]
@pytest.mark.skipif(platform.uname()[0 ] != "Windows" ,
reason="Expected contents are platform-dependent" )
def test_make_hosts_file_windows():
with ConfigBuilder(logger,
ports={"http" : [8000 ]},
browser_host="foo.bar" ,
alternate_hosts={"alt" : "foo2.bar" },
subdomains={"a" , "b" },
not_subdomains={"x" , "y" }) as c:
hosts = serve.make_hosts_file(c, "192.168.42.42" )
lines = hosts.split("\n" )
assert lines == [
"# Start web-platform-tests hosts",
"192.168.42.42\tfoo.bar" ,
"192.168.42.42\ta.foo.bar" ,
"192.168.42.42\tb.foo.bar" ,
"192.168.42.42\tfoo2.bar" ,
"192.168.42.42\ta.foo2.bar" ,
"192.168.42.42\tb.foo2.bar" ,
"0.0.0.0\tx.foo.bar" ,
"0.0.0.0\ty.foo.bar" ,
"0.0.0.0\tx.foo2.bar" ,
"0.0.0.0\ty.foo2.bar" ,
"# End web-platform-tests hosts",
"" ,
]
def test_ws_doc_root_default():
with ConfigBuilder(logger) as c:
assert c.doc_root == localpaths.repo_root
assert c.ws_doc_root == os.path.join(localpaths.repo_root, "websockets" , "handlers" )
assert c.paths["ws_doc_root" ] == c.ws_doc_root
def test_init_ws_doc_root():
with ConfigBuilder(logger, ws_doc_root="/" ) as c:
assert c.doc_root == localpaths.repo_root # check this hasn't changed
assert c.ws_doc_root == "/"
assert c.paths["ws_doc_root" ] == c.ws_doc_root
def test_set_ws_doc_root():
cb = ConfigBuilder(logger)
cb.ws_doc_root = "/"
with cb as c:
assert c.doc_root == localpaths.repo_root # check this hasn't changed
assert c.ws_doc_root == "/"
assert c.paths["ws_doc_root" ] == c.ws_doc_root
def test_pickle():
# Ensure that the config object can be pickled
with ConfigBuilder(logger) as c:
pickle.dumps(c)
def test_alternate_host_unspecified():
ConfigBuilder(logger, browser_host="web-platform.test" )
@pytest.mark.parametrize("primary, alternate" , [
("web-platform.test" , "web-platform.test" ),
("a.web-platform.test" , "web-platform.test" ),
("web-platform.test" , "a.web-platform.test" ),
("a.web-platform.test" , "a.web-platform.test" ),
])
def test_alternate_host_invalid(primary, alternate):
with pytest.raises(ValueError):
ConfigBuilder(logger, browser_host=primary, alternate_hosts={"alt" : alternate})
@pytest.mark.parametrize("primary, alternate" , [
("web-platform.test" , "not-web-platform.test" ),
("a.web-platform.test" , "b.web-platform.test" ),
("web-platform-tests.dev" , "web-platform-tests.live" ),
])
def test_alternate_host_valid(primary, alternate):
ConfigBuilder(logger, browser_host=primary, alternate_hosts={"alt" : alternate})
# A token marking the location of expected script injection.
INJECT_SCRIPT_MARKER = b"<!-- inject here -->"
def test_inject_script_after_head():
html = b"" "<!DOCTYPE html>
<html>
<head>
<!-- inject here --><script src="test.js" ></script>
</head>
<body>
</body>
</html>"" "
assert INJECT_SCRIPT_MARKER in html
assert inject_script(html.replace(INJECT_SCRIPT_MARKER, b"" ), INJECT_SCRIPT_MARKER) == html
def test_inject_script_no_html_head():
html = b"" "<!DOCTYPE html>
<!-- inject here --><div></div>"" "
assert INJECT_SCRIPT_MARKER in html
assert inject_script(html.replace(INJECT_SCRIPT_MARKER, b"" ), INJECT_SCRIPT_MARKER) == html
def test_inject_script_no_doctype():
html = b"" "<!-- inject here --><div></div>" ""
assert INJECT_SCRIPT_MARKER in html
assert inject_script(html.replace(INJECT_SCRIPT_MARKER, b"" ), INJECT_SCRIPT_MARKER) == html
def test_inject_script_parse_error():
html = b"" "<!--<!-- inject here --><div></div>" ""
assert INJECT_SCRIPT_MARKER in html
# On a parse error, the script should not be injected and the original content should be
# returned.
assert INJECT_SCRIPT_MARKER not in inject_script(html.replace(INJECT_SCRIPT_MARKER, b"" ), INJECT_SCRIPT_MARKER)
@pytest.fixture
def handler_setup() -> Generator[Tuple[str, str], None , None ]:
"" "Provides a mocked filesystem environment for testing any handler class." ""
tests_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "tests" , "testdata" ))
url_base = "/"
mock_file_contents = {
os.path.normpath(os.path.join(tests_root, "test262" , "basic.js" )): "" "/*---\ndescription: A basic test
includes: [assert .js, sta.js]
---*/
assert .sameValue(1 , 1 );
"" ",
os.path.normpath(os.path.join(tests_root, "test262" , "negative.js" )): "" "/*---\ndescription: A negative test
negative:
phase: runtime
type: TypeError
---*/
throw new TypeError();
"" ",
os.path.normpath(os.path.join(tests_root, "test262" , "module.js" )): "" "/*---\ndescription: A module test
flags: [module]
---*/
import {} from 'some-module' ;
"" ",
os.path.normpath(os.path.join(tests_root, "test262" , "async.js" )): "" "/*---
description: An async test
flags: [async]
---*/
print('Test262:AsyncTestComplete' );
"" ",
os.path.normpath(os.path.join(tests_root, "test262" , "teststrict.js" )): "" "/*---\ndescription: A strict mode test
flags: [onlyStrict]
includes: [propertyHelper.js]
---*/
console.log('hello' );
"" "
}
# Store original functions to be called if our mock doesn't handle the file
original_open = builtins.open
original_exists = os.path.exists
original_isdir = os.path.isdir
def custom_open(file, mode='r' , *args, **kwargs):
normalized_file = os.path.normpath(file)
if normalized_file in mock_file_contents:
if 'b' in mode:
return io.BytesIO(mock_file_contents[normalized_file].encode('utf-8' ))
else :
return io.StringIO(mock_file_contents[normalized_file])
return original_open(file, mode, *args, **kwargs)
def custom_exists(path):
normalized_path = os.path.normpath(path)
return normalized_path in mock_file_contents or original_exists(path)
def custom_isdir(path):
normalized_path = os.path.normpath(path)
expected_dir = os.path.normpath(os.path.join(tests_root, "test262" ))
return normalized_path == expected_dir or original_isdir(path)
with patch('builtins.open' , side_effect=custom_open), \
patch('os.path.exists' , side_effect=custom_exists), \
patch('os.path.isdir' , side_effect=custom_isdir):
yield tests_root, url_base
def _create_mock_request(path: str) -> MagicMock:
mock_request = MagicMock()
mock_request.url_parts.path = path
mock_request.url_parts.query = ""
return mock_request
# Ensure pytest doesn't consider Test-prefixed classes to be testcases
Test262WindowHandler.__test__ = False # type: ignore[attr-defined]
Test262WindowTestHandler.__test__ = False # type: ignore[attr-defined]
Test262WindowModuleHandler.__test__ = False # type: ignore[attr-defined]
Test262WindowModuleTestHandler.__test__ = False # type: ignore[attr-defined]
Test262StrictWindowHandler.__test__ = False # type: ignore[attr-defined]
Test262StrictWindowTestHandler.__test__ = False # type: ignore[attr-defined]
Test262StrictHandler.__test__ = False # type: ignore[attr-defined]
@pytest.mark.parametrize("handler_cls, expected" , [
(Test262WindowHandler, [(".test262.html" , ".js" , ".test262-test.html" )]),
(Test262WindowTestHandler, [(".test262-test.html" , ".js" )]),
(Test262WindowModuleHandler, [(".test262-module.html" , ".js" , ".test262-module-test.html" )]),
(Test262WindowModuleTestHandler, [(".test262-module-test.html" , ".js" )]),
(Test262StrictWindowHandler, [(".test262.strict.html" , ".js" , ".test262-test.strict.html" )]),
(Test262StrictWindowTestHandler, [(".test262-test.strict.html" , ".js" , ".test262.strict.js" )]),
])
def test_path_replace(handler_setup, handler_cls, expected):
"" "Verifies that handlers correctly map request paths to internal resources." ""
root, url_base = handler_setup
handler = handler_cls(base_path=root, url_base=url_base)
assert handler.path_replace == expected
@pytest.mark.parametrize("handler_cls, request_path, expected_tags" , [
(
Test262WindowTestHandler,
"/test262/basic.test262-test.html" ,
[
'<script src="/third_party/test262/harness/assert.js"></script>' ,
'<script src="/third_party/test262/harness/sta.js"></script>' ,
]
),
(
Test262WindowTestHandler,
"/test262/negative.test262-test.html" ,
[
"<script>test262Negative('TypeError', 'runtime')</script>" ,
]
),
(
Test262WindowTestHandler,
"/test262/async.test262-test.html" ,
[
"<script>test262IsAsync(true)</script>" ,
'<script src="/third_party/test262/harness/doneprintHandle.js"></script>' ,
]
),
(
Test262StrictWindowTestHandler,
"/test262/teststrict.test262-test.strict.html" ,
[
'<script src="/third_party/test262/harness/propertyHelper.js"></script>' ,
]
),
])
def test_get_meta_and_script(handler_setup, handler_cls, request_path, expected_tags):
"" "Verifies script and meta injection logic for Test262 handlers." ""
root, url_base = handler_setup
handler = handler_cls(root, url_base)
mock_request = _create_mock_request(request_path)
# Combine output of _get_meta and _get_script
output = list(handler._get_meta(mock_request)) + list(handler._get_script(mock_request))
for item in expected_tags:
assert item in output
assert len(expected_tags) == len(output)
@pytest.mark.parametrize("handler_cls, request_path, expected_substrings" , [
# Test262WindowHandler: Should contain the iframe pointing to the test
(
Test262WindowHandler,
"/test262/basic.test262.html" ,
[
'<script src="/resources/testharness.js"></script>' ,
'<script src="/resources/testharnessreport.js"></script>' ,
'window.test262HarnessDone = t.step_func_done(function(status, message)' ,
'<iframe id="test262-iframe" src="/test262/basic.test262-test.html"></iframe>'
]
),
# Test262WindowTestHandler: Should contain script tags
(
Test262WindowTestHandler,
"/test262/basic.test262-test.html" ,
[
'<script src="/test262/basic.js" onerror="test262ScriptError()"></script>' ,
'<script>test262Setup()</script>' ,
]
),
# Test262WindowModuleTestHandler: Should contain module import and new catch logic
(
Test262WindowModuleTestHandler,
"/test262/module.test262-module-test.html" ,
[
'<script type="module">' ,
'test262Setup();' ,
'import("/test262/module.js")' ,
'setTimeout(() => { throw error; });' ,
]
),
# Verification of the 'negative' replacement in the HTML
(
Test262WindowTestHandler,
"/test262/negative.test262-test.html" ,
[
"<script>test262Negative('TypeError', 'runtime')</script>" ,
]
),
# Verification of the 'async' replacement in the HTML
(
Test262WindowTestHandler,
"/test262/async.test262-test.html" ,
[
"<script>test262IsAsync(true)</script>" ,
'<script src="/third_party/test262/harness/doneprintHandle.js">'
]
),
# Strict HTML Case: points to the .strict.js variant
(
Test262StrictWindowTestHandler,
"/test262/teststrict.test262-test.strict.html" ,
['src="/test262/teststrict.test262.strict.js"' ]
),
# Strict JS Case: The handler that serves the actual script
(
Test262StrictHandler,
"/test262/teststrict.test262.strict.js" ,
['"use strict";' , "console.log('hello');" ]
),
])
def test_wrapper_content(handler_setup, handler_cls, request_path, expected_substrings):
"" "Verifies generated HTML/JS content for any handler." ""
root, url_base = handler_setup
handler = handler_cls(base_path=root, url_base=url_base)
mock_request = _create_mock_request(request_path)
mock_response = MagicMock()
handler.handle_request(mock_request, mock_response)
content = mock_response.content
for item in expected_substrings:
assert item in content
Messung V0.5 in Prozent C=94 H=95 G=94
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-26)
¤
*© Formatika GbR, Deutschland