Update web-platform-tests to revision 6c36430fc9e5ae99b06eba617f557e0271dd78b7

This commit is contained in:
WPT Sync Bot 2020-08-14 08:19:33 +00:00
parent 216c13cdc4
commit 594dfab11c
142 changed files with 987 additions and 9381 deletions

View file

@ -1,4 +0,0 @@
[hit-test-floats-003.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

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

View file

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

View file

@ -0,0 +1,10 @@
[Event-dispatch-click.html]
[event state during post-click handling]
expected: FAIL
[disabled radio should be checked from dispatchEvent(new MouseEvent("click"))]
expected: FAIL
[disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))]
expected: FAIL

View file

@ -315,15 +315,18 @@
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<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>: combined response Content-Type: text/html;x=" text/plain]
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain ]
expected: FAIL

View file

@ -56,6 +56,9 @@
[separate text/javascript x/x]
expected: FAIL
[separate text/javascript error]
[separate text/javascript;charset=windows-1252 error text/javascript]
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!]
expected: FAIL
[X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_3.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

@ -1,4 +0,0 @@
[creating_browsing_context_test_01.html]
[first argument: absolute url]
expected: FAIL

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,13 +1,14 @@
[htmlanchorelement_noopener.html]
expected: TIMEOUT
[Check that targeting of rel=noopener with a given name reuses an existing window with that name]
expected: FAIL
[Check that rel=noopener with target=_top does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_self does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[077.html]
[ adding several types of scripts through the DOM and removing some of them confuses scheduler ]
expected: FAIL

View file

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

View file

@ -0,0 +1,7 @@
[xrSession_requestSessionDuringEnd.https.html]
[Create new session in OnSessionEnded event]
expected: FAIL
[Create mew session in end promise]
expected: FAIL

View file

@ -15751,6 +15751,13 @@
{}
]
],
"historical-manual.html": [
"0e2147222d9435793374e37bdf1cb49796749711",
[
null,
{}
]
],
"relatedTarget-attribute-manual.html": [
"c5a897d68e4cd79265d99bb0f637feaf144f6cd4",
[
@ -16081,7 +16088,7 @@
},
"the-dragevent-interface": {
"dragevent-manual.html": [
"aafe83205fdf3fda301caba3a5313a9a177771b6",
"e4d754e459077bbe5dcb59d0ca9ab2d92fa3bdfd",
[
null,
{}
@ -245365,40 +245372,6 @@
}
}
},
"webgpu": {
"webgpu": {
"web-platform": {
"reftests": {
"canvas_clear.html": [
"86a3da939dbe94efbeec04e5d366a40736ca4560",
[
null,
[
[
"/webgpu/webgpu/web-platform/reftests/ref/canvas_clear-ref.html",
"=="
]
],
{}
]
],
"canvas_complex_bgra8unorm.html": [
"1310543648e4fd640b0deb227000731af7b88b00",
[
null,
[
[
"/webgpu/webgpu/web-platform/reftests/ref/canvas_complex-ref.html",
"=="
]
],
{}
]
]
}
}
}
},
"webvtt": {
"rendering": {
"cues-with-video": {
@ -248892,7 +248865,7 @@
]
},
"support-promises.js": [
"8195be341e18860865c072bc78a1efa1f25f2d56",
"9128bfe151ab9cda59ff6e3d4487024b0b7cd0cb",
[]
],
"support.js": [
@ -330366,7 +330339,7 @@
[]
],
"build.sh": [
"ae1563ad85de7f5cc502d75b079121236de9b249",
"f69fa4ff17d9ffe18559c34546139872c6a8e2e2",
[]
],
"current-work-canvas.xhtml": [
@ -341389,7 +341362,7 @@
]
},
"lint.ignore": [
"6b79e8a757ddbc16278511d0ace1a69720f5bdb9",
"a17a09402e01ca07a56b8270d1ec45f745377544",
[]
],
"loading": {
@ -351367,11 +351340,11 @@
[]
],
"lint.py": [
"8a1149c7f054c897163c9310f335ec2183259afc",
"7bec438b773da96e30986aa974b66043248bc079",
[]
],
"rules.py": [
"1bf78b7bb405f132536d162ba920dd2de9e08f09",
"f6e23aef58ad3a97a0ba8bf5514cb802f2e0f31b",
[]
],
"tests": {
@ -351576,7 +351549,7 @@
[]
],
"test_path_lints.py": [
"7368216cd3dd6ba54843cfe7390b876a357d3490",
"9fefb7a1d7e0615044ae00acb0b8e64481e41b97",
[]
]
}
@ -358091,7 +358064,7 @@
[]
],
"executormarionette.py": [
"05223d374feb7bfeea1321d2ec8fbd99fa9fddb7",
"1ba9f06aabc8cf10e91cf3aa92643562f05a1c1a",
[]
],
"executoropera.py": [
@ -360637,7 +360610,7 @@
[]
],
"test_actions_wdspec.html": [
"39a8876e54ad183b900acbb552a5930b5b4b83fd",
"0253add960792f79bef8a8747dac26661c4a2f86",
[]
]
}
@ -360804,357 +360777,13 @@
[]
],
"META.yml": [
"befe8a68dd5d060da9480f9a967fd11060281967",
"163130faea362a087959cee4cfbaba729893e225",
[]
],
"README.md": [
"ef0dbfee60ce3e787131ca40e5be64952e578e03",
"24a68b3ad3e89ea6617f02d90c890c1d04cf717e",
[]
],
"common": {
"framework": {
"file_loader.js": [
"0f25ca465d3df9231ad1faecd4373305ee423847",
[]
],
"fixture.js": [
"ef23f06596bd7cc244484102008db8ca9485c2c8",
[]
],
"gpu": {
"device_pool.js": [
"848e5802817b43e26c8e25ecfec48c0ea9fe8816",
[]
],
"implementation.js": [
"670872b5d6e32ebf3815935fdd9fec605056a30c",
[]
]
},
"logging": {
"log_message.js": [
"11f352f892e76eb0140f0fe36249f41e103e1e05",
[]
],
"logger.js": [
"8d66c554c5ad8b48df127d914883fc8f4578bc38",
[]
],
"result.js": [
"813e781ba28ce0471d17d439c0fc20ed400f68ac",
[]
],
"test_case_recorder.js": [
"d16af0f2b861421cb77050648440ae4e4fbd3d39",
[]
]
},
"params_builder.js": [
"10dd239df93c6ce1a9ae8559586c6c304b3243e2",
[]
],
"params_utils.js": [
"161feb5d4306ea30ae56c7ba6f76ac81f90a25ba",
[]
],
"query": {
"compare.js": [
"52396f352e64e13e30d9823f04e55525be38624e",
[]
],
"encode_selectively.js": [
"e153cf8ccd89b8e6bfb0346581e0139eed865565",
[]
],
"parseQuery.js": [
"758227cc520f486f4a0662d0935eaa86a1aa937b",
[]
],
"query.js": [
"8b352241f8b95b1caa60ac331e7f4c47b5236c64",
[]
],
"separators.js": [
"e378a9d1d290de77dfc46f00e8afa644ce13cb18",
[]
],
"stringify_params.js": [
"b5503ffb54ead8677dfb5189aecd9e46fcf30cad",
[]
],
"validQueryPart.js": [
"3c051afc94b46f2500b13eafceac6a8dc0171c3e",
[]
]
},
"test_group.js": [
"5ced9cd3d372ad9b5d6e1ad3f240554e2bab490b",
[]
],
"test_suite_listing.js": [
"99c900217c1463e09faefd01e0db96498db7ca92",
[]
],
"tree.js": [
"69dfac21a635c278dae9daab4c8adb81aec550d9",
[]
],
"util": {
"async_mutex.js": [
"cb900605bcfe77bae785c207419787e317bf1d73",
[]
],
"collect_garbage.js": [
"d4b5bb19b233f4306241973e5d7935af715f7141",
[]
],
"stack.js": [
"99653f888066181e5fbac7a7a4331f6cb4fe3ecb",
[]
],
"timeout.js": [
"e565a518efc045cfc90e7dd7b23dc65604c6b805",
[]
],
"util.js": [
"b64379982a60f7b4551b7611feb7fdcf288d560e",
[]
]
},
"version.js": [
"4b233137825b86fb1d70896601d6e63a4f42865d",
[]
]
},
"runtime": {
"helper": {
"options.js": [
"1a90beadf1ee459911b2b549fc9359b44fe37bbd",
[]
],
"test_worker-worker.js": [
"a02c98c2bbfbc27ae109fed082702f5367b2afad",
[]
],
"test_worker.js": [
"7e8b9a47c077261e8dcacb21487989edbd146e2c",
[]
]
},
"wpt.js": [
"dc38b77b1d5ad3517f0463285f35881cf28aee08",
[]
]
}
},
"webgpu": {
"api": {
"operation": {
"buffers": {
"create_mapped.spec.js": [
"1c3b1254d503727d9efd189ec6b9eba5bac3a79b",
[]
],
"map.spec.js": [
"e8c86ec1b8a4539742d10309967b1d0578b38cee",
[]
],
"map_detach.spec.js": [
"8ae0be0b197ac1ae1a6bac48dacd00ecc8ec2a9e",
[]
],
"map_oom.spec.js": [
"8494dc7ddc769f166a6422531d34565cd4810a16",
[]
],
"mapping_test.js": [
"b7349059035d46dffc1156314c7dfe7ec7526d54",
[]
]
},
"command_buffer": {
"basic.spec.js": [
"547a08683f7318d5aceb2e26096166c1c994c579",
[]
],
"copies.spec.js": [
"cc2ea6deae161d2025119beda183dfb767b63795",
[]
],
"render": {
"basic.spec.js": [
"815eb5b70b0092c096fe385ad94729f62ef44761",
[]
]
}
},
"fences.spec.js": [
"f9f079b6241fa99a6895250329b18fb88d895ac3",
[]
],
"resource_init": {
"copied_texture_clear.spec.js": [
"f5b8b697d74e75ecd2e5fb149f29d69e8c6c3610",
[]
],
"texture_zero_init_test.js": [
"8dda949f85954069826ee50aa5b58933b5fc8e3f",
[]
]
}
},
"validation": {
"createBindGroup.spec.js": [
"5deed893d5e4ef039d25479b63c2a35892e81d17",
[]
],
"createBindGroupLayout.spec.js": [
"2fec032c178f8be0b92ef45278d39886ad9cfc8d",
[]
],
"createPipelineLayout.spec.js": [
"4e293fa725dfe18f789f4fb7afaf0fad4a0cd14c",
[]
],
"createTexture.spec.js": [
"2ef8d19523311d64519af8ecff18d27ac9695749",
[]
],
"createView.spec.js": [
"3ad1ca97d7d069b6fd6fd0fb216051a0c6dbf742",
[]
],
"error_scope.spec.js": [
"3edbec2dc417fc4cb95ab67baefc1d0f1a798154",
[]
],
"fences.spec.js": [
"2ab0691e3ce6cadb532a94a43d568b8a111a8430",
[]
],
"queue_submit.spec.js": [
"24e386b9d22c2bbea0fca8e8b5c94c770e8ed7d5",
[]
],
"render_pass_descriptor.spec.js": [
"3c1b111fea4a79aab8cd8defbc61152e7e5302ea",
[]
],
"setBindGroup.spec.js": [
"95786a8f78d3a6fe230d6a08c3cfb83c93a97666",
[]
],
"setBlendColor.spec.js": [
"469641df04341795efdad946ea65eb517a51265c",
[]
],
"setScissorRect.spec.js": [
"8381865a6938c4a32d81744fb1bbaaf41ae309fb",
[]
],
"setStencilReference.spec.js": [
"f205239d86142ea08880f226f9d9ae052a385aa1",
[]
],
"setViewport.spec.js": [
"f1168c11086fd4fa7114c36b9895bab49b66a410",
[]
],
"validation_test.js": [
"17eb97bcc63daafbda34a661bafd0da688d7bb8b",
[]
]
}
},
"capability_info.js": [
"47d508ac3e3c5abfe9d2c4da3ab1ee412dec8030",
[]
],
"examples.spec.js": [
"28b9ae47f2c25183ba68b1bcb7303a033541213b",
[]
],
"gpu_test.js": [
"e740af1113b88f548768c33a0d378490d3d8320b",
[]
],
"idl": {
"constants": {
"flags.spec.js": [
"5a6d7868aa531677f8660768ce87a73564727314",
[]
]
},
"idl_test.js": [
"0665ad208cd8453352a1c4a030614b40b3783de7",
[]
]
},
"listing.js": [
"a8b67e72547db017720f5e7fb4e88f024eab2bf4",
[]
],
"util": {
"conversion.js": [
"73c04fe56badcff5aee3bf665465b24c81d4f3bf",
[]
],
"math.js": [
"19720d631c55590bfbfc223e9c6409eded4d6232",
[]
],
"texture": {
"layout.js": [
"425aa2020d75eace60d793d9148cc9cd531af475",
[]
],
"subresource.js": [
"04a8e7221a8ad8a9f76369d4e3f2ffa4fe21a056",
[]
],
"texelData.js": [
"2ea7275e710a5e47a59480ca2a56c1026172e6bf",
[]
]
}
},
"web-platform": {
"canvas": {
"context_creation.spec.js": [
"427b15fced447160db36ca3d6f829211f5080206",
[]
]
},
"copyImageBitmapToTexture.spec.js": [
"efdc21ded93736439f8112c35e9a39600b07739c",
[]
],
"reftests": {
"canvas_clear.js": [
"52ffaedad84c7552fd13cbac89cd800c09a012c0",
[]
],
"canvas_complex.js": [
"1e63a0ab20233e9db7e9c628493af178edd386c9",
[]
],
"gpu_ref_test.js": [
"f45f232557cdd05406317b3a521d06e3e1bbd960",
[]
],
"ref": {
"canvas_clear-ref.html": [
"2e0781186273ac49d6c70b5e5a9c68103aa5f173",
[]
],
"canvas_complex-ref.html": [
"3d5b3b3376d23cfdcda57f0c53fc3192e8a77bb6",
[]
]
}
}
}
}
]
},
"webmessaging": {
"META.yml": [
@ -368531,7 +368160,7 @@
]
],
"idbobjectstore_putall.tentative.any.js": [
"a312d71d03d59c5c9369afa1492aacd0e91e9a5d",
"26bcc87a4c3234c2de5699c5443d75b4419eab02",
[
"IndexedDB/idbobjectstore_putall.tentative.any.html",
{
@ -416222,7 +415851,7 @@
]
],
"Event-dispatch-click.html": [
"7690f753d9cd0b47f2c2c25352576caed970cd19",
"4b07103027139b4d7679da4e50eb3d82ab8b12d2",
[
null,
{}
@ -432154,7 +431783,7 @@
]
],
"event-counts-zero.html": [
"3ec90dd69138f35197774239dfc12f554c9284b2",
"e00eb40255b853b67ea959bf7ebeb12d066374ec",
[
null,
{
@ -459609,6 +459238,13 @@
]
]
},
"historical.html": [
"5cba688ff83e6dae90100b315a9fa86f69974502",
[
null,
{}
]
],
"synthetic": {
"001.html": [
"f90c345740df3f9c4366d01a3d47e323b30069fc",
@ -486616,6 +486252,20 @@
{}
]
],
"first-contentful-canvas-none.html": [
"33a4352126c0d59668e5fdd30d96a4c54ad34468",
[
null,
{}
]
],
"first-contentful-canvas-webgl2.html": [
"f7c5f50ecba0bd5a5d45fb41a02d0457e49e6713",
[
null,
{}
]
],
"first-contentful-canvas.html": [
"e6a4365b760c7126be458c505a49ef1ea7234d53",
[
@ -501642,7 +501292,7 @@
]
],
"scroll-animation-effect-phases.tentative.html": [
"df7ab69404cb00a9e09ec03593f531a50999630a",
"b8e678e9218395f43f2690a67fb1d887ce73dacc",
[
null,
{
@ -504615,6 +504265,13 @@
{}
]
],
"element-internals-shadowroot.tentative.html": [
"0f01cc41acf153512ff00b1147ccc224087167eb",
[
null,
{}
]
],
"getinnerhtml.tentative.html": [
"2f8ecad418b818f35220550479f9c02e1889744e",
[
@ -524535,6 +524192,15 @@
]
]
},
"webcodecs": {
"video-track-reader.html": [
"087e0bb935b6033876c9b7eed10274bab02d8910",
[
null,
{}
]
]
},
"webdriver": {
"tests": {
"idlharness.html": [
@ -524633,119 +524299,6 @@
]
]
},
"webgpu": {
"cts.html": [
"e78afee421ad7d11a16adbd89fb4a833d0b1aece",
[
"webgpu/cts.html?q=webgpu:api,operation,buffers,create_mapped:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,buffers,map:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,buffers,map_detach:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,buffers,map_oom:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,command_buffer,basic:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,command_buffer,copies:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,command_buffer,render,basic:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,fences:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,operation,resource_init,copied_texture_clear:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,createBindGroup:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,createBindGroupLayout:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,createPipelineLayout:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,createTexture:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,createView:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,error_scope:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,fences:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,queue_submit:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,render_pass_descriptor:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,setBindGroup:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,setBlendColor:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,setScissorRect:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,setStencilReference:*",
{}
],
[
"webgpu/cts.html?q=webgpu:api,validation,setViewport:*",
{}
],
[
"webgpu/cts.html?q=webgpu:examples:*",
{}
],
[
"webgpu/cts.html?q=webgpu:idl,constants,flags:*",
{}
],
[
"webgpu/cts.html?q=webgpu:web-platform,canvas,context_creation:*",
{}
],
[
"webgpu/cts.html?q=webgpu:web-platform,copyImageBitmapToTexture:*",
{}
]
]
},
"webhid": {
"idlharness.https.window.js": [
"fa763e0d80ac7e196cd276a9aed5a7a33f9d8331",
@ -533117,6 +532670,13 @@
{}
]
],
"xrSession_requestSessionDuringEnd.https.html": [
"2ab6cb7fbb5ede0523a143e042a459e6f3c5cde5",
[
null,
{}
]
],
"xrSession_sameObject.https.html": [
"66aeef81c50c36ff2fc50dcc7c45749f25605893",
[
@ -563277,7 +562837,7 @@
]
],
"pointer.py": [
"a752203587bed5ebcfa50599f0548feb69ca4c98",
"d021eee7c9404cf09194a41632b6093c72ce961d",
[
null,
{

View file

@ -1,4 +0,0 @@
[hit-test-floats-003.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

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

View file

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

View file

@ -2,3 +2,10 @@
type: testharness
[event state during post-click handling]
expected: FAIL
[disabled radio should be checked from dispatchEvent(new MouseEvent("click"))]
expected: FAIL
[disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))]
expected: FAIL

View file

@ -315,15 +315,18 @@
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<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>: combined response Content-Type: text/html;x=" text/plain]
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain ]
expected: FAIL

View file

@ -56,6 +56,9 @@
[separate text/javascript x/x]
expected: FAIL
[separate text/javascript error]
[separate text/javascript;charset=windows-1252 error text/javascript]
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!]
expected: FAIL
[X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_3.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

@ -1,4 +0,0 @@
[creating_browsing_context_test_01.html]
[first argument: absolute url]
expected: FAIL

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,6 @@
[htmlanchorelement_noopener.html]
type: testharness
expected: TIMEOUT
[Check that targeting of rel=noopener with a given name ignores an existing window with that name]
expected: NOTRUN
@ -7,11 +8,11 @@
expected: FAIL
[Check that rel=noopener with target=_top does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_self does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[077.html]
[ adding several types of scripts through the DOM and removing some of them confuses scheduler ]
expected: FAIL

View file

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

View file

@ -0,0 +1,7 @@
[xrSession_requestSessionDuringEnd.https.html]
[Create new session in OnSessionEnded event]
expected: FAIL
[Create mew session in end promise]
expected: FAIL

View file

@ -6,12 +6,13 @@ promise_test(async testCase => {
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
let values = [
const values = [
{isbn: 'one', title: 'title1'},
{isbn: 'two', title: 'title2'},
{isbn: 'three', title: 'title3'}
];
let putAllRequest = objectStore.putAll(values);
const putAllRequest = objectStore.putAllValues(values);
// TODO(nums): Check that correct keys are returned.
await promiseForRequest(testCase, putAllRequest);
await promiseForTransaction(testCase, txn);
@ -28,4 +29,152 @@ promise_test(async testCase => {
['title1', 'title2', 'title3'],
'All three retrieved titles should match those that were put.');
db.close();
}, 'Data can be successfully inputted into an object store using putAll.');
}, 'Data can be successfully inserted into an object store using putAll.');
promise_test(async testCase => {
const db = await createDatabase(testCase, db => {
const store = createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const values = [
{isbn: ['one', 'two', 'three'], title: 'title1'},
{isbn: ['four', 'five', 'six'], title: 'title2'},
{isbn: ['seven', 'eight', 'nine'], title: 'title3'}
];
const putAllRequest = objectStore.putAllValues(values);
// TODO(nums): Check that correct keys are returned.
await promiseForRequest(testCase, putAllRequest);
await promiseForTransaction(testCase, txn);
const txn2 = db.transaction(['books'], 'readonly');
const objectStore2 = txn2.objectStore('books');
const getRequest1 = objectStore2.get(['one', 'two', 'three']);
const getRequest2 = objectStore2.get(['four', 'five', 'six']);
const getRequest3 = objectStore2.get(['seven', 'eight', 'nine']);
await promiseForTransaction(testCase, txn2);
assert_array_equals(
[getRequest1.result.title,
getRequest2.result.title,
getRequest3.result.title],
['title1', 'title2', 'title3'],
'All three retrieved titles should match those that were put.');
db.close();
}, 'Values with array keys can be successfully inserted into an object'
+ ' store using putAll.');
promise_test(async testCase => {
const db = await createDatabase(testCase, db => {
const store = createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const putAllRequest = objectStore.putAllValues([]);
await promiseForRequest(testCase, putAllRequest);
await promiseForTransaction(testCase, txn);
// TODO(nums): Check that an empty key array is returned.
db.close();
}, 'Inserting an empty list using putAll.');
promise_test(async testCase => {
const db = await createDatabase(testCase, db => {
const store = createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const putAllRequest = objectStore.putAllValues([{}, {}, {}]);
// TODO(nums): Check that correct keys are returned.
await promiseForRequest(testCase, putAllRequest);
await promiseForTransaction(testCase, txn);
const txn2 = db.transaction(['books'], 'readonly');
const objectStore2 = txn2.objectStore('books');
const getRequest1 = objectStore2.get(1);
const getRequest2 = objectStore2.get(2);
const getRequest3 = objectStore2.get(3);
await Promise.all([
promiseForRequest(testCase, getRequest1),
promiseForRequest(testCase, getRequest2),
promiseForRequest(testCase, getRequest3),
]);
db.close();
}, 'Empty values can be inserted into an objectstore'
+ ' with a key generator using putAll.');
promise_test(async testCase => {
const db = await createDatabase(testCase, db => {
const store = createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readonly');
const objectStore = txn.objectStore('books');
assert_throws_dom('ReadOnlyError',
() => { objectStore.putAllValues([{}]); },
'The transaction is readonly');
db.close();
}, 'Attempting to insert with a read only transaction using putAll throws a '
+ 'ReadOnlyError.');
promise_test(async testCase => {
const db = await createDatabase(testCase, db => {
const store = createBooksStore(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const putRequest = await objectStore.put({isbn: 1, title: "duplicate"});
await promiseForRequest(testCase, putRequest);
const putAllRequest = objectStore.putAllValues([
{isbn: 2, title: "duplicate"},
{isbn: 3, title: "duplicate"}
]);
const errorEvent = await requestWatcher(testCase,
putAllRequest).wait_for('error');
assert_equals(errorEvent.target.error.name, "ConstraintError");
errorEvent.preventDefault();
// The transaction still receives the error event even though it
// isn't aborted.
await transactionWatcher(testCase, txn).wait_for(['error', 'complete']);
const txn2 = db.transaction(['books'], 'readonly');
const objectStore2 = txn2.objectStore('books');
const getRequest1 = objectStore2.get(1);
const getRequest2 = objectStore2.get(2);
const getRequest3 = objectStore2.get(3);
await promiseForTransaction(testCase, txn2);
assert_array_equals(
[getRequest1.result.title, getRequest2.result, getRequest3.result],
["duplicate", undefined, undefined],
'None of the values should have been inserted.');
db.close();
}, 'Inserting duplicate unique keys into a store that already has the key'
+ 'using putAll throws a ConstraintError.');
promise_test(async testCase => {
const db = await createDatabase(testCase, db => {
const store = createBooksStoreWithoutAutoIncrement(testCase, db);
});
const txn = db.transaction(['books'], 'readwrite');
const objectStore = txn.objectStore('books');
const values = [
{title: "title1", isbn: 1},
{title: "title2"}
];
assert_throws_dom('DataError',
() => { const putAllRequest = objectStore.putAllValues(values); },
"Evaluating the object store's key path did not yield a value");
const txn2 = db.transaction(['books'], 'readonly');
const objectStore2 = txn2.objectStore('books');
const getRequest1 = objectStore2.get(1);
const getRequest2 = objectStore2.get(2);
await promiseForTransaction(testCase, txn2);
assert_array_equals(
[getRequest1.result, getRequest2.result],
[undefined, undefined],
'No data should have been inserted');
db.close();
}, 'Inserting values without the key into an object store that'
+ ' does not have generated keys throws an exception.');
// TODO(nums): Add test for insertion into multi entry indexes
// TODO(nums): Add test for inserting unique keys into a store
// that doesn't already have the key https://crbug.com/1115649

View file

@ -196,7 +196,19 @@ const createBooksStore = (testCase, database) => {
{ keyPath: 'isbn', autoIncrement: true });
store.createIndex('by_author', 'author');
store.createIndex('by_title', 'title', { unique: true });
for (let record of BOOKS_RECORD_DATA)
for (const record of BOOKS_RECORD_DATA)
store.put(record);
return store;
}
// Creates a 'books' object store whose contents closely resembles the first
// example in the IndexedDB specification, just without autoincrementing.
const createBooksStoreWithoutAutoIncrement = (testCase, database) => {
const store = database.createObjectStore('books',
{ keyPath: 'isbn' });
store.createIndex('by_author', 'author');
store.createIndex('by_title', 'title', { unique: true });
for (const record of BOOKS_RECORD_DATA)
store.put(record);
return store;
}

View file

@ -209,6 +209,38 @@ async_test(t => {
input.dispatchEvent(new MouseEvent('click'));
}, `disconnected radio should be checked from dispatchEvent(new MouseEvent('click'))`);
test(() => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
input.dispatchEvent(new MouseEvent("click"));
assert_true(input.checked);
}, `disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))`);
test(() => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
input.dispatchEvent(new MouseEvent("click"));
assert_true(input.checked);
}, `disabled radio should be checked from dispatchEvent(new MouseEvent("click"))`);
async_test(t => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
input.onclick = t.step_func_done();
input.dispatchEvent(new MouseEvent("click"));
}, `disabled checkbox should fire onclick`);
async_test(t => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
input.onclick = t.step_func_done();
input.dispatchEvent(new MouseEvent("click"));
}, `disabled radio should fire onclick`);
async_test(function(t) {
var form = document.createElement("form")
var didSubmit = false

View file

@ -43,7 +43,6 @@
'dragstart',
'dragend',
'dragenter',
// 'dragexit'? Unclear if it will be removed from HTML spec or not.
'dragleave',
'dragover',
'drop'

View file

@ -2,6 +2,6 @@
set -ex
cd "${0%/*}"
virtualenv -p python2 .virtualenv
virtualenv -p python .virtualenv
.virtualenv/bin/pip install pyyaml cairocffi
.virtualenv/bin/python gentest.py

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<title>Historical drag-and-drop features</title>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
.test-square {
width: 100px;
height: 100px;
}
#draggable {
background: orange;
}
#dropzone {
background: blue;
}
</style>
<p>Drag the orange square onto the blue square and release it.</p>
<div draggable="true" id="draggable" class="test-square" ondragstart="event.dataTransfer.setData('text/plain', null)"></div>
<div id="dropzone" class="test-square"></div>
<script>
"use strict";
async_test(t => {
let dragexitCount = 0;
document.addEventListener("dragexit", () => {
++dragexitCount;
});
// Prevent the event to allow drop
document.addEventListener("dragover", e => {
e.preventDefault();
});
document.addEventListener("drop", t.step_func_done(() => {
assert_equals(dragexitCount, 0);
}));
}, `dragexit must not fire during drag-and-drop`);
</script>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<title>Historical drag-and-drop features</title>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
const potentialBadLocations = [
window,
document,
HTMLElement.prototype,
SVGElement.prototype,
Document.prototype,
HTMLDocument.prototype,
Element.prototype
];
for (const location of potentialBadLocations) {
assert_false("ondragexit" in location,
`${location.constructor.name} must not have a property "ondragexit"`);
}
}, `ondragexit must not be present on the GlobalEventHandlers locations`);
</script>

View file

@ -29,7 +29,7 @@
<script>
var drag, element;
var Events = ['ondragstart', 'ondrag', 'ondragover', 'ondragenter', 'ondragexit', 'ondragleave', 'ondrop', 'ondragend'];
var Events = ['ondragstart', 'ondrag', 'ondragover', 'ondragenter', 'ondragleave', 'ondrop', 'ondragend'];
setup(function() {
drag = document.querySelector('#drag');
@ -54,10 +54,6 @@
assert_inherits(element, 'ondragenter', 'Check if have ondragenter attribute');
}, 'Check if have ondragenter attribute');
test(function() {
assert_inherits(element, 'ondragexit', 'Check if have ondragexit attribute');
}, 'Check if have ondragexit attribute');
test(function() {
assert_inherits(element, 'ondragleave', 'Check if have dragleave attribute');
}, 'Check if have dragleave attribute');

View file

@ -726,6 +726,12 @@ MISSING DEPENDENCY: web-nfc/resources/nfc-helpers.js
MISSING DEPENDENCY: webusb/resources/usb-helpers.js
MISSING DEPENDENCY: webxr/resources/webxr_util.js
# TODO(Hexcles): delete these files once we include them in mojojs.zip.
MOJOM-JS: resources/chromium/image_capture.mojom.js
MOJOM-JS: resources/chromium/sensor_provider.mojom.js
MOJOM-JS: resources/chromium/mojo_web_test_helper_test.mojom.js
MOJOM-JS: resources/chromium/sensor.mojom.js
# Tests that are false positives for using Ahem as a system font
AHEM SYSTEM FONT: acid/acid3/test.html
AHEM SYSTEM FONT: resource-timing/resources/all_resource_types.htm

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<head>
<title>Performance Paint Timing Test: FCP due to canvas</title>
</head>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<canvas id="canvas" width="200" height="200"></canvas>
<script>
setup({"hide_test_state": true});
promise_test(async t => {
assert_implements(window.PerformancePaintTiming, "Paint Timing isn't supported.");
await new Promise(r => window.addEventListener('load', r));
await assertNoFirstContentfulPaint(t);
}, 'First contentful paint should not fire for canvas type none');
</script>
</body>
</html>

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<head>
<title>Performance Paint Timing Test: FCP due to canvas</title>
</head>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<canvas id="canvas" width="200" height="200"></canvas>
<script>
setup({ "hide_test_state": true });
async_test(function (t) {
assert_implements(window.PerformancePaintTiming, "Paint Timing isn't supported.");
const canvas = document.getElementById("canvas");
const context = canvas.getContext("webgl2");
if (!context) {
assert_implements_optional(context, "WebGL 2 Canvas isn't supported.")
}
context.clearColor(0.3, 0.3, 0.3, 1);
context.clear(context.COLOR_BUFFER_BIT);
function testPaintEntries() {
const bufferedEntries = performance.getEntriesByType('paint');
if (bufferedEntries.length < 2) {
t.step_timeout(function () {
testPaintEntries();
}, 20);
return;
}
t.step(function () {
assert_equals(bufferedEntries.length, 2, "There should be two paint timing instances.");
assert_equals(bufferedEntries[0].entryType, "paint");
assert_equals(bufferedEntries[0].name, "first-paint");
assert_equals(bufferedEntries[1].entryType, "paint");
assert_equals(bufferedEntries[1].name, "first-contentful-paint");
t.done();
});
};
t.step(function () {
testPaintEntries();
});
}, "First contentful paint fires due to webgl2 canvas render.");
</script>
</body>
</html>

View file

@ -151,4 +151,167 @@
);
}
}
function createKeyframeEffectOpacity(test){
return new KeyframeEffect(
createDiv(test),
{
opacity: [0.3, 0.7]
},
{
duration: 1000
}
);
}
function verifyTimelineBeforePhase(animation){
assert_equals(animation.timeline.phase, "before");
assert_equals(animation.timeline.currentTime, 0);
assert_equals(animation.currentTime, 0);
assert_equals(
animation.effect.getComputedTiming().localTime,
0,
"effect local time in timeline before phase");
}
function verifyEffectBeforePhase(animation){
// progress == null AND opacity == 1 implies we are in the effect before
// phase
assert_equals(
animation.effect.getComputedTiming().progress,
null
);
assert_equals(
window.getComputedStyle(animation.effect.target).getPropertyValue("opacity"),
"1"
);
}
promise_test(async t => {
const animation = new Animation(
createKeyframeEffectOpacity(t),
createScrollTimelineWithOffsets(t, "20%", "80%")
);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
verifyTimelineBeforePhase(animation);
verifyEffectBeforePhase(animation);
animation.pause();
await waitForNextFrame();
verifyTimelineBeforePhase(animation);
verifyEffectBeforePhase(animation);
animation.play();
await waitForNextFrame();
verifyTimelineBeforePhase(animation);
verifyEffectBeforePhase(animation);
}, 'Verify that (play -> pause -> play) doesn\'t change phase/progress.');
promise_test(async t => {
const animation = new Animation(
createKeyframeEffectOpacity(t),
createScrollTimelineWithOffsets(t, "20%", "80%")
);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
verifyTimelineBeforePhase(animation);
verifyEffectBeforePhase(animation);
animation.pause();
await waitForNextFrame();
verifyTimelineBeforePhase(animation);
verifyEffectBeforePhase(animation);
// Scrolling should not cause the animation effect to change.
scroller.scrollTop = 0.5 * maxScroll;
await waitForNextFrame();
// Check timeline phase
assert_equals(animation.timeline.phase, "active");
assert_equals(animation.timeline.currentTime, 500);
assert_equals(animation.currentTime, 0);
assert_equals(
animation.effect.getComputedTiming().localTime,
0,
"effect local time"
);
// Make sure the effect is still in the before phase even though the
// timeline is not.
verifyEffectBeforePhase(animation);
}, 'Pause in before phase, scroll timeline into active phase, animation ' +
'should remain in the before phase');
promise_test(async t => {
const animation = new Animation(
createKeyframeEffectOpacity(t),
createScrollTimelineWithOffsets(t, "20%", "80%")
);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
// Causes the timeline to be inactive
scroller.style.overflow = "visible";
await waitForNextFrame();
await waitForNextFrame();
// Check timeline phase
assert_equals(animation.timeline.phase, "inactive");
assert_equals(animation.timeline.currentTime, null);
assert_equals(animation.currentTime, null);
assert_equals(
animation.effect.getComputedTiming().localTime,
null,
"effect local time with inactive timeline"
);
verifyEffectBeforePhase(animation);
// Setting the current time while timeline is inactive should cause hold phase
// and hold time to be populated
animation.currentTime = 500;
await waitForNextFrame();
await waitForNextFrame();
// Check timeline phase
assert_equals(animation.timeline.phase, "inactive");
assert_equals(animation.timeline.currentTime, null);
assert_equals(animation.currentTime, 500);
assert_equals(
animation.effect.getComputedTiming().localTime,
500,
"effect local time after setting animation current time"
);
// Check effect phase
// progress == 0.5 AND opacity == 0.5 shows we are in the effect active phase
assert_equals(
animation.effect.getComputedTiming().progress,
0.5,
"effect progress"
);
assert_equals(
window.getComputedStyle(animation.effect.target).getPropertyValue("opacity"),
"0.5",
"effect opacity after setting animation current time"
);
}, 'Make scroller inactive, then set current time to an in range time');
</script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>ElementInternals.shadowRoot</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel="help" href="https://github.com/w3c/webcomponents/issues/871">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(() => {
let constructed = false;
customElements.define('custom-open', class extends HTMLElement {
constructor() {
super();
const elementInternals = this.attachInternals();
assert_equals(elementInternals.shadowRoot, null);
const shadow = this.attachShadow({mode: 'open'});
assert_equals(elementInternals.shadowRoot, shadow);
constructed = true;
}
});
const element = document.createElement('custom-open');
assert_true(constructed);
}, 'ElementInternals.shadowRoot allows access to open shadow root');
test(() => {
let constructed = false;
customElements.define('custom-closed', class extends HTMLElement {
constructor() {
super();
const elementInternals = this.attachInternals();
assert_equals(elementInternals.shadowRoot, null);
const shadow = this.attachShadow({mode: 'closed'});
assert_equals(elementInternals.shadowRoot, shadow);
assert_equals(this.shadowRoot, null);
constructed = true;
}
});
const element = document.createElement('custom-closed');
assert_true(constructed);
}, 'ElementInternals.shadowRoot allows access to closed shadow root');
</script>

View file

@ -198,6 +198,13 @@ def check_gitignore_file(repo_root, path):
return [rules.GitIgnoreFile.error(path)]
def check_mojom_js(repo_root, path):
# type: (Text, Text) -> List[rules.Error]
if path.endswith(".mojom.js"):
return [rules.MojomJSFile.error(path)]
return []
def check_ahem_copy(repo_root, path):
# type: (Text, Text) -> List[rules.Error]
lpath = path.lower()
@ -997,8 +1004,9 @@ def lint(repo_root, paths, output_format, ignore_glob=None):
logger.info(line)
return sum(itervalues(error_count))
path_lints = [check_file_type, check_path_length, check_worker_collision, check_ahem_copy,
check_tentative_directories, check_gitignore_file]
check_mojom_js, check_tentative_directories, check_gitignore_file]
all_paths_lints = [check_css_globally_unique, check_unique_testharness_basenames]
file_lints = [check_regexp_line, check_parsed, check_python_ast, check_script_metadata,
check_ahem_system_font]

View file

@ -81,6 +81,18 @@ class GitIgnoreFile(Rule):
description = ".gitignore found outside the root"
class MojomJSFile(Rule):
name = "MOJOM-JS"
description = "Don't check *.mojom.js files into WPT"
to_fix = """
Check if the file is already included in mojojs.zip:
https://source.chromium.org/chromium/chromium/src/+/master:chrome/tools/build/linux/FILES.cfg
If yes, use `loadMojoResources` from `resources/test-only-api.js` to load
it; if not, contact ecosystem-infra@chromium.org for adding new files
to mojojs.zip.
"""
class AhemCopy(Rule):
name = "AHEM COPY"
description = "Don't add extra copies of Ahem, use /fonts/Ahem.ttf"

View file

@ -7,6 +7,7 @@ from ..lint import check_path
from .base import check_errors
import pytest
def test_allowed_path_length():
basename = 29 * "test/"
@ -29,6 +30,7 @@ def test_forbidden_path_length():
check_errors(errors)
assert errors == [("PATH LENGTH", message, filename, None)]
@pytest.mark.parametrize("path_ending,generated", [(".worker.html", ".worker.js"),
(".any.worker.html", ".any.js"),
(".any.html", ".any.js")])
@ -70,6 +72,7 @@ def test_ahem_copy(path):
assert errors == [expected_error]
@pytest.mark.parametrize("path", ["ahem.woff",
"ahem.ttff",
"support/ahem.woff",
@ -79,6 +82,16 @@ def test_ahem_copy_negative(path):
assert errors == []
def test_mojom_js_file():
path = "resources/fake_device.mojom.js"
errors = check_path("/foo/", path)
assert errors == [("MOJOM-JS",
"Don't check *.mojom.js files into WPT",
path,
None)]
@pytest.mark.parametrize("path", ["css/foo.tentative/bar.html",
"css/.tentative/bar.html",
"css/tentative.bar/baz.html",
@ -94,6 +107,7 @@ def test_tentative_directories(path):
assert errors == [expected_error]
@pytest.mark.parametrize("path", ["css/bar.html",
"css/tentative/baz.html"])
def test_tentative_directories_negative(path):
@ -102,6 +116,7 @@ def test_tentative_directories_negative(path):
assert errors == []
@pytest.mark.parametrize("path", ["elsewhere/.gitignore",
"else/where/.gitignore"
"elsewhere/tools/.gitignore",
@ -120,6 +135,7 @@ def test_gitignore_file(path):
assert errors == [expected_error]
@pytest.mark.parametrize("path", [".gitignore",
"elsewhere/.gitignores",
"elsewhere/name.gitignore",

View file

@ -56,6 +56,24 @@ def do_delayed_imports():
from marionette_driver import marionette, errors
def _switch_to_window(marionette, handle):
"""Switch to the specified window; subsequent commands will be
directed at the new window.
This is a workaround for issue 24924[0]; marionettedriver 3.1.0 dropped the
'name' parameter from its switch_to_window command, but it is still needed
for at least Firefox 79.
[0]: https://github.com/web-platform-tests/wpt/issues/24924
:param marionette: The Marionette instance
:param handle: The id of the window to switch to.
"""
marionette._send_message("WebDriver:SwitchToWindow",
{"handle": handle, "name": handle, "focus": True})
marionette.window = handle
class MarionetteBaseProtocolPart(BaseProtocolPart):
def __init__(self, parent):
super(MarionetteBaseProtocolPart, self).__init__(parent)
@ -83,7 +101,7 @@ class MarionetteBaseProtocolPart(BaseProtocolPart):
return self.marionette.current_window_handle
def set_window(self, handle):
self.marionette.switch_to_window(handle)
_switch_to_window(self.marionette, handle)
def load(self, url):
self.marionette.navigate(url)
@ -171,13 +189,13 @@ class MarionetteTestharnessProtocolPart(TestharnessProtocolPart):
for handle in handles:
try:
self.logger.info("Closing window %s" % handle)
self.marionette.switch_to_window(handle)
_switch_to_window(self.marionette, handle)
self.dismiss_alert(lambda: self.marionette.close())
except errors.NoSuchWindowException:
# We might have raced with the previous test to close this
# window, skip it.
pass
self.marionette.switch_to_window(runner_handle)
_switch_to_window(self.marionette, runner_handle)
return runner_handle
def close_old_windows(self, url_protocol):
@ -489,7 +507,7 @@ class MarionetteCoverageProtocolPart(CoverageProtocolPart):
def dump(self):
if len(self.marionette.window_handles):
handle = self.marionette.window_handles[0]
self.marionette.switch_to_window(handle)
_switch_to_window(self.marionette, handle)
script = """
var callback = arguments[arguments.length - 1];
@ -585,7 +603,7 @@ class MarionettePrintProtocolPart(PrintProtocolPart):
def pdf_to_png(self, pdf_base64, page_ranges):
handle = self.marionette.current_window_handle
self.marionette.switch_to_window(self.runner_handle)
_switch_to_window(self.marionette, self.runner_handle)
try:
rv = self.marionette.execute_async_script("""
let callback = arguments[arguments.length - 1];
@ -594,7 +612,7 @@ render('%s').then(result => callback(result))""" % pdf_base64, new_sandbox=False
rv = [item for i, item in enumerate(rv) if i + 1 in page_numbers]
return rv
finally:
self.marionette.switch_to_window(handle)
_switch_to_window(self.marionette, handle)
class MarionetteProtocol(Protocol):
implements = [MarionetteBaseProtocolPart,
@ -883,7 +901,7 @@ class MarionetteRefTestExecutor(RefTestExecutor):
if self.protocol.marionette and self.protocol.marionette.session_id:
handles = self.protocol.marionette.window_handles
if handles:
self.protocol.marionette.switch_to_window(handles[0])
_switch_to_window(self.protocol.marionette, handles[0])
super(MarionetteRefTestExecutor, self).teardown()
except Exception:
# Ignore errors during teardown
@ -903,8 +921,8 @@ class MarionetteRefTestExecutor(RefTestExecutor):
if not isinstance(self.implementation, InternalRefTestImplementation):
if self.close_after_done and self.has_window:
self.protocol.marionette.close()
self.protocol.marionette.switch_to_window(
self.protocol.marionette.window_handles[-1])
_switch_to_window(self.protocol.marionette,
self.protocol.marionette.window_handles[-1])
self.has_window = False
if not self.has_window:
@ -1012,7 +1030,7 @@ class InternalRefTestImplementation(RefTestImplementation):
# focus
handles = self.executor.protocol.marionette.window_handles
if handles:
self.executor.protocol.marionette.switch_to_window(handles[0])
_switch_to_window(self.executor.protocol.marionette, handles[0])
except Exception:
# Ignore errors during teardown
self.logger.warning(traceback.format_exc())

View file

@ -0,0 +1,132 @@
<!DOCTYPE html>
<html>
<title>Test the VideoTrackReader API.</title>
<body></body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/media.js"></script>
<script>
var testVideo = {
url: getVideoURI('/media/movie_5'),
height: 240,
width: 320,
}
async function getMediaStream() {
let video = document.createElement('video');
document.body.appendChild(video);
video.src = testVideo.url;
await video.play();
return video.captureStream();
}
async_test(async function(t) {
let stream = await getMediaStream();
let vtr = new VideoTrackReader(stream.getVideoTracks()[0]);
t.done();
}, 'Test we can construct a VideoTrackReader.');
async_test(async function(t) {
let stream = await getMediaStream();
let vtr = new VideoTrackReader(stream.getVideoTracks()[0]);
let numberFrames = 0;
vtr.start(t.step_func((frame) => {
assert_equals(frame.codedWidth, testVideo.width);
assert_equals(frame.codedHeight, testVideo.height);
assert_not_equals(frame.timestamp, null);
frame.destroy();
if (++numberFrames == 5){
vtr.stop();
t.done();
}
}));
}, 'Test we can start and stop a VideoTrackReader.');
async_test(async function(t) {
let stream = await getMediaStream();
let vtr = new VideoTrackReader(stream.getVideoTracks()[0]);
let stoppedOnce = false;
vtr.start(t.step_func(() => {
if(!stoppedOnce) {
vtr.stop();
vtr.start(t.step_func_done());
stoppedOnce = true;
} else {
assert_unreached("A stopped callback should never be called again");
}
}));
}, 'Test we can restart a stopped VideoTrackReader.');
async_test(async function(t) {
let stream = await getMediaStream();
let track = stream.getVideoTracks()[0];
let vtr_a = new VideoTrackReader(track);
let vtr_b = new VideoTrackReader(track);
let receivedFrame_a = false;
let receivedFrame_b = false;
vtr_a.start(t.step_func(() => {
receivedFrame_a = true;
if (receivedFrame_a && receivedFrame_b)
t.done();
}));
vtr_b.start(t.step_func(() => {
receivedFrame_b = true;
if (receivedFrame_a && receivedFrame_b)
t.done();
}));
}, 'Test we can create multiple VideoTrackReaders from the same track.');
async_test(async function(t) {
let stream = await getMediaStream();
let audioTrack = stream.getAudioTracks()[0];
assert_throws_js(TypeError, () => {
let vtr = new VideoTrackReader(audioTrack);
})
t.done();
}, 'Test creating a VideoTrackReaders from an audio track throws.');
async_test(async function(t) {
let stream = await getMediaStream();
let vtr = new VideoTrackReader(stream.getVideoTracks()[0]);
assert_throws_dom("InvalidStateError", () => {
vtr.stop();
})
t.done();
}, 'Test stopping a stopped VideoTrackReader throws.');
async_test(async function(t) {
let stream = await getMediaStream();
let vtr = new VideoTrackReader(stream.getVideoTracks()[0]);
vtr.start(() => {});
assert_throws_dom("InvalidStateError", () => {
vtr.start(() => {});
})
t.done();
}, 'Test starting a started VideoTrackReader throws.');
</script>
</html>

View file

@ -169,6 +169,5 @@ def test_drag_and_drop_with_draggable_element(session,
drag_events_captured = [ev["type"] for ev in e if ev["type"].startswith("drag") or ev["type"].startswith("drop")]
assert "dragend" in drag_events_captured
assert "dragenter" in drag_events_captured
assert "dragexit" in drag_events_captured
assert "dragleave" in drag_events_captured
assert "drop" in drag_events_captured

View file

@ -178,7 +178,6 @@
draggable.addEventListener("dragend", recordPointerEvent);
draggable.addEventListener("dragleave", recordPointerEvent);
draggable.addEventListener("dragover", recordPointerEvent);
draggable.addEventListener("dragexit", recordPointerEvent);
var droppable = document.getElementById("droppable");
droppable.addEventListener("drop", recordPointerEvent);

View file

@ -1,5 +1,4 @@
spec: https://gpuweb.github.io/gpuweb/
suggested_reviewers:
- kainino0x
- JusSn
- kvark

View file

@ -5,6 +5,13 @@ support and hardware support, so this API cannot run on most automated testing
infrastructure. Tests inside this directory should always be skipped if
appropriate GPU hardware is not available.
The contents of this directory are automatically generated from TypeScript
~~The contents of this directory are automatically generated from TypeScript
sources which live upstream in the [WebGPU CTS](https://github.com/gpuweb/cts).
They are periodically built and pushed to WPT.
They are periodically built and pushed to WPT.~~
**NOTE:** This directory is currently empty while WebGPU is in flux, as it's
not practical for browser developers to sync their WebGPU implementations with
WPT auto-import and auto-export of these tests. Instead, browsers should pin
("vendor") a specific version of the gpuweb/cts repository, and check the built
files into the browser repository as non-exported wpt tests (like Chromium's
`wpt_internal`).

View file

@ -1,36 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { parseQuery } from './query/parseQuery.js';
import { loadTreeForQuery } from './tree.js'; // A listing file, e.g. either of:
// - `src/webgpu/listing.ts` (which is dynamically computed, has a Promise<TestSuiteListing>)
// - `out/webgpu/listing.js` (which is pre-baked, has a TestSuiteListing)
// Base class for DefaultTestFileLoader and FakeTestFileLoader.
export class TestFileLoader {
importSpecFile(suite, path) {
return this.import(`${suite}/${path.join('/')}.spec.js`);
}
async loadTree(query, subqueriesToExpand = []) {
return loadTreeForQuery(this, query, subqueriesToExpand.map(q => parseQuery(q)));
}
async loadCases(query) {
const tree = await this.loadTree(query);
return tree.iterateLeaves();
}
}
export class DefaultTestFileLoader extends TestFileLoader {
async listing(suite) {
return (await import(`../../${suite}/listing.js`)).listing;
}
import(path) {
return import(`../../${path}`);
}
}
//# sourceMappingURL=file_loader.js.map

View file

@ -1,120 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { assert } from './util/util.js';
export class SkipTestCase extends Error {} // A Fixture is a class used to instantiate each test case at run time.
// A new instance of the Fixture is created for every single test case
// (i.e. every time the test function is run).
export class Fixture {
constructor(rec, params) {
_defineProperty(this, "params", void 0);
_defineProperty(this, "rec", void 0);
_defineProperty(this, "eventualExpectations", []);
_defineProperty(this, "numOutstandingAsyncExpectations", 0);
this.rec = rec;
this.params = params;
} // This has to be a member function instead of an async `createFixture` function, because
// we need to be able to ergonomically override it in subclasses.
async init() {}
debug(msg) {
this.rec.debug(new Error(msg));
}
skip(msg) {
throw new SkipTestCase(msg);
}
async finalize() {
assert(this.numOutstandingAsyncExpectations === 0, 'there were outstanding asynchronous expectations (e.g. shouldReject) at the end of the test');
await Promise.all(this.eventualExpectations);
}
warn(msg) {
this.rec.warn(new Error(msg));
}
fail(msg) {
this.rec.expectationFailed(new Error(msg));
}
async immediateAsyncExpectation(fn) {
this.numOutstandingAsyncExpectations++;
const ret = await fn();
this.numOutstandingAsyncExpectations--;
return ret;
}
eventualAsyncExpectation(fn) {
const promise = fn(new Error());
this.eventualExpectations.push(promise);
return promise;
}
expectErrorValue(expectedName, ex, niceStack) {
if (!(ex instanceof Error)) {
niceStack.message = `THREW non-error value, of type ${typeof ex}: ${ex}`;
this.rec.expectationFailed(niceStack);
return;
}
const actualName = ex.name;
if (actualName !== expectedName) {
niceStack.message = `THREW ${actualName}, instead of ${expectedName}: ${ex}`;
this.rec.expectationFailed(niceStack);
} else {
niceStack.message = `OK: threw ${actualName}${ex.message}`;
this.rec.debug(niceStack);
}
}
shouldReject(expectedName, p, msg) {
this.eventualAsyncExpectation(async niceStack => {
const m = msg ? ': ' + msg : '';
try {
await p;
niceStack.message = 'DID NOT REJECT' + m;
this.rec.expectationFailed(niceStack);
} catch (ex) {
niceStack.message = m;
this.expectErrorValue(expectedName, ex, niceStack);
}
});
}
shouldThrow(expectedName, fn, msg) {
const m = msg ? ': ' + msg : '';
try {
fn();
this.rec.expectationFailed(new Error('DID NOT THROW' + m));
} catch (ex) {
this.expectErrorValue(expectedName, ex, new Error(m));
}
}
expect(cond, msg) {
if (cond) {
const m = msg ? ': ' + msg : '';
this.rec.debug(new Error('expect OK' + m));
} else {
this.rec.expectationFailed(new Error(msg));
}
return cond;
}
}
//# sourceMappingURL=fixture.js.map

View file

@ -1,132 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { assert, raceWithRejectOnTimeout, unreachable, assertReject } from '../util/util.js';
import { getGPU } from './implementation.js';
class TestFailedButDeviceReusable extends Error {}
export class TestOOMedShouldAttemptGC extends Error {}
const kPopErrorScopeTimeoutMS = 5000;
export class DevicePool {
constructor() {
_defineProperty(this, "failed", false);
_defineProperty(this, "holder", undefined);
}
// undefined if "uninitialized" (not yet initialized, or lost)
async acquire() {
assert(!this.failed, 'WebGPU device previously failed to initialize; not retrying');
if (this.holder === undefined) {
try {
this.holder = await DevicePool.makeHolder();
} catch (ex) {
this.failed = true;
throw ex;
}
}
assert(!this.holder.acquired, 'Device was in use on DevicePool.acquire');
this.holder.acquired = true;
this.beginErrorScopes();
return this.holder.device;
} // When a test is done using a device, it's released back into the pool.
// This waits for error scopes, checks their results, and checks for various error conditions.
async release(device) {
const holder = this.holder;
assert(holder !== undefined, 'trying to release a device while pool is uninitialized');
assert(holder.acquired, 'trying to release a device while already released');
assert(device === holder.device, 'Released device was the wrong device');
try {
// Time out if popErrorScope never completes. This could happen due to a browser bug - e.g.,
// as of this writing, on Chrome GPU process crash, popErrorScope just hangs.
await raceWithRejectOnTimeout(this.endErrorScopes(), kPopErrorScopeTimeoutMS, 'finalization popErrorScope timed out'); // (Hopefully if the device was lost, it has been reported by the time endErrorScopes()
// has finished (or timed out). If not, it could cause a finite number of extra test
// failures following this one (but should recover eventually).)
const lostReason = holder.lostReason;
if (lostReason !== undefined) {
// Fail the current test.
unreachable(`Device was lost: ${lostReason}`);
}
} catch (ex) {
// Any error that isn't explicitly TestFailedButDeviceReusable forces a new device to be
// created for the next test.
if (!(ex instanceof TestFailedButDeviceReusable)) {
this.holder = undefined;
}
throw ex;
} finally {
// TODO: device.destroy()
// Mark the holder as free. (This only has an effect if the pool still has the holder.)
// This could be done at the top but is done here to guard against async-races during release.
holder.acquired = false;
}
} // Gets a device and creates a DeviceHolder.
// If the device is lost, DeviceHolder.lostReason gets set.
static async makeHolder() {
const gpu = getGPU();
const adapter = await gpu.requestAdapter();
const holder = {
acquired: false,
device: await adapter.requestDevice(),
lostReason: undefined
};
holder.device.lost.then(ev => {
holder.lostReason = ev.message;
});
return holder;
} // Create error scopes that wrap the entire test.
beginErrorScopes() {
assert(this.holder !== undefined);
this.holder.device.pushErrorScope('out-of-memory');
this.holder.device.pushErrorScope('validation');
} // End the whole-test error scopes. Check that there are no extra error scopes, and that no
// otherwise-uncaptured errors occurred during the test.
async endErrorScopes() {
assert(this.holder !== undefined);
let gpuValidationError;
let gpuOutOfMemoryError;
try {
// May reject if the device was lost.
gpuValidationError = await this.holder.device.popErrorScope();
gpuOutOfMemoryError = await this.holder.device.popErrorScope();
} catch (ex) {
assert(this.holder.lostReason !== undefined, "popErrorScope failed, but device.lost hasn't fired (yet)");
throw ex;
}
await assertReject(this.holder.device.popErrorScope(), 'There was an extra error scope on the stack after a test');
if (gpuValidationError !== null) {
assert(gpuValidationError instanceof GPUValidationError); // Allow the device to be reused.
throw new TestFailedButDeviceReusable(`Unexpected validation error occurred: ${gpuValidationError.message}`);
}
if (gpuOutOfMemoryError !== null) {
assert(gpuOutOfMemoryError instanceof GPUOutOfMemoryError); // Don't allow the device to be reused; unexpected OOM could break the device.
throw new TestOOMedShouldAttemptGC('Unexpected out-of-memory error occurred');
}
}
}
//# sourceMappingURL=device_pool.js.map

View file

@ -1,17 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
/// <reference types="@webgpu/types" />
import { assert } from '../util/util.js';
let impl = undefined;
export function getGPU() {
if (impl) {
return impl;
}
assert(typeof navigator !== 'undefined' && navigator.gpu !== undefined, 'No WebGPU implementation found');
impl = navigator.gpu;
return impl;
}
//# sourceMappingURL=implementation.js.map

View file

@ -1,50 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { extractImportantStackTrace } from '../util/stack.js';
export class LogMessageWithStack extends Error {
constructor(name, ex) {
super(ex.message);
_defineProperty(this, "stackHidden", false);
_defineProperty(this, "timesSeen", 1);
this.name = name;
this.stack = ex.stack;
}
/** Set a flag so the stack is not printed in toJSON(). */
setStackHidden() {
this.stackHidden = true;
}
/** Increment the "seen x times" counter. */
incrementTimesSeen() {
this.timesSeen++;
}
toJSON() {
let m = this.name + ': ';
if (!this.stackHidden && this.stack) {
// this.message is already included in this.stack
m += extractImportantStackTrace(this);
} else {
m += this.message;
}
if (this.timesSeen > 1) {
m += `\n(seen ${this.timesSeen} times with identical stack)`;
}
return m;
}
}
//# sourceMappingURL=log_message.js.map

View file

@ -1,35 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { version } from '../version.js';
import { TestCaseRecorder } from './test_case_recorder.js';
export class Logger {
constructor(debug) {
_defineProperty(this, "debug", void 0);
_defineProperty(this, "results", new Map());
this.debug = debug;
}
record(name) {
const result = {
status: 'running',
timems: -1
};
this.results.set(name, result);
return [new TestCaseRecorder(result, this.debug), result];
}
asJSON(space) {
return JSON.stringify({
version,
results: Array.from(this.results)
}, undefined, space);
}
}
//# sourceMappingURL=logger.js.map

View file

@ -1,4 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
//# sourceMappingURL=result.js.map

View file

@ -1,137 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { SkipTestCase } from '../fixture.js';
import { now, assert } from '../util/util.js';
import { LogMessageWithStack } from './log_message.js';
var LogSeverity;
(function (LogSeverity) {
LogSeverity[LogSeverity["Pass"] = 0] = "Pass";
LogSeverity[LogSeverity["Skip"] = 1] = "Skip";
LogSeverity[LogSeverity["Warn"] = 2] = "Warn";
LogSeverity[LogSeverity["ExpectFailed"] = 3] = "ExpectFailed";
LogSeverity[LogSeverity["ValidationFailed"] = 4] = "ValidationFailed";
LogSeverity[LogSeverity["ThrewException"] = 5] = "ThrewException";
})(LogSeverity || (LogSeverity = {}));
const kMaxLogStacks = 2;
/** Holds onto a LiveTestCaseResult owned by the Logger, and writes the results into it. */
export class TestCaseRecorder {
/** Used to dedup log messages which have identical stacks. */
constructor(result, debugging) {
_defineProperty(this, "result", void 0);
_defineProperty(this, "maxLogSeverity", LogSeverity.Pass);
_defineProperty(this, "startTime", -1);
_defineProperty(this, "logs", []);
_defineProperty(this, "logLinesAtCurrentSeverity", 0);
_defineProperty(this, "debugging", false);
_defineProperty(this, "messagesForPreviouslySeenStacks", new Map());
this.result = result;
this.debugging = debugging;
}
start() {
assert(this.startTime < 0, 'TestCaseRecorder cannot be reused');
this.startTime = now();
}
finish() {
assert(this.startTime >= 0, 'finish() before start()');
const timeMilliseconds = now() - this.startTime; // Round to next microsecond to avoid storing useless .xxxx00000000000002 in results.
this.result.timems = Math.ceil(timeMilliseconds * 1000) / 1000; // Convert numeric enum back to string (but expose 'exception' as 'fail')
this.result.status = this.maxLogSeverity === LogSeverity.Pass ? 'pass' : this.maxLogSeverity === LogSeverity.Skip ? 'skip' : this.maxLogSeverity === LogSeverity.Warn ? 'warn' : 'fail'; // Everything else is an error
this.result.logs = this.logs;
}
injectResult(injectedResult) {
Object.assign(this.result, injectedResult);
}
debug(ex) {
if (!this.debugging) {
return;
}
const logMessage = new LogMessageWithStack('DEBUG', ex);
logMessage.setStackHidden();
this.logImpl(LogSeverity.Pass, logMessage);
}
skipped(ex) {
this.logImpl(LogSeverity.Skip, new LogMessageWithStack('SKIP', ex));
}
warn(ex) {
this.logImpl(LogSeverity.Warn, new LogMessageWithStack('WARN', ex));
}
expectationFailed(ex) {
this.logImpl(LogSeverity.ExpectFailed, new LogMessageWithStack('EXPECTATION FAILED', ex));
}
validationFailed(ex) {
this.logImpl(LogSeverity.ValidationFailed, new LogMessageWithStack('VALIDATION FAILED', ex));
}
threw(ex) {
if (ex instanceof SkipTestCase) {
this.skipped(ex);
return;
}
this.logImpl(LogSeverity.ThrewException, new LogMessageWithStack('EXCEPTION', ex));
}
logImpl(level, logMessage) {
// Deduplicate errors with the exact same stack
if (logMessage.stack) {
const seen = this.messagesForPreviouslySeenStacks.get(logMessage.stack);
if (seen) {
seen.incrementTimesSeen();
return;
}
this.messagesForPreviouslySeenStacks.set(logMessage.stack, logMessage);
} // Mark printStack=false for all logs except 2 at the highest severity
if (level > this.maxLogSeverity) {
this.logLinesAtCurrentSeverity = 0;
this.maxLogSeverity = level;
if (!this.debugging) {
// Go back and turn off printStack for everything of a lower log level
for (const log of this.logs) {
log.setStackHidden();
}
}
}
if (level < this.maxLogSeverity || this.logLinesAtCurrentSeverity >= kMaxLogStacks) {
if (!this.debugging) {
logMessage.setStackHidden();
}
}
this.logs.push(logMessage);
this.logLinesAtCurrentSeverity++;
}
}
//# sourceMappingURL=test_case_recorder.js.map

View file

@ -1,111 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
let _Symbol$iterator;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { publicParamsEquals } from './params_utils.js';
import { assert } from './util/util.js'; // https://stackoverflow.com/a/56375136
export function poptions(name, values) {
const iter = makeReusableIterable(function* () {
for (const value of values) {
yield {
[name]: value
};
}
});
return iter;
}
export function pbool(name) {
return poptions(name, [false, true]);
}
export function params() {
return new ParamsBuilder();
}
_Symbol$iterator = Symbol.iterator;
export class ParamsBuilder {
constructor() {
_defineProperty(this, "paramSpecs", [{}]);
}
[_Symbol$iterator]() {
const iter = this.paramSpecs[Symbol.iterator]();
return iter;
}
combine(newParams) {
const paramSpecs = this.paramSpecs;
this.paramSpecs = makeReusableIterable(function* () {
for (const a of paramSpecs) {
for (const b of newParams) {
yield mergeParams(a, b);
}
}
});
return this;
}
expand(expander) {
const paramSpecs = this.paramSpecs;
this.paramSpecs = makeReusableIterable(function* () {
for (const a of paramSpecs) {
for (const b of expander(a)) {
yield mergeParams(a, b);
}
}
});
return this;
}
filter(pred) {
const paramSpecs = this.paramSpecs;
this.paramSpecs = makeReusableIterable(function* () {
for (const p of paramSpecs) {
if (pred(p)) {
yield p;
}
}
});
return this;
}
unless(pred) {
return this.filter(x => !pred(x));
}
exclude(exclude) {
const excludeArray = Array.from(exclude);
const paramSpecs = this.paramSpecs;
this.paramSpecs = makeReusableIterable(function* () {
for (const p of paramSpecs) {
if (excludeArray.every(e => !publicParamsEquals(p, e))) {
yield p;
}
}
});
return this;
}
} // If you create an Iterable by calling a generator function (e.g. in IIFE), it is exhausted after
// one use. This just wraps a generator function in an object so it be iterated multiple times.
function makeReusableIterable(generatorFn) {
return {
[Symbol.iterator]: generatorFn
};
}
// (keyof A & keyof B) is not empty, so they overlapped
function mergeParams(a, b) {
for (const key of Object.keys(a)) {
assert(!(key in b), 'Duplicate key: ' + key);
}
return { ...a,
...b
};
}
//# sourceMappingURL=params_builder.js.map

View file

@ -1,26 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { comparePublicParamsPaths, Ordering } from './query/compare.js';
import { kWildcard, kParamSeparator, kParamKVSeparator } from './query/separators.js'; // Consider adding more types here if needed
export function paramKeyIsPublic(key) {
return !key.startsWith('_');
}
export function extractPublicParams(params) {
const publicParams = {};
for (const k of Object.keys(params)) {
if (paramKeyIsPublic(k)) {
publicParams[k] = params[k];
}
}
return publicParams;
}
export const badParamValueChars = new RegExp('[' + kParamKVSeparator + kParamSeparator + kWildcard + ']');
export function publicParamsEquals(x, y) {
return comparePublicParamsPaths(x, y) === Ordering.Equal;
}
//# sourceMappingURL=params_utils.js.map

View file

@ -1,104 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { paramKeyIsPublic } from '../params_utils.js';
import { assert, objectEquals } from '../util/util.js';
export let Ordering;
/**
* Compares two queries for their ordering (which is used to build the tree).
*
* See src/unittests/query_compare.spec.ts for examples.
*/
(function (Ordering) {
Ordering[Ordering["Unordered"] = 0] = "Unordered";
Ordering[Ordering["StrictSuperset"] = 1] = "StrictSuperset";
Ordering[Ordering["Equal"] = 2] = "Equal";
Ordering[Ordering["StrictSubset"] = 3] = "StrictSubset";
})(Ordering || (Ordering = {}));
export function compareQueries(a, b) {
if (a.suite !== b.suite) {
return Ordering.Unordered;
}
const filePathOrdering = comparePaths(a.filePathParts, b.filePathParts);
if (filePathOrdering !== Ordering.Equal || a.isMultiFile || b.isMultiFile) {
return compareOneLevel(filePathOrdering, a.isMultiFile, b.isMultiFile);
}
assert('testPathParts' in a && 'testPathParts' in b);
const testPathOrdering = comparePaths(a.testPathParts, b.testPathParts);
if (testPathOrdering !== Ordering.Equal || a.isMultiTest || b.isMultiTest) {
return compareOneLevel(testPathOrdering, a.isMultiTest, b.isMultiTest);
}
assert('params' in a && 'params' in b);
const paramsPathOrdering = comparePublicParamsPaths(a.params, b.params);
if (paramsPathOrdering !== Ordering.Equal || a.isMultiCase || b.isMultiCase) {
return compareOneLevel(paramsPathOrdering, a.isMultiCase, b.isMultiCase);
}
return Ordering.Equal;
}
/**
* Compares a single level of a query.
*
* "IsBig" means the query is big relative to the level, e.g. for test-level:
* - Anything >= `suite:a,*` is big
* - Anything <= `suite:a:*` is small
*/
function compareOneLevel(ordering, aIsBig, bIsBig) {
assert(ordering !== Ordering.Equal || aIsBig || bIsBig);
if (ordering === Ordering.Unordered) return Ordering.Unordered;
if (aIsBig && bIsBig) return ordering;
if (!aIsBig && !bIsBig) return Ordering.Unordered; // Equal case is already handled
// Exactly one of (a, b) is big.
if (aIsBig && ordering !== Ordering.StrictSubset) return Ordering.StrictSuperset;
if (bIsBig && ordering !== Ordering.StrictSuperset) return Ordering.StrictSubset;
return Ordering.Unordered;
}
function comparePaths(a, b) {
const shorter = Math.min(a.length, b.length);
for (let i = 0; i < shorter; ++i) {
if (a[i] !== b[i]) {
return Ordering.Unordered;
}
}
if (a.length === b.length) {
return Ordering.Equal;
} else if (a.length < b.length) {
return Ordering.StrictSuperset;
} else {
return Ordering.StrictSubset;
}
}
export function comparePublicParamsPaths(a, b) {
const aKeys = Object.keys(a).filter(k => paramKeyIsPublic(k));
const commonKeys = new Set(aKeys.filter(k => k in b));
for (const k of commonKeys) {
if (!objectEquals(a[k], b[k])) {
return Ordering.Unordered;
}
}
const bKeys = Object.keys(b).filter(k => paramKeyIsPublic(k));
const aRemainingKeys = aKeys.length - commonKeys.size;
const bRemainingKeys = bKeys.length - commonKeys.size;
if (aRemainingKeys === 0 && bRemainingKeys === 0) return Ordering.Equal;
if (aRemainingKeys === 0) return Ordering.StrictSuperset;
if (bRemainingKeys === 0) return Ordering.StrictSubset;
return Ordering.Unordered;
}
//# sourceMappingURL=compare.js.map

View file

@ -1,32 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
/**
* Encodes a stringified TestQuery so that it can be placed in a `?q=` parameter in a URL.
*
* `encodeURIComponent` encodes in accordance with `application/x-www-form-urlencoded`,
* but URLs don't actually have to be as strict as HTML form encoding
* (we interpret this purely from JavaScript).
* So we encode the component, then selectively convert some %-encoded escape codes
* back to their original form for readability/copyability.
*/
export function encodeURIComponentSelectively(s) {
let ret = encodeURIComponent(s);
ret = ret.replace(/%22/g, '"'); // for JSON strings
ret = ret.replace(/%2C/g, ','); // for path separator, and JSON arrays
ret = ret.replace(/%3A/g, ':'); // for big separator
ret = ret.replace(/%3B/g, ';'); // for param separator
ret = ret.replace(/%3D/g, '='); // for params (k=v)
ret = ret.replace(/%5B/g, '['); // for JSON arrays
ret = ret.replace(/%5D/g, ']'); // for JSON arrays
return ret;
}
//# sourceMappingURL=encode_selectively.js.map

View file

@ -1,122 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { badParamValueChars, paramKeyIsPublic } from '../params_utils.js';
import { assert } from '../util/util.js';
import { TestQueryMultiFile, TestQueryMultiTest, TestQueryMultiCase, TestQuerySingleCase } from './query.js';
import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './separators.js';
import { validQueryPart } from './validQueryPart.js';
export function parseQuery(s) {
try {
return parseQueryImpl(s);
} catch (ex) {
ex.message += '\n on: ' + s;
throw ex;
}
}
function parseQueryImpl(s) {
// Undo encodeURIComponentSelectively
s = decodeURIComponent(s); // bigParts are: suite, group, test, params (note kBigSeparator could appear in params)
const [suite, fileString, testString, paramsString] = s.split(kBigSeparator, 4);
assert(fileString !== undefined, `filter string must have at least one ${kBigSeparator}`);
const {
parts: file,
wildcard: filePathHasWildcard
} = parseBigPart(fileString, kPathSeparator);
if (testString === undefined) {
// Query is file-level
assert(filePathHasWildcard, `File-level query without wildcard ${kWildcard}. Did you want a file-level query \
(append ${kPathSeparator}${kWildcard}) or test-level query (append ${kBigSeparator}${kWildcard})?`);
return new TestQueryMultiFile(suite, file);
}
assert(!filePathHasWildcard, `Wildcard ${kWildcard} must be at the end of the query string`);
const {
parts: test,
wildcard: testPathHasWildcard
} = parseBigPart(testString, kPathSeparator);
if (paramsString === undefined) {
// Query is test-level
assert(testPathHasWildcard, `Test-level query without wildcard ${kWildcard}; did you want a test-level query \
(append ${kPathSeparator}${kWildcard}) or case-level query (append ${kBigSeparator}${kWildcard})?`);
assert(file.length > 0, 'File part of test-level query was empty (::)');
return new TestQueryMultiTest(suite, file, test);
} // Query is case-level
assert(!testPathHasWildcard, `Wildcard ${kWildcard} must be at the end of the query string`);
const {
parts: paramsParts,
wildcard: paramsHasWildcard
} = parseBigPart(paramsString, kParamSeparator);
assert(test.length > 0, 'Test part of case-level query was empty (::)');
const params = {};
for (const paramPart of paramsParts) {
const [k, v] = parseSingleParam(paramPart);
assert(validQueryPart.test(k), 'param key names must match ' + validQueryPart);
params[k] = v;
}
if (paramsHasWildcard) {
return new TestQueryMultiCase(suite, file, test, params);
} else {
return new TestQuerySingleCase(suite, file, test, params);
}
} // webgpu:a,b,* or webgpu:a,b,c:*
const kExampleQueries = `\
webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}${kWildcard} or \
webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}c${kBigSeparator}${kWildcard}`;
function parseBigPart(s, separator) {
if (s === '') {
return {
parts: [],
wildcard: false
};
}
const parts = s.split(separator);
let endsWithWildcard = false;
for (const [i, part] of parts.entries()) {
if (i === parts.length - 1) {
endsWithWildcard = part === kWildcard;
}
assert(part.indexOf(kWildcard) === -1 || endsWithWildcard, `Wildcard ${kWildcard} must be complete last part of a path (e.g. ${kExampleQueries})`);
}
if (endsWithWildcard) {
// Remove the last element of the array (which is just the wildcard).
parts.length = parts.length - 1;
}
return {
parts,
wildcard: endsWithWildcard
};
}
function parseSingleParam(paramSubstring) {
assert(paramSubstring !== '', 'Param in a query must not be blank (is there a trailing comma?)');
const i = paramSubstring.indexOf('=');
assert(i !== -1, 'Param in a query must be of form key=value');
const k = paramSubstring.substring(0, i);
assert(paramKeyIsPublic(k), 'Param in a query must not be private (start with _)');
const v = paramSubstring.substring(i + 1);
return [k, parseSingleParamValue(v)];
}
function parseSingleParamValue(s) {
assert(!badParamValueChars.test(s), `param value must not match ${badParamValueChars} - was ${s}`);
return s === 'undefined' ? undefined : JSON.parse(s);
}
//# sourceMappingURL=parseQuery.js.map

View file

@ -1,125 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { assert } from '../util/util.js';
import { encodeURIComponentSelectively } from './encode_selectively.js';
import { kBigSeparator, kPathSeparator, kWildcard, kParamSeparator } from './separators.js';
import { stringifyPublicParams } from './stringify_params.js';
/**
* Represents a test query of some level.
*
* TestQuery types are immutable.
*/
// SingleCase
/**
* A multi-file test query, like `s:*` or `s:a,b,*`.
*
* Immutable (makes copies of constructor args).
*/
export class TestQueryMultiFile {
constructor(suite, file) {
_defineProperty(this, "level", 1);
_defineProperty(this, "isMultiFile", true);
_defineProperty(this, "suite", void 0);
_defineProperty(this, "filePathParts", void 0);
this.suite = suite;
this.filePathParts = [...file];
}
toString() {
return encodeURIComponentSelectively(this.toStringHelper().join(kBigSeparator));
}
toStringHelper() {
return [this.suite, [...this.filePathParts, kWildcard].join(kPathSeparator)];
}
}
/**
* A multi-test test query, like `s:f:*` or `s:f:a,b,*`.
*
* Immutable (makes copies of constructor args).
*/
export class TestQueryMultiTest extends TestQueryMultiFile {
constructor(suite, file, test) {
super(suite, file);
_defineProperty(this, "level", 2);
_defineProperty(this, "isMultiFile", false);
_defineProperty(this, "isMultiTest", true);
_defineProperty(this, "testPathParts", void 0);
assert(file.length > 0, 'multi-test (or finer) query must have file-path');
this.testPathParts = [...test];
}
toStringHelper() {
return [this.suite, this.filePathParts.join(kPathSeparator), [...this.testPathParts, kWildcard].join(kPathSeparator)];
}
}
/**
* A multi-case test query, like `s:f:t:*` or `s:f:t:a,b,*`.
*
* Immutable (makes copies of constructor args), except for param values
* (which aren't normally supposed to change; they're marked readonly in CaseParams).
*/
export class TestQueryMultiCase extends TestQueryMultiTest {
constructor(suite, file, test, params) {
super(suite, file, test);
_defineProperty(this, "level", 3);
_defineProperty(this, "isMultiTest", false);
_defineProperty(this, "isMultiCase", true);
_defineProperty(this, "params", void 0);
assert(test.length > 0, 'multi-case (or finer) query must have test-path');
this.params = { ...params
};
}
toStringHelper() {
const paramsParts = stringifyPublicParams(this.params);
return [this.suite, this.filePathParts.join(kPathSeparator), this.testPathParts.join(kPathSeparator), [...paramsParts, kWildcard].join(kParamSeparator)];
}
}
/**
* A multi-case test query, like `s:f:t:` or `s:f:t:a=1,b=1`.
*
* Immutable (makes copies of constructor args).
*/
export class TestQuerySingleCase extends TestQueryMultiCase {
constructor(...args) {
super(...args);
_defineProperty(this, "level", 4);
_defineProperty(this, "isMultiCase", false);
}
toStringHelper() {
const paramsParts = stringifyPublicParams(this.params);
return [this.suite, this.filePathParts.join(kPathSeparator), this.testPathParts.join(kPathSeparator), paramsParts.join(kParamSeparator)];
}
}
//# sourceMappingURL=query.js.map

View file

@ -1,19 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
/** Separator between big parts: suite:file:test:case */
export const kBigSeparator = ':';
/** Separator between path,to,file or path,to,test */
export const kPathSeparator = ',';
/** Separator between k=v;k=v */
export const kParamSeparator = ';';
/** Separator between key and value in k=v */
export const kParamKVSeparator = '=';
/** Final wildcard, if query is not single-case */
export const kWildcard = '*';
//# sourceMappingURL=separators.js.map

View file

@ -1,20 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { badParamValueChars, paramKeyIsPublic } from '../params_utils.js';
import { assert } from '../util/util.js';
import { kParamKVSeparator } from './separators.js';
export function stringifyPublicParams(p) {
return Object.keys(p).filter(k => paramKeyIsPublic(k)).map(k => stringifySingleParam(k, p[k]));
}
export function stringifySingleParam(k, v) {
return `${k}${kParamKVSeparator}${stringifySingleParamValue(v)}`;
}
function stringifySingleParamValue(v) {
const s = v === undefined ? 'undefined' : JSON.stringify(v);
assert(!badParamValueChars.test(s), `JSON.stringified param value must not match ${badParamValueChars} - was ${s}`);
return s;
}
//# sourceMappingURL=stringify_params.js.map

View file

@ -1,7 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
/** Applies to group parts, test parts, params keys. */
export const validQueryPart = /^[a-zA-Z0-9_]+$/;
//# sourceMappingURL=validQueryPart.js.map

View file

@ -1,161 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { extractPublicParams, publicParamsEquals } from './params_utils.js';
import { kPathSeparator } from './query/separators.js';
import { stringifyPublicParams } from './query/stringify_params.js';
import { validQueryPart } from './query/validQueryPart.js';
import { assert } from './util/util.js';
export function makeTestGroup(fixture) {
return new TestGroup(fixture);
} // Interface for running tests
export function makeTestGroupForUnitTesting(fixture) {
return new TestGroup(fixture);
}
class TestGroup {
constructor(fixture) {
_defineProperty(this, "fixture", void 0);
_defineProperty(this, "seen", new Set());
_defineProperty(this, "tests", []);
this.fixture = fixture;
}
*iterate() {
for (const test of this.tests) {
yield* test.iterate();
}
}
checkName(name) {
assert( // Shouldn't happen due to the rule above. Just makes sure that treated
// unencoded strings as encoded strings is OK.
name === decodeURIComponent(name), `Not decodeURIComponent-idempotent: ${name} !== ${decodeURIComponent(name)}`);
assert(!this.seen.has(name), `Duplicate test name: ${name}`);
this.seen.add(name);
} // TODO: This could take a fixture, too, to override the one for the group.
test(name) {
this.checkName(name);
const parts = name.split(kPathSeparator);
for (const p of parts) {
assert(validQueryPart.test(p), `Invalid test name part ${p}; must match ${validQueryPart}`);
}
const test = new TestBuilder(parts, this.fixture);
this.tests.push(test);
return test;
}
checkCaseNamesAndDuplicates() {
for (const test of this.tests) {
test.checkCaseNamesAndDuplicates();
}
}
}
class TestBuilder {
constructor(testPath, fixture) {
_defineProperty(this, "testPath", void 0);
_defineProperty(this, "fixture", void 0);
_defineProperty(this, "testFn", void 0);
_defineProperty(this, "cases", undefined);
this.testPath = testPath;
this.fixture = fixture;
}
fn(fn) {
this.testFn = fn;
}
checkCaseNamesAndDuplicates() {
if (this.cases === undefined) {
return;
} // This is n^2.
const seen = [];
for (const testcase of this.cases) {
// stringifyPublicParams also checks for invalid params values
const testcaseString = stringifyPublicParams(testcase);
assert(!seen.some(x => publicParamsEquals(x, testcase)), `Duplicate public test case params: ${testcaseString}`);
seen.push(testcase);
}
}
params(casesIterable) {
assert(this.cases === undefined, 'test case is already parameterized');
this.cases = Array.from(casesIterable);
return this;
}
*iterate() {
assert(this.testFn !== undefined, 'No test function (.fn()) for test');
for (const params of this.cases || [{}]) {
yield new RunCaseSpecific(this.testPath, params, this.fixture, this.testFn);
}
}
}
class RunCaseSpecific {
constructor(testPath, params, fixture, fn) {
_defineProperty(this, "id", void 0);
_defineProperty(this, "params", void 0);
_defineProperty(this, "fixture", void 0);
_defineProperty(this, "fn", void 0);
this.id = {
test: testPath,
params: extractPublicParams(params)
};
this.params = params;
this.fixture = fixture;
this.fn = fn;
}
async run(rec) {
rec.start();
try {
const inst = new this.fixture(rec, this.params || {});
try {
await inst.init();
await this.fn(inst);
} finally {
// Runs as long as constructor succeeded, even if initialization or the test failed.
await inst.finalize();
}
} catch (ex) {
// There was an exception from constructor, init, test, or finalize.
// An error from init or test may have been a SkipTestCase.
// An error from finalize may have been an eventualAsyncExpectation failure
// or unexpected validation/OOM error from the GPUDevice.
rec.threw(ex);
}
rec.finish();
}
}
//# sourceMappingURL=test_group.js.map

View file

@ -1,4 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
//# sourceMappingURL=test_suite_listing.js.map

View file

@ -1,361 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { compareQueries, Ordering } from './query/compare.js';
import { TestQueryMultiCase, TestQuerySingleCase, TestQueryMultiFile, TestQueryMultiTest } from './query/query.js';
import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './query/separators.js';
import { stringifySingleParam } from './query/stringify_params.js';
import { assert } from './util/util.js'; // `loadTreeForQuery()` loads a TestTree for a given queryToLoad.
// The resulting tree is a linked-list all the way from `suite:*` to queryToLoad,
// and under queryToLoad is a tree containing every case matched by queryToLoad.
//
// `subqueriesToExpand` influences the `collapsible` flag on nodes in the resulting tree.
// A node is considered "collapsible" if none of the subqueriesToExpand is a StrictSubset
// of that node.
//
// In WebKit/Blink-style web_tests, an expectation file marks individual cts.html "variants" as
// "Failure", "Crash", etc.
// By passing in the list of expectations as the subqueriesToExpand, we can programmatically
// subdivide the cts.html "variants" list to be able to implement arbitrarily-fine suppressions
// (instead of having to suppress entire test files, which would lose a lot of coverage).
//
// `iterateCollapsedQueries()` produces the list of queries for the variants list.
//
// Though somewhat complicated, this system has important benefits:
// - Avoids having to suppress entire test files, which would cause large test coverage loss.
// - Minimizes the number of page loads needed for fine-grained suppressions.
// (In the naive case, we could do one page load per test case - but the test suite would
// take impossibly long to run.)
// - Enables developers to put any number of tests in one file as appropriate, without worrying
// about expectation granularity.
export class TestTree {
constructor(root) {
_defineProperty(this, "root", void 0);
this.root = root;
}
iterateCollapsedQueries() {
return TestTree.iterateSubtreeCollapsedQueries(this.root);
}
iterateLeaves() {
return TestTree.iterateSubtreeLeaves(this.root);
}
/**
* If a parent and its child are at different levels, then
* generally the parent has only one child, i.e.:
* a,* { a,b,* { a,b:* { ... } } }
* Collapse that down into:
* a,* { a,b:* { ... } }
* which is less needlessly verbose when displaying the tree in the standalone runner.
*/
dissolveLevelBoundaries() {
const newRoot = dissolveLevelBoundaries(this.root);
assert(newRoot === this.root);
}
toString() {
return TestTree.subtreeToString('(root)', this.root, '');
}
static *iterateSubtreeCollapsedQueries(subtree) {
for (const [, child] of subtree.children) {
if ('children' in child && !child.collapsible) {
yield* TestTree.iterateSubtreeCollapsedQueries(child);
} else {
yield child.query;
}
}
}
static *iterateSubtreeLeaves(subtree) {
for (const [, child] of subtree.children) {
if ('children' in child) {
yield* TestTree.iterateSubtreeLeaves(child);
} else {
yield child;
}
}
}
static subtreeToString(name, tree, indent) {
const collapsible = 'run' in tree ? '>' : tree.collapsible ? '+' : '-';
let s = indent + `${collapsible} ${JSON.stringify(name)} => ${tree.query}`;
if ('children' in tree) {
if (tree.description !== undefined) {
s += `\n${indent} | ${JSON.stringify(tree.description)}`;
}
for (const [name, child] of tree.children) {
s += '\n' + TestTree.subtreeToString(name, child, indent + ' ');
}
}
return s;
}
} // TODO: Consider having subqueriesToExpand actually impact the depth-order of params in the tree.
export async function loadTreeForQuery(loader, queryToLoad, subqueriesToExpand) {
const suite = queryToLoad.suite;
const specs = await loader.listing(suite);
const subqueriesToExpandEntries = Array.from(subqueriesToExpand.entries());
const seenSubqueriesToExpand = new Array(subqueriesToExpand.length);
seenSubqueriesToExpand.fill(false);
const isCollapsible = subquery => subqueriesToExpandEntries.every(([i, toExpand]) => {
const ordering = compareQueries(toExpand, subquery); // If toExpand == subquery, no expansion is needed (but it's still "seen").
if (ordering === Ordering.Equal) seenSubqueriesToExpand[i] = true;
return ordering !== Ordering.StrictSubset;
}); // L0 = suite-level, e.g. suite:*
// L1 = file-level, e.g. suite:a,b:*
// L2 = test-level, e.g. suite:a,b:c,d:*
// L3 = case-level, e.g. suite:a,b:c,d:
let foundCase = false; // L0 is suite:*
const subtreeL0 = makeTreeForSuite(suite);
isCollapsible(subtreeL0.query); // mark seenSubqueriesToExpand
for (const entry of specs) {
if (entry.file.length === 0 && 'readme' in entry) {
// Suite-level readme.
assert(subtreeL0.description === undefined);
subtreeL0.description = entry.readme.trim();
continue;
}
{
const queryL1 = new TestQueryMultiFile(suite, entry.file);
const orderingL1 = compareQueries(queryL1, queryToLoad);
if (orderingL1 === Ordering.Unordered) {
// File path is not matched by this query.
continue;
}
}
if ('readme' in entry) {
// Entry is a README that is an ancestor or descendant of the query.
// (It's included for display in the standalone runner.)
// readmeSubtree is suite:a,b,*
// (This is always going to dedup with a file path, if there are any test spec files under
// the directory that has the README).
const readmeSubtree = addSubtreeForDirPath(subtreeL0, entry.file);
assert(readmeSubtree.description === undefined);
readmeSubtree.description = entry.readme.trim();
continue;
} // Entry is a spec file.
const spec = await loader.importSpecFile(queryToLoad.suite, entry.file);
const description = spec.description.trim(); // subtreeL1 is suite:a,b:*
const subtreeL1 = addSubtreeForFilePath(subtreeL0, entry.file, description, isCollapsible); // TODO: If tree generation gets too slow, avoid actually iterating the cases in a file
// if there's no need to (based on the subqueriesToExpand).
for (const t of spec.g.iterate()) {
{
const queryL3 = new TestQuerySingleCase(suite, entry.file, t.id.test, t.id.params);
const orderingL3 = compareQueries(queryL3, queryToLoad);
if (orderingL3 === Ordering.Unordered || orderingL3 === Ordering.StrictSuperset) {
// Case is not matched by this query.
continue;
}
} // subtreeL2 is suite:a,b:c,d:*
const subtreeL2 = addSubtreeForTestPath(subtreeL1, t.id.test, isCollapsible); // Leaf for case is suite:a,b:c,d:x=1;y=2
addLeafForCase(subtreeL2, t, isCollapsible);
foundCase = true;
}
}
for (const [i, sq] of subqueriesToExpandEntries) {
const seen = seenSubqueriesToExpand[i];
assert(seen, `subqueriesToExpand entry did not match anything \
(can happen due to overlap with another subquery): ${sq.toString()}`);
}
assert(foundCase, 'Query does not match any cases');
return new TestTree(subtreeL0);
}
function makeTreeForSuite(suite) {
return {
readableRelativeName: suite + kBigSeparator,
query: new TestQueryMultiFile(suite, []),
children: new Map(),
collapsible: false
};
}
function addSubtreeForDirPath(tree, file) {
const subqueryFile = []; // To start, tree is suite:*
// This loop goes from that -> suite:a,* -> suite:a,b,*
for (const part of file) {
subqueryFile.push(part);
tree = getOrInsertSubtree(part, tree, () => {
const query = new TestQueryMultiFile(tree.query.suite, subqueryFile);
return {
readableRelativeName: part + kPathSeparator + kWildcard,
query,
collapsible: false
};
});
}
return tree;
}
function addSubtreeForFilePath(tree, file, description, checkCollapsible) {
// To start, tree is suite:*
// This goes from that -> suite:a,* -> suite:a,b,*
tree = addSubtreeForDirPath(tree, file); // This goes from that -> suite:a,b:*
const subtree = getOrInsertSubtree('', tree, () => {
const query = new TestQueryMultiTest(tree.query.suite, tree.query.filePathParts, []);
assert(file.length > 0, 'file path is empty');
return {
readableRelativeName: file[file.length - 1] + kBigSeparator + kWildcard,
query,
description,
collapsible: checkCollapsible(query)
};
});
return subtree;
}
function addSubtreeForTestPath(tree, test, isCollapsible) {
const subqueryTest = []; // To start, tree is suite:a,b:*
// This loop goes from that -> suite:a,b:c,* -> suite:a,b:c,d,*
for (const part of test) {
subqueryTest.push(part);
tree = getOrInsertSubtree(part, tree, () => {
const query = new TestQueryMultiTest(tree.query.suite, tree.query.filePathParts, subqueryTest);
return {
readableRelativeName: part + kPathSeparator + kWildcard,
query,
collapsible: isCollapsible(query)
};
});
} // This goes from that -> suite:a,b:c,d:*
return getOrInsertSubtree('', tree, () => {
const query = new TestQueryMultiCase(tree.query.suite, tree.query.filePathParts, subqueryTest, {});
assert(subqueryTest.length > 0, 'subqueryTest is empty');
return {
readableRelativeName: subqueryTest[subqueryTest.length - 1] + kBigSeparator + kWildcard,
kWildcard,
query,
collapsible: isCollapsible(query)
};
});
}
function addLeafForCase(tree, t, checkCollapsible) {
const query = tree.query;
let name = '';
const subqueryParams = {}; // To start, tree is suite:a,b:c,d:*
// This loop goes from that -> suite:a,b:c,d:x=1;* -> suite:a,b:c,d:x=1;y=2;*
for (const [k, v] of Object.entries(t.id.params)) {
name = stringifySingleParam(k, v);
subqueryParams[k] = v;
tree = getOrInsertSubtree(name, tree, () => {
const subquery = new TestQueryMultiCase(query.suite, query.filePathParts, query.testPathParts, subqueryParams);
return {
readableRelativeName: name + kParamSeparator + kWildcard,
query: subquery,
collapsible: checkCollapsible(subquery)
};
});
} // This goes from that -> suite:a,b:c,d:x=1;y=2
const subquery = new TestQuerySingleCase(query.suite, query.filePathParts, query.testPathParts, subqueryParams);
checkCollapsible(subquery); // mark seenSubqueriesToExpand
insertLeaf(tree, subquery, t);
}
function getOrInsertSubtree(key, parent, createSubtree) {
let v;
const child = parent.children.get(key);
if (child !== undefined) {
assert('children' in child); // Make sure cached subtree is not actually a leaf
v = child;
} else {
v = { ...createSubtree(),
children: new Map()
};
parent.children.set(key, v);
}
return v;
}
function insertLeaf(parent, query, t) {
const key = '';
const leaf = {
readableRelativeName: readableNameForCase(query),
query,
run: rec => t.run(rec)
};
assert(!parent.children.has(key));
parent.children.set(key, leaf);
}
function dissolveLevelBoundaries(tree) {
if ('children' in tree) {
if (tree.children.size === 1 && tree.description === undefined) {
// Loops exactly once
for (const [, child] of tree.children) {
if (child.query.level > tree.query.level) {
const newtree = dissolveLevelBoundaries(child);
return newtree;
}
}
}
for (const [k, child] of tree.children) {
const newChild = dissolveLevelBoundaries(child);
if (newChild !== child) {
tree.children.set(k, newChild);
}
}
}
return tree;
}
/** Generate a readable relative name for a case (used in standalone). */
function readableNameForCase(query) {
const paramsKeys = Object.keys(query.params);
if (paramsKeys.length === 0) {
return query.testPathParts[query.testPathParts.length - 1] + kBigSeparator;
} else {
const lastKey = paramsKeys[paramsKeys.length - 1];
return stringifySingleParam(lastKey, query.params[lastKey]);
}
}
//# sourceMappingURL=tree.js.map

View file

@ -1,32 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
export class AsyncMutex {
constructor() {
_defineProperty(this, "newestQueueItem", void 0);
}
// Run an async function with a lock on this mutex.
// Waits until the mutex is available, locks it, runs the function, then releases it.
async with(fn) {
const p = (async () => {
// If the mutex is locked, wait for the last thing in the queue before running.
// (Everything in the queue runs in order, so this is after everything currently enqueued.)
if (this.newestQueueItem) {
await this.newestQueueItem;
}
return fn();
})(); // Push the newly-created Promise onto the queue by replacing the old "newest" item.
this.newestQueueItem = p; // And return so the caller can wait on the result.
return p;
}
}
//# sourceMappingURL=async_mutex.js.map

View file

@ -1,53 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { resolveOnTimeout } from './util.js';
export async function attemptGarbageCollection() {
const w = self;
if (w.GCController) {
w.GCController.collect();
return;
}
if (w.opera && w.opera.collect) {
w.opera.collect();
return;
}
try {
w.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils).garbageCollect();
return;
} catch (e) {}
if (w.gc) {
w.gc();
return;
}
if (w.CollectGarbage) {
w.CollectGarbage();
return;
}
let i;
function gcRec(n) {
if (n < 1) return;
let temp = {
i: 'ab' + i + i / 100000
};
temp = temp + 'foo';
temp; // dummy use of unused variable
gcRec(n - 1);
}
for (i = 0; i < 1000; i++) {
gcRec(10);
}
return resolveOnTimeout(35); // Let the event loop run a few frames in case it helps.
}
//# sourceMappingURL=collect_garbage.js.map

View file

@ -1,83 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
// Returns the stack trace of an Error, but without the extra boilerplate at the bottom
// (e.g. RunCaseSpecific, processTicksAndRejections, etc.), for logging.
export function extractImportantStackTrace(e) {
if (!e.stack) {
return '';
}
const lines = e.stack.split('\n');
for (let i = lines.length - 1; i >= 0; --i) {
const line = lines[i];
if (line.indexOf('.spec.') !== -1) {
return lines.slice(0, i + 1).join('\n');
}
}
return e.stack;
} // *** Examples ***
//
// Node fail()
// > Error:
// > at CaseRecorder.fail (/Users/kainino/src/cts/src/common/framework/logger.ts:99:30)
// > at RunCaseSpecific.exports.g.test.t [as fn] (/Users/kainino/src/cts/src/unittests/logger.spec.ts:80:7)
// x at RunCaseSpecific.run (/Users/kainino/src/cts/src/common/framework/test_group.ts:121:18)
// x at processTicksAndRejections (internal/process/task_queues.js:86:5)
//
// Node throw
// > Error: hello
// > at RunCaseSpecific.g.test.t [as fn] (/Users/kainino/src/cts/src/unittests/test_group.spec.ts:51:11)
// x at RunCaseSpecific.run (/Users/kainino/src/cts/src/common/framework/test_group.ts:121:18)
// x at processTicksAndRejections (internal/process/task_queues.js:86:5)
//
// Firefox fail()
// > fail@http://localhost:8080/out/framework/logger.js:104:30
// > expect@http://localhost:8080/out/framework/default_fixture.js:59:16
// > @http://localhost:8080/out/unittests/util.spec.js:35:5
// x run@http://localhost:8080/out/framework/test_group.js:119:18
//
// Firefox throw
// > @http://localhost:8080/out/unittests/test_group.spec.js:48:11
// x run@http://localhost:8080/out/framework/test_group.js:119:18
//
// Safari fail()
// > fail@http://localhost:8080/out/framework/logger.js:104:39
// > expect@http://localhost:8080/out/framework/default_fixture.js:59:20
// > http://localhost:8080/out/unittests/util.spec.js:35:11
// x http://localhost:8080/out/framework/test_group.js:119:20
// x asyncFunctionResume@[native code]
// x [native code]
// x promiseReactionJob@[native code]
//
// Safari throw
// > http://localhost:8080/out/unittests/test_group.spec.js:48:20
// x http://localhost:8080/out/framework/test_group.js:119:20
// x asyncFunctionResume@[native code]
// x [native code]
// x promiseReactionJob@[native code]
//
// Chrome fail()
// x Error
// x at CaseRecorder.fail (http://localhost:8080/out/framework/logger.js:104:30)
// x at DefaultFixture.expect (http://localhost:8080/out/framework/default_fixture.js:59:16)
// > at RunCaseSpecific.fn (http://localhost:8080/out/unittests/util.spec.js:35:5)
// x at RunCaseSpecific.run (http://localhost:8080/out/framework/test_group.js:119:18)
// x at async runCase (http://localhost:8080/out/runtime/standalone.js:37:17)
// x at async http://localhost:8080/out/runtime/standalone.js:102:7
//
// Chrome throw
// x Error: hello
// > at RunCaseSpecific.fn (http://localhost:8080/out/unittests/test_group.spec.js:48:11)
// x at RunCaseSpecific.run (http://localhost:8080/out/framework/test_group.js:119:18)"
// x at async Promise.all (index 0)
// x at async TestGroupTest.run (http://localhost:8080/out/unittests/test_group_test.js:6:5)
// x at async RunCaseSpecific.fn (http://localhost:8080/out/unittests/test_group.spec.js:53:15)
// x at async RunCaseSpecific.run (http://localhost:8080/out/framework/test_group.js:119:7)
// x at async runCase (http://localhost:8080/out/runtime/standalone.js:37:17)
// x at async http://localhost:8080/out/runtime/standalone.js:102:7
//# sourceMappingURL=stack.js.map

View file

@ -1,6 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const timeout = typeof step_timeout !== 'undefined' ? step_timeout : setTimeout;
//# sourceMappingURL=timeout.js.map

View file

@ -1,63 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { timeout } from './timeout.js';
export function assert(condition, msg) {
if (!condition) {
throw new Error(msg && (typeof msg === 'string' ? msg : msg()));
}
}
export async function assertReject(p, msg) {
try {
await p;
unreachable(msg);
} catch (ex) {// Assertion OK
}
}
export function unreachable(msg) {
throw new Error(msg);
} // performance.now() is available in all browsers, but not in scope by default in Node.
const perf = typeof performance !== 'undefined' ? performance : require('perf_hooks').performance;
export function now() {
return perf.now();
}
export function resolveOnTimeout(ms) {
return new Promise(resolve => {
timeout(() => {
resolve();
}, ms);
});
}
export class PromiseTimeoutError extends Error {}
export function rejectOnTimeout(ms, msg) {
return new Promise((_resolve, reject) => {
timeout(() => {
reject(new PromiseTimeoutError(msg));
}, ms);
});
}
export function raceWithRejectOnTimeout(p, ms, msg) {
return Promise.race([p, rejectOnTimeout(ms, msg)]);
}
export function objectEquals(x, y) {
if (typeof x !== 'object' || typeof y !== 'object') return x === y;
if (x === null || y === null) return x === y;
if (x.constructor !== y.constructor) return false;
if (x instanceof Function) return x === y;
if (x instanceof RegExp) return x === y;
if (x === y || x.valueOf() === y.valueOf()) return true;
if (Array.isArray(x) && Array.isArray(y) && x.length !== y.length) return false;
if (x instanceof Date) return false;
if (!(x instanceof Object)) return false;
if (!(y instanceof Object)) return false;
const x1 = x;
const y1 = y;
const p = Object.keys(x);
return Object.keys(y).every(i => p.indexOf(i) !== -1) && p.every(i => objectEquals(x1[i], y1[i]));
}
export function range(n, fn) {
return [...new Array(n)].map((_, i) => fn(i));
}
//# sourceMappingURL=util.js.map

View file

@ -1,3 +0,0 @@
// AUTO-GENERATED - DO NOT EDIT. See tools/gen_version.
export const version = '21f8f997c1db17e2daa6d0c9e8794a5c3216f373';

View file

@ -1,10 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
const url = new URL(window.location.toString());
export function optionEnabled(opt) {
const val = url.searchParams.get(opt);
return val !== null && val !== '0';
}
//# sourceMappingURL=options.js.map

View file

@ -1,26 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { DefaultTestFileLoader } from '../../framework/file_loader.js';
import { Logger } from '../../framework/logging/logger.js';
import { parseQuery } from '../../framework/query/parseQuery.js';
import { assert } from '../../framework/util/util.js';
// should be DedicatedWorkerGlobalScope
const loader = new DefaultTestFileLoader();
self.onmessage = async ev => {
const query = ev.data.query;
const debug = ev.data.debug;
const log = new Logger(debug);
const testcases = Array.from(await loader.loadCases(parseQuery(query)));
assert(testcases.length === 1, 'worker query resulted in != 1 cases');
const testcase = testcases[0];
const [rec, result] = log.record(testcase.query.toString());
await testcase.run(rec);
self.postMessage({
query,
result
});
};
//# sourceMappingURL=test_worker-worker.js.map

View file

@ -1,51 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { LogMessageWithStack } from '../../framework/logging/log_message.js';
export class TestWorker {
constructor(debug) {
_defineProperty(this, "debug", void 0);
_defineProperty(this, "worker", void 0);
_defineProperty(this, "resolvers", new Map());
this.debug = debug;
const selfPath = import.meta.url;
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js';
this.worker = new Worker(workerPath, {
type: 'module'
});
this.worker.onmessage = ev => {
const query = ev.data.query;
const result = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
}
this.resolvers.get(query)(result); // TODO(kainino0x): update the Logger with this result (or don't have a logger and update the
// entire results JSON somehow at some point).
};
}
async run(rec, query) {
this.worker.postMessage({
query,
debug: this.debug
});
const workerResult = await new Promise(resolve => {
this.resolvers.set(query, resolve);
});
rec.injectResult(workerResult);
}
}
//# sourceMappingURL=test_worker.js.map

View file

@ -1,58 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { DefaultTestFileLoader } from '../framework/file_loader.js';
import { Logger } from '../framework/logging/logger.js';
import { parseQuery } from '../framework/query/parseQuery.js';
import { AsyncMutex } from '../framework/util/async_mutex.js';
import { assert } from '../framework/util/util.js';
import { optionEnabled } from './helper/options.js';
import { TestWorker } from './helper/test_worker.js';
(async () => {
const loader = new DefaultTestFileLoader();
const qs = new URLSearchParams(window.location.search).getAll('q');
assert(qs.length === 1, 'currently, there must be exactly one ?q=');
const testcases = await loader.loadCases(parseQuery(qs[0]));
await addWPTTests(testcases);
})(); // Note: `async_test`s must ALL be added within the same task. This function *must not* be async.
function addWPTTests(testcases) {
const worker = optionEnabled('worker') ? new TestWorker(false) : undefined;
const log = new Logger(false);
const mutex = new AsyncMutex();
const running = [];
for (const testcase of testcases) {
const name = testcase.query.toString();
const wpt_fn = function () {
const p = mutex.with(async () => {
const [rec, res] = log.record(name);
if (worker) {
await worker.run(rec, name);
} else {
await testcase.run(rec);
}
this.step(() => {
// Unfortunately, it seems not possible to surface any logs for warn/skip.
if (res.status === 'fail') {
throw (res.logs || []).map(s => s.toJSON()).join('\n\n');
}
});
this.done();
});
running.push(p);
return p;
};
async_test(wpt_fn, name);
}
return Promise.all(running).then(() => log);
}
//# sourceMappingURL=wpt.js.map

View file

@ -1,56 +0,0 @@
<!-- AUTO-GENERATED - DO NOT EDIT. See WebGPU CTS: tools/gen_wpt_cts_html. -->
<!--
This test suite is built from the TypeScript sources at:
https://github.com/gpuweb/cts
If you are debugging WebGPU conformance tests, it's highly recommended that
you use the standalone interactive runner in that repository, which
provides tools for easier debugging and editing (source maps, debug
logging, warn/skip functionality, etc.)
NOTE:
The WPT version of this file is generated with *one variant per test spec
file*. If your harness needs more fine-grained suppressions, you'll need to
generate your own variants list from your suppression list.
See `tools/gen_wpt_cts_html` to do this.
When run under browser CI, the original cts.html should be skipped, and
this alternate version should be run instead, under a non-exported WPT test
directory (e.g. Chromium's wpt_internal).
-->
<!doctype html>
<title>WebGPU CTS</title>
<meta charset=utf-8>
<link rel=help href='https://gpuweb.github.io/gpuweb/'>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script type=module src=/webgpu/common/runtime/wpt.js></script>
<meta name=variant content='?q=webgpu:api,operation,buffers,create_mapped:*'>
<meta name=variant content='?q=webgpu:api,operation,buffers,map:*'>
<meta name=variant content='?q=webgpu:api,operation,buffers,map_detach:*'>
<meta name=variant content='?q=webgpu:api,operation,buffers,map_oom:*'>
<meta name=variant content='?q=webgpu:api,operation,command_buffer,basic:*'>
<meta name=variant content='?q=webgpu:api,operation,command_buffer,copies:*'>
<meta name=variant content='?q=webgpu:api,operation,command_buffer,render,basic:*'>
<meta name=variant content='?q=webgpu:api,operation,fences:*'>
<meta name=variant content='?q=webgpu:api,operation,resource_init,copied_texture_clear:*'>
<meta name=variant content='?q=webgpu:api,validation,createBindGroup:*'>
<meta name=variant content='?q=webgpu:api,validation,createBindGroupLayout:*'>
<meta name=variant content='?q=webgpu:api,validation,createPipelineLayout:*'>
<meta name=variant content='?q=webgpu:api,validation,createTexture:*'>
<meta name=variant content='?q=webgpu:api,validation,createView:*'>
<meta name=variant content='?q=webgpu:api,validation,error_scope:*'>
<meta name=variant content='?q=webgpu:api,validation,fences:*'>
<meta name=variant content='?q=webgpu:api,validation,queue_submit:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pass_descriptor:*'>
<meta name=variant content='?q=webgpu:api,validation,setBindGroup:*'>
<meta name=variant content='?q=webgpu:api,validation,setBlendColor:*'>
<meta name=variant content='?q=webgpu:api,validation,setScissorRect:*'>
<meta name=variant content='?q=webgpu:api,validation,setStencilReference:*'>
<meta name=variant content='?q=webgpu:api,validation,setViewport:*'>
<meta name=variant content='?q=webgpu:examples:*'>
<meta name=variant content='?q=webgpu:idl,constants,flags:*'>
<meta name=variant content='?q=webgpu:web-platform,canvas,context_creation:*'>
<meta name=variant content='?q=webgpu:web-platform,copyImageBitmapToTexture:*'>

View file

@ -1,21 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const description = '';
import { params, pbool, poptions } from '../../../../common/framework/params_builder.js';
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { MappingTest } from './mapping_test.js';
export const g = makeTestGroup(MappingTest);
g.test('createBufferMapped').params(params().combine(poptions('size', [12, 512 * 1024])).combine(pbool('mappable'))).fn(t => {
const {
size,
mappable
} = t.params;
const [buffer, arrayBuffer] = t.device.createBufferMapped({
size,
usage: GPUBufferUsage.COPY_SRC | (mappable ? GPUBufferUsage.MAP_WRITE : 0)
});
t.checkMapWrite(buffer, arrayBuffer, size);
});
//# sourceMappingURL=create_mapped.spec.js.map

View file

@ -1,51 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const description = '';
import { pbool, poptions, params } from '../../../../common/framework/params_builder.js';
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { MappingTest } from './mapping_test.js';
export const g = makeTestGroup(MappingTest);
g.test('mapWriteAsync').params(poptions('size', [12, 512 * 1024])).fn(async t => {
const {
size
} = t.params;
const buffer = t.device.createBuffer({
size,
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE
});
const arrayBuffer = await buffer.mapWriteAsync();
t.checkMapWrite(buffer, arrayBuffer, size);
});
g.test('mapReadAsync').params(poptions('size', [12, 512 * 1024])).fn(async t => {
const {
size
} = t.params;
const [buffer, init] = t.device.createBufferMapped({
size,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
});
const expected = new Uint32Array(new ArrayBuffer(size));
const data = new Uint32Array(init);
for (let i = 0; i < data.length; ++i) {
data[i] = expected[i] = i + 1;
}
buffer.unmap();
const actual = new Uint8Array(await buffer.mapReadAsync());
t.expectBuffer(actual, new Uint8Array(expected.buffer));
});
g.test('createBufferMapped').params(params().combine(poptions('size', [12, 512 * 1024])).combine(pbool('mappable'))).fn(async t => {
const {
size,
mappable
} = t.params;
const [buffer, arrayBuffer] = t.device.createBufferMapped({
size,
usage: GPUBufferUsage.COPY_SRC | (mappable ? GPUBufferUsage.MAP_WRITE : 0)
});
t.checkMapWrite(buffer, arrayBuffer, size);
});
//# sourceMappingURL=map.spec.js.map

View file

@ -1,82 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const description = '';
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { GPUTest } from '../../../gpu_test.js';
class F extends GPUTest {
checkDetach(buffer, arrayBuffer, unmap, destroy) {
const view = new Uint8Array(arrayBuffer);
this.expect(arrayBuffer.byteLength === 4);
this.expect(view.length === 4);
if (unmap) buffer.unmap();
if (destroy) buffer.destroy();
this.expect(arrayBuffer.byteLength === 0, 'ArrayBuffer should be detached');
this.expect(view.byteLength === 0, 'ArrayBufferView should be detached');
}
}
export const g = makeTestGroup(F);
g.test('mapWriteAsync').params([{
unmap: true,
destroy: false
}, //
{
unmap: false,
destroy: true
}, {
unmap: true,
destroy: true
}]).fn(async t => {
const buffer = t.device.createBuffer({
size: 4,
usage: GPUBufferUsage.MAP_WRITE
});
const arrayBuffer = await buffer.mapWriteAsync();
t.checkDetach(buffer, arrayBuffer, t.params.unmap, t.params.destroy);
});
g.test('mapReadAsync').params([{
unmap: true,
destroy: false
}, //
{
unmap: false,
destroy: true
}, {
unmap: true,
destroy: true
}]).fn(async t => {
const buffer = t.device.createBuffer({
size: 4,
usage: GPUBufferUsage.MAP_READ
});
const arrayBuffer = await buffer.mapReadAsync();
t.checkDetach(buffer, arrayBuffer, t.params.unmap, t.params.destroy);
});
g.test('create_mapped').params([{
unmap: true,
destroy: false
}, {
unmap: false,
destroy: true
}, {
unmap: true,
destroy: true
}]).fn(async t => {
const desc = {
size: 4,
usage: GPUBufferUsage.MAP_WRITE
};
const [buffer, arrayBuffer] = t.device.createBufferMapped(desc);
const view = new Uint8Array(arrayBuffer);
t.expect(arrayBuffer.byteLength === 4);
t.expect(view.length === 4);
if (t.params.unmap) buffer.unmap();
if (t.params.destroy) buffer.destroy();
t.expect(arrayBuffer.byteLength === 0, 'ArrayBuffer should be detached');
t.expect(view.byteLength === 0, 'ArrayBufferView should be detached');
});
//# sourceMappingURL=map_detach.spec.js.map

View file

@ -1,34 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const description = '';
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { GPUTest } from '../../../gpu_test.js';
function getBufferDesc(usage) {
return {
size: Number.MAX_SAFE_INTEGER,
usage
};
}
export const g = makeTestGroup(GPUTest);
g.test('mapWriteAsync').fn(async t => {
const buffer = t.expectGPUError('out-of-memory', () => {
return t.device.createBuffer(getBufferDesc(GPUBufferUsage.MAP_WRITE));
});
t.shouldReject('OperationError', buffer.mapWriteAsync());
});
g.test('mapReadAsync').fn(async t => {
const buffer = t.expectGPUError('out-of-memory', () => {
return t.device.createBuffer(getBufferDesc(GPUBufferUsage.MAP_READ));
});
t.shouldReject('OperationError', buffer.mapReadAsync());
});
g.test('createBufferMapped').fn(async t => {
t.shouldThrow('RangeError', () => {
t.device.createBufferMapped(getBufferDesc(GPUBufferUsage.COPY_SRC));
});
});
//# sourceMappingURL=map_oom.spec.js.map

View file

@ -1,39 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
import { GPUTest } from '../../../gpu_test.js';
export class MappingTest extends GPUTest {
checkMapWrite(buffer, mappedContents, size) {
this.checkMapWriteZeroed(mappedContents, size);
const mappedView = new Uint32Array(mappedContents);
const expected = new Uint32Array(new ArrayBuffer(size));
this.expect(mappedView.byteLength === size);
for (let i = 0; i < mappedView.length; ++i) {
mappedView[i] = expected[i] = i + 1;
}
buffer.unmap();
this.expectContents(buffer, expected);
}
checkMapWriteZeroed(arrayBuffer, expectedSize) {
this.expect(arrayBuffer.byteLength === expectedSize);
const view = new Uint8Array(arrayBuffer);
this.expectZero(view);
}
expectZero(actual) {
const size = actual.byteLength;
for (let i = 0; i < size; ++i) {
if (actual[i] !== 0) {
this.fail(`at [${i}], expected zero, got ${actual[i]}`);
break;
}
}
}
}
//# sourceMappingURL=mapping_test.js.map

View file

@ -1,16 +0,0 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const description = `
Basic tests.
`;
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { GPUTest } from '../../../gpu_test.js';
export const g = makeTestGroup(GPUTest);
g.test('empty').fn(async t => {
const encoder = t.device.createCommandEncoder();
const cmd = encoder.finish();
t.device.defaultQueue.submit([cmd]);
});
//# sourceMappingURL=basic.spec.js.map

Some files were not shown because too many files have changed in this diff Show more