Update web-platform-tests to revision 8ba782c9d5a545b850cd8920032cb14cfbab2c35

This commit is contained in:
WPT Sync Bot 2020-07-17 08:20:46 +00:00
parent b17a302356
commit 986610f6ed
91 changed files with 1030 additions and 429 deletions

View file

@ -4,7 +4,7 @@
expected: TIMEOUT expected: TIMEOUT
[Opening a blob URL in a new window immediately before revoking it works.] [Opening a blob URL in a new window immediately before revoking it works.]
expected: TIMEOUT expected: FAIL
[Fetching a blob URL immediately before revoking it works in an iframe.] [Fetching a blob URL immediately before revoking it works in an iframe.]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-004.html]
[Miss float below something else]
expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -0,0 +1,4 @@
[CaretPosition-001.html]
[Element at (400, 100)]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized] [listeners are called when <iframe> is resized]
expected: FAIL expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -17,6 +17,3 @@
[test the top of layer] [test the top of layer]
expected: FAIL expected: FAIL
[test some point of the element: top left corner]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -1,2 +0,0 @@
[matchMedia-display-none-iframe.html]
expected: ERROR

View file

@ -312,21 +312,24 @@
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK] [Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
expected: NOTRUN expected: NOTRUN
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk] [<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*] [<iframe>: combined response Content-Type: */* text/html]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain] [<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL

View file

@ -53,9 +53,3 @@
[combined text/javascript ] [combined text/javascript ]
expected: FAIL expected: FAIL
[separate text/javascript x/x]
expected: FAIL
[separate text/javascript ]
expected: FAIL

View file

@ -11,6 +11,3 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!] [X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL expected: FAIL
[Content-Type-Options%3A%20nosniff]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_4.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -14,3 +14,6 @@
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: FAIL
[Non-HTMLElement should not support autofocus]
expected: FAIL

View file

@ -5,3 +5,9 @@
[Below-viewport iframes load lazily] [Below-viewport iframes load lazily]
expected: FAIL expected: FAIL
[Below-viewport data: url iframes load lazily]
expected: FAIL
[Below-viewport blob url iframes load lazily]
expected: FAIL

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-1.html] [iframe_sandbox_popups_escaping-1.html]
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_nonescaping-1.html] [iframe_sandbox_popups_nonescaping-1.html]
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: NOTRUN

View file

@ -1,4 +1,5 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL expected: NOTRUN

View file

@ -1,4 +1,5 @@
[iframe_sandbox_popups_nonescaping-3.html] [iframe_sandbox_popups_nonescaping-3.html]
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL expected: NOTRUN

View file

@ -0,0 +1,13 @@
[image-loading-lazy.html]
[Below-viewport data:url images only load when in the viewport and do not block the window load event]
expected: FAIL
[Below-viewport loading=lazy images only load when in the viewport and do not block the window load event]
expected: FAIL
[Below-viewport blob URL images only load when in the viewport and do not block the window load event]
expected: FAIL
[In-viewport loading=lazy images load immediately but do not block the window load event]
expected: FAIL

View file

@ -1,4 +0,0 @@
[module-static-import-delayed.html]
[document.write in an imported module]
expected: FAIL

View file

@ -4,5 +4,5 @@
expected: TIMEOUT expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document] [The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT expected: FAIL

View file

@ -1,5 +1,4 @@
[realtimeanalyser-fft-scaling.html] [realtimeanalyser-fft-scaling.html]
expected: TIMEOUT
[X 2048-point FFT peak position is not equal to 64. Got 0.] [X 2048-point FFT peak position is not equal to 64. Got 0.]
expected: FAIL expected: FAIL

View file

@ -1,5 +0,0 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -7,7 +7,7 @@
expected: FAIL expected: FAIL
[Opening a blob URL in a new window immediately before revoking it works.] [Opening a blob URL in a new window immediately before revoking it works.]
expected: TIMEOUT expected: FAIL
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.] [Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
expected: TIMEOUT expected: TIMEOUT

View file

@ -139718,6 +139718,19 @@
{} {}
] ]
], ],
"position-relative-percentage-top-002.html": [
"698f310e90268e74193313aba2e5966914cf8457",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"scrollbars-auto.html": [ "scrollbars-auto.html": [
"ed1ffb8d93aec7c95eb3c9bbdbb6bd31ae402593", "ed1ffb8d93aec7c95eb3c9bbdbb6bd31ae402593",
[ [
@ -166533,6 +166546,45 @@
{} {}
] ]
], ],
"abspos-009.tentative.html": [
"0e71de200d5736cf047498e81f9f57bc5ce88d4b",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"abspos-010.tentative.html": [
"1d7ddec7f5e0add7c81c9e087ca0820432bb93d3",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"abspos-011.tentative.html": [
"01fac9dae156ca1f5b1e8b629deb97ecf9a10ca4",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"auto-margins-001.tentative.html": [ "auto-margins-001.tentative.html": [
"9e89ab6ca7f5220ea030aa537bcb3b64f156043d", "9e89ab6ca7f5220ea030aa537bcb3b64f156043d",
[ [
@ -324731,7 +324783,7 @@
[] []
], ],
"infinite-slow-response.py": [ "infinite-slow-response.py": [
"fa2c482ec19d94336f729cbd52673820873d4268", "a26cd8064c88531e6877d2561cd16df964eb7f6e",
[] []
], ],
"inspect-headers.py": [ "inspect-headers.py": [
@ -324767,11 +324819,11 @@
[] []
], ],
"stash-put.py": [ "stash-put.py": [
"36527b98b71785809cd6a490196dd9112fef9181", "3af7d9199ace9fd0a4c4f840e14fbb70d7bc79f8",
[] []
], ],
"stash-take.py": [ "stash-take.py": [
"fcaf96c96a6411f5391276e984aaa226c8cb15b6", "e6db80dd86df1e5a80e177b78bd40a59234885b0",
[] []
], ],
"status.py": [ "status.py": [
@ -338781,7 +338833,7 @@
[] []
], ],
"audio-output.idl": [ "audio-output.idl": [
"cf0f46d08bc3dafae5f62cc505b3b3791ad3f7da", "2041e6ea8fdb5d2f67cf9596a71de4b290bee869",
[] []
], ],
"background-fetch.idl": [ "background-fetch.idl": [
@ -339273,7 +339325,7 @@
[] []
], ],
"streams.idl": [ "streams.idl": [
"35f558f624a83f3e2526e89b9be909a7883ecb08", "3d7484a20e0553daba3cc336ba1b61c233e35e68",
[] []
], ],
"text-detection-api.tentative.idl": [ "text-detection-api.tentative.idl": [
@ -339293,7 +339345,7 @@
[] []
], ],
"uievents.idl": [ "uievents.idl": [
"b00f7badb90b307c45c86e15b4213d91dcc088de", "67405ebf118b4b584d9cc335918bc45eb3e5907b",
[] []
], ],
"url.idl": [ "url.idl": [
@ -339317,7 +339369,7 @@
[] []
], ],
"wai-aria.idl": [ "wai-aria.idl": [
"d5d8f32521a3b22647eece7a7662861b6da9e060", "5b1bacc932ffdafffd6869d50146fb467ffc168a",
[] []
], ],
"wake-lock.idl": [ "wake-lock.idl": [
@ -344564,7 +344616,7 @@
[] []
], ],
"mock-screenenumeration.js": [ "mock-screenenumeration.js": [
"5a2d7b18d28229d9e0e3e53a22006a082de25dea", "2e41f59ea809b6434d9363228b162dbcf3538f61",
[] []
], ],
"mock-screenenumeration.js.header": [ "mock-screenenumeration.js.header": [
@ -345213,7 +345265,7 @@
}, },
"screen_enumeration": { "screen_enumeration": {
"README.md": [ "README.md": [
"e3de83d0a8983b2131327556ff5acb011bcbf7e5", "42a5ebfc5169f43fa9289e85fed4d640071fde3d",
[] []
], ],
"resources": { "resources": {
@ -349422,7 +349474,7 @@
[] []
], ],
"epochs_update.sh": [ "epochs_update.sh": [
"4b393fa6db5f90c18daccf6cef3a9706f1411415", "f460814c962076b4ec72c072dff09925427c90a6",
[] []
], ],
"jobs.py": [ "jobs.py": [
@ -349610,11 +349662,11 @@
[] []
], ],
"lint.py": [ "lint.py": [
"14052e7a9723ce52cc3ffd64bc6ef454e834f751", "ad053dcca584cd2616e62dd8b414192efeb5f9d8",
[] []
], ],
"rules.py": [ "rules.py": [
"6ffd749b9ad539b56ab93f4cd3dfffe8ed324aa1", "c67745792d1bec367fe6e2faa28d725fdedaf1fc",
[] []
], ],
"tests": { "tests": {
@ -349811,7 +349863,7 @@
} }
}, },
"test_file_lints.py": [ "test_file_lints.py": [
"7dacfad6380dc8b668a22dc7c4fe2e74d375469f", "be95890d6fb3b95a2b335c9998d6e9bb98c3dcc0",
[] []
], ],
"test_lint.py": [ "test_lint.py": [
@ -355896,7 +355948,7 @@
[] []
], ],
"run.py": [ "run.py": [
"95d9369f2a888657c23315d8d97b9eb636e3db96", "e977b9a0d36ee4f05072b4ff6554bd8ddb85d09e",
[] []
], ],
"testfiles.py": [ "testfiles.py": [
@ -356944,7 +356996,7 @@
[] []
], ],
"test_server.py": [ "test_server.py": [
"51331a67efa88d78ea56130f00e5420633b6aac6", "051dc3f1defa847148999cc173e058eb3d861447",
[] []
], ],
"test_stash.py": [ "test_stash.py": [
@ -356961,7 +357013,7 @@
[] []
], ],
"test_request.py": [ "test_request.py": [
"869d3d4604409411984cb49fcd40eb7e971b3c52", "91390b28e41550fed788f25f7c34b58e389113bc",
[] []
], ],
"test_response.py": [ "test_response.py": [
@ -357003,11 +357055,11 @@
[] []
], ],
"request.py": [ "request.py": [
"541ac04e7d087c882f1e254ffb21ad6393e7f4c4", "28f407c806528c9574642794447605182a42f098",
[] []
], ],
"response.py": [ "response.py": [
"b24f0cdf476850a10cdbe94bb857fc61ce32bcf8", "895f174d5f057afdec7ca6fc7388a39263fea874",
[] []
], ],
"router.py": [ "router.py": [
@ -357019,7 +357071,7 @@
[] []
], ],
"server.py": [ "server.py": [
"c2498c4ee1e8f45de604f71394c3d6feef82aef1", "56342ed287d8fa1028796e5083e1f1f99375217a",
[] []
], ],
"sslutils": { "sslutils": {
@ -364583,7 +364635,7 @@
] ]
], ],
"idb-explicit-commit-throw.any.js": [ "idb-explicit-commit-throw.any.js": [
"3b8d148d76c1e9cd59486b4b612bfc7641023c37", "751096a3307d88ca910e8844579b1c0c59a41cec",
[ [
"IndexedDB/idb-explicit-commit-throw.any.html", "IndexedDB/idb-explicit-commit-throw.any.html",
{ {
@ -364608,7 +364660,7 @@
] ]
], ],
"idb-explicit-commit.any.js": [ "idb-explicit-commit.any.js": [
"038c04720f8d949dc611c981659e6b5428b8574e", "922f2907c9536becbd083e5229f263682c01123f",
[ [
"IndexedDB/idb-explicit-commit.any.html", "IndexedDB/idb-explicit-commit.any.html",
{ {
@ -366760,7 +366812,7 @@
] ]
], ],
"idbobjectstore_putall.tentative.any.js": [ "idbobjectstore_putall.tentative.any.js": [
"c66669595ea16b74000c11ad8163ec19c93e35fa", "8bdc765906d86504bcb344e1e579a97f8f602c6e",
[ [
"IndexedDB/idbobjectstore_putall.tentative.any.html", "IndexedDB/idbobjectstore_putall.tentative.any.html",
{ {
@ -375583,7 +375635,7 @@
}, },
"audio-output": { "audio-output": {
"idlharness.https.window.js": [ "idlharness.https.window.js": [
"c13b167296d8059b96bfa4704714051e341ee987", "d7cdbd076833481b53f35b26d5ee016fd70c4111",
[ [
"audio-output/idlharness.https.window.html", "audio-output/idlharness.https.window.html",
{ {
@ -395501,6 +395553,13 @@
{} {}
] ]
], ],
"grid-item-flex-container-001.html": [
"56c999c55882dabb78c35436fa7f9ac890e6901f",
[
null,
{}
]
],
"grid-item-min-auto-size-001.html": [ "grid-item-min-auto-size-001.html": [
"f50e9ef312418f4d3b737bd55b4a7e5c75f09230", "f50e9ef312418f4d3b737bd55b4a7e5c75f09230",
[ [
@ -463366,7 +463425,7 @@
] ]
], ],
"iframe-loading-lazy.html": [ "iframe-loading-lazy.html": [
"51b442695e01e9496ee4f5754023f722e6636f36", "336703ebc47d7c78e7f367969977edd6cfafc26c",
[ [
null, null,
{} {}
@ -464076,13 +464135,6 @@
{} {}
] ]
], ],
"image-loading-lazy-load-event.html": [
"0da5379df48a20f16374774c989fa459dbe18ee5",
[
null,
{}
]
],
"image-loading-lazy-move-document.html": [ "image-loading-lazy-move-document.html": [
"ff7e83105cc904145e67eb156653b69b6f0b113a", "ff7e83105cc904145e67eb156653b69b6f0b113a",
[ [
@ -464140,7 +464192,7 @@
] ]
], ],
"image-loading-lazy.html": [ "image-loading-lazy.html": [
"0c1c39a8ae95f0b978f3b2a3ebd822598295372b", "35f25f8a15455ec3e504c67f343112c088aee872",
[ [
null, null,
{} {}
@ -498815,7 +498867,7 @@
}, },
"screen_enumeration": { "screen_enumeration": {
"getScreens.tentative.https.window.js": [ "getScreens.tentative.https.window.js": [
"f496282b01620f8b1d2d10c11e961f6fbb9dc56a", "ad982b219cbe2baa540e37f27e4096d274ac09a2",
[ [
"screen_enumeration/getScreens.tentative.https.window.html", "screen_enumeration/getScreens.tentative.https.window.html",
{ {
@ -498837,7 +498889,36 @@
] ]
], ],
"getScreens.values.https.html": [ "getScreens.values.https.html": [
"3b8060786e13fc1c11f9b54b4c3e927ecab1e43b", "881396adbc3befefb39b55020d8f798379bfa648",
[
null,
{}
]
],
"isMultiScreen.tentative.https.window.js": [
"515731cc04fc7b0026f5972d9a5b96e649d8bc9e",
[
"screen_enumeration/isMultiScreen.tentative.https.window.html",
{
"script_metadata": [
[
"global",
"window"
],
[
"script",
"/resources/testdriver.js"
],
[
"script",
"/resources/testdriver-vendor.js"
]
]
}
]
],
"isMultiScreen.values.https.html": [
"5146803ea9c20c5f8ae43cf385895a95fc361747",
[ [
null, null,
{} {}
@ -520321,6 +520402,15 @@
{} {}
] ]
], ],
"constructor-allowed-to-start.html": [
"f866b5f7a1cb408c1a0c26c21c99bb7a28d53e82",
[
null,
{
"testdriver": true
}
]
],
"processing-after-resume.https.html": [ "processing-after-resume.https.html": [
"e000ab124fefa6f0eea4e5517d04436428c0cd8c", "e000ab124fefa6f0eea4e5517d04436428c0cd8c",
[ [

View file

@ -0,0 +1,4 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-004.html]
[Miss float below something else]
expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -0,0 +1,4 @@
[CaretPosition-001.html]
[Element at (400, 100)]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized] [listeners are called when <iframe> is resized]
expected: FAIL expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -21,6 +21,3 @@
[test the top of layer] [test the top of layer]
expected: FAIL expected: FAIL
[test some point of the element: top left corner]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -1,2 +0,0 @@
[matchMedia-display-none-iframe.html]
expected: ERROR

View file

@ -312,21 +312,24 @@
[fetch(): separate response Content-Type: text/plain ] [fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN expected: NOTRUN
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk] [<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*] [<iframe>: combined response Content-Type: */* text/html]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain] [<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL

View file

@ -53,9 +53,3 @@
[combined text/javascript ] [combined text/javascript ]
expected: FAIL expected: FAIL
[separate text/javascript x/x]
expected: FAIL
[separate text/javascript ]
expected: FAIL

View file

@ -11,6 +11,3 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!] [X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL expected: FAIL
[Content-Type-Options%3A%20nosniff]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_4.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -14,3 +14,6 @@
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: FAIL
[Non-HTMLElement should not support autofocus]
expected: FAIL

View file

@ -5,3 +5,9 @@
[Below-viewport iframes load lazily] [Below-viewport iframes load lazily]
expected: FAIL expected: FAIL
[Below-viewport data: url iframes load lazily]
expected: FAIL
[Below-viewport blob url iframes load lazily]
expected: FAIL

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_escaping-1.html] [iframe_sandbox_popups_escaping-1.html]
type: testharness type: testharness
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_nonescaping-1.html] [iframe_sandbox_popups_nonescaping-1.html]
type: testharness type: testharness
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: NOTRUN

