Update web-platform-tests to revision 4cec5596c806088cd8f1781bdaab1d10abb72394

This commit is contained in:
WPT Sync Bot 2020-03-11 08:18:58 +00:00
parent 58f3766c5b
commit 57fbf23022
95 changed files with 1292 additions and 700 deletions

View file

@ -16770,13 +16770,6 @@
null,
{}
]
],
"native_FileSystemWriter-manual.https.tentative.html": [
"fbfbd301e1659a7fac5273507358e4f712b53b3c",
[
null,
{}
]
]
},
"notifications": {
@ -236340,7 +236333,7 @@
}
},
".gitignore": [
"60d06876d962c726907f0bc0d5d46e1ae5382875",
"4f85ad3c52367e52f4b9d6c3a2bc24a49361da5b",
[]
],
".mailmap": [
@ -309660,7 +309653,7 @@
],
"admin": {
"index.md": [
"c711f7712dca9a53def0638269ec1155875f6cdc",
"98725bfa31b90162ae7fe9a3f381a8d9494db09c",
[]
]
},
@ -309974,6 +309967,28 @@
[]
]
},
"reporting": {
"oversized-images-reporting.html.headers": [
"206db539c1ea12e962b279e4b550e85f12bc50d1",
[]
],
"oversized.jpg": [
"497ed770bfb6fb367f2eeb1978225bc4d036055b",
[]
],
"unoptimized-image.jpg": [
"599137a55d710fe6b8d3052c05c81915622ea0d0",
[]
],
"unoptimized-lossy-images-reporting-onload.html.headers": [
"261d5db13e3c1879ba8a582e84485b717851dbb9",
[]
],
"unoptimized-lossy-images-reporting.html.headers": [
"261d5db13e3c1879ba8a582e84485b717851dbb9",
[]
]
},
"required-policy": {
"document-policy.html.headers": [
"d321c265d1502c364a8d1caa5ab24710e853983e",
@ -309987,6 +310002,12 @@
"0dcb2328ae7c48f451f43a7f89fcf90828d5f8a2",
[]
]
},
"resources": {
"document-policy-report-json.js": [
"035857ba39e8f18b308931520393b09dac4e6987",
[]
]
}
},
"dom": {
@ -312457,14 +312478,6 @@
"0e145978a014f08fb5faff42750e9338da0f9ede",
[]
],
"oversized-images-reporting.html.headers": [
"02bcbb92a866d3f3f423bf2ebb1a5cd45dcbf167",
[]
],
"oversized.jpg": [
"497ed770bfb6fb367f2eeb1978225bc4d036055b",
[]
],
"payment-report-only.https.html.headers": [
"dc41987d022b3d46bc7927480dc3174a7fa501ed",
[]
@ -312497,18 +312510,6 @@
"21a909e1fb6d84f066f42c09488f1bef032171c9",
[]
],
"unoptimized-image.jpg": [
"599137a55d710fe6b8d3052c05c81915622ea0d0",
[]
],
"unoptimized-lossy-images-reporting-onload.html.headers": [
"5cda6ae012803cdd9425cbcafcfd929921e06236",
[]
],
"unoptimized-lossy-images-reporting.html.headers": [
"5cda6ae012803cdd9425cbcafcfd929921e06236",
[]
],
"unsized-media-reporting.html.headers": [
"db2dcbc1929b9e1264855e9b80f77dfbda5d4f38",
[]
@ -315729,6 +315730,10 @@
"289659a41fdf41178781c764643f8946f4ec09b7",
[]
],
"reporting.https.html.sub.headers": [
"cda6ab2272fc4858f8ba4119d13ca07104c7601f",
[]
],
"require-corp-about-blank.html.headers": [
"8df98474b589d070992677cb0134bd47bd0509c4",
[]
@ -315807,7 +315812,15 @@
[]
],
"report.py": [
"8adf3009d08e2311cdf9c2008d7a10a0882ce030",
"17ca65cbf6b3f384dabff5a479eb22730d3de511",
[]
],
"reporting-empty-frame.html": [
"b1579add2e033e9dfc6c8bb18f9e523b246326ac",
[]
],
"reporting-empty-frame.html.headers": [
"66302f108fd5fc9142460a60f6f20b5303b46780",
[]
],
"require-corp-sw-import-scripts.js": [
@ -315830,18 +315843,6 @@
"9db755226020479fd87e87f42ea622c999b38f7d",
[]
],
"stash-take.py": [
"73e0def86caed347bf673b0daa8df46b9a4e074d",
[]
],
"subresource-corp.html": [
"4b029700e0e9a7545dae07df489eef7e32256030",
[]
],
"subresource-corp.html.sub.headers": [
"00609991031ea5a07c5a3fa802fcc73dcd00863e",
[]
],
"sw-store-to-cache-storage.js": [
"00b9e9395a7ec2171b3fee9d75f6ccb1d46ee60f",
[]
@ -316013,11 +316014,11 @@
[]
],
"common.js": [
"760db60365fbe79a70d37c770a48a162c5058002",
"fb517e8c40ac56587f21ecec2af7a5c30c3a191a",
[]
],
"coop-coep.py": [
"0271d7834af98a1d25fd2869c11c6f56b08bfcd3",
"8a7e0bc0a838fd7b432f40614212cfa63752a0e6",
[]
],
"iframe-popup.sub.html": [
@ -325727,7 +325728,7 @@
[]
],
"webxr.idl": [
"6734f5c209216d6912bdebeadd4afe2fb7dd728e",
"e95acca7ca3d1f8170cd0fd28d0281581fb59544",
[]
],
"worklets.idl": [
@ -326588,7 +326589,7 @@
[]
],
"common.js": [
"92ff11b35b1d6ab501a7b7dbac52411c08711a83",
"f7332a862277d44a70455f6b4edd57be8f10d98f",
[]
],
"grandchild.sub.html": [
@ -328652,7 +328653,7 @@
[]
],
"test-helpers.js": [
"d0360921f1d8ce7257bd7d6586d333b8534c620d",
"eb123bf6da6eec15ea9bb228c87fe6a799cf1f1e",
[]
]
},
@ -328718,7 +328719,7 @@
[]
],
"FileSystemFileHandle-getFile.js": [
"6b7d9f9a3171c96aaa2e1312451b3a9cac6c2e9b",
"80593418bb1622b76e440a1c55cd745c59b8a582",
[]
],
"FileSystemWritableFileStream-piped.js": [
@ -328732,10 +328733,6 @@
"FileSystemWritableFileStream.js": [
"778437e2a592120c05e8872ec11ab76986861023",
[]
],
"FileSystemWriter.js": [
"5e1f31942886e3f285af417c932a056e613fd24e",
[]
]
}
},
@ -329081,6 +329078,30 @@
"3d906d500ba797dd686c64ba1beb9d5fe11d3a28",
[]
],
"op11 no-ids.json": [
"0f3907bb3e61b60750762db1167611184cfcf384",
[]
],
"op12 empty-ids.json": [
"e5c31d2561c1a52ecd728239c20a96c7052804ba",
[]
],
"op13 empty-ids-after-nonempty.json": [
"773772457448691e1c82003aabbe484a10903aa3",
[]
],
"op14 non-array-id.json": [
"bc7cf74fbaa766c7bc6d5af4603fd23aa6bec999",
[]
],
"op15 mix-of-ids.json": [
"b49637dbd5c6cecbbbebdad0535895809e87f8c0",
[]
],
"op16 two-ids.json": [
"7a7d8398aa1b8a10c3b4235da35b0094ef5a2214",
[]
],
"op2 cspfp-double-top-level.json": [
"26d798b585d96fd29994dc39544a15bd2f6a639d",
[]
@ -329120,11 +329141,11 @@
},
"resources": {
"origin-policy-test-runner.js": [
"a1c6453debd20d7abc3923a273a0c1890dcab7a6",
"d3fd2e4ce11a7d18075c900a9087f47438d42c10",
[]
],
"subframe-with-origin-policy.py": [
"636a649a0e20bebe36ccd013b72b8e1f315d674e",
"258f23754ef7ef0b5c68f351c7c330c7e288c0c8",
[]
]
}
@ -329188,7 +329209,7 @@
[]
],
"utils.js": [
"6ccb5f6d7317a14547c755cdbf21c858b0d17a61",
"9375b175296c305c8c75eb0a6c618a7ff62364ee",
[]
]
}
@ -347939,7 +347960,7 @@
[]
],
"test_wpt.py": [
"c8adef557d01b126ba8b93e69733c2ff5e917053",
"b3e85fc293c315f960e3781033db25c963258bd9",
[]
]
},
@ -347960,7 +347981,7 @@
[]
],
"wpt.py": [
"49ee6345381450c4087423b2f7d1c9538f813c92",
"9abf2cb190088e583278aced87cd96838f0f841d",
[]
]
},
@ -355138,11 +355159,11 @@
[]
],
"referrer-tests.js": [
"b3c4a048f5a12350ce79ba93049d81858f54201f",
"10cfcf4b8b4c2b01d63b0bf9d5affc7945bfe0d7",
[]
],
"referrer-window.html": [
"934e3dc41b1cda364a00fe4fae0e4bc114e9c4b6",
"1d8d38b719be8de7676af20323943034ca1fa000",
[]
],
"service-worker-interception-tests.js": [
@ -363341,7 +363362,7 @@
]
],
"idbfactory_deleteDatabase4.htm": [
"73adb1a4d89f2e98a22342df7c4c934294a80003",
"2f680853b90d63b60696d47e0abdcdf02b3abae8",
[
null,
{}
@ -364572,7 +364593,7 @@
]
],
"idbtransaction.htm": [
"5baa3db557d0fa2a8a4ec33d1ce07f4646a47ccd",
"d5bafda1cab078afbb810e2d3efa258e4139c5e2",
[
null,
{}
@ -364593,7 +364614,7 @@
]
],
"idbversionchangeevent.htm": [
"e7ffecabd04fd553d31c896c6e82ec199c012c7f",
"fc4cd9a2f8765d331e43c3989f2b7c735f6dc444",
[
null,
{}
@ -365902,7 +365923,7 @@
]
],
"transaction-lifetime-blocked.htm": [
"79ba82f9baf8d4865705504d417bca5b3599b8b7",
"82c3ae032e8523d7da4ea8422588600373389411",
[
null,
{}
@ -365916,7 +365937,7 @@
]
],
"transaction-lifetime.htm": [
"28836448aca6925b4860f85b52c6c0dbac0214c9",
"2c8fd2f58089bf8752868bd3ceb7a5180fc79cf2",
[
null,
{}
@ -374918,9 +374939,77 @@
]
}
},
"getDevices": {
"granted-devices-with-services.https.window.js": [
"34b5912315ab843ec9c49dbf9ec41912325da2ca",
[
"bluetooth/getDevices/granted-devices-with-services.https.window.html",
{
"script_metadata": [
[
"script",
"/resources/testdriver.js"
],
[
"script",
"/resources/testdriver-vendor.js"
],
[
"script",
"/bluetooth/resources/bluetooth-helpers.js"
]
]
}
]
],
"no-granted-devices.https.window.js": [
"d945c3ff242c069027e5b6558c3c1fed9286e7b2",
[
"bluetooth/getDevices/no-granted-devices.https.window.html",
{
"script_metadata": [
[
"script",
"/resources/testdriver.js"
],
[
"script",
"/resources/testdriver-vendor.js"
],
[
"script",
"/bluetooth/resources/bluetooth-helpers.js"
]
]
}
]
],
"returns-same-bluetooth-device-object.https.window.js": [
"7c80703d5f5bb825b8d94f9c3a7fd7f2a7a6c7da",
[
"bluetooth/getDevices/returns-same-bluetooth-device-object.https.window.html",
{
"script_metadata": [
[
"script",
"/resources/testdriver.js"
],
[
"script",
"/resources/testdriver-vendor.js"
],
[
"script",
"/bluetooth/resources/bluetooth-helpers.js"
]
]
}
]
]
},
"idl": {
"idl-Bluetooth.https.html": [
"7322df53e5c227571d5155550e07aca4ed3688e5",
"60ec9aac26814fedf7e23f6a37431f99bd53f30f",
[
null,
{}
@ -407920,6 +408009,29 @@
]
]
},
"reporting": {
"oversized-images-reporting.html": [
"bef7db27a7ad821a5aa57164d407558b669c494f",
[
null,
{}
]
],
"unoptimized-lossy-images-reporting-onload.html": [
"948c43522567df041fde2bcad1ea5d8d450410d2",
[
null,
{}
]
],
"unoptimized-lossy-images-reporting.html": [
"d4b8611a19d097668624edb687c4da491db6ba6b",
[
null,
{}
]
]
},
"required-policy": {
"document-policy.html": [
"1935be3dd0a961add3d80aa35ded92734d9f8869",
@ -424465,13 +424577,6 @@
{}
]
],
"oversized-images-reporting.html": [
"ef365e060c4e4d883051c5ad70f10ffe9139d5a2",
[
null,
{}
]
],
"payment-report-only.https.html": [
"d2b8e5ee9cc017d3012a2cdd79143230495b4544",
[
@ -424536,20 +424641,6 @@
{}
]
],
"unoptimized-lossy-images-reporting-onload.html": [
"8c060477230c92c0932e73fbb91bf374316d2d9f",
[
null,
{}
]
],
"unoptimized-lossy-images-reporting.html": [
"8dcf110dd2b39f1b48e16d3aefbe53e9e7565ea5",
[
null,
{}
]
],
"unsized-media-reporting.html": [
"bb81a496ca5b8128b7438e6f1dd4ed0dd574238c",
[
@ -431646,7 +431737,7 @@
]
],
"none.https.html": [
"548525968352147dc14ceeeab1ad6b6a93b2729a",
"e603753084cf2c3c85b0187a7a8f66b3de8cf401",
[
null,
{
@ -431664,7 +431755,7 @@
]
],
"reporting.https.html": [
"3a0aebe49a7baf67ad2e3fc1ac57eb6bf3fbb5f2",
"bb0a6a2b0a8101665a25f2187c138ab0bdfd14e5",
[
null,
{}
@ -431713,7 +431804,7 @@
]
],
"require-corp.https.html": [
"6f799b6e4086c1e73654b694174cacc496b2582d",
"769bc87586d8038372255c27b6ce1db2fa3a6e51",
[
null,
{
@ -431992,7 +432083,7 @@
]
],
"popup-redirect-cache.https.html": [
"d68c80664bc549ca0e9786653bc0b3759ca31953",
"2ef7c0998af7835b0595f5eb2a6b7664841c59b2",
[
null,
{
@ -443698,7 +443789,7 @@
]
],
"referrer-origin-when-cross-origin.sub.html": [
"8351289029190f908c86ad507886ed393937ec45",
"4cd427ee88766f7f836ef86a3617244864ac5e40",
[
null,
{}
@ -443712,7 +443803,7 @@
]
],
"referrer-same-origin.sub.html": [
"1d470e668992ad546f721138441a80926dd630cb",
"7d6d515a477ce50cf2123745e29e5a3738a3eaf6",
[
null,
{}
@ -459035,47 +459126,6 @@
]
}
]
],
"sandboxed_FileSystemWriter.tentative.https.any.js": [
"8352e2487fe0823a2d353372757d833d85e98c4b",
[
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.html",
{
"script_metadata": [
[
"script",
"resources/test-helpers.js"
],
[
"script",
"resources/sandboxed-fs-test-helpers.js"
],
[
"script",
"script-tests/FileSystemWriter.js"
]
]
}
],
[
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.worker.html",
{
"script_metadata": [
[
"script",
"resources/test-helpers.js"
],
[
"script",
"resources/sandboxed-fs-test-helpers.js"
],
[
"script",
"script-tests/FileSystemWriter.js"
]
]
}
]
]
},
"navigation-timing": {
@ -471151,6 +471201,143 @@
{}
]
]
},
"idlharness.any.js": [
"c8ee8a326d1325ab38cae686c4647a81ec12e517",
[
"origin-policy/idlharness.any.html",
{
"script_metadata": [
[
"global",
"window,worker"
],
[
"script",
"/resources/WebIDLParser.js"
],
[
"script",
"/resources/idlharness.js"
]
]
}
],
[
"origin-policy/idlharness.any.serviceworker.html",
{
"script_metadata": [
[
"global",
"window,worker"
],
[
"script",
"/resources/WebIDLParser.js"
],
[
"script",
"/resources/idlharness.js"
]
]
}
],
[
"origin-policy/idlharness.any.sharedworker.html",
{
"script_metadata": [
[
"global",
"window,worker"
],
[
"script",
"/resources/WebIDLParser.js"
],
[
"script",
"/resources/idlharness.js"
]
]
}
],
[
"origin-policy/idlharness.any.worker.html",
{
"script_metadata": [
[
"global",
"window,worker"
],
[
"script",
"/resources/WebIDLParser.js"
],
[
"script",
"/resources/idlharness.js"
]
]
}
]
],
"ids": {
"empty-ids-after-nonempty.https.html": [
"3bffa9cffa713d49a78ce5effdb736ca07022da2",
[
null,
{}
]
],
"empty-ids.https.html": [
"385aa7c66fe639b3f7d52c7d936a0ed09522e131",
[
null,
{}
]
],
"mix-of-ids.https.html": [
"7be2c9f48df9fd192b4855e984cad13466caaf7b",
[
null,
{}
]
],
"no-ids.https.html": [
"1fe3d480d0acebeb869b82cc7838575a6d915bbb",
[
null,
{}
]
],
"non-array-id.https.html": [
"223b78f929c1346774fca040e767d93bc7605e40",
[
null,
{}
]
],
"same-object-returned.https.html": [
"9286f9f7344808c4fa548f47c675a9e963421229",
[
null,
{}
]
],
"still-present-in-http.html": [
"01969450f92aca7657b69fd1c58888d4627d58f6",
[
null,
{}
]
],
"two-ids.https.html": [
"630f07280790e0631fe1c2e795194bd541ffee72",
[
null,
{}
]
]
}
},
"page-visibility": {
@ -471244,6 +471431,13 @@
{}
]
],
"border-image.html": [
"636874817670489a47f23d0936a6a37dd5189594",
[
null,
{}
]
],
"buffered-flag.window.js": [
"4654c925ca0cf069d3b0a96f0daef25ef67ba187",
[
@ -471335,7 +471529,14 @@
]
],
"input-text.html": [
"38527a4c667061de54c385add53eeb49f0d6bbfd",
"e55c8d2d4747c1507636e6bfcd51158f37767522",
[
null,
{}
]
],
"mask-image.html": [
"35a6213f6ff817a1e8540f0663d9b8fc9f0eaa18",
[
null,
{}
@ -471348,6 +471549,13 @@
{}
]
],
"replaced-content-image.html": [
"244833ffdd07a67993b81d974254a1958dd28901",
[
null,
{}
]
],
"sibling-painting-first-image.html": [
"16a6f145db0265b60a10b5f7da9fab9dc97a946a",
[
@ -553273,6 +553481,13 @@
]
],
"protocol": {
"bundle.https.html": [
"fcc9d470b9f7c5c4215da09666e471dfa0a192d1",
[
null,
{}
]
],
"candidate-exchange.https.html": [
"b741de55eccd870e705324d3c75d2c06305e017a",
[
@ -559077,7 +559292,7 @@
]
},
"idlharness.https.window.js": [
"3e54e367787cb95dada398790fe23b10174df29f",
"04b2e3d91eb38acb512ec469b1bb261d8eb625b2",
[
"webxr/idlharness.https.window.html",
{

View file

@ -0,0 +1,4 @@
[granted-devices-with-services.https.window.html]
[getDevices() resolves with permitted devices that can be GATT connected to.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[no-granted-devices.https.window.html]
[getDevices() resolves with empty array if no device permissions have been granted.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[returns-same-bluetooth-device-object.https.window.html]
[multiple calls to getDevices() resolves with the sameBluetoothDevice objects for each granted Bluetooth device.]
expected: FAIL

View file

@ -0,0 +1,4 @@
[idl-Bluetooth.https.html]
[Bluetooth IDL test]
expected: FAIL

View file

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

View file

@ -2,6 +2,3 @@
[Hit test intersecting scaled box]
expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -0,0 +1,4 @@
[CaretPosition-001.html]
[Element at (400, 100)]
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]
expected: FAIL
[test some point of the element: top left corner]
expected: FAIL

View file

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

View file

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

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

View file

@ -18,3 +18,6 @@
[Set HTTP URL frame location.protocol to ftp]
expected: FAIL
[Set data URL frame location.protocol to file]
expected: FAIL

View file

@ -4,7 +4,7 @@
expected: FAIL
[Element with tabindex should support autofocus]
expected: FAIL
expected: TIMEOUT
[Host element with delegatesFocus including no focusable descendants should be skipped]
expected: NOTRUN
@ -16,5 +16,5 @@
expected: NOTRUN
[Non-HTMLElement should not support autofocus]
expected: TIMEOUT
expected: NOTRUN

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_escaping-3.html]
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]
expected: TIMEOUT

View file

@ -2,9 +2,9 @@
[Importing a same-origin descendant script from a same-origin top-level script with the same-origin policy.]
expected: FAIL
[Importing a same-origin descendant script from a remote-origin top-level script with the same-origin policy.]
expected: FAIL
[Importing a same-origin top-level script with the same-origin policy.]
expected: FAIL
[Importing a remote-origin descendant script from a remote-origin top-level script with the same-origin policy.]
expected: FAIL

View file

@ -50,3 +50,6 @@
[X Rendered audio for channel 5 does not equal [0,0.0626220703125,0.125030517578125,0.18695068359375,0.24810791015625,0.308319091796875,0.3673095703125,0.42486572265625,0.480743408203125,0.53472900390625,0.58660888671875,0.636199951171875,0.68328857421875,0.727691650390625,0.76922607421875,0.8077392578125...\] with an element-wise tolerance of {"absoluteThreshold":0.000030517578125,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t3.6732959747314453e-1\t6.2622070312500000e-2\t3.0470752716064453e-1\t4.8658168859649127e+0\t3.0517578125000000e-5\n\t[2\]\t6.8329977989196777e-1\t1.2503051757812500e-1\t5.5826926231384277e-1\t4.4650639949963384e+0\t3.0517578125000000e-5\n\t[3\]\t9.0373212099075317e-1\t1.8695068359375000e-1\t7.1678143739700317e-1\t3.8340669508039502e+0\t3.0517578125000000e-5\n\t[4\]\t9.9780619144439697e-1\t2.4810791015625000e-1\t7.4969828128814697e-1\t3.0216621502152523e+0\t3.0517578125000000e-5\n\t[5\]\t9.5236867666244507e-1\t3.0831909179687500e-1\t6.4404958486557007e-1\t2.0889059484187866e+0\t3.0517578125000000e-5\n\t...and 40513 more errors.\n\tMax AbsError of 1.9999977350234985e+0 at index of 36821.\n\t[36821\]\t9.9999773502349854e-1\t-1.0000000000000000e+0\t1.9999977350234985e+0\t1.9999977350234985e+0\t3.0517578125000000e-5\n\tMax RelError of Infinity at index of 14112.\n\t[14112\]\t-9.5105654001235962e-1\t0.0000000000000000e+0\t9.5105654001235962e-1\tInfinity\t3.0517578125000000e-5\n]
expected: FAIL
[X Rendered audio for channel 5 does not equal [0,0.0626220703125,0.125030517578125,0.18695068359375,0.24810791015625,0.308319091796875,0.3673095703125,0.42486572265625,0.480743408203125,0.53472900390625,0.58660888671875,0.636199951171875,0.68328857421875,0.727691650390625,0.76922607421875,0.8077392578125...\] with an element-wise tolerance of {"absoluteThreshold":0.000030517578125,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t3.6732959747314453e-1\t6.2622070312500000e-2\t3.0470752716064453e-1\t4.8658168859649127e+0\t3.0517578125000000e-5\n\t[2\]\t6.8329977989196777e-1\t1.2503051757812500e-1\t5.5826926231384277e-1\t4.4650639949963384e+0\t3.0517578125000000e-5\n\t[3\]\t9.0373212099075317e-1\t1.8695068359375000e-1\t7.1678143739700317e-1\t3.8340669508039502e+0\t3.0517578125000000e-5\n\t[4\]\t9.9780619144439697e-1\t2.4810791015625000e-1\t7.4969828128814697e-1\t3.0216621502152523e+0\t3.0517578125000000e-5\n\t[5\]\t9.5236867666244507e-1\t3.0831909179687500e-1\t6.4404958486557007e-1\t2.0889059484187866e+0\t3.0517578125000000e-5\n\t...and 40534 more errors.\n\tMax AbsError of 1.9986916780471802e+0 at index of 29020.\n\t[29020\]\t9.9994289875030518e-1\t-9.9874877929687500e-1\t1.9986916780471802e+0\t2.0011956154322119e+0\t3.0517578125000000e-5\n\tMax RelError of Infinity at index of 12348.\n\t[12348\]\t9.5105654001235962e-1\t0.0000000000000000e+0\t9.5105654001235962e-1\tInfinity\t3.0517578125000000e-5\n]
expected: FAIL

View file

@ -203,3 +203,6 @@
[X Stitched sine-wave buffers at sample rate 44100 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.000090957,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[31080\]\t1.9926784238063802e-24\t5.6332010030746460e-1\t5.6332010030746460e-1\t1.0000000000000000e+0\t9.0957000000000003e-5\n\t[31081\]\t4.5629080595344693e-41\t6.1397600173950195e-1\t6.1397600173950195e-1\t1.0000000000000000e+0\t9.0957000000000003e-5\n\tMax AbsError of 6.1397600173950195e-1 at index of 31081.\n\tMax RelError of 1.0000000000000000e+0 at index of 31080.\n]
expected: FAIL
[X Stitched sine-wave buffers at sample rate 44100 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.000090957,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[31080\]\t7.7856257262238438e-27\t5.6332010030746460e-1\t5.6332010030746460e-1\t1.0000000000000000e+0\t9.0957000000000003e-5\n\t[31081\]\t4.5762203949455551e-41\t6.1397600173950195e-1\t6.1397600173950195e-1\t1.0000000000000000e+0\t9.0957000000000003e-5\n\tMax AbsError of 6.1397600173950195e-1 at index of 31081.\n\tMax RelError of 1.0000000000000000e+0 at index of 31080.\n]
expected: FAIL

View file

@ -140,3 +140,24 @@
[XRSystem interface: operation requestSession(XRSessionMode, optional XRSessionInit)]
expected: FAIL
[XRPermissionStatus interface: attribute granted]
expected: FAIL
[XRPermissionStatus interface object length]
expected: FAIL
[XRPermissionStatus interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[XRPermissionStatus interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[XRPermissionStatus interface object name]
expected: FAIL
[XRPermissionStatus interface: existence and properties of interface prototype object]
expected: FAIL
[XRPermissionStatus interface: existence and properties of interface object]
expected: FAIL

View file

@ -6,7 +6,7 @@
.pytest_cache/
.tox/
.virtualenv/
_venv/
_venv*/
_virtualenv/
# Node

View file

@ -9,11 +9,14 @@
<script>
var t = async_test("Delete an existing database");
var t = async_test("Delete an existing database"),
dbname = location + '-' + t.name;
t.step(function() {
indexedDB.deleteDatabase(dbname);
var db;
var openrq = indexedDB.open('db', 3);
var openrq = indexedDB.open(dbname, 3);
openrq.onupgradeneeded = function(e) {
e.target.result.createObjectStore('store');
@ -36,7 +39,7 @@
});
function Second(e) {
var deleterq = indexedDB.deleteDatabase('db');
var deleterq = indexedDB.deleteDatabase(dbname);
deleterq.onsuccess = function(e) { t.done(); }

View file

@ -7,7 +7,9 @@
<script>
async_test(function(t) {
var open_rq = indexedDB.open("idbtransaction-" + document.location + t.name);
var dbname = "idbtransaction-" + document.location + t.name;
indexedDB.deleteDatabase(dbname);
var open_rq = indexedDB.open(dbname);
open_rq.onblocked = t.unreached_func('open_rq.onblocked');
open_rq.onerror = t.unreached_func('open_rq.onerror');
@ -31,7 +33,9 @@ async_test(function(t) {
}, document.title + " - request gotten by the handler");
async_test(function(t) {
var open_rq = indexedDB.open("idbtransaction-" + document.location + t.name);
var dbname = "idbtransaction-" + document.location + t.name;
indexedDB.deleteDatabase(dbname);
var open_rq = indexedDB.open(dbname);
assert_equals(open_rq.transaction, null, "IDBOpenDBRequest.transaction");
assert_equals(open_rq.source, null, "IDBOpenDBRequest.source");

View file

@ -13,10 +13,13 @@
<script>
var db,
t = async_test();
t = async_test(),
dbname = location + '-' + t.name;
t.step(function() {
var openrq = indexedDB.open('db', 3);
indexedDB.deleteDatabase(dbname);
var openrq = indexedDB.open(dbname, 3);
openrq.onupgradeneeded = t.step_func(function(e) {
assert_equals(e.oldVersion, 0, "old version (upgradeneeded)");
@ -48,7 +51,7 @@
});
function deleteDB (e) {
var deleterq = indexedDB.deleteDatabase('db');
var deleterq = indexedDB.deleteDatabase(dbname);
deleterq.onsuccess = t.step_func(function(e) {
assert_equals(e.result, undefined, "result (delete.success for nonexistent db)");

View file

@ -11,10 +11,13 @@
var db, db_got_versionchange, db2,
events = [],
t = async_test();
t = async_test(),
dbname = location + '-' + t.name;
t.step(function() {
var openrq = indexedDB.open('db', 3);
indexedDB.deleteDatabase(dbname);
var openrq = indexedDB.open(dbname, 3);
// 1
openrq.onupgradeneeded = t.step_func(function(e) {
@ -55,7 +58,7 @@
assert_equals(db + "", "[object IDBDatabase]");
assert_array_equals(db.objectStoreNames, [ "store" ]);
var openrq2 = indexedDB.open('db', 4);
var openrq2 = indexedDB.open(dbname, 4);
// 4
openrq2.onblocked = t.step_func(function(e) {
@ -102,7 +105,7 @@
// Cleanup
add_completion_callback(function(tests) {
if (db2) db2.close();
indexedDB.deleteDatabase('db');
indexedDB.deleteDatabase(dbname);
})
</script>

View file

@ -11,10 +11,13 @@
var db, db_got_versionchange, db2,
events = [],
t = async_test();
t = async_test(),
dbname = location + '-' + t.name;
t.step(function() {
var openrq = indexedDB.open('db', 3);
indexedDB.deleteDatabase(dbname);
var openrq = indexedDB.open(dbname, 3);
// 1
openrq.onupgradeneeded = t.step_func(function(e) {
@ -55,7 +58,7 @@
assert_equals(db + "", "[object IDBDatabase]");
assert_array_equals(db.objectStoreNames, [ "store" ]);
var openrq2 = indexedDB.open('db', 4);
var openrq2 = indexedDB.open(dbname, 4);
// 4
openrq2.onupgradeneeded = t.step_func(function(e) {
@ -95,7 +98,7 @@
// Cleanup
add_completion_callback(function(tests) {
if (db2) db2.close();
indexedDB.deleteDatabase('db');
indexedDB.deleteDatabase(dbname);
})
</script>

View file

@ -0,0 +1,71 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
// META: script=/bluetooth/resources/bluetooth-helpers.js
'use strict';
const test_desc = 'getDevices() resolves with permitted devices that can be ' +
'GATT connected to.';
bluetooth_test(async () => {
// Set up two connectable Bluetooth devices with their services discovered.
// One device is a Health Thermometer device with the 'health_thermometer'
// service while the other is a Heart Rate device with the 'heart_rate'
// service. Both devices contain the 'generic_access' service.
let fake_peripherals = await setUpHealthThermometerAndHeartRateDevices();
for (let fake_peripheral of fake_peripherals) {
await fake_peripheral.setNextGATTConnectionResponse({code: HCI_SUCCESS});
await fake_peripheral.addFakeService({uuid: 'generic_access'});
if (fake_peripheral.address === '09:09:09:09:09:09')
await fake_peripheral.addFakeService({uuid: 'health_thermometer'});
else
await fake_peripheral.addFakeService({uuid: 'heart_rate'});
await fake_peripheral.setNextGATTDiscoveryResponse({code: HCI_SUCCESS});
}
// Request the Health Thermometer device with access to its 'generic_access'
// service.
await requestDeviceWithTrustedClick(
{filters: [{name: 'Health Thermometer', services: ['generic_access']}]});
let devices = await navigator.bluetooth.getDevices();
assert_equals(
devices.length, 1,
`getDevices() should return the 'Health Thermometer' device.`);
// Only the 'generic_access' service can be accessed.
try {
await devices[0].gatt.connect();
await devices[0].gatt.getPrimaryService('generic_access');
assert_promise_rejects_with_message(
devices[0].gatt.getPrimaryService('health_thermometer'),
{name: 'SecurityError'});
} catch (err) {
assert_unreached(`${err.name}: ${err.message}`);
}
// Request the Heart Rate device with access to both of its services.
await requestDeviceWithTrustedClick({
filters: [{name: 'Heart Rate', services: ['generic_access', 'heart_rate']}]
});
devices = await navigator.bluetooth.getDevices();
assert_equals(
devices.length, 2,
`getDevices() should return the 'Health Thermometer' and 'Health ` +
`Monitor' devices`);
// All of Heart Rate device's services can be accessed, while only the
// 'generic_access' service can be accessed on Health Thermometer.
try {
for (let device of devices) {
await device.gatt.connect();
await device.gatt.getPrimaryService('generic_access');
if (device.name === 'Heart Rate') {
await device.gatt.getPrimaryService('heart_rate');
} else {
assert_promise_rejects_with_message(
devices[0].gatt.getPrimaryService('health_thermometer'),
{name: 'SecurityError'});
}
}
} catch (err) {
assert_unreached(`${err.name}: ${err.message}`);
}
}, test_desc);

View file

@ -0,0 +1,14 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
// META: script=/bluetooth/resources/bluetooth-helpers.js
'use strict';
const test_desc = 'getDevices() resolves with empty array if no device ' +
'permissions have been granted.';
bluetooth_test(async () => {
await navigator.bluetooth.test.simulateCentral({state: 'powered-on'});
let devices = await navigator.bluetooth.getDevices();
assert_equals(
0, devices.length, 'getDevices() should resolve with an empty array');
}, test_desc);

View file

@ -0,0 +1,22 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
// META: script=/bluetooth/resources/bluetooth-helpers.js
'use strict';
const test_desc = 'multiple calls to getDevices() resolves with the same' +
'BluetoothDevice objects for each granted Bluetooth device.';
bluetooth_test(async () => {
await getConnectedHealthThermometerDevice();
let firstDevices = await navigator.bluetooth.getDevices();
assert_equals(
firstDevices.length, 1, 'getDevices() should return the granted device.');
let secondDevices = await navigator.bluetooth.getDevices();
assert_equals(
secondDevices.length, 1,
'getDevices() should return the granted device.');
assert_equals(
firstDevices[0], secondDevices[0],
'getDevices() should produce the same BluetoothDevice objects for a ' +
'given Bluetooth device.');
}, test_desc);

View file

@ -16,6 +16,7 @@ test(() => {
// Bluetooth implements BluetoothDiscovery;
assert_true('requestDevice' in navigator.bluetooth);
assert_true('getDevices' in navigator.bluetooth);
assert_equals(navigator.bluetooth.requestDevice.length, 0);
}, test_desc);
</script>

View file

@ -35,8 +35,11 @@ explicitly-managed secret.
- web-human@w3.org
- [Google Domains](https://domains.google/): https://wpt.fyi
- foolip@google.com
- jeffcarp@google.com
- robertma@google.com
- mike@bocoup.com
- (Google internal): https://wpt.live https://wptpr.live
- foolip@google.com
- robertma@google.com
- [GitHub](https://github.com/): web-platform-tests
- [@foolip](https://github.com/foolip)
- [@Hexcles](https://github.com/Hexcles)
@ -48,14 +51,13 @@ explicitly-managed secret.
- [GitHub](https://github.com/): w3c
- [@plehegar](https://github.com/plehegar)
- [@sideshowbarker](https://github.com/sideshowbarker)
- [Google Cloud Platform](https://cloud.google.com/): wptdashboard
- boaz@bocoup.com
- [Google Cloud Platform](https://cloud.google.com/): wptdashboard{-staging}
- robertma@google.com
- smcgruer@google.com
- foolip@google.com
- geoffers@gmail.com
- jeffcarp@google.com
- markdittmer@google.com
- mike@bocoup.com
- rick@bocoup.com
- [Google Cloud Platform](https://cloud.google.com/): wpt-live
- smcgruer@google.com
- robertma@google.com
- [Google Cloud Platform](https://cloud.google.com/): wpt-pr-bot
- smcgruer@google.com
- robertma@google.com
@ -72,3 +74,21 @@ explicitly-managed secret.
[web-platform-tests]: https://github.com/e3c/web-platform-tests
[wpt.fyi]: https://github.com/web-platform-tests/wpt.fyi
## Emergency playbook
### Lock down write access to the repo
**Recommended but not yet verified approach:** Create a [new branch protection
rule](https://github.com/web-platform-tests/wpt/settings/branch_protection_rules/new)
that applies to `*` (i.e. all branches), and check "Restrict who can push to
matching branches". This should prevent everyone except those with the
"Maintain" role (currently only the GitHub admins listed above) from pushing
to *any* branch. To lift the limit, delete this branch protection rule.
**Alternative approach proven to work in
[#21424](https://github.com/web-platform-tests/wpt/issues/21424):** Go to
[manage access](https://github.com/web-platform-tests/wpt/settings/access),
and change the permission of "reviewers" to "Read". To lift the limit, change
it back to "Write". This has the known downside of *resubscribing all reviewers
to repo notifications*.

View file

@ -3,7 +3,7 @@
<head>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='../resources/feature-policy-report-json.js'></script>
<script src='../resources/document-policy-report-json.js'></script>
</head>
<body>
<img src="./oversized.jpg" alt="oversized image" width="50" height="50">
@ -13,7 +13,7 @@
t.step_func_done((reports, _) => {
assert_greater_than(reports.length, 0);
const report = reports[0];
assert_equals(report.type, "feature-policy-violation");
assert_equals(report.type, "document-policy-violation");
assert_equals(report.url, document.location.href);
const rbody = report.body;
assert_equals(rbody.featureId, "oversized-images");
@ -22,7 +22,7 @@
assert_equals(rbody.columnNumber, null);
check_report_json(reports[0]);
}),
{types: ['feature-policy-violation'], buffered: true}
{types: ['document-policy-violation'], buffered: true}
).observe();
},
"oversized-images Report Format")

View file

@ -0,0 +1 @@
Document-Policy: oversized-images;scale=2.0

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

View file

@ -11,7 +11,7 @@ image.src = "./unoptimized-image.jpg";
var check_report_format = (reports, observer) => {
let report = reports[0];
assert_equals(report.type, "feature-policy-violation");
assert_equals(report.type, "document-policy-violation");
assert_equals(report.url, document.location.href);
assert_equals(report.body.featureId, "unoptimized-lossy-images");
assert_equals(report.body.disposition, "enforce");
@ -19,7 +19,7 @@ var check_report_format = (reports, observer) => {
async_test(t => {
new ReportingObserver(t.step_func_done(check_report_format),
{types: ['feature-policy-violation'], buffered: true}).observe();
{types: ['document-policy-violation'], buffered: true}).observe();
}, "unoptimized-images Report Format");
</script>
</body>

View file

@ -0,0 +1 @@
Document-Policy: unoptimized-lossy-images;bpp=0.5

View file

@ -9,7 +9,7 @@
<script>
var check_report_format = (reports, observer) => {
let report = reports[0];
assert_equals(report.type, "feature-policy-violation");
assert_equals(report.type, "document-policy-violation");
assert_equals(report.url, document.location.href);
assert_equals(report.body.featureId, "unoptimized-lossy-images");
assert_equals(report.body.disposition, "enforce");
@ -20,7 +20,7 @@ var check_report_format = (reports, observer) => {
async_test(t => {
new ReportingObserver(t.step_func_done(check_report_format),
{types: ['feature-policy-violation'], buffered: true}).observe();
{types: ['document-policy-violation'], buffered: true}).observe();
}, "unoptimized-images Report Format");
</script>
</body>

View file

@ -0,0 +1 @@
Document-Policy: unoptimized-lossy-images;bpp=0.5

View file

@ -0,0 +1,20 @@
/**
* @fileoverview functions for ensuring document policy report is serializable
*/
const check_report_json = (report) => {
// Ensures toJSON method exists on report.
assert_equals(typeof report.toJSON, "function");
const report_json = report.toJSON();
// Ensures toJSON() call is successful.
assert_equals(report.type, report_json.type);
assert_equals(report.url, report_json.url);
assert_equals(report.body.featureId, report_json.body.featureId);
assert_equals(report.body.disposition, report_json.body.disposition);
assert_equals(report.body.sourceFile, report_json.body.sourceFile);
assert_equals(report.body.lineNumber, report_json.body.lineNumber);
assert_equals(report.body.columnNumber, report_json.body.columnNumber);
// Ensures JSON.stringify() serializes the report correctly.
assert_false(JSON.stringify(report) === "{}");
assert_equals(JSON.stringify(report), JSON.stringify(report_json));
}

View file

@ -1 +0,0 @@
Feature-Policy: oversized-images 'none'

View file

@ -1 +0,0 @@
Feature-Policy: unoptimized-lossy-images 'none'

View file

@ -1 +0,0 @@
Feature-Policy: unoptimized-lossy-images 'none'

View file

@ -84,8 +84,6 @@ async_test(t => {
assert_equals(win, null);
}, `"require-corp" top-level noopener popup: navigating to "none" should succeed`);
// CORP is checked because COEP of the frame is "require-corp". The parent
// frame's COEP value doesn't matter.
async_test(t => {
const frame = document.createElement("iframe");
const id = token();
@ -96,33 +94,8 @@ async_test(t => {
t.done();
}
}));
// REMOTE_ORIGIN is cross-origin, same-site.
frame.src = `${HOST.HTTPS_REMOTE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`;
document.body.append(frame);
}, 'CORP: same-site is checked and allowed.');
// CORP is checked because COEP of the frame is "require-corp". The parent
// frame's COEP value doesn't matter.
async_test(t => {
const frame = document.createElement("iframe");
const id = token();
t.add_cleanup(() => frame.remove());
let loaded = false;
window.addEventListener('message', t.step_func((e) => {
if (e.data === id) {
loaded = true;
}
}));
t.step_timeout(() => {
// Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a
// timeout is used here. Long term all network error handling should be similar and have a
// reliable event.
assert_false(loaded);
t.done();
}, 2000);
// NOTESAMESITE_ORIGIN is cross-origin, cross-site.
frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`;
document.body.append(frame);
}, 'CORP: same-site is checked and blocked.');
}, 'CORP: same-site is not checked.');
</script>

View file

@ -8,61 +8,139 @@
<script src="/common/get-host-info.sub.js"></script>
<script>
const HOST = get_host_info();
function getIframeUrl(filename, token1, token2) {
let query = `template=${filename}`;
if (token1) {
query += `&coep=${token1}`
}
if (token2) {
query += `&coep-report-only=${token2}`
}
return `resources/reporting-iframe.py?${query}`;
const REMOTE_ORIGIN = HOST.REMOTE_ORIGIN;
const BASE = new URL("resources", location).pathname
function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
}
function checkReports(reports, contextUrl) {
assert_not_equals(reports, null);
assert_equals(reports.length, 2);
assert_equals(reports[0].type, 'coep');
assert_equals(reports[0].url, contextUrl);
assert_equals(reports[0].body.type, 'corp');
assert_equals(reports[1].type, 'coep');
assert_equals(reports[1].url, contextUrl);
assert_equals(reports[1].body.type, 'corp');
async function pollReports(endpoint, reports) {
while (true) {
await wait(200);
const res = await fetch(`resources/report.py?endpoint=${endpoint}`, {cache: 'no-store'});
if (res.status !== 200) {
continue;
}
for (const report of await res.json()) {
reports.push(report);
}
}
}
// The order of the reports is non-deterministic.
const actualBlockedUrls = reports.map((r) => r.body['blocked-url']).sort();
const expectedBlockedUrls = [
`${HOST.REMOTE_ORIGIN}/common/text-plain.txt`,
`${HOST.ORIGIN}/common/redirect.py?location=${HOST.REMOTE_ORIGIN}/common/text-plain.txt`,
];
assert_array_equals(actualBlockedUrls.sort(), expectedBlockedUrls.sort());
let reports = []
let reportsForReportOnly = []
pollReports('endpoint', reports);
pollReports('report-only-endpoint', reportsForReportOnly);
function checkCorpReportExistence(reports, blockedUrl, contextUrl) {
blockedUrl = new URL(blockedUrl, location).href;
contextUrl = new URL(contextUrl, location).href;
for (const report of reports) {
if (report.type !== 'coep' || report.url !== contextUrl ||
report.body.type !== 'corp') {
continue;
}
if (report.body['blocked-url'] === blockedUrl) {
return;
}
}
assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`);
}
function checkReportNonExistence(reports, blockedUrl, contextUrl) {
blockedUrl = new URL(blockedUrl, location).href;
contextUrl = new URL(contextUrl, location).href;
for (const report of reports) {
if (report.type !== 'coep' || report.url !== contextUrl) {
continue;
}
assert_not_equals(report.body['blocked-url'], blockedUrl);
}
}
async_test(async (t) => {
try {
const iframe = document.createElement('iframe');
t.add_cleanup(() => iframe.remove());
const token1 = token();
const token2 = token();
iframe.src = `resources/subresource-corp.html?token1=${token1}&token2=${token2}`;
iframe.src = `resources/reporting-empty-frame.html`
document.body.appendChild(iframe);
await new Promise(resolve => {
iframe.addEventListener('load', resolve, {once: true});
});
function fetchInIframe(url) {
const init = { mode: 'no-cors', cache: 'no-store' };
iframe.contentWindow.fetch(url, init).catch(() => {});
}
const suffix = 'subresource-corp';
const sameOriginUrl = `/common/text-plain.txt?${suffix}`;
const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`;
const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`;
const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`;
const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`;
fetchInIframe(sameOriginUrl);
fetchInIframe(blockedByPureCorp);
fetchInIframe(blockedDueToCoep);
fetchInIframe(redirect);
await new Promise(resolve => t.step_timeout(resolve, 3000));
const res1 = await fetch(`resources/stash-take.py?key=${token1}`);
const res2 = await fetch(`resources/stash-take.py?key=${token2}`);
const reports = JSON.parse(await res1.text());
const reportsForReportOnly = JSON.parse(await res2.text());
checkReports(reports, iframe.src);
checkReports(reportsForReportOnly, iframe.src);
checkReportNonExistence(reports, sameOriginUrl, iframe.src);
checkReportNonExistence(reports, blockedByPureCorp, iframe.src);
checkCorpReportExistence(reports, blockedDueToCoep, iframe.src);
checkCorpReportExistence(reports, redirect, iframe.src);
checkReportNonExistence(reports, dest, iframe.src);
t.done();
} catch (e) {
t.step(() => { throw e });
};
}, 'report-to parameter for COEP and COEP-report-only');
}
}, 'subresource CORP');
async_test(async (t) => {
try {
const iframe = document.createElement('iframe');
t.add_cleanup(() => iframe.remove());
iframe.src = `resources/reporting-empty-frame.html`
document.body.appendChild(iframe);
await new Promise(resolve => {
iframe.addEventListener('load', resolve, {once: true});
});
const w = iframe.contentWindow;
function attachFrame(url) {
const frame = w.document.createElement('iframe');
frame.src = url;
w.document.body.appendChild(frame);
}
const suffix = 'navigation-corp';
const sameOrigin = `/common/blank.html?${suffix}`;
const blockedDueToCoep = `${REMOTE_ORIGIN}/common/blank.html?abc&${suffix}`;
const dest = `${REMOTE_ORIGIN}/common/blank.html?xyz&${suffix}`;
const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`;
attachFrame(sameOrigin);
attachFrame(blockedDueToCoep);
attachFrame(redirect);
await new Promise(resolve => t.step_timeout(resolve, 3000));
checkReportNonExistence(reports, sameOrigin, iframe.src);
checkCorpReportExistence(reports, blockedDueToCoep, iframe.src);
checkCorpReportExistence(reports, redirect, iframe.src);
checkReportNonExistence(reports, dest, iframe.src);
t.done();
} catch (e) {
t.step(() => { throw e });
}
}, 'navigation CORP');
</script>

View file

@ -0,0 +1 @@
report-to: { "group": "endpoint", "max_age": 10886400, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?endpoint=endpoint" }] }, { "group": "report-only-endpoint", "max_age": 10886400, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?endpoint=report-only-endpoint" }] }

View file

@ -232,4 +232,28 @@ async_test(t => {
document.body.append(frame);
}, 'navigation CORP is checked with the parent frame, not the navigation source - to be blocked');
async_test(t => {
const bc = new BroadcastChannel(token());
let loaded = false;
bc.onmessage = t.step_func((event) => {
loaded = true;
});
t.step_timeout(() => {
// Make sure the iframe didn't load. See
// https://github.com/whatwg/html/issues/125 for why a timeout is used
// here. Long term all network error handling should be similar and have a
// reliable event.
assert_false(loaded);
t.done();
}, 2000);
const dest = `${HOST.ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`;
const frame = document.createElement("iframe");
t.add_cleanup(() => frame.remove());
// |dest| is a same-origin URL and hence not blocked by CORP but reidirect.py
// is a cross-origin (actually cross-site) URL, so blocked by CORP.
frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}/common/redirect.py?location=${encodeURIComponent(dest)}`;
document.body.append(frame);
}, 'navigation CORP is checked for each redirect');
</script>

View file

@ -9,11 +9,29 @@ def main(request, response):
response.headers.set('Access-Control-Allow-Headers', 'content-type')
return ''
url_dir = '/'.join(request.url_parts.path.split('/')[:-1]) + '/'
key = request.GET.first('key')
reports = request.server.stash.take(key, url_dir) or []
uuidMap = {
'endpoint': '01234567-0123-0123-0123-0123456789AB',
'report-only-endpoint': '01234567-0123-0123-0123-0123456789CD'
}
response.headers.set('Access-Control-Allow-Origin', '*')
endpoint = request.GET.first('endpoint')
if endpoint not in uuidMap:
response.status = 400
return 'invalid endpoint'
path = '/'.join(request.url_parts.path.split('/')[:-1]) + '/'
key = uuidMap[endpoint]
if request.method == 'POST':
reports = request.server.stash.take(key, path) or []
for report in json.loads(request.body):
reports.append(report)
request.server.stash.put(key, reports, url_dir)
response.headers.set('Access-Control-Allow-Origin', '*')
request.server.stash.put(key, reports, path)
return 'done'
if request.method == 'GET':
return json.dumps(request.server.stash.take(key, path) or [])
response.status = 400
return 'invalid method'

View file

@ -0,0 +1,5 @@
<!doctype html>
<html>
<body>
</body>
</html>

View file

@ -0,0 +1,2 @@
cross-origin-embedder-policy: require-corp; report-to="endpoint"
cross-origin-embedder-policy-report-only: require-corp; report-to="report-only-endpoint";

View file

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

View file

@ -1,35 +0,0 @@
<!doctype html>
<html>
<script src="/common/get-host-info.sub.js"></script>
<script>
const HOST = get_host_info();
const current = new URL(window.location.href);
const token = current.searchParams.get("token");
const cache = 'no-store';
const mode = 'no-cors';
async function run() {
const init = { mode, cache };
// This is not blocked.
await fetch('/common/text-plain.txt', init);
// This is blocked but not due to COEP.
try {
await fetch('nothing-same-origin-corp.txt', init);
} catch (e) {
}
try {
await fetch(`${HOST.REMOTE_ORIGIN}/common/text-plain.txt`, init);
} catch (e) {
}
try {
await fetch(`/common/redirect.py?location=${HOST.REMOTE_ORIGIN}/common/text-plain.txt`, init);
} catch (e) {
}
}
run();
</script>
</html>

View file

@ -1,4 +0,0 @@
cache-control: no-store, no-cache
report-to: { "group": "endpoint", "max_age": 3600, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?key={{GET[token1]}}" }] }, { "group": "report-only-endpoint", "max_age": 3600, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?key={{GET[token2]}}" }] }
cross-origin-embedder-policy: require-corp; report-to="endpoint"
cross-origin-embedder-policy-report-only: require-corp; report-to="report-only-endpoint"

View file

@ -13,13 +13,11 @@ function url_test_cache(t, url, channelName, hasOpener) {
const bc = new BroadcastChannel(channelName);
bc.onmessage = t.step_func(event => {
const payload = event.data;
assert_equals(payload.name, hasOpener ? channelName : "");
assert_equals(payload.opener, hasOpener);
assert_equals(w.closed, !hasOpener);
validate_results(() => {
bc.close()
// test the same url for cache
url_test(t, url, channelName, hasOpener);
}, t, w, channelName, hasOpener, undefined /* OpenerDomAccess */, payload)
});
const w = window.open(url, channelName);

View file

@ -2,17 +2,38 @@ const SAME_ORIGIN = {origin: get_host_info().HTTPS_ORIGIN, name: "SAME_ORIGIN"};
const SAME_SITE = {origin: get_host_info().HTTPS_REMOTE_ORIGIN, name: "SAME_SITE"};
const CROSS_ORIGIN = {origin: get_host_info().HTTPS_NOTSAMESITE_ORIGIN, name: "CROSS_ORIGIN"}
function url_test(t, url, channelName, hasOpener, openerDOMAccess) {
const bc = new BroadcastChannel(channelName);
bc.onmessage = t.step_func_done(event => {
const payload = event.data;
function verify_window(callback, w, hasOpener) {
// If there's no opener, the w must be closed:
assert_equals(w.closed, !hasOpener, 'w.closed');
// Opener's access on w.length is possible only if hasOpener:
assert_equals(w.length, hasOpener? 1: 0, 'w.length');
callback();
}
function validate_results(callback, test, w, channelName, hasOpener, openerDOMAccess, payload) {
assert_equals(payload.name, hasOpener ? channelName : "", 'name');
assert_equals(payload.opener, hasOpener, 'opener');
// TODO(zcorpan): add openerDOMAccess expectations to all tests
if (openerDOMAccess !== undefined) {
assert_equals(payload.openerDOMAccess, openerDOMAccess, 'openerDOMAccess');
}
assert_equals(w.closed, !hasOpener, 'Openee browsing context closed');
// The window proxy in Chromium might still reflect the previous frame,
// until its unloaded. This delays the verification of w here.
if( !w.closed && w.length == 0) {
test.step_timeout( () => {
verify_window(callback, w, hasOpener);
}, 500);
} else {
verify_window(callback, w, hasOpener);
}
}
function url_test(t, url, channelName, hasOpener, openerDOMAccess) {
const bc = new BroadcastChannel(channelName);
bc.onmessage = t.step_func(event => {
const payload = event.data;
validate_results(() => { t.done(); }, t, w, channelName, hasOpener, openerDOMAccess, payload);
});
const w = window.open(url, channelName);

View file

@ -19,7 +19,7 @@ def main(request, response):
<!doctype html>
<meta charset=utf-8>
<script src="/common/get-host-info.sub.js"></script>
<iframe></iframe>
<body></body>
<script>
const params = new URL(location).searchParams;
const navHistory = params.get("navHistory");
@ -57,13 +57,14 @@ def main(request, response):
close();
}
});
const iframe = document.querySelector("iframe");
iframe = document.createElement("iframe");
iframe.onload = () => {
const payload = { name: self.name, opener: !!self.opener, openerDOMAccess: openerDOMAccessAllowed };
iframe.contentWindow.postMessage(payload, "*");
};
const channelName = new URL(location).searchParams.get("channel");
iframe.src = `${get_host_info().HTTPS_ORIGIN}/html/cross-origin-opener-policy/resources/postback.html?channel=${channelName}`;
document.body.appendChild(iframe);
}
</script>
"""

View file

@ -29,14 +29,15 @@ const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
test(t => {
assert_equals(
referrerSame, location.href,
"Referrer should be sent for the same-origin top-level script.");
"Full referrer should be sent for the same-origin top-level script.");
}, "Importing a same-origin top-level script with the " +
"origin-when-cross-origin policy.");
test(t => {
assert_equals(
referrerRemote, origin,
"Referrer should be sent for the remote-origin top-level script.");
"Referrer should be stripped to the origin when importing " +
"remote-origin top-level script.");
}, "Importing a remote-origin top-level script with the " +
"origin-when-cross-origin policy.");
@ -45,31 +46,34 @@ test(t => {
new URL("resources/import-referrer-checker.sub.js", location.href)
assert_equals(
referrerSameSame, scriptURL + "?name=same_same",
"Referrer should be sent for the same-origin descendant script.");
"Full referrer should be sent for same-origin descendant script" +
"imported by same-origin top-level script.");
}, "Importing a same-origin descendant script from a same-origin top-level " +
"script with the origin-when-cross-origin policy.");
test(t => {
assert_equals(
referrerSameRemote, origin,
"Referrer should be sent for the remote-origin descendant script.");
"Referrer should be stripped to the origin for the remote-origin " +
"descendant script imported from same-origin top-level script.");
}, "Importing a remote-origin descendant script from a same-origin top-level " +
"script with the origin-when-cross-origin policy.");
test(t => {
assert_equals(
referrerRemoteRemote, remoteOrigin,
"Referrer should be sent for the remote-origin descendant script.");
const scriptURL = new URL(
"html/semantics/scripting-1/the-script-element/module/resources/" +
"import-referrer-checker.sub.js",
remoteOrigin);
assert_equals(referrerRemoteRemote, scriptURL + "?name=remote_remote",
"Full referrer should be sent for the remote-origin descendant script " +
"imported from a remote-origin top-level script.");
}, "Importing a remote-origin descendant script from a remote-origin " +
"top-level script with the origin-when-cross-origin policy.");
test(t => {
const scriptURL = new URL(
"html/semantics/scripting-1/the-script-element/module/resources/" +
"import-same-origin-referrer-checker-from-remote-origin.sub.js",
remoteOrigin);
assert_equals(referrerRemoteSame, scriptURL + "?name=remote_same",
"Referrer should be sent for the same-origin descendant script.");
assert_equals(referrerRemoteSame, remoteOrigin,
"Referrer should be stripped to the origin for the same-origin " +
"descendant script imported by remote-origin top-level script.");
}, "Importing a same-origin descendant script from a remote-origin " +
"top-level script with the origin-when-cross-origin policy.");

View file

@ -54,22 +54,21 @@ test(t => {
"script with the same-origin policy.");
test(t => {
const scriptURL = new URL(
"html/semantics/scripting-1/the-script-element/module/resources/" +
"import-referrer-checker.sub.js", remoteOrigin);
assert_equals(
referrerRemoteRemote, "",
"Referrer should not be sent for the remote-origin descendant script " +
"even if it is imported from the script in the same remote-origin.");
referrerRemoteRemote, scriptURL + "?name=remote_remote",
"Referrer should be sent for the remote-origin descendant script " +
"when it is imported from a top-level script in the same remote-origin.");
}, "Importing a remote-origin descendant script from a remote-origin " +
"top-level script with the same-origin policy.");
test(t => {
const scriptURL = new URL(
"html/semantics/scripting-1/the-script-element/module/resources/" +
"import-same-origin-referrer-checker-from-remote-origin.sub.js",
remoteOrigin);
assert_equals(
referrerRemoteSame, scriptURL + "?name=remote_same",
"Referrer should be sent for the same-origin descendant script " +
"even if it is imported from the script in the remote-origin.");
referrerRemoteSame, "",
"Referrer should not be sent for the same-origin descendant script " +
"when it is imported from a top-level remote-origin script.");
}, "Importing a same-origin descendant script from a remote-origin " +
"top-level script with the same-origin policy.");

View file

@ -260,3 +260,13 @@ dictionary XRReferenceSpaceEventInit : EventInit {
required XRReferenceSpace referenceSpace;
XRRigidTransform transform;
};
dictionary XRPermissionDescriptor: PermissionDescriptor {
XRSessionMode mode;
sequence<any> requiredFeatures;
sequence<any> optionalFeatures;
};
interface XRPermissionStatus: PermissionStatus {
attribute FrozenArray<any> granted;
};

View file

@ -5,8 +5,10 @@ function checkMeasureMemoryBreakdown(breakdown, options) {
let allowed = new Set(options.allowed);
assert_own_property(breakdown, 'bytes');
assert_greater_than_equal(breakdown.bytes, 0);
assert_own_property(breakdown, 'type');
assert_equals(typeof breakdown.type, 'string');
assert_own_property(breakdown, 'userAgentSpecificTypes');
for (let userAgentSpecificType of breakdown.userAgentSpecificTypes) {
assert_equals(typeof userAgentSpecificType, 'string');
}
assert_own_property(breakdown, 'attribution');
for (let attribution of breakdown.attribution) {
assert_equals(typeof attribution, 'string');

View file

@ -1,10 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<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 src="resources/test-helpers.js"></script>
<script src="resources/native-fs-test-helpers.js"></script>
<script src="script-tests/FileSystemWriter.js"></script>

View file

@ -73,8 +73,8 @@ async function createEmptyFile(test, name, parent) {
async function createFileWithContents(test, name, contents, parent) {
const handle = await createEmptyFile(test, name, parent);
const writer = await handle.createWriter();
await writer.write(0, new Blob([contents]));
const writer = await handle.createWritable();
await writer.write(new Blob([contents]));
await writer.close();
return handle;
}

View file

@ -1,3 +0,0 @@
// META: script=resources/test-helpers.js
// META: script=resources/sandboxed-fs-test-helpers.js
// META: script=script-tests/FileSystemWriter.js

View file

@ -20,8 +20,8 @@ directory_test(async (t, root) => {
});
await timeout;
const writer = await handle.createWriter({keepExistingData: false});
await writer.write(0, new Blob(['foo']));
const writer = await handle.createWritable({keepExistingData: false});
await writer.write(new Blob(['foo']));
await writer.close();
file = await handle.getFile();

View file

@ -1,287 +0,0 @@
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'empty_blob', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob([]));
await writer.close();
assert_equals(await getFileContents(handle), '');
assert_equals(await getFileSize(handle), 0);
}, 'write() with an empty blob to an empty file');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'valid_blob', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['1234567890']));
await writer.close();
assert_equals(await getFileContents(handle), '1234567890');
assert_equals(await getFileSize(handle), 10);
}, 'write() a blob to an empty file');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'blob_with_offset', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['1234567890']));
await writer.write(4, new Blob(['abc']));
await writer.close();
assert_equals(await getFileContents(handle), '1234abc890');
assert_equals(await getFileSize(handle), 10);
}, 'write() called with a blob and a valid offset');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'bad_offset', root);
const writer = await handle.createWriter();
await promise_rejects_dom(
t, 'InvalidStateError', writer.write(4, new Blob(['abc'])));
await writer.close();
assert_equals(await getFileContents(handle), '');
assert_equals(await getFileSize(handle), 0);
}, 'write() called with an invalid offset');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'empty_string', root);
const writer = await handle.createWriter();
await writer.write(0, '');
await writer.close();
assert_equals(await getFileContents(handle), '');
assert_equals(await getFileSize(handle), 0);
}, 'write() with an empty string to an empty file');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'valid_utf8_string', root);
const writer = await handle.createWriter();
await writer.write(0, 'foo🤘');
await writer.close();
assert_equals(await getFileContents(handle), 'foo🤘');
assert_equals(await getFileSize(handle), 7);
}, 'write() with a valid utf-8 string');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'string_with_unix_line_ending', root);
const writer = await handle.createWriter();
await writer.write(0, 'foo\n');
await writer.close();
assert_equals(await getFileContents(handle), 'foo\n');
assert_equals(await getFileSize(handle), 4);
}, 'write() with a string with unix line ending preserved');
directory_test(async (t, root) => {
const handle =
await createEmptyFile(t, 'string_with_windows_line_ending', root);
const writer = await handle.createWriter();
await writer.write(0, 'foo\r\n');
await writer.close();
assert_equals(await getFileContents(handle), 'foo\r\n');
assert_equals(await getFileSize(handle), 5);
}, 'write() with a string with windows line ending preserved');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'empty_array_buffer', root);
const writer = await handle.createWriter();
let buf = new ArrayBuffer(0);
await writer.write(0, buf);
await writer.close();
assert_equals(await getFileContents(handle), '');
assert_equals(await getFileSize(handle), 0);
}, 'write() with an empty array buffer to an empty file');
directory_test(async (t, root) => {
const handle =
await createEmptyFile(t, 'valid_string_typed_byte_array', root);
const writer = await handle.createWriter();
let buf = new ArrayBuffer(3);
let intView = new Uint8Array(buf);
intView[0] = 0x66;
intView[1] = 0x6f;
intView[2] = 0x6f;
await writer.write(0, buf);
await writer.close();
assert_equals(await getFileContents(handle), 'foo');
assert_equals(await getFileSize(handle), 3);
}, 'write() with a valid typed array buffer');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'trunc_shrink', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['1234567890']));
await writer.truncate(5);
await writer.close();
assert_equals(await getFileContents(handle), '12345');
assert_equals(await getFileSize(handle), 5);
}, 'truncate() to shrink a file');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'trunc_grow', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['abc']));
await writer.truncate(5);
await writer.close();
assert_equals(await getFileContents(handle), 'abc\0\0');
assert_equals(await getFileSize(handle), 5);
}, 'truncate() to grow a file');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'parent_dir', root);
const file_name = 'create_writer_fails_when_dir_removed.txt';
const handle = await createEmptyFile(t, file_name, dir);
await root.removeEntry('parent_dir', {recursive: true});
await promise_rejects_dom(t, 'NotFoundError', handle.createWriter());
}, 'createWriter() fails when parent directory is removed');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'parent_dir', root);
const file_name = 'write_fails_when_dir_removed.txt';
const handle = await createEmptyFile(t, file_name, dir);
const writer = await handle.createWriter();
await root.removeEntry('parent_dir', {recursive: true});
await promise_rejects_dom(t, 'NotFoundError', writer.write(0, new Blob(['foo'])));
}, 'write() fails when parent directory is removed');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'parent_dir', root);
const file_name = 'truncate_fails_when_dir_removed.txt';
const handle = await createEmptyFile(t, file_name, dir);
const writer = await handle.createWriter();
await root.removeEntry('parent_dir', {recursive: true});
await promise_rejects_dom(t, 'NotFoundError', writer.truncate(0));
}, 'truncate() fails when parent directory is removed');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'parent_dir', root);
const file_name = 'close_fails_when_dir_removed.txt';
const handle = await createEmptyFile(t, file_name, dir);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['foo']));
await root.removeEntry('parent_dir', {recursive: true});
await promise_rejects_dom(t, 'NotFoundError', writer.close());
}, 'atomic writes: close() fails when parent directory is removed');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'atomic_writes.txt', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['foox']));
const writer2 = await handle.createWriter();
await writer2.write(0, new Blob(['bar']));
assert_equals(await getFileSize(handle), 0);
await writer2.close();
assert_equals(await getFileContents(handle), 'bar');
assert_equals(await getFileSize(handle), 3);
await writer.close();
assert_equals(await getFileContents(handle), 'foox');
assert_equals(await getFileSize(handle), 4);
}, 'atomic writes: writers make atomic changes on close');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'atomic_write_after_close.txt', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['foo']));
await writer.close();
assert_equals(await getFileContents(handle), 'foo');
assert_equals(await getFileSize(handle), 3);
await promise_rejects_dom(
t, 'InvalidStateError', writer.write(0, new Blob(['abc'])));
}, 'atomic writes: write() after close() fails');
directory_test(async (t, root) => {
const handle =
await createEmptyFile(t, 'atomic_truncate_after_close.txt', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['foo']));
await writer.close();
assert_equals(await getFileContents(handle), 'foo');
assert_equals(await getFileSize(handle), 3);
await promise_rejects_dom(t, 'InvalidStateError', writer.truncate(0));
}, 'atomic writes: truncate() after close() fails');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'atomic_close_after_close.txt', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['foo']));
await writer.close();
assert_equals(await getFileContents(handle), 'foo');
assert_equals(await getFileSize(handle), 3);
await promise_rejects_dom(t, 'InvalidStateError', writer.close());
}, 'atomic writes: close() after close() fails');
directory_test(async (t, root) => {
const handle = await createEmptyFile(t, 'there_can_be_only_one.txt', root);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['foo']));
// This test might be flaky if there is a race condition allowing
// close() to be called multiple times.
let success_promises =
[...Array(100)].map(() => writer.close().then(() => 1).catch(() => 0));
let close_attempts = await Promise.all(success_promises);
let success_count = close_attempts.reduce((x, y) => x + y);
assert_equals(success_count, 1);
}, 'atomic writes: only one close() operation may succeed');
directory_test(async (t, root) => {
const handle = await createFileWithContents(
t, 'atomic_file_is_copied.txt', 'fooks', root);
const writer = await handle.createWriter({keepExistingData: true});
await writer.write(0, new Blob(['bar']));
await writer.close();
assert_equals(await getFileContents(handle), 'barks');
assert_equals(await getFileSize(handle), 5);
}, 'createWriter({keepExistingData: true}): atomic writer initialized with source contents');
directory_test(async (t, root) => {
const handle = await createFileWithContents(
t, 'atomic_file_is_not_copied.txt', 'very long string', root);
const writer = await handle.createWriter({keepExistingData: false});
await writer.write(0, new Blob(['bar']));
assert_equals(await getFileContents(handle), 'very long string');
await writer.close();
assert_equals(await getFileContents(handle), 'bar');
assert_equals(await getFileSize(handle), 3);
}, 'createWriter({keepExistingData: false}): atomic writer initialized with empty file');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'parent_dir', root);
const file_name = 'atomic_writer_persists_removed.txt';
const handle = await createFileWithContents(t, file_name, 'foo', dir);
const writer = await handle.createWriter();
await writer.write(0, new Blob(['bar']));
await dir.removeEntry(file_name);
await promise_rejects_dom(t, 'NotFoundError', getFileContents(handle));
await writer.close();
assert_equals(await getFileContents(handle), 'bar');
assert_equals(await getFileSize(handle), 3);
}, 'atomic writes: writer persists file on close, even if file is removed');

View file

@ -0,0 +1,17 @@
// META: global=window,worker
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
'use strict';
idl_test(
['origin-policy'],
['html', 'dom'],
idl_array => {
if (self.Window) {
idl_array.add_objects({ Window: ['self'] });
} else {
idl_array.add_objects({ WorkerGlobalScope: ['self'] });
}
}
);

View file

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with empty-array "ids" member that occurs after a non-empty "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op13",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with empty-array "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op12",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy must include valid IDs and exclude non-strings and invalid strings</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op15",
testJS: "../content-security/resources/disallow-unsafe-eval-disallow-images.mjs",
expectedIds: [
"my-policy-1",
"my-policy-2",
"~",
" ",
"!\"#$%&'()*+,-./:;<=>?@{|}~",
"azAZ",
"my~policy"
]
});
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy with no "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op11",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy a non-array "ids" member must be ignored</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op14",
testJS: "../content-security/resources/allow-unsafe-eval.mjs",
expectedIds: []
});
</script>

View file

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>originPolicyIds must return the same object each time</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
// Failing this test is a common failure mode for FrozenArray attributes,
// so let's be sure implementations get it right.
assert_equals(window.originPolicyIds, window.originPolicyIds);
});
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>originPolicyIds must return an empty array in http: pages</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
assert_equals(location.protocol, "http:");
}, "Prerequisite check: running on HTTP, not HTTPS");
test(() => {
assert_array_equals(window.originPolicyIds, []);
}, "The attribute is still present and returns an empty frozen array");
</script>

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Origin policy second "ids" member must take precedence</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/origin-policy-test-runner.js"></script>
<div id="log"></div>
<script>
"use strict";
runTestsInSubframe({
hostname: "op16",
testJS: "../content-security/resources/disallow-unsafe-eval-disallow-images.mjs",
expectedIds: [
"3",
"4"
]
});
</script>

View file

@ -0,0 +1,7 @@
{
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -0,0 +1,8 @@
{
"ids": [],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -0,0 +1,11 @@
{
"ids": [
"this should be overwritten by the subsequent one"
],
"ids": [],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -0,0 +1,8 @@
{
"ids": "this is not an array",
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'"
]
}
}

View file

@ -0,0 +1,28 @@
{
"ids": [
"my-policy-1",
["my-policy-array"],
5,
null,
{ "id": "my-policy-object" },
"my-policy-2",
true,
"~",
" ",
"\u0000",
"\t",
"my\tpolicy",
"!\"#$%&'()*+,-./:;<=>?@{|}~",
"my\u007Fpolicy",
"azAZ",
"my\u0080policy",
"my~policy",
"my\u1234policy"
],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'",
"img-src 'none'"
]
}
}

View file

@ -0,0 +1,16 @@
{
"ids": [
"1",
"2"
],
"ids": [
"3",
"4"
],
"content_security": {
"policies": [
"script-src 'self' 'unsafe-inline'",
"img-src 'none'"
]
}
}

View file

@ -1,4 +1,4 @@
window.runTestsInSubframe = ({ hostname, testJS }) => {
window.runTestsInSubframe = ({ hostname, testJS, expectedIds }) => {
test(() => {
assert_equals(location.protocol, "https:");
}, "Prerequisite check: running on HTTPS");
@ -12,6 +12,8 @@ window.runTestsInSubframe = ({ hostname, testJS }) => {
// to themselves.
url.searchParams.append("test", new URL(testJS, document.baseURI).pathname);
url.searchParams.append("expectedIds", JSON.stringify(expectedIds));
const iframe = document.createElement("iframe");
iframe.src = url.href;

View file

@ -9,10 +9,12 @@ def main(request, response):
"""
test_file = request.GET.first("test")
expected_ids = request.GET.first("expectedIds")
response.headers.set("Origin-Policy", "allowed=(latest)")
response.headers.set("Content-Type", "text/html")
return """
ret_val = """
<!DOCTYPE html>
<meta charset="utf-8">
<title>Origin policy subframe</title>
@ -24,3 +26,14 @@ def main(request, response):
<script type="module" src="%s"></script>
""" % test_file
if expected_ids != "undefined":
ret_val += """
<script type="module">
test(() => {
assert_array_equals(originPolicyIds, %s);
}, "Expected originPolicyIDs check");
</script>
""" % expected_ids
return ret_val

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<style>
#bordered {
width: 100px;
height: 100px;
border: 30px solid transparent;
border-image-source: url(resources/circle.svg);
border-image-width: 0px;
}
</style>
<div id='bordered'></div>
<script>
promise_test(async t => {
const onload = new Promise(r => window.addEventListener('load', r));
await onload;
return assertNoFirstContentfulPaint(t).then(() => {
document.getElementById('bordered').style.borderImageWidth = '30px';
}).then(() => {
return assertFirstContentfulPaint(t);
});
}, 'Border image triggers First Contentful Paint.');
</script>
</body>

View file

@ -7,13 +7,13 @@
<input type="text" id='myInput'>
</form>
<script>
promise_test(async () => {
promise_test(async t => {
const onload = new Promise(r => window.addEventListener('load', r));
await onload;
return assertNoFirstContentfulPaint().then(() => {
return assertNoFirstContentfulPaint(t).then(() => {
document.getElementById('myInput').value = 'default text';
return assertFirstContentfulPaint();
})
return assertFirstContentfulPaint(t);
});
}, 'Text from a form control triggers First Contentful Paint.');
</script>
</body>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<style>
#masked {
width: 0px;
height: 100px;
-webkit-mask-image: url(resources/circle.svg);
mask-image: url(resources/circle.svg);
}
</style>
<div id='masked'></div>
<script>
promise_test(async t => {
const onload = new Promise(r => window.addEventListener('load', r));
await onload;
return assertNoFirstContentfulPaint(t).then(() => {
document.getElementById('masked').style.width = '100px';
}).then(() => {
return assertFirstContentfulPaint(t);
});
}, 'Mask image triggers First Contentful Paint.');
</script>
</body>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<style>
img {
content: url(resources/circle.svg);
}
</style>
<img></img>
<script>
promise_test(async t => {
const onload = new Promise(r => window.addEventListener('load', r));
await onload;
return assertFirstContentfulPaint(t);
}, 'Replaced content image triggers First Contentful Paint.');
</script>
</body>

View file

@ -1,8 +1,15 @@
// We use requestAnimationFrame() calls to force the user agent to paint. Hence, set
// |numFramesWaiting| to 3 and use that constant whenever the test needs to wait for
// the next paint to occur.
// Number milliseconds to wait for CSS resources to load.
const numMillisecondsWait = 50;
// We use requestAnimationFrame() calls to force the user agent to paint and give enough
// time for FCP to show up in the performance timeline. Hence, set |numFramesWaiting| to
// 3 and use that constant whenever the test needs to wait for the next paint to occur.
const numFramesWaiting = 3;
function waitTime(t) {
return new Promise(resolve => t.step_timeout(resolve, numMillisecondsWait));
}
function waitForAnimationFrames(count) {
return new Promise(resolve => {
if (count-- <= 0) {
@ -15,8 +22,11 @@ function waitForAnimationFrames(count) {
});
}
function assertNoFirstContentfulPaint() {
return waitForAnimationFrames(numFramesWaiting).then(() => {
// Asserts that there is currently no FCP reported, even after some wait.
function assertNoFirstContentfulPaint(t) {
return waitTime(t).then(() => {
return waitForAnimationFrames(numFramesWaiting);
}).then(() => {
return new Promise((resolve, reject) => {
const observer = new PerformanceObserver(entryList =>{
const entries = entryList.getEntriesByName('first-contentful-paint');
@ -33,8 +43,12 @@ function assertNoFirstContentfulPaint() {
});
}
function assertFirstContentfulPaint() {
return waitForAnimationFrames(numFramesWaiting).then(() => {
// Asserts that FCP is reported, possibly after some wait. The wait is needed
// because sometimes the FCP relies on some CSS resources to finish loading.
function assertFirstContentfulPaint(t) {
return waitTime(t).then(() => {
return waitForAnimationFrames(numFramesWaiting);
}).then(() => {
return new Promise((resolve, reject) => {
const observer = new PerformanceObserver(entryList =>{
const entries = entryList.getEntriesByName('first-contentful-paint');

View file

@ -240,9 +240,9 @@ def test_run_verify_unstable(temp_test):
@pytest.mark.remote_network
def test_install_chromedriver():
if sys.platform == "win32":
chromedriver_path = os.path.join(wpt.localpaths.repo_root, "_venv", "Scripts", "chromedriver.exe")
chromedriver_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "Scripts", "chromedriver.exe")
else:
chromedriver_path = os.path.join(wpt.localpaths.repo_root, "_venv", "bin", "chromedriver")
chromedriver_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "bin", "chromedriver")
if os.path.exists(chromedriver_path):
os.unlink(chromedriver_path)
with pytest.raises(SystemExit) as excinfo:
@ -258,9 +258,9 @@ def test_install_chromedriver():
reason="https://github.com/web-platform-tests/wpt/issues/17074")
def test_install_firefox():
if sys.platform == "darwin":
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app")
fx_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "Firefox Nightly.app")
else:
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox")
fx_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "firefox")
if os.path.exists(fx_path):
shutil.rmtree(fx_path)
with pytest.raises(SystemExit) as excinfo:

View file

@ -108,13 +108,15 @@ def create_complete_parser():
return parser
def venv_dir():
return "_venv" + str(sys.version_info[0])
def setup_virtualenv(path, skip_venv_setup, props):
if skip_venv_setup and path is None:
raise ValueError("Must set --venv when --skip-venv-setup is used")
should_skip_setup = path is not None and skip_venv_setup
if path is None:
path = os.path.join(wpt_root, "_venv")
path = os.path.join(wpt_root, venv_dir())
venv = virtualenv.Virtualenv(path, should_skip_setup)
if not should_skip_setup:
venv.start()

View file

@ -0,0 +1,52 @@
<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection BUNDLE</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../RTCPeerConnection-helper.js"></script>
<script>
'use strict';
promise_test(async t => {
const caller = new RTCPeerConnection();
t.add_cleanup(() => caller.close());
const callee = new RTCPeerConnection();
t.add_cleanup(() => callee.close());
const stream = await getNoiseStream({audio: true, video: true});
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
stream.getTracks().forEach(track => caller.addTrack(track, stream));
let metadataToBeLoaded;
callee.ontrack = (e) => {
const stream = e.streams[0];
const v = document.createElement('video');
v.autoplay = true;
v.srcObject = stream;
v.id = stream.id
metadataToBeLoaded = new Promise((resolve) => {
v.addEventListener('loadedmetadata', () => {
resolve();
});
});
};
exchangeIceCandidates(caller, callee);
const offer = await caller.createOffer();
// remove the a=group:BUNDLE from the SDP when signaling.
const sdp = offer.sdp.replace(/a=group:BUNDLE (.*)\r\n/, '');
await callee.setRemoteDescription({type: 'offer', sdp});
await caller.setLocalDescription(offer);
const answer = await callee.createAnswer();
await caller.setRemoteDescription(answer);
await callee.setLocalDescription(answer);
await metadataToBeLoaded;
const senders = caller.getSenders();
const dtlsTransports = senders.map(s => s.transport);
assert_equals(dtlsTransports.length, 2);
assert_not_equals(dtlsTransports[0], dtlsTransports[1]);
const iceTransports = dtlsTransports.map(t => t.iceTransport);
assert_equals(iceTransports.length, 2);
assert_not_equals(iceTransports[0], iceTransports[1]);
}, 'not negotiating BUNDLE creates two separate ice and dtls transports');
</script>

View file

@ -7,7 +7,7 @@
idl_test(
['webxr'],
['webgl1', 'html', 'dom'],
['permissions', 'webgl1', 'html', 'dom'],
async idl_array => {
idl_array.add_objects({
Navigator: ['navigator'],

View file

@ -188,7 +188,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'remote',
descendant: 'same' } });
}, 'Importing a same-origin script from a remote-origin worklet script ' +
'that has "same-origin" referrer policy should send referrer.');
'that has "same-origin" referrer policy should not send referrer.');
promise_test(() => {
return runReferrerTest({ workletType: workletType,
@ -197,7 +197,7 @@ function runReferrerTests(workletType) {
scriptOrigins: { topLevel: 'remote',
descendant: 'remote' } });
}, 'Importing a remote-origin script from a remote-origin worklet script ' +
'that has "same-origin" referrer policy should not send referrer.');
'that has "same-origin" referrer policy should send referrer.');
// TODO(domfarolino): Add tests for more referrer policies.
}

View file

@ -51,8 +51,10 @@ function createScriptURLForDecendant(scriptOrigins) {
function isDestinationCrossOrigin(fetchType, scriptOrigins) {
if (fetchType === 'top-level')
return scriptOrigins.topLevel === 'remote';
// Compute a descendant's cross-origin-ness relative to the top-level script.
if (fetchType === 'descendant')
return scriptOrigins.descendant === 'remote';
return scriptOrigins.descendant !== scriptOrigins.topLevel;
assert_unreached('fetchType has an invalid value.');
}