View file

@ -1,5 +1,6 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL expected: NOTRUN

View file

@ -1,5 +1,6 @@
[iframe_sandbox_popups_nonescaping-3.html] [iframe_sandbox_popups_nonescaping-3.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL expected: NOTRUN

View file

@ -1,4 +0,0 @@
[image-loading-lazy-load-event.html]
[In-viewport loading=lazy images do not block the window load event]
expected: FAIL

View file

@ -2,3 +2,15 @@
[Images with loading='lazy' load only when in the viewport] [Images with loading='lazy' load only when in the viewport]
expected: FAIL expected: FAIL
[Below-viewport data:url images only load when in the viewport and do not block the window load event]
expected: FAIL
[Below-viewport loading=lazy images only load when in the viewport and do not block the window load event]
expected: FAIL
[Below-viewport blob URL images only load when in the viewport and do not block the window load event]
expected: FAIL
[In-viewport loading=lazy images load immediately but do not block the window load event]
expected: FAIL

View file

@ -1,4 +0,0 @@
[module-static-import-delayed.html]
[document.write in an imported module]
expected: FAIL

View file

@ -5,5 +5,5 @@
expected: TIMEOUT expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document] [The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT expected: FAIL

View file

@ -1,5 +1,4 @@
[realtimeanalyser-fft-scaling.html] [realtimeanalyser-fft-scaling.html]
expected: TIMEOUT
[X 2048-point FFT peak position is not equal to 64. Got 0.] [X 2048-point FFT peak position is not equal to 64. Got 0.]
expected: FAIL expected: FAIL

View file

@ -1,5 +0,0 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -1,13 +1,5 @@
// META: script=support-promises.js // META: script=support-promises.js
/**
* This file contains a test that was separated out from the rest of the idb
* explict commit tests because it requires the flag 'allow_uncaught_exception',
* which prevents unintentionally thrown errors from failing tests.
*
* @author andreasbutler@google.com
*/
setup({allow_uncaught_exception:true}); setup({allow_uncaught_exception:true});
promise_test(async testCase => { promise_test(async testCase => {

View file

@ -1,12 +1,5 @@
// META: script=support-promises.js // META: script=support-promises.js
/**
* This file contains the webplatform tests for the explicit commit() method
* of the IndexedDB transaction API.
*
* @author andreasbutler@google.com
*/
promise_test(async testCase => { promise_test(async testCase => {
const db = await createDatabase(testCase, db => { const db = await createDatabase(testCase, db => {
createBooksStore(testCase, db); createBooksStore(testCase, db);

View file

@ -1,12 +1,5 @@
// META: script=support-promises.js // META: script=support-promises.js
/**
* This file contains the webplatform tests for the explicit commit() method
* of the IndexedDB transaction API.
*
* @author nums@google.com
*/
promise_test(async testCase => { promise_test(async testCase => {
const db = await createDatabase(testCase, db => { const db = await createDatabase(testCase, db => {
const store = createBooksStore(testCase, db); const store = createBooksStore(testCase, db);

View file

@ -7,13 +7,14 @@
idl_test( idl_test(
['audio-output'], ['audio-output'],
['html', 'dom'], ['mediacapture-streams', 'html', 'dom'],
idl_array => { idl_array => {
self.audio = document.createElement('audio'); self.audio = document.createElement('audio');
self.video = document.createElement('video'); self.video = document.createElement('video');
idl_array.add_objects({ idl_array.add_objects({
HTMLAudioElement: ['audio'], HTMLAudioElement: ['audio'],
HTMLVideoElement: ['video'] HTMLVideoElement: ['video'],
MediaDevices: ['navigator.mediaDevices'],
}); });
} }
); );

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<meta name="assert" content="This ensures that a relative-positioned grandchild (of a flexbox) correctly resolves percentages against its stretched parent.">
<link rel="help" href="https://crbug.com/1106074">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; height: 100px; background: red;"></div>
<div style="display: flex; width: 100px;">
<div style="height: 100px;"></div>
<div style="width: 100px;">
<div style="background: green; height: 100px; position: relative; top: -100%;"></div>
</div>
</div>

View file

@ -0,0 +1,132 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid item which is also a flex container</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="http://www.w3.org/TR/css-grid-1">
<meta name="assert" content="Checks that the grid is updated when the contents of the grid item flex container change their size dynamically.">
<style>
.grid {
display: grid;
width: 100px;
background: cyan;
}
.flex {
display: flex;
min-height: 0;
height: 100%;
}
.height200 {
height: 200px;
}
.height100 {
height: 100px;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<div id="log"></div>
<pre>grid-template-rows: minmax(auto, auto);</pre>
<div class="grid" style="grid-template-rows: minmax(auto, auto);" data-expected-height="100" >
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(min-content, auto);</pre>
<div class="grid" style="grid-template-rows: minmax(min-content, auto);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(max-content, auto);</pre>
<div class="grid" style="grid-template-rows: minmax(max-content, auto);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(auto, min-content);</pre>
<div class="grid" style="grid-template-rows: minmax(auto, min-content);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(min-content, min-content);</pre>
<div class="grid" style="grid-template-rows: minmax(min-content, min-content);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(max-content, min-content);</pre>
<div class="grid" style="grid-template-rows: minmax(max-content, min-content);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(auto, max-content);</pre>
<div class="grid" style="grid-template-rows: minmax(auto, max-content);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(min-content, max-content);</pre>
<div class="grid" style="grid-template-rows: minmax(min-content, max-content);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<pre>grid-template-rows: minmax(max-content, max-content);</pre>
<div class="grid" style="grid-template-rows: minmax(max-content, max-content);" data-expected-height="100">
<div class="flex">
<div>
<div class="height200"></div>
</div>
</div>
</div>
<script>
// Force layout
document.body.offsetLeft;
// Change content sizes
for (let el of document.querySelectorAll(".height200")) {
el.className = "height100";
}
// Check final layout
checkLayout('.grid');
</script>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: abspos div inline size with percentage height</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 500px; position: relative;">
<div style="background: green; aspect-ratio: 1/1; height: 100%; position: absolute; left: 0; right: 0; top: 0; bottom: 0;"></div>
<div style="height: 100px"></div> <!-- for sizing the abspos containing block -->
</div>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: out-of-flow div block size with box-sizing</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; padding: 10px 20px 30px 40px; aspect-ratio: 1/1; position: absolute; box-sizing: border-box;"></div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: out-of-flow div block size with box-sizing</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 80px; padding: 0px 5px 0px 15px; aspect-ratio: 1/1; position: absolute; box-sizing: content-box;"></div>
<div style="height: 80px;"></div>
<div style="background: green; width: 100px; height: 20px;"></div>

View file

@ -2,7 +2,7 @@ import time
def url_dir(request): def url_dir(request):
return '/'.join(request.url_parts.path.split('/')[:-1]) + '/' return u'/'.join(request.url_parts.path.split(u'/')[:-1]) + u'/'
def stash_write(request, key, value): def stash_write(request, key, value):
@ -12,24 +12,23 @@ def stash_write(request, key, value):
def main(request, response): def main(request, response):
stateKey = request.GET.first("stateKey", "") stateKey = request.GET.first(b"stateKey", b"")
abortKey = request.GET.first("abortKey", "") abortKey = request.GET.first(b"abortKey", b"")
if stateKey: if stateKey:
stash_write(request, stateKey, 'open') stash_write(request, stateKey, 'open')
response.headers.set("Content-type", "text/plain") response.headers.set(b"Content-type", b"text/plain")
response.write_status_headers() response.write_status_headers()
# Writing an initial 2k so browsers realise it's there. *shrug* # Writing an initial 2k so browsers realise it's there. *shrug*
response.writer.write("." * 2048) response.writer.write(b"." * 2048)
while True: while True:
if not response.writer.flush(): if not response.writer.write(b"."):
break break
if abortKey and request.server.stash.take(abortKey, url_dir(request)): if abortKey and request.server.stash.take(abortKey, url_dir(request)):
break break
response.writer.write(".")
time.sleep(0.01) time.sleep(0.01)
if stateKey: if stateKey:

View file

@ -1,14 +1,14 @@
def main(request, response): def main(request, response):
if request.method == 'OPTIONS': if request.method == u'OPTIONS':
# CORS preflight # CORS preflight
response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set(b'Access-Control-Allow-Origin', b'*')
response.headers.set('Access-Control-Allow-Methods', '*') response.headers.set(b'Access-Control-Allow-Methods', b'*')
response.headers.set('Access-Control-Allow-Headers', '*') response.headers.set(b'Access-Control-Allow-Headers', b'*')
return 'done' return 'done'
url_dir = '/'.join(request.url_parts.path.split('/')[:-1]) + '/' url_dir = u'/'.join(request.url_parts.path.split(u'/')[:-1]) + u'/'
key = request.GET.first("key") key = request.GET.first(b"key")
value = request.GET.first("value") value = request.GET.first(b"value")
request.server.stash.put(key, value, url_dir) request.server.stash.put(key, value, url_dir)
response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set(b'Access-Control-Allow-Origin', b'*')
return "done" return "done"

View file

@ -3,7 +3,7 @@ from wptserve.handlers import json_handler
@json_handler @json_handler
def main(request, response): def main(request, response):
dir = '/'.join(request.url_parts.path.split('/')[:-1]) + '/' dir = u'/'.join(request.url_parts.path.split(u'/')[:-1]) + u'/'
key = request.GET.first("key") key = request.GET.first(b"key")
response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set(b'Access-Control-Allow-Origin', b'*')
return request.server.stash.take(key, dir) return request.server.stash.take(key, dir)

View file

@ -11,12 +11,22 @@
<script> <script>
const t_in_viewport = const t_in_viewport =
async_test('In-viewport iframes load eagerly'); async_test('In-viewport iframes load eagerly');
const t_in_viewport_srcdoc=
async_test('In-viewport srcdoc iframes load eagerly');
const t_below_viewport = const t_below_viewport =
async_test('Below-viewport iframes load lazily'); async_test('Below-viewport iframes load lazily');
const t_below_viewport_srcdoc = const t_below_viewport_srcdoc =
async_test('Below-viewport srcdoc iframes load lazily'); async_test('Below-viewport srcdoc iframes load lazily');
const t_below_viewport_data_url =
async_test('Below-viewport data: url iframes load lazily');
const t_below_viewport_blob_url =
async_test('Below-viewport blob url iframes load lazily');
document.addEventListener('DOMContentLoaded', e => {
const blob_url_iframe = document.querySelector('#below_viewport_blob_url');
const blob = new Blob(['<p>Blob subframe</p>'], {type: 'text/html'});
const url = URL.createObjectURL(blob);
blob_url_iframe.src = url;
});
let has_window_loaded = false; let has_window_loaded = false;
@ -25,11 +35,6 @@
"The in_viewport iframe should not block the load event"); "The in_viewport iframe should not block the load event");
}); });
const in_viewport_srcdoc_iframe_onload = t_in_viewport_srcdoc.step_func_done(() => {
assert_false(has_window_loaded,
"The in_viewport srcdoc iframe should not block the load event");
});
window.addEventListener("load", () => { window.addEventListener("load", () => {
has_window_loaded = true; has_window_loaded = true;
document.getElementById("below_viewport_srcdoc").scrollIntoView(); document.getElementById("below_viewport_srcdoc").scrollIntoView();
@ -41,6 +46,7 @@
"the below-viewport iframe loads"); "the below-viewport iframe loads");
}); });
// Onload handlers for below-viewport srcdoc iframe.
// Must make this accessible to the srcdoc iframe's body. // Must make this accessible to the srcdoc iframe's body.
window.below_viewport_srcdoc_iframe_subresource_onload = t_below_viewport_srcdoc.step_func(() => { window.below_viewport_srcdoc_iframe_subresource_onload = t_below_viewport_srcdoc.step_func(() => {
assert_true(has_window_loaded, assert_true(has_window_loaded,
@ -53,16 +59,27 @@
"The window load event should have fired before " + "The window load event should have fired before " +
"the below-viewport srcdoc iframe loads"); "the below-viewport srcdoc iframe loads");
}); });
// Onload handler for below-viewport data url iframe.
const below_viewport_data_url_iframe_onload = t_below_viewport_data_url.step_func_done(() => {
assert_true(has_window_loaded,
"The window load event should have fired before " +
"the below-viewport data url iframe loads");
});
// Onload handler for below-viewport blob url iframe.
const below_viewport_blob_url_iframe_onload = t_below_viewport_blob_url.step_func_done(() => {
assert_true(has_window_loaded,
"The window load event should have fired before " +
"the below-viewport blob url iframe loads");
});
</script> </script>
<body> <body>
<iframe id="in_viewport" src="resources/subframe.html?in-viewport" <iframe id="in_viewport" src="resources/subframe.html?in-viewport"
loading="lazy" width="200px" height="100px" loading="lazy" width="200px" height="100px"
onload="in_viewport_iframe_onload();"></iframe> onload="in_viewport_iframe_onload();"></iframe>
<iframe id="in_viewport_srcdoc"
srcdoc="<body><img src='/common/square.png?in-viewport'></body>"
loading="lazy" width="200px" height="100px"
onload="in_viewport_srcdoc_iframe_onload();"></iframe>
<div style="height:2000vh;"></div> <div style="height:2000vh;"></div>
<iframe id="below_viewport" src="resources/subframe.html?below-viewport" <iframe id="below_viewport" src="resources/subframe.html?below-viewport"
@ -73,6 +90,15 @@
onload='parent.below_viewport_srcdoc_iframe_subresource_onload();'></body>" onload='parent.below_viewport_srcdoc_iframe_subresource_onload();'></body>"
loading="lazy" width="200px" height="100px" loading="lazy" width="200px" height="100px"
onload="below_viewport_srcdoc_iframe_onload();"></iframe> onload="below_viewport_srcdoc_iframe_onload();"></iframe>
<iframe id="below_viewport_data_url"
src="data:text/html,<p>Subframe</p>"
loading="lazy" width="200px" height="100px"
onload="below_viewport_data_url_iframe_onload();"></iframe>
<!-- This iframe has its `src` set to a blob URL dynamically above -->
<iframe id="below_viewport_blob_url"
loading="lazy" width="200px" height="100px"
onload="below_viewport_blob_url_iframe_onload();"></iframe>
<!-- This async script loads very slowly in order to ensure that, if the <!-- This async script loads very slowly in order to ensure that, if the

View file

@ -1,51 +0,0 @@
<!DOCTYPE html>
<head>
<title>In-viewport loading=lazy images do not block the window load event</title>
<link rel="author" title="Rob Buis" href="mailto:rbuis@igalia.com">
<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/common.js"></script>
</head>
<body>
<!-- This image blocks the window load event for 1 second -->
<img src="resources/image.png?window-load-blocking&pipe=trickle(d1)">
<!-- These images must load because they intersect the viewport, but they must
not block the window load event, because they are loading=lazy -->
<img id="visible"
src="resources/image.png?visible&pipe=trickle(d3)" loading="lazy"
onload="visible_img.resolve();" onerror="visible_img.reject();">
<img id="visibility_hidden" style="visibility:hidden;"
src="resources/image.png?visibility_hidden&pipe=trickle(d3)" loading="lazy"
onload="visibility_hidden_img.resolve();" onerror="visibility_hidden_img.reject();">
</body>
<script>
const visible_img = new ElementLoadPromise("visible");
const visibility_hidden_img = new ElementLoadPromise("visibility_hidden");
async_test(t => {
let has_window_loaded = false;
window.addEventListener("load", t.step_func(() => {
has_window_loaded = true;
}));
Promise.all([visible_img.promise, visibility_hidden_img.promise])
.then(t.step_func_done(() => {
assert_true(has_window_loaded,
"The window load event should fire before the " +
"in-viewport loading=lazy images load");
assert_true(visible_img.element().complete,
"The in-viewport loading=lazy visible image is complete");
assert_true(visibility_hidden_img.element().complete,
"The in-viewport loading=lazy visibility:hidden image is " +
"complete");
}))
.catch(t.unreached_func("The images should load successfully"));
}, "In-viewport loading=lazy images do not block the window load event");
</script>

View file

@ -1,38 +1,95 @@
<!DOCTYPE html> <!DOCTYPE html>
<head> <head>
<title>Images with loading='lazy' load only when in the viewport</title> <title>Images with loading='lazy' load only when in the viewport</title>
<link rel="author" title="Scott Little" href="mailto:sclittle@chromium.org">
<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org"> <link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org">
<link rel="author" title="Scott Little" href="mailto:sclittle@chromium.org">
<link rel="help" href="https://github.com/scott-little/lazyload"> <link rel="help" href="https://github.com/scott-little/lazyload">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
</head> </head>
<script> <script>
const t = async_test("Images with loading='lazy' load only when in the viewport"); const in_viewport_test =
async_test("In-viewport loading=lazy images load immediately but do not " +
"block the window load event");
const below_viewport_test =
async_test("Below-viewport loading=lazy images only load when in the " +
"viewport and do not block the window load event");
const below_viewport_data_url_test =
async_test("Below-viewport data:url images only load when in the " +
"viewport and do not block the window load event");
const below_viewport_blob_url_test =
async_test("Below-viewport blob URL images only load when in the " +
"viewport and do not block the window load event");
document.addEventListener('DOMContentLoaded', e => {
const img = document.querySelector('#below_viewport_blob_url');
// Blob URL helper.
// Source: https://bl.ocks.org/nolanlawson/0eac306e4dac2114c752.
function fixBinary(bin) {
const length = bin.length;
const buf = new ArrayBuffer(length);
const arr = new Uint8Array(buf);
for (var i = 0; i < length; i++) {
arr[i] = bin.charCodeAt(i);
}
return buf;
}
const base64 =
"R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA";
const binary = fixBinary(atob(base64));
const blob = new Blob([binary], {type: 'image/png'});
const url = URL.createObjectURL(blob);
img.src = url;
}) // DOMContentLoaded.
let has_in_viewport_loaded = false;
let has_window_load_fired = false; let has_window_load_fired = false;
let has_in_viewport_loaded = false;
const in_viewport_img_onload = t.step_func(() => { window.onload = e => {
assert_false(has_in_viewport_loaded, has_window_load_fired = true;
"The in_viewport element should load only once."); }
// Helper assertion messages for the below tests.
const kScrollAssertion = "images only load when scrolled into view";
const kWindowLoadAssertion = "images do not block the load event";
const in_viewport_img_onload = in_viewport_test.step_func_done(() => {
has_in_viewport_loaded = true; has_in_viewport_loaded = true;
assert_true(document.getElementById("in_viewport").complete); document.querySelector('#bottom').scrollIntoView();
document.getElementById("below_viewport").scrollIntoView(); assert_true(has_window_load_fired,
"In-viewport loading=lazy images do not block the window " +
"load event");
}); });
window.addEventListener("load", t.step_func(() => { const below_viewport_img_onload = below_viewport_test.step_func_done(() => {
has_window_load_fired = true;
}));
const below_viewport_img_onload = t.step_func_done(() => {
assert_true(has_in_viewport_loaded, assert_true(has_in_viewport_loaded,
"The below-viewport image should not load until it has been " + "Below-viewport loading=lazy images only load once loaded " +
"scrolled into viewport, after the in-viewport image loads"); "into the viewport");
assert_true(has_window_load_fired, assert_true(has_window_load_fired,
"Below-viewport loading=lazy images should not block the " + "Below-viewport loading=lazy images should not block the " +
"window load event from firing"); "window load event");
});
const below_viewport_data_url_img_onload = below_viewport_data_url_test.step_func_done(() => {
assert_true(has_in_viewport_loaded,
"Below-viewport loading=lazy data: url images " +
kScrollAssertion);
assert_true(has_window_load_fired,
"Below-viewport loading=lazy data: url images " +
kWindowLoadAssertion);
});
const below_viewport_blob_url_img_onload = below_viewport_blob_url_test.step_func_done(() => {
assert_true(has_in_viewport_loaded,
"Below-viewport loading=lazy blob url images " +
kScrollAssertion);
assert_true(has_window_load_fired,
"Below-viewport loading=lazy blob url images " +
kWindowLoadAssertion);
}); });
</script> </script>
@ -41,8 +98,15 @@
support lazy loading, |below_viewport| finishes before |in_viewport|, and support lazy loading, |below_viewport| finishes before |in_viewport|, and
the test will dependably fail without relying on a timeout. --> the test will dependably fail without relying on a timeout. -->
<img id="in_viewport" loading="lazy" src="resources/image.png?first&pipe=trickle(d2)" <img id="in_viewport" loading="lazy" src="resources/image.png?first&pipe=trickle(d2)"
onload="in_viewport_img_onload();"> onload="in_viewport_img_onload()">
<div style="height:1000vh;"></div> <div style="height:1000vh;"></div>
<img id="below_viewport" loading="lazy" src="resources/image.png?second" <img id="below_viewport" loading="lazy" src="resources/image.png?second"
onload="below_viewport_img_onload();"> onload="below_viewport_img_onload()">
<img id="below_viewport_data_url" loading="lazy"
src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA"
onload="below_viewport_data_url_img_onload()">
<!-- This image has its `src` set to a blob URL dynamically above -->
<img id="below_viewport_blob_url" loading="lazy"
onload="below_viewport_blob_url_img_onload()">
<div id="bottom"></div>
</body> </body>

View file

@ -7,3 +7,7 @@ partial interface HTMLMediaElement {
[SecureContext] readonly attribute DOMString sinkId; [SecureContext] readonly attribute DOMString sinkId;
[SecureContext] Promise<void> setSinkId (DOMString sinkId); [SecureContext] Promise<void> setSinkId (DOMString sinkId);
}; };
partial interface MediaDevices {
Promise<MediaDeviceInfo> selectAudioOutput();
};

View file

@ -137,7 +137,7 @@ dictionary UnderlyingSink {
}; };
callback UnderlyingSinkStartCallback = any (WritableStreamDefaultController controller); callback UnderlyingSinkStartCallback = any (WritableStreamDefaultController controller);
callback UnderlyingSinkWriteCallback = Promise<void> (WritableStreamDefaultController controller, optional any chunk); callback UnderlyingSinkWriteCallback = Promise<void> (any chunk, WritableStreamDefaultController controller);
callback UnderlyingSinkCloseCallback = Promise<void> (); callback UnderlyingSinkCloseCallback = Promise<void> ();
callback UnderlyingSinkAbortCallback = Promise<void> (optional any reason); callback UnderlyingSinkAbortCallback = Promise<void> (optional any reason);
@ -180,7 +180,7 @@ dictionary Transformer {
callback TransformerStartCallback = any (TransformStreamDefaultController controller); callback TransformerStartCallback = any (TransformStreamDefaultController controller);
callback TransformerFlushCallback = Promise<void> (TransformStreamDefaultController controller); callback TransformerFlushCallback = Promise<void> (TransformStreamDefaultController controller);
callback TransformerTransformCallback = Promise<void> (TransformStreamDefaultController controller, optional any chunk); callback TransformerTransformCallback = Promise<void> (any chunk, TransformStreamDefaultController controller);
[Exposed=(Window,Worker,Worklet)] [Exposed=(Window,Worker,Worklet)]
interface TransformStreamDefaultController { interface TransformStreamDefaultController {

View file

@ -3,8 +3,9 @@
// (https://github.com/tidoust/reffy-reports) // (https://github.com/tidoust/reffy-reports)
// Source: UI Events (https://w3c.github.io/uievents/) // Source: UI Events (https://w3c.github.io/uievents/)
[Constructor(DOMString type, optional UIEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface UIEvent : Event { interface UIEvent : Event {
constructor(DOMString type, optional UIEventInit eventInitDict);
readonly attribute Window? view; readonly attribute Window? view;
readonly attribute long detail; readonly attribute long detail;
}; };
@ -14,8 +15,9 @@ dictionary UIEventInit : EventInit {
long detail = 0; long detail = 0;
}; };
[Constructor(DOMString type, optional FocusEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface FocusEvent : UIEvent { interface FocusEvent : UIEvent {
constructor(DOMString type, optional FocusEventInit eventInitDict);
readonly attribute EventTarget? relatedTarget; readonly attribute EventTarget? relatedTarget;
}; };
@ -23,8 +25,9 @@ dictionary FocusEventInit : UIEventInit {
EventTarget? relatedTarget = null; EventTarget? relatedTarget = null;
}; };
[Constructor(DOMString type, optional MouseEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface MouseEvent : UIEvent { interface MouseEvent : UIEvent {
constructor(DOMString type, optional MouseEventInit eventInitDict);
readonly attribute long screenX; readonly attribute long screenX;
readonly attribute long screenY; readonly attribute long screenY;
readonly attribute long clientX; readonly attribute long clientX;
@ -72,8 +75,9 @@ dictionary EventModifierInit : UIEventInit {
boolean modifierSymbolLock = false; boolean modifierSymbolLock = false;
}; };
[Constructor(DOMString type, optional WheelEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface WheelEvent : MouseEvent { interface WheelEvent : MouseEvent {
constructor(DOMString type, optional WheelEventInit eventInitDict);
// DeltaModeCode // DeltaModeCode
const unsigned long DOM_DELTA_PIXEL = 0x00; const unsigned long DOM_DELTA_PIXEL = 0x00;
const unsigned long DOM_DELTA_LINE = 0x01; const unsigned long DOM_DELTA_LINE = 0x01;
@ -92,8 +96,9 @@ dictionary WheelEventInit : MouseEventInit {
unsigned long deltaMode = 0; unsigned long deltaMode = 0;
}; };
[Constructor(DOMString type, optional InputEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface InputEvent : UIEvent { interface InputEvent : UIEvent {
constructor(DOMString type, optional InputEventInit eventInitDict);
readonly attribute DOMString? data; readonly attribute DOMString? data;
readonly attribute boolean isComposing; readonly attribute boolean isComposing;
readonly attribute DOMString inputType; readonly attribute DOMString inputType;
@ -105,8 +110,9 @@ dictionary InputEventInit : UIEventInit {
DOMString inputType = ""; DOMString inputType = "";
}; };
[Constructor(DOMString type, optional KeyboardEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface KeyboardEvent : UIEvent { interface KeyboardEvent : UIEvent {
constructor(DOMString type, optional KeyboardEventInit eventInitDict);
// KeyLocationCode // KeyLocationCode
const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00; const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
const unsigned long DOM_KEY_LOCATION_LEFT = 0x01; const unsigned long DOM_KEY_LOCATION_LEFT = 0x01;
@ -136,8 +142,9 @@ dictionary KeyboardEventInit : EventModifierInit {
boolean isComposing = false; boolean isComposing = false;
}; };
[Constructor(DOMString type, optional CompositionEventInit eventInitDict), Exposed=Window] [Exposed=Window]
interface CompositionEvent : UIEvent { interface CompositionEvent : UIEvent {
constructor(DOMString type, optional CompositionEventInit eventInitDict);
readonly attribute DOMString data; readonly attribute DOMString data;
}; };

View file

@ -10,53 +10,53 @@ Element includes AccessibilityRole;
interface mixin AriaAttributes { interface mixin AriaAttributes {
attribute DOMString? ariaAtomic; attribute DOMString ariaAtomic;
attribute DOMString? ariaAutoComplete; attribute DOMString ariaAutoComplete;
attribute DOMString? ariaBusy; attribute DOMString ariaBusy;
attribute DOMString? ariaChecked; attribute DOMString ariaChecked;
attribute DOMString? ariaColCount; attribute DOMString ariaColCount;
attribute DOMString? ariaColIndex; attribute DOMString ariaColIndex;
attribute DOMString? ariaColIndexText; attribute DOMString ariaColIndexText;
attribute DOMString? ariaColSpan; attribute DOMString ariaColSpan;
attribute DOMString? ariaCurrent; attribute DOMString ariaCurrent;
attribute DOMString? ariaDescription; attribute DOMString ariaDescription;
attribute DOMString? ariaDisabled; attribute DOMString ariaDisabled;
attribute DOMString? ariaExpanded; attribute DOMString ariaExpanded;
attribute DOMString? ariaHasPopup; attribute DOMString ariaHasPopup;
attribute DOMString? ariaHidden; attribute DOMString ariaHidden;
attribute DOMString? ariaInvalid; attribute DOMString ariaInvalid;
attribute DOMString? ariaKeyShortcuts; attribute DOMString ariaKeyShortcuts;
attribute DOMString? ariaLabel; attribute DOMString ariaLabel;
attribute DOMString? ariaLevel; attribute DOMString ariaLevel;
attribute DOMString? ariaLive; attribute DOMString ariaLive;
attribute DOMString? ariaModal; attribute DOMString ariaModal;
attribute DOMString? ariaMultiLine; attribute DOMString ariaMultiLine;
attribute DOMString? ariaMultiSelectable; attribute DOMString ariaMultiSelectable;
attribute DOMString? ariaOrientation; attribute DOMString ariaOrientation;
attribute DOMString? ariaPlaceholder; attribute DOMString ariaPlaceholder;
attribute DOMString? ariaPosInSet; attribute DOMString ariaPosInSet;
attribute DOMString? ariaPressed; attribute DOMString ariaPressed;
attribute DOMString? ariaReadOnly; attribute DOMString ariaReadOnly;
attribute DOMString? ariaRelevant;
attribute DOMString? ariaRequired; attribute DOMString ariaRequired;
attribute DOMString? ariaRoleDescription; attribute DOMString ariaRoleDescription;
attribute DOMString? ariaRowCount; attribute DOMString ariaRowCount;
attribute DOMString? ariaRowIndex; attribute DOMString ariaRowIndex;
attribute DOMString? ariaRowIndexText; attribute DOMString ariaRowIndexText;
attribute DOMString? ariaRowSpan; attribute DOMString ariaRowSpan;
attribute DOMString? ariaSelected; attribute DOMString ariaSelected;
attribute DOMString? ariaSetSize; attribute DOMString ariaSetSize;
attribute DOMString? ariaSort; attribute DOMString ariaSort;
attribute DOMString? ariaValueMax; attribute DOMString ariaValueMax;
attribute DOMString? ariaValueMin; attribute DOMString ariaValueMin;
attribute DOMString? ariaValueNow; attribute DOMString ariaValueNow;
attribute DOMString? ariaValueText; attribute DOMString ariaValueText;
}; };
Element includes AriaAttributes; Element includes AriaAttributes;

View file

@ -44,11 +44,22 @@ var ScreenEnumerationTest = (() => {
} }
async getDisplays() { async getDisplays() {
if (!this.success_)
return Promise.resolve({ result: undefined, });
let value = new blink.mojom.Displays();
value.displays = this.displays_;
value.internalId = this.internalId_;
value.primaryId = this.primaryId_;
return Promise.resolve({ result: value, });
}
async hasMultipleDisplays() {
if (!this.success_)
return Promise.resolve({ result: blink.mojom.MultipleDisplays.kError });
return Promise.resolve({ return Promise.resolve({
displays: this.displays_, result: this.displays_.length > 1
internalId: this.internalId_, ? blink.mojom.MultipleDisplays.kTrue
primaryId: this.primaryId_, : blink.mojom.MultipleDisplays.kFalse,
success: this.success_,
}); });
} }
} }

View file

@ -19,6 +19,7 @@ The `ScreenEnumerationTest` interface is defined as:
addDisplay(display); // Push display to the display vector. addDisplay(display); // Push display to the display vector.
removeDisplay(id); // Remove display from the display vector. removeDisplay(id); // Remove display from the display vector.
async getDisplays(); // Interceptor of getDisplays (screen_enumeration.mojom). async getDisplays(); // Interceptor of getDisplays (screen_enumeration.mojom).
async hasMultipleDisplays(); // Interceptor of hasMultipleDisplays (screen_enumeration.mojom).
}; };
``` ```

View file

@ -1,39 +1,63 @@
// META: global=window // META: global=window
// META: script=/resources/testdriver.js // META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js // META: script=/resources/testdriver-vendor.js
"use strict"; 'use strict';
promise_test(async testCase => { promise_test(async t => {
assert_equals(typeof self.getScreens, "function"); assert_equals(typeof self.getScreens, 'function');
}, "self.getScreens is present"); }, 'getScreens() is present');
promise_test(async testCase => { promise_test(async t => {
await test_driver.set_permission({name: "window-placement"}, "granted"); await test_driver.set_permission({name: 'window-placement'}, 'granted');
const screens = await self.getScreens(); const screens = await self.getScreens();
assert_greater_than(screens.length, 0); assert_greater_than(screens.length, 0);
assert_equals(typeof screens[0].availWidth, "number"); assert_equals(typeof screens[0].availWidth, 'number');
assert_equals(typeof screens[0].availHeight, "number"); assert_equals(typeof screens[0].availHeight, 'number');
assert_equals(typeof screens[0].width, "number"); assert_equals(typeof screens[0].width, 'number');
assert_equals(typeof screens[0].height, "number"); assert_equals(typeof screens[0].height, 'number');
assert_equals(typeof screens[0].colorDepth, "number"); assert_equals(typeof screens[0].colorDepth, 'number');
assert_equals(typeof screens[0].pixelDepth, "number"); assert_equals(typeof screens[0].pixelDepth, 'number');
assert_equals(typeof screens[0].availLeft, "number"); assert_equals(typeof screens[0].availLeft, 'number');
assert_equals(typeof screens[0].availTop, "number"); assert_equals(typeof screens[0].availTop, 'number');
assert_equals(typeof screens[0].left, "number"); assert_equals(typeof screens[0].left, 'number');
assert_equals(typeof screens[0].top, "number"); assert_equals(typeof screens[0].top, 'number');
assert_equals(typeof screens[0].orientation, "object"); assert_equals(typeof screens[0].orientation, 'object');
assert_equals(typeof screens[0].primary, "boolean"); assert_equals(typeof screens[0].primary, 'boolean');
assert_equals(typeof screens[0].internal, "boolean"); assert_equals(typeof screens[0].internal, 'boolean');
assert_equals(typeof screens[0].scaleFactor, "number"); assert_equals(typeof screens[0].scaleFactor, 'number');
assert_equals(typeof screens[0].id, "string"); assert_equals(typeof screens[0].id, 'string');
assert_equals(typeof screens[0].touchSupport, "boolean"); assert_equals(typeof screens[0].touchSupport, 'boolean');
}, "self.getScreens returns at least 1 Screen with permission granted"); }, 'getScreens() returns at least 1 Screen with permission granted');
promise_test(async testCase => { promise_test(async t => {
await test_driver.set_permission({name: 'window-placement'}, 'granted');
assert_greater_than((await self.getScreens()).length, 0);
await test_driver.set_permission({name: 'window-placement'}, 'denied'); await test_driver.set_permission({name: 'window-placement'}, 'denied');
const screens = await self.getScreens(); await promise_rejects_dom(t, 'NotAllowedError', self.getScreens());
assert_equals(screens.length, 0); }, 'getScreens() rejects the promise with permission denied');
}, 'self.getScreens returns no Screen objects with permission denied');
async_test(async t => {
await test_driver.set_permission({name: 'window-placement'}, 'granted');
let iframe = document.body.appendChild(document.createElement('iframe'));
assert_greater_than((await iframe.contentWindow.getScreens()).length, 0);
iframe.contentWindow.onunload = t.step_func(async () => {
// TODO(crbug.com/1106132): This should reject or resolve; not hang.
// assert_greater_than((await iframe.contentWindow.getScreens()).length, 0);
let iframeGetScreens = iframe.contentWindow.getScreens;
let constructor = iframe.contentWindow.DOMException;
assert_not_equals(iframeGetScreens, undefined);
assert_not_equals(constructor, undefined);
await t.step_wait(() => !iframe.contentWindow, "execution context invalid");
assert_equals(iframe.contentWindow, null);
await promise_rejects_dom(t, 'InvalidStateError', constructor, iframeGetScreens());
t.done();
});
document.body.removeChild(iframe);
}, "getScreens() resolves for attached iframe; rejects for detached iframe");

View file

@ -1,19 +1,37 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset='utf-8'>
<title>Screen Enumeration: getScreens() tentative</title> <title>Screen Enumeration: getScreens() tentative</title>
<!-- TODO: update link to W3C whenever specifications are ready --> <!-- TODO: update link to W3C whenever specifications are ready -->
<link rel="help" href="https://github.com/webscreens/screen-enumeration"/> <link rel='help' href='https://github.com/webscreens/screen-enumeration'/>
<script src="/resources/testharness.js"></script> <script src='/resources/testharness.js'></script>
<script src="/resources/testharnessreport.js"></script> <script src='/resources/testharnessreport.js'></script>
<script src="resources/screenenumeration-helpers.js"></script> <script src='resources/screenenumeration-helpers.js'></script>
<script> <script>
"use strict"; 'use strict';
function check_screen_matches_display(screen, display) {
assert_equals(screen.left, display.bounds.x);
assert_equals(screen.top, display.bounds.y);
assert_equals(screen.width, display.bounds.width);
assert_equals(screen.height, display.bounds.height);
assert_equals(screen.availLeft, display.workArea.x);
assert_equals(screen.availTop, display.workArea.y);
assert_equals(screen.availWidth, display.workArea.width);
assert_equals(screen.availHeight, display.workArea.height);
assert_equals(screen.scaleFactor, display.deviceScaleFactor);
}
screen_enumeration_test(async (t, mockScreenEnum) => {
mockScreenEnum.setSuccess(true);
await test_driver.set_permission({name: 'window-placement'}, 'granted');
assert_equals((await self.getScreens()).length, 0);
}, 'getScreens() supports an empty set of mocked screens');
screen_enumeration_test(async (t, mockScreenEnum) => { screen_enumeration_test(async (t, mockScreenEnum) => {
let display1 = makeDisplay(10, let display1 = makeDisplay(10,
{x: 0, y: 10, width: 1200, height: 800}, {x: 0, y: 0, width: 800, height: 600},
{x: 20, y: 30, width: 1000, height: 600}, {x: 0, y: 0, width: 800, height: 550},
1.0); 1.0);
mockScreenEnum.addDisplay(display1); mockScreenEnum.addDisplay(display1);
@ -21,43 +39,31 @@ screen_enumeration_test(async (t, mockScreenEnum) => {
mockScreenEnum.setInternalId(mockScreenEnum.displays_[0].id); mockScreenEnum.setInternalId(mockScreenEnum.displays_[0].id);
mockScreenEnum.setSuccess(true); mockScreenEnum.setSuccess(true);
// Grant window-placement permissions for testdriver. await test_driver.set_permission({name: 'window-placement'}, 'granted');
await test_driver.set_permission({name: "window-placement"}, "granted");
// This returns the mocked displays via MockScreenEnumeration implementation.
const screens = await self.getScreens(); const screens = await self.getScreens();
assert_equals(screens.length, 1); assert_equals(screens.length, 1);
check_screen_matches_display(screens[0], display1);
assert_equals(screens[0].left, 0);
assert_equals(screens[0].top, 10);
assert_equals(screens[0].width, 1200);
assert_equals(screens[0].height, 800);
assert_equals(screens[0].availLeft, 20);
assert_equals(screens[0].availTop, 30);
assert_equals(screens[0].availWidth, 1000);
assert_equals(screens[0].availHeight, 600);
assert_equals(screens[0].primary, true); assert_equals(screens[0].primary, true);
assert_equals(screens[0].internal, true); assert_equals(screens[0].internal, true);
assert_equals(screens[0].scaleFactor, 1.0); assert_equals(screens[0].id, '0');
assert_equals(screens[0].id, "0"); }, 'getScreens() supports a single mocked screen');
}, "getScreens() returns a single mocked screen");
screen_enumeration_test(async (t, mockScreenEnum) => { screen_enumeration_test(async (t, mockScreenEnum) => {
let display1 = makeDisplay(10, let display1 = makeDisplay(10,
{x: 0, y: 10, width: 1200, height: 800}, {x: 0, y: 0, width: 800, height: 600},
{x: 20, y: 30, width: 1000, height: 600}, {x: 0, y: 0, width: 800, height: 550},
1.0); 1.0);
let display2 = makeDisplay(11, let display2 = makeDisplay(11,
{x: 0, y: 10, width: 1200, height: 800}, {x: 800, y: 0, width: 800, height: 600},
{x: 20, y: 30, width: 1000, height: 600}, {x: 800, y: 0, width: 800, height: 550},
1.0); 2.0);
let display3 = makeDisplay(12, let display3 = makeDisplay(12,
{x: 0, y: 10, width: 1200, height: 800}, {x: 0, y: 600, width: 1200, height: 800},
{x: 20, y: 30, width: 1000, height: 600}, {x: 50, y: 50, width: 1150, height: 750},
1.0); 1.5);
mockScreenEnum.addDisplay(display1); mockScreenEnum.addDisplay(display1);
mockScreenEnum.addDisplay(display2); mockScreenEnum.addDisplay(display2);
@ -66,29 +72,42 @@ screen_enumeration_test(async (t, mockScreenEnum) => {
mockScreenEnum.setInternalId(mockScreenEnum.displays_[0].id); mockScreenEnum.setInternalId(mockScreenEnum.displays_[0].id);
mockScreenEnum.setSuccess(true); mockScreenEnum.setSuccess(true);
// Grant window-placement permissions for testdriver. await test_driver.set_permission({name: 'window-placement'}, 'granted');
await test_driver.set_permission({name: "window-placement"}, "granted");
// This returns the mocked displays via MockScreenEnumeration implementation.
let screens = await self.getScreens(); let screens = await self.getScreens();
assert_equals(screens.length, 3); assert_equals(screens.length, 3);
assert_equals(screens[0].id, "0"); check_screen_matches_display(screens[0], display1);
assert_equals(screens[1].id, "1"); assert_equals(screens[0].primary, true);
assert_equals(screens[2].id, "2"); assert_equals(screens[0].internal, true);
assert_equals(screens[0].id, '0');
check_screen_matches_display(screens[1], display2);
assert_equals(screens[1].primary, false);
assert_equals(screens[1].internal, false);
assert_equals(screens[1].id, '1');
check_screen_matches_display(screens[2], display3);
assert_equals(screens[2].primary, false);
assert_equals(screens[2].internal, false);
assert_equals(screens[2].id, '2');
mockScreenEnum.removeDisplay(display2.id); mockScreenEnum.removeDisplay(display2.id);
screens = await self.getScreens(); screens = await self.getScreens();
assert_equals(screens.length, 2); assert_equals(screens.length, 2);
assert_equals(screens[0].id, "0"); check_screen_matches_display(screens[0], display1);
assert_equals(screens[1].id, "1"); assert_equals(screens[0].id, '0');
check_screen_matches_display(screens[1], display3);
assert_equals(screens[1].id, '1');
mockScreenEnum.removeDisplay(display1.id); mockScreenEnum.removeDisplay(display1.id);
screens = await self.getScreens(); screens = await self.getScreens();
assert_equals(screens.length, 1); assert_equals(screens.length, 1);
assert_equals(screens[0].id, "0"); check_screen_matches_display(screens[0], display3);
}, "getScreens() supports multiple mocked screens"); assert_equals(screens[0].id, '0');
}, 'getScreens() supports multiple mocked screens');
screen_enumeration_test(async (t, mockScreenEnum) => {
mockScreenEnum.setSuccess(false);
await test_driver.set_permission({name: 'window-placement'}, 'granted');
promise_rejects_dom(t, 'NotAllowedError', self.getScreens());
}, 'getScreens() rejects when the mock success value is set to false');
</script> </script>

View file

@ -0,0 +1,40 @@
// META: global=window
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
'use strict';
promise_test(async t => {
assert_equals(typeof self.isMultiScreen, 'function');
}, 'isMultiScreen() is present');
promise_test(async t => {
await test_driver.set_permission({name: 'window-placement'}, 'granted');
assert_equals(typeof await self.isMultiScreen(), 'boolean');
}, 'isMultiScreen() returns a boolean value with permission granted');
promise_test(async t => {
await test_driver.set_permission({name: 'window-placement'}, 'denied');
assert_equals(typeof await self.isMultiScreen(), 'boolean');
}, 'isMultiScreen() returns a boolean value with permission denied');
async_test(async t => {
let iframe = document.body.appendChild(document.createElement('iframe'));
assert_equals(typeof await iframe.contentWindow.isMultiScreen(), 'boolean');
iframe.contentWindow.onunload = t.step_func(async () => {
// TODO(crbug.com/1106132): This should reject or resolve; not hang.
// assert_equals(typeof await iframe.contentWindow.isMultiScreen(), 'boolean');
let iframeIsMultiScreen = iframe.contentWindow.isMultiScreen;
let constructor = iframe.contentWindow.DOMException;
assert_not_equals(iframeIsMultiScreen, undefined);
assert_not_equals(constructor, undefined);
await t.step_wait(() => !iframe.contentWindow, "execution context invalid");
assert_equals(iframe.contentWindow, null);
await promise_rejects_dom(t, 'InvalidStateError', constructor, iframeIsMultiScreen());
t.done();
});
document.body.removeChild(iframe);
}, "isMultiScreen() resolves for attached iframe; rejects for detached iframe");

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<meta charset='utf-8'>
<title>Screen Enumeration: isMultiScreen() tentative</title>
<!-- TODO: update link to W3C whenever specifications are ready -->
<link rel='help' href='https://github.com/webscreens/screen-enumeration'/>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/screenenumeration-helpers.js'></script>
<script>
'use strict';
screen_enumeration_test(async (t, mockScreenEnum) => {
let display1 = makeDisplay(10,
{x: 0, y: 0, width: 800, height: 600},
{x: 0, y: 0, width: 800, height: 550},
1.0);
let display2 = makeDisplay(11,
{x: 800, y: 0, width: 800, height: 600},
{x: 800, y: 0, width: 800, height: 550},
2.0);
mockScreenEnum.setSuccess(true);
assert_equals(await self.isMultiScreen(), false);
mockScreenEnum.addDisplay(display1);
assert_equals(await self.isMultiScreen(), false);
mockScreenEnum.addDisplay(display2);
assert_equals(await self.isMultiScreen(), true);
mockScreenEnum.removeDisplay(display2.id);
assert_equals(await self.isMultiScreen(), false);
}, 'isMultiScreen() works as expected with mocked screens');
screen_enumeration_test(async (t, mockScreenEnum) => {
mockScreenEnum.setSuccess(false);
promise_rejects_dom(t, 'NotAllowedError', self.isMultiScreen());
}, 'isMultiScreen() rejects when the mock success value is set to false');
</script>

View file

@ -26,7 +26,12 @@ main () {
do do
EPOCH=$(get_epoch_timeval ${e}) EPOCH=$(get_epoch_timeval ${e})
EPOCH_BRANCH_NAME=$(get_epoch_branch_name ${e}) EPOCH_BRANCH_NAME=$(get_epoch_branch_name ${e})
git branch ${EPOCH_BRANCH_NAME} $(./wpt rev-list --epoch ${EPOCH}) EPOCH_SHA=$(./wpt rev-list --epoch ${EPOCH})
if [ "${EPOCH_SHA}" = "" ]; then
echo "ERROR: Empty SHA returned from ./wpt rev-list"
exit 1
fi
git branch "${EPOCH_BRANCH_NAME}" "${EPOCH_SHA}"
ALL_BRANCHES_NAMES="${ALL_BRANCHES_NAMES} ${EPOCH_BRANCH_NAME}" ALL_BRANCHES_NAMES="${ALL_BRANCHES_NAMES} ${EPOCH_BRANCH_NAME}"
done done
# This is safe because `git push` will by default fail for a non-fast-forward # This is safe because `git push` will by default fail for a non-fast-forward

View file

@ -48,6 +48,11 @@ if MYPY:
# ignores the error. # ignores the error.
Ignorelist = Dict[Text, Dict[Text, Set[Optional[int]]]] Ignorelist = Dict[Text, Dict[Text, Set[Optional[int]]]]
try:
from xml.etree import cElementTree as ElementTree
except ImportError:
from xml.etree import ElementTree as ElementTree # type: ignore
logger = None # type: Optional[logging.Logger] logger = None # type: Optional[logging.Logger]
@ -521,6 +526,9 @@ def check_parsed(repo_root, path, f):
if timeout_value != "long": if timeout_value != "long":
errors.append(rules.InvalidTimeout.error(path, (timeout_value,))) errors.append(rules.InvalidTimeout.error(path, (timeout_value,)))
required_elements = [] # type: List[Text]
testharnessreport_nodes = [] # type: List[ElementTree.Element]
if source_file.testharness_nodes: if source_file.testharness_nodes:
test_type = source_file.manifest_items()[0] test_type = source_file.manifest_items()[0]
if test_type not in ("testharness", "manual"): if test_type not in ("testharness", "manual"):
@ -543,31 +551,12 @@ def check_parsed(repo_root, path, f):
if variant != "" and variant[0] not in ("?", "#"): if variant != "" and variant[0] not in ("?", "#"):
errors.append(rules.MalformedVariant.error(path, (path,))) errors.append(rules.MalformedVariant.error(path, (path,)))
seen_elements = {"timeout": False, required_elements.extend(key for key, value in {"testharness": True,
"testharness": False, "testharnessreport": len(testharnessreport_nodes) > 0,
"testharnessreport": False} "timeout": len(source_file.timeout_nodes) > 0}.items()
required_elements = [key for key, value in {"testharness": True, if value)
"testharnessreport": len(testharnessreport_nodes) > 0,
"timeout": len(source_file.timeout_nodes) > 0}.items()
if value]
for elem in source_file.root.iter():
if source_file.timeout_nodes and elem == source_file.timeout_nodes[0]:
seen_elements["timeout"] = True
if seen_elements["testharness"]:
errors.append(rules.LateTimeout.error(path))
elif elem == source_file.testharness_nodes[0]:
seen_elements["testharness"] = True
elif testharnessreport_nodes and elem == testharnessreport_nodes[0]:
seen_elements["testharnessreport"] = True
if not seen_elements["testharness"]:
errors.append(rules.EarlyTestharnessReport.error(path))
if all(seen_elements[name] for name in required_elements):
break
testdriver_vendor_nodes = [] # type: List[ElementTree.Element]
if source_file.testdriver_nodes: if source_file.testdriver_nodes:
if len(source_file.testdriver_nodes) > 1: if len(source_file.testdriver_nodes) > 1:
errors.append(rules.MultipleTestdriver.error(path)) errors.append(rules.MultipleTestdriver.error(path))
@ -579,6 +568,38 @@ def check_parsed(repo_root, path, f):
if len(testdriver_vendor_nodes) > 1: if len(testdriver_vendor_nodes) > 1:
errors.append(rules.MultipleTestdriverVendor.error(path)) errors.append(rules.MultipleTestdriverVendor.error(path))
required_elements.append("testdriver")
if len(testdriver_vendor_nodes) > 0:
required_elements.append("testdriver-vendor")
if required_elements:
seen_elements = defaultdict(bool)
for elem in source_file.root.iter():
if source_file.timeout_nodes and elem == source_file.timeout_nodes[0]:
seen_elements["timeout"] = True
if seen_elements["testharness"]:
errors.append(rules.LateTimeout.error(path))
elif source_file.testharness_nodes and elem == source_file.testharness_nodes[0]:
seen_elements["testharness"] = True
elif testharnessreport_nodes and elem == testharnessreport_nodes[0]:
seen_elements["testharnessreport"] = True
if not seen_elements["testharness"]:
errors.append(rules.EarlyTestharnessReport.error(path))
elif source_file.testdriver_nodes and elem == source_file.testdriver_nodes[0]:
seen_elements["testdriver"] = True
elif testdriver_vendor_nodes and elem == testdriver_vendor_nodes[0]:
seen_elements["testdriver-vendor"] = True
if not seen_elements["testdriver"]:
errors.append(rules.EarlyTestdriverVendor.error(path))
if all(seen_elements[name] for name in required_elements):
break
for element in source_file.root.findall(".//{http://www.w3.org/1999/xhtml}script[@src]"): for element in source_file.root.findall(".//{http://www.w3.org/1999/xhtml}script[@src]"):
src = element.attrib["src"] src = element.attrib["src"]

View file

@ -242,6 +242,16 @@ class EarlyTestharnessReport(Rule):
to_fix = "flip the order" to_fix = "flip the order"
class EarlyTestdriverVendor(Rule):
name = "EARLY-TESTDRIVER-VENDOR"
description = collapse("""
Test file has an instance of
`<script src='/resources/testdriver-vendor.js'>` prior to
`<script src='/resources/testdriver.js'>`
""")
to_fix = "flip the order"
class MultipleTestdriver(Rule): class MultipleTestdriver(Rule):
name = "MULTIPLE-TESTDRIVER" name = "MULTIPLE-TESTDRIVER"
description = "More than one `<script src='/resources/testdriver.js'>`" description = "More than one `<script src='/resources/testdriver.js'>`"

View file

@ -337,6 +337,33 @@ def test_multiple_testharnessreport():
] ]
def test_early_testdriver_vendor():
code = b"""
<html xmlns="http://www.w3.org/1999/xhtml">
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver.js"></script>
</html>
"""
error_map = check_with_files(code)
for (filename, (errors, kind)) in error_map.items():
check_errors(errors)
if kind in ["web-lax", "web-strict"]:
assert errors == [
("EARLY-TESTDRIVER-VENDOR",
"Test file has an instance of "
"`<script src='/resources/testdriver-vendor.js'>` "
"prior to `<script src='/resources/testdriver.js'>`",
filename,
None),
]
elif kind == "python":
assert errors == [
("PARSE-FAILED", "Unable to parse file", filename, 2),
]
def test_multiple_testdriver(): def test_multiple_testdriver():
code = b""" code = b"""
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">

View file

@ -309,8 +309,8 @@ class FirefoxAndroid(BrowserSetup):
os.environ["ADB_PATH"] = adb_path os.environ["ADB_PATH"] = adb_path
adb_path = os.environ["ADB_PATH"] adb_path = os.environ["ADB_PATH"]
device = mozdevice.ADBDevice(adb=adb_path, device = mozdevice.ADBDeviceFactory(adb=adb_path,
device=kwargs["device_serial"]) device=kwargs["device_serial"])
if install: if install:
device.uninstall_app(app) device.uninstall_app(app)

View file

@ -14,6 +14,7 @@ class TestFileHandler(TestUsingServer):
self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.code, 404)
class TestRewriter(TestUsingServer): class TestRewriter(TestUsingServer):
def test_rewrite(self): def test_rewrite(self):
@wptserve.handlers.handler @wptserve.handlers.handler
@ -27,6 +28,7 @@ class TestRewriter(TestUsingServer):
self.assertEqual(200, resp.getcode()) self.assertEqual(200, resp.getcode())
self.assertEqual(b"/test/rewritten", resp.read()) self.assertEqual(b"/test/rewritten", resp.read())
class TestRequestHandler(TestUsingServer): class TestRequestHandler(TestUsingServer):
def test_exception(self): def test_exception(self):
@wptserve.handlers.handler @wptserve.handlers.handler
@ -40,6 +42,24 @@ class TestRequestHandler(TestUsingServer):
self.assertEqual(cm.exception.code, 500) self.assertEqual(cm.exception.code, 500)
def test_many_headers(self):
headers = {"X-Val%d" % i: str(i) for i in range(256)}
@wptserve.handlers.handler
def handler(request, response):
# Additional headers are added by urllib.request.
assert len(request.headers) > len(headers)
for k, v in headers.items():
assert request.headers.get(k) == \
wptserve.utils.isomorphic_encode(v)
return "OK"
route = ("GET", "/test/headers", handler)
self.server.router.register(*route)
resp = self.request("/test/headers", headers=headers)
self.assertEqual(200, resp.getcode())
class TestFileHandlerH2(TestUsingH2Server): class TestFileHandlerH2(TestUsingH2Server):
def test_not_handled(self): def test_not_handled(self):
self.conn.request("GET", "/not_existing") self.conn.request("GET", "/not_existing")
@ -47,6 +67,7 @@ class TestFileHandlerH2(TestUsingH2Server):
assert resp.status == 404 assert resp.status == 404
class TestRewriterH2(TestUsingH2Server): class TestRewriterH2(TestUsingH2Server):
def test_rewrite(self): def test_rewrite(self):
@wptserve.handlers.handler @wptserve.handlers.handler
@ -61,6 +82,7 @@ class TestRewriterH2(TestUsingH2Server):
assert resp.status == 200 assert resp.status == 200
assert resp.read() == b"/test/rewritten" assert resp.read() == b"/test/rewritten"
class TestRequestHandlerH2(TestUsingH2Server): class TestRequestHandlerH2(TestUsingH2Server):
def test_exception(self): def test_exception(self):
@wptserve.handlers.handler @wptserve.handlers.handler
@ -86,5 +108,6 @@ class TestRequestHandlerH2(TestUsingH2Server):
assert resp.status == 500 assert resp.status == 500
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View file

@ -1,7 +1,7 @@
import mock import mock
from six import binary_type from six import binary_type
from wptserve.request import Request, RequestHeaders from wptserve.request import Request, RequestHeaders, MultiDict
class MockHTTPMessage(dict): class MockHTTPMessage(dict):
@ -76,3 +76,30 @@ def test_request_url_from_host_header():
request = Request(request_handler) request = Request(request_handler)
assert request.url == 'http://web-platform.test:8001/demo' assert request.url == 'http://web-platform.test:8001/demo'
assert isinstance(request.url, str) assert isinstance(request.url, str)
def test_multidict():
m = MultiDict()
m["foo"] = "bar"
m["bar"] = "baz"
m.add("foo", "baz")
m.add("baz", "qux")
assert m["foo"] == "bar"
assert m.get("foo") == "bar"
assert m["bar"] == "baz"
assert m.get("bar") == "baz"
assert m["baz"] == "qux"
assert m.get("baz") == "qux"
assert m.first("foo") == "bar"
assert m.last("foo") == "baz"
assert m.get_list("foo") == ["bar", "baz"]
assert m.get_list("non_existent") == []
assert m.get("non_existent") is None
try:
m["non_existent"]
assert False, "An exception should be raised"
except KeyError:
pass

View file

@ -560,6 +560,17 @@ class MultiDict(dict):
return default return default
raise KeyError(key) raise KeyError(key)
# We need to explicitly override dict.get; otherwise, it won't call
# __getitem__ and would return a list instead.
def get(self, key, default=None):
"""Get the first value with a given key
:param key: The key to lookup
:param default: The default to return if key is
not found (None by default)
"""
return self.first(key, default)
def get_list(self, key): def get_list(self, key):
"""Get all values with a given key as a list """Get all values with a given key as a list

View file

@ -762,9 +762,10 @@ class ResponseWriter(object):
self.content_written = True self.content_written = True
try: try:
self._wfile.write(self.encode(data)) self._wfile.write(self.encode(data))
return True
except socket.error: except socket.error:
# This can happen if the socket got closed by the remote end # This can happen if the socket got closed by the remote end
pass return False
def write_content_file(self, data): def write_content_file(self, data):
"""Write a file-like object directly to the response in chunks. """Write a file-like object directly to the response in chunks.

View file

@ -29,6 +29,16 @@ from .router import Router
from .utils import HTTPException from .utils import HTTPException
from .constants import h2_headers from .constants import h2_headers
# We need to stress test that browsers can send/receive many headers (there is
# no specified limit), but the Python stdlib has an arbitrary limit of 100
# headers. Hitting the limit would produce an exception that is silently caught
# in Python 2 but leads to HTTP 431 in Python 3, so we monkey patch it higher.
# https://bugs.python.org/issue26586
# https://github.com/web-platform-tests/wpt/pull/24451
from six.moves import http_client
assert isinstance(getattr(http_client, '_MAXHEADERS'), int)
setattr(http_client, '_MAXHEADERS', 512)
""" """
HTTP server designed for testing purposes. HTTP server designed for testing purposes.

View file

@ -0,0 +1,25 @@
<!doctype html>
<title>AudioContext state around "allowed to start" in constructor</title>
<link rel=help href=https://webaudio.github.io/web-audio-api/#dom-audiocontext-audiocontext>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script>
setup({ single_test: true });
test_driver.bless("audio playback", () => {
const ctx = new AudioContext();
// Immediately after the constructor the state is "suspended" because the
// control message to start processing has just been sent, but the state
// should change soon.
assert_equals(ctx.state, "suspended", "initial state");
ctx.onstatechange = () => {
assert_equals(ctx.state, "running", "state after statechange event");
// Now create another context and ensure it starts out in the "suspended"
// state too, ensuring it's not synchronously "running".
const ctx2 = new AudioContext();
assert_equals(ctx2.state, "suspended", "initial state of 2nd context");
done();
};
});
</script>

View file

@ -194,3 +194,6 @@
[WebGL test #50: attachment 5 should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 1,1,0,0] [WebGL test #50: attachment 5 should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 1,1,0,0]
expected: FAIL expected: FAIL
[WebGL test #50: attachment 5 should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 0,0,0,255]
expected: FAIL