mirror of
https://github.com/servo/servo.git
synced 2025-06-06 00:25:37 +00:00
Update web-platform-tests to revision 6d85a3b422cab97d032ad3db47cb741ca364185f
This commit is contained in:
parent
cd663ea332
commit
b524b7c279
37 changed files with 1446 additions and 178 deletions
|
@ -1,20 +1,19 @@
|
|||
[createImageBitmap-drawImage.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[createImageBitmap from a HTMLImageElement, and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a HTMLCanvasElement, and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a HTMLVideoElement, and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
@ -38,19 +37,19 @@
|
|||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas with negative sw/sh, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData with negative sw/sh, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap with negative sw/sh, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob with negative sw/sh, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap HTMLImageElement, and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
@ -65,16 +64,16 @@
|
|||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement, and drawImage on the created ImageBitmap]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector SVGImageElement, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLCanvasElement scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
@ -128,56 +127,56 @@
|
|||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement scaled up, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement resized, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector SVGImageElement scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector SVGImageElement scaled up, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector SVGImageElement resized, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas scaled up, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas resized, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData scaled up, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData resized, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap scaled up, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap resized, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob scaled down, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob scaled up, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob resized, and drawImage on the created ImageBitmap]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -68193,6 +68193,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/CSS2/normal-flow/margin-collapse-through-zero-height-block.html": [
|
||||
[
|
||||
"/css/CSS2/normal-flow/margin-collapse-through-zero-height-block.html",
|
||||
[
|
||||
[
|
||||
"/css/reference/ref-filled-green-200px-square.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/CSS2/normal-flow/max-height-001.xht": [
|
||||
[
|
||||
"/css/CSS2/normal-flow/max-height-001.xht",
|
||||
|
@ -184742,6 +184754,11 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"IndexedDB/interleaved-cursors-common.js": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"IndexedDB/nested-cloning-common.js": [
|
||||
[
|
||||
{}
|
||||
|
@ -302217,9 +302234,17 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"IndexedDB/interleaved-cursors.html": [
|
||||
"IndexedDB/interleaved-cursors-large.html": [
|
||||
[
|
||||
"/IndexedDB/interleaved-cursors.html",
|
||||
"/IndexedDB/interleaved-cursors-large.html",
|
||||
{
|
||||
"timeout": "long"
|
||||
}
|
||||
]
|
||||
],
|
||||
"IndexedDB/interleaved-cursors-small.html": [
|
||||
[
|
||||
"/IndexedDB/interleaved-cursors-small.html",
|
||||
{
|
||||
"timeout": "long"
|
||||
}
|
||||
|
@ -308083,6 +308108,12 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-color/color-function-parsing.html": [
|
||||
[
|
||||
"/css/css-color/color-function-parsing.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-color/color-resolving-hsl.html": [
|
||||
[
|
||||
"/css/css-color/color-resolving-hsl.html",
|
||||
|
@ -359643,24 +359674,96 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-attestation.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-attestation.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-authnrselection.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-authnrselection.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-challenge.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-challenge.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-rp.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-rp.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-user.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-user.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-excludecredentials.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-excludecredentials.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-extensions.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-extensions.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-passing.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-passing.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-pubkeycredparams.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-pubkeycredparams.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-timeout.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-timeout.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-badargs-rpid.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-badargs-rpid.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-badargs-userverification.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-badargs-userverification.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-extensions.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-extensions.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-passing.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-passing.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-timeout.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-timeout.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/interfaces.https.html": [
|
||||
[
|
||||
"/webauthn/interfaces.https.html",
|
||||
|
@ -385713,7 +385816,7 @@
|
|||
"support"
|
||||
],
|
||||
"./lint.whitelist": [
|
||||
"fc1e09fcc92c3f54ed75fe93681c5ff0a53d25a4",
|
||||
"626b91c285aee2f19f3ca80750b093594de2054b",
|
||||
"support"
|
||||
],
|
||||
"./serve.py": [
|
||||
|
@ -391352,8 +391455,16 @@
|
|||
"fdacaee0ed6b2a97b579495f5944df04e70b7deb",
|
||||
"testharness"
|
||||
],
|
||||
"IndexedDB/interleaved-cursors.html": [
|
||||
"131b1965caae735de9ef8893e6ca55f24ce36f81",
|
||||
"IndexedDB/interleaved-cursors-common.js": [
|
||||
"6744105fe1a15a91058e3e5993f8a1f88548e3a3",
|
||||
"support"
|
||||
],
|
||||
"IndexedDB/interleaved-cursors-large.html": [
|
||||
"4ee13538a407fe15fe310c8776d84c7526b7b363",
|
||||
"testharness"
|
||||
],
|
||||
"IndexedDB/interleaved-cursors-small.html": [
|
||||
"04e4aad6c03ba0bc413a72f7674587816e1f63a2",
|
||||
"testharness"
|
||||
],
|
||||
"IndexedDB/key-conversion-exceptions.htm": [
|
||||
|
@ -448036,6 +448147,10 @@
|
|||
"a19a4cc8d7c500e01a0b591b16c13cd9a18773db",
|
||||
"reftest"
|
||||
],
|
||||
"css/CSS2/normal-flow/margin-collapse-through-zero-height-block.html": [
|
||||
"33e6e180ed6e9896b7aeb3fcd9060bedb162291c",
|
||||
"reftest"
|
||||
],
|
||||
"css/CSS2/normal-flow/max-height-001.xht": [
|
||||
"34a501cb70b591b6998234f3366361c33a064a18",
|
||||
"reftest"
|
||||
|
@ -475573,7 +475688,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"css/css-align/content-distribution/place-content-shorthand-004.html": [
|
||||
"5aa5cda5b2b0204bd2deb5c813532f394644b31f",
|
||||
"17c135945710d209b2e410d36867f6244ac358a0",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-align/content-distribution/place-content-shorthand-005.html": [
|
||||
|
@ -475621,7 +475736,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"css/css-align/default-alignment/parse-justify-items-002.html": [
|
||||
"b74652a3770f5bf8b7184748d62a21625f9121b3",
|
||||
"12902e19304a7f02a52c576f3daf72fd9eb45ff8",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-align/default-alignment/parse-justify-items-003.html": [
|
||||
|
@ -475653,7 +475768,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"css/css-align/default-alignment/place-items-shorthand-004.html": [
|
||||
"d4b6346f68b085a297ba5b15a5803258cbf661da",
|
||||
"51b0eff81deca9f5e056f5db1d49f3e9be80435b",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-align/default-alignment/place-items-shorthand-005.html": [
|
||||
|
@ -479468,6 +479583,10 @@
|
|||
"ec85953fb0594db50a69ca9952092aeab403cf2c",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-color/color-function-parsing.html": [
|
||||
"7c6abb0ab3f4c08d075cb1a5a13fe78964d55e15",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-color/color-resolving-hsl.html": [
|
||||
"672137820a0289306d53b3866ffa1f00daacc019",
|
||||
"testharness"
|
||||
|
@ -537249,7 +537368,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"custom-elements/Document-createElementNS.html": [
|
||||
"04cd97839e98c6082f67740dbcfc7588e2b251b9",
|
||||
"799f59e3bf8ab0830e44faa3ffef6d3303da42eb",
|
||||
"testharness"
|
||||
],
|
||||
"custom-elements/HTMLElement-constructor.html": [
|
||||
|
@ -563625,7 +563744,7 @@
|
|||
"support"
|
||||
],
|
||||
"interfaces/accelerometer.idl": [
|
||||
"eaa4e8fd76cf191c84921df18e9347a087e8c3d9",
|
||||
"badeb96ae83c8173bb00884346d4f6dc675bbffa",
|
||||
"support"
|
||||
],
|
||||
"interfaces/ambient-light.idl": [
|
||||
|
@ -592820,20 +592939,68 @@
|
|||
"368ab4153a7f6843ce65ce924a3b4af92f3488ee",
|
||||
"support"
|
||||
],
|
||||
"webauthn/createcredential-badargs-attestation.https.html": [
|
||||
"397a6f0b95e75cf2b743eb208f6c79c767ec648a",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-authnrselection.https.html": [
|
||||
"f5f5c8316551a921823bfe000031d42d91d9baa1",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-challenge.https.html": [
|
||||
"741efba3e4c583d5983a5005803f718bdaa435b0",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-rp.https.html": [
|
||||
"941a9bda02e22b7d54855e3a4714a49d8392fa9d",
|
||||
"8ab678da79853a5c41ff142704bb4732b026e06c",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-user.https.html": [
|
||||
"37f734eed5ecd34f6feb90bb96154e16a763140a",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-excludecredentials.https.html": [
|
||||
"387387626892215c1552ef5e742fd32d800df4ad",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-extensions.https.html": [
|
||||
"9642dafa7ed7ce75d5812328fcd3ac2239e33ebd",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-passing.https.html": [
|
||||
"32a6ac38f91ec6b887e9e57519eb1603b4abcdbb",
|
||||
"e89da85133f56cf0b5b78f6d6f39b43926ed9fda",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-pubkeycredparams.https.html": [
|
||||
"009193df4404190c820618840104da8db380eaa8",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-timeout.https.html": [
|
||||
"c0e639f8a32a1bc3553fd437a4fcf694a63960c2",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-badargs-rpid.https.html": [
|
||||
"275511dbafc9a536f92e74ef4c0531a7d8b7a437",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-badargs-userverification.https.html": [
|
||||
"5ac7b919d473bfc126c3e57df70c2f0defc60671",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-extensions.https.html": [
|
||||
"ea4d0533a5939927dd9eaa5d81116dbcc2f3ccbe",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-passing.https.html": [
|
||||
"6272128ea3af65ecb4fc40055b062a678bfbb2fd",
|
||||
"1b0f77b533a4e528b3abc484ba4d74b56833131f",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-timeout.https.html": [
|
||||
"b8c71a3fccdf39c2e35bd34a3cd42561cac5836b",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/helpers.js": [
|
||||
"e6224e8e2be8657e2e312f4197cbe0225c819cea",
|
||||
"9ce729fb89ba1863fb14dfc4d567e6b544a5238d",
|
||||
"support"
|
||||
],
|
||||
"webauthn/interfaces.https.html": [
|
||||
|
@ -592845,11 +593012,11 @@
|
|||
"support"
|
||||
],
|
||||
"webauthn/securecontext.http.html": [
|
||||
"afc1492723d140e34027a3bdbf0d1e09843ef5d6",
|
||||
"7abf48e74debed79578e39934d1b84655731a3ea",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/securecontext.https.html": [
|
||||
"7f7a7aba32b9e049c618203121fae0884936643a",
|
||||
"9bdd7e09c7f468b9b0c106d4764d61e77b32131f",
|
||||
"testharness"
|
||||
],
|
||||
"webdriver/OWNERS": [
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[attachment-local-clipping-color-4.html]
|
||||
type: reftest
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[box-shadow-syntax-001.xht]
|
||||
type: reftest
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
[color-function-parsing.html]
|
||||
[Basic sRGB white]
|
||||
expected: FAIL
|
||||
|
||||
[White with lots of space]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB color]
|
||||
expected: FAIL
|
||||
|
||||
[Different case for sRGB]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB color with unnecessary decimals]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB white with 0.5 alpha]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB white with 0 alpha]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB white with 50% alpha]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB white with 0% alpha]
|
||||
expected: FAIL
|
||||
|
||||
[One missing component is 0]
|
||||
expected: FAIL
|
||||
|
||||
[Two missing components are 0]
|
||||
expected: FAIL
|
||||
|
||||
[All components missing]
|
||||
expected: FAIL
|
||||
|
||||
[Display P3 color]
|
||||
expected: FAIL
|
||||
|
||||
[Different case for Display P3]
|
||||
expected: FAIL
|
||||
|
||||
[Unknown color space should fallback]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB color with negative component should clamp to 0]
|
||||
expected: FAIL
|
||||
|
||||
[sRGB color with component > 1 should clamp]
|
||||
expected: FAIL
|
||||
|
||||
[Display P3 color with negative component should clamp to 0]
|
||||
expected: FAIL
|
||||
|
||||
[Display P3 color with component > 1 should clamp]
|
||||
expected: FAIL
|
||||
|
||||
[Alpha > 1 should clamp]
|
||||
expected: FAIL
|
||||
|
||||
[Negative alpha should clamp]
|
||||
expected: FAIL
|
||||
|
|
@ -2,6 +2,3 @@
|
|||
[elementsFromPoint on the root document for points in iframe elements]
|
||||
expected: FAIL
|
||||
|
||||
[elementsFromPoint on inner documents]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[Create-blocked-port.htm]
|
||||
expected: CRASH
|
|
@ -1,8 +1,5 @@
|
|||
[extended-payload-length.html]
|
||||
type: testharness
|
||||
[Application data is (0xFFFF + 1) byte which starts to use the 64 bit 'Extended payload length' field]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
||||
[extended-payload-length.html?wss]
|
||||
type: testharness
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>IndexedDB: Interleaved iteration of multiple cursors</title>
|
||||
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="support-promises.js"></script>
|
||||
<script>
|
||||
// Infrastructure shared by interleaved-cursors-{small,large}.html
|
||||
|
||||
// Number of objects that each iterator goes over.
|
||||
const itemCount = 10;
|
||||
|
||||
|
@ -169,7 +162,7 @@ function interleaveCursors(testCase, store, cursorCount) {
|
|||
});
|
||||
}
|
||||
|
||||
for (let cursorCount of [1, 10, 100, 500]) {
|
||||
function cursorTest(cursorCount) {
|
||||
promise_test(testCase => {
|
||||
return createDatabase(testCase, (database, transaction) => {
|
||||
const store = database.createObjectStore('cache',
|
||||
|
@ -193,4 +186,3 @@ for (let cursorCount of [1, 10, 100, 500]) {
|
|||
});
|
||||
}, `${cursorCount} cursors`);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>IndexedDB: Interleaved iteration of multiple cursors</title>
|
||||
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="support-promises.js"></script>
|
||||
<script src="interleaved-cursors-common.js"></script>
|
||||
<script>
|
||||
cursorTest(250);
|
||||
</script>
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>IndexedDB: Interleaved iteration of multiple cursors</title>
|
||||
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="support-promises.js"></script>
|
||||
<script src="interleaved-cursors-common.js"></script>
|
||||
<script>
|
||||
cursorTest(1);
|
||||
cursorTest(10);
|
||||
cursorTest(100);
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Collapse bottom margin from previous sibling through zero height block to next sibling</title>
|
||||
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
|
||||
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#collapsing-margins" title="8.3.1 Collapsing margins">
|
||||
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div style="overflow:hidden; width:200px; height:400px; background:green;">
|
||||
<div style="margin-bottom:200px;"></div>
|
||||
<div style="height:0;"></div>
|
||||
<div style="height:200px; margin-top:100px; background:white;"></div>
|
||||
<div style="height:200px; background:red;"></div>
|
||||
</div>
|
|
@ -47,6 +47,12 @@
|
|||
checkInvalidValues("start auto")
|
||||
}, "Verify 'auto' values are invalid");
|
||||
|
||||
test(function() {
|
||||
checkInvalidValues("self-start")
|
||||
checkInvalidValues("center self-end")
|
||||
checkInvalidValues("self-end start")
|
||||
}, "Verify self-position values are invalid");
|
||||
|
||||
test(function() {
|
||||
checkInvalidValues("")
|
||||
}, "Verify empty declaration is invalid");
|
||||
|
|
|
@ -19,39 +19,39 @@ document.body.appendChild(container);
|
|||
test(function() {
|
||||
element = document.createElement("div");
|
||||
document.body.appendChild(element);
|
||||
checkValues(element, "justifyItems", "justify-items", "", "legacy");
|
||||
checkValues(element, "justifyItems", "justify-items", "", "normal");
|
||||
}, "Test 'initial' value when nothing is specified");
|
||||
|
||||
test(function() {
|
||||
container.style.display = "";
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "center", "legacy");
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "center", "normal");
|
||||
}, "Test justify-items: 'initial'");
|
||||
|
||||
test(function() {
|
||||
container.style.display = "grid";
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "safe start", "legacy");
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "safe start", "normal");
|
||||
}, "Test grid items justify-items: 'initial'");
|
||||
|
||||
test(function() {
|
||||
container.style.display = "flex";
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "unsafe end", "legacy");
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "unsafe end", "normal");
|
||||
}, "Test flex items justify-items: 'initial'");
|
||||
|
||||
test(function() {
|
||||
container.style.display = "";
|
||||
element.style.position = "absolute";
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "start", "legacy");
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "start", "normal");
|
||||
}, "Test absolute positioned elements justify-items: 'initial'");
|
||||
|
||||
test(function() {
|
||||
container.style.display = "grid";
|
||||
element.style.position = "absolute";
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "end", "legacy");
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "end", "normal");
|
||||
}, "Test absolute positioned grid items justify-items: 'initial'");
|
||||
|
||||
test(function() {
|
||||
container.style.display = "flex";
|
||||
element.style.position = "absolute";
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "end", "legacy");
|
||||
checkInitialValues(element, "justifyItems", "justify-items", "end", "normal");
|
||||
}, "Test absolute positioned flex items justify-items: 'initial'");
|
||||
</script>
|
||||
|
|
|
@ -37,7 +37,18 @@
|
|||
checkInvalidValues("auto")
|
||||
checkInvalidValues("auto right")
|
||||
checkInvalidValues("auto auto")
|
||||
}, "Verify 'auto' value is invalid as first longhand value.");
|
||||
checkInvalidValues("center auto")
|
||||
}, "Verify 'auto' value is invalid.");
|
||||
|
||||
test(function() {
|
||||
checkInvalidValues("legacy")
|
||||
checkInvalidValues("legacy start")
|
||||
checkInvalidValues("end legacy")
|
||||
checkInvalidValues("legacy left")
|
||||
checkInvalidValues("center legacy")
|
||||
checkInvalidValues("start legacy center")
|
||||
}, "Verify 'legacy' value is invalid.");
|
||||
|
||||
|
||||
test(function() {
|
||||
checkInvalidValues("")
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Color 4: color() parsing</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-color-4/#color-function">
|
||||
<meta name="assert" content="Tests basic parsing of the color function">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="test"></div>
|
||||
<script>
|
||||
const div = document.querySelector("#test");
|
||||
function testColorFunction(description, rule, expectedValue) {
|
||||
test(function() {
|
||||
div.style.color = "black";
|
||||
div.style.color = rule;
|
||||
assert_equals(getComputedStyle(div).color, expectedValue);
|
||||
}, description);
|
||||
}
|
||||
|
||||
testColorFunction("Basic sRGB white", "color(srgb 1 1 1)", "color(srgb 1 1 1)");
|
||||
testColorFunction("White with lots of space", "color( srgb 1 1 1 )", "color(srgb 1 1 1)");
|
||||
testColorFunction("sRGB color", "color(srgb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)");
|
||||
testColorFunction("Different case for sRGB", "color(SrGb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)");
|
||||
testColorFunction("sRGB color with unnecessary decimals", "color(srgb 1.00000 0.500000 0.20)", "color(srgb 1 0.5 0.2)");
|
||||
testColorFunction("sRGB white with 0.5 alpha", "color(srgb 1 1 1 / 0.5)", "color(srgb 1 1 1 / 0.5)");
|
||||
testColorFunction("sRGB white with 0 alpha", "color(srgb 1 1 1 / 0)", "color(srgb 1 1 1 / 0)");
|
||||
testColorFunction("sRGB white with 50% alpha", "color(srgb 1 1 1 / 50%)", "color(srgb 1 1 1 / 0.5)");
|
||||
testColorFunction("sRGB white with 0% alpha", "color(srgb 1 1 1 / 0%)", "color(srgb 1 1 1 / 0)");
|
||||
testColorFunction("One missing component is 0", "color(srgb 1 1)", "color(srgb 1 1 0)");
|
||||
testColorFunction("Two missing components are 0", "color(srgb 1)", "color(srgb 1 0 0)");
|
||||
testColorFunction("All components missing", "color(srgb)", "color(srgb 0 0 0)");
|
||||
testColorFunction("Display P3 color", "color(display-p3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)");
|
||||
testColorFunction("Different case for Display P3", "color(dIspLaY-P3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)");
|
||||
|
||||
testColorFunction("Unknown color space should fallback", "color(unknown 1 2 3, red)", "color(unknown 1 2 3, red)");
|
||||
|
||||
testColorFunction("sRGB color with negative component should clamp to 0", "color(srgb -0.25 0.5 0.75)", "color(srgb 0 0.5 0.75)");
|
||||
testColorFunction("sRGB color with component > 1 should clamp", "color(srgb 0.25 1.5 0.75)", "color(srgb 0.25 1 0.75)");
|
||||
testColorFunction("Display P3 color with negative component should clamp to 0", "color(display-p3 0.5 -199 0.75)", "color(display-p3 0.5 0 0.75)");
|
||||
testColorFunction("Display P3 color with component > 1 should clamp", "color(display-p3 184 1.00001 2347329746587)", "color(display-p3 1 1 1)");
|
||||
testColorFunction("Alpha > 1 should clamp", "color(srgb 0.1 0.2 0.3 / 1.9)", "color(srgb 0.1 0.2 0.3)");
|
||||
testColorFunction("Negative alpha should clamp", "color(srgb 1 1 1 / -0.2)", "color(srgb 1 1 1 / 0)");
|
||||
|
||||
// Invalid properties
|
||||
testColorFunction("Empty", "color()", "rgb(0, 0, 0)");
|
||||
testColorFunction("Bad color space", "color(banana 1 1 1)", "rgb(0, 0, 0)");
|
||||
testColorFunction("Bad Display P3 color space", "color(displayp3 1 1 1)", "rgb(0, 0, 0)");
|
||||
testColorFunction("No color space", "color(1 1 1)", "rgb(0, 0, 0)");
|
||||
testColorFunction("Too many parameters", "color(srgb 1 1 1 1)", "rgb(0, 0, 0)");
|
||||
testColorFunction("Way too many parameters", "color(srgb 1 1 1 1 1)", "rgb(0, 0, 0)");
|
||||
testColorFunction("Bad parameters", "color(srgb 1 eggs 1)", "rgb(0, 0, 0)");
|
||||
testColorFunction("Bad alpha", "color(srgb 1 1 1 / bacon)", "rgb(0, 0, 0)");
|
||||
testColorFunction("Junk after alpha", "color(srgb 1 1 1 / 1 cucumber)", "rgb(0, 0, 0)");
|
||||
</script>
|
|
@ -23,6 +23,14 @@ test(() => {
|
|||
assert_false(element instanceof MyElement2);
|
||||
}, 'autonomous: document.createElementNS should check namespaces.');
|
||||
|
||||
test(() => {
|
||||
const xhtmlNS = 'http://www.w3.org/1999/xhtml';
|
||||
assert_false(document.createElementNS(xhtmlNS, 'x-foo') instanceof HTMLUnknownElement);
|
||||
assert_false(document.createElementNS(xhtmlNS, 'x-foo', {}) instanceof HTMLUnknownElement);
|
||||
assert_false((new Document()).createElementNS(xhtmlNS, 'x-foo') instanceof HTMLUnknownElement);
|
||||
assert_false((new Document()).createElementNS(xhtmlNS, 'x-foo', {}) instanceof HTMLUnknownElement);
|
||||
}, 'autonomous: document.createElementNS should not create HTMLUnknownElement for a valid custom element name');
|
||||
|
||||
test(() => {
|
||||
class MyBuiltinElement extends HTMLElement {};
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
[Constructor(optional SensorOptions options), SecureContext, Exposed=Window]
|
||||
enum LocalCoordinateSystem { "device", "screen" };
|
||||
|
||||
dictionary SpatialSensorOptions : SensorOptions {
|
||||
LocalCoordinateSystem referenceFrame = "device";
|
||||
};
|
||||
|
||||
[Constructor(optional SpatialSensorOptions options), SecureContext, Exposed=Window]
|
||||
interface Accelerometer : Sensor {
|
||||
readonly attribute double? x;
|
||||
readonly attribute double? y;
|
||||
readonly attribute double? z;
|
||||
};
|
||||
|
||||
[Constructor(optional SensorOptions options), SecureContext, Exposed=Window]
|
||||
[Constructor(optional SpatialSensorOptions options), SecureContext, Exposed=Window]
|
||||
interface LinearAccelerationSensor : Accelerometer {
|
||||
};
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ SET TIMEOUT: streams/writable-streams/byte-length-queuing-strategy.js
|
|||
SET TIMEOUT: user-timing/*
|
||||
SET TIMEOUT: webaudio/js/lodash.js
|
||||
SET TIMEOUT: webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html
|
||||
SET TIMEOUT: webauthn/*timeout.https.html
|
||||
SET TIMEOUT: webdriver/*
|
||||
SET TIMEOUT: webmessaging/*
|
||||
SET TIMEOUT: websockets/*
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() attestation parameter Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// attestation bad values
|
||||
new CreateCredentialsTest("options.publicKey.attestation", {}).runTest("Bad attestation parameter: attestation is empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", []).runTest("Bad attestation parameter: attestation is empty array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", null).runTest("Bad attestation parameter: attestation is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "noneofyourbusiness").runTest("Bad attestation parameter: attestation is \"noneofyourbusiness\"", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "").runTest("Bad attestation parameter: attestation is empty string", new TypeError());
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
</script>
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() authenticator selection Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var defaultAuthnrSel = {
|
||||
authenticatorAttachment: "cross-platform",
|
||||
requireResidentKey: false,
|
||||
userVerification: "preferred"
|
||||
};
|
||||
// attachment
|
||||
var authnrSelAttachPlatform = cloneObject(defaultAuthnrSel);
|
||||
authnrSelAttachPlatform.authenticatorAttachment = "platform";
|
||||
var authnrSelBadAttachEmptyStr = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadAttachEmptyStr.authenticatorAttachment = "";
|
||||
var authnrSelBadAttachEmptyObj = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadAttachEmptyObj.authenticatorAttachment = {};
|
||||
var authnrSelBadAttachNull = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadAttachNull.authenticatorAttachment = null;
|
||||
// resident key
|
||||
var authnrSelRkTrue = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkTrue.requireResidentKey = true;
|
||||
var authnrSelRkBadString = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkBadString.requireResidentKey = "foo";
|
||||
// user verification
|
||||
var authnrSelUvRequired = cloneObject(defaultAuthnrSel);
|
||||
authnrSelUvRequired.userVerification = "required";
|
||||
var authnrSelBadUvEmptyStr = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvEmptyStr.userVerification = "";
|
||||
var authnrSelBadUvEmptyObj = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvEmptyObj.userVerification = {};
|
||||
var authnrSelBadUvStr = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvStr.userVerification = "requiredshirtshoestshirt";
|
||||
var authnrSelBadUvNull = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvNull.userVerification = null;
|
||||
|
||||
// authenticatorSelection bad values
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", []).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", null).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", "").runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", "none").runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is string", new TypeError());
|
||||
|
||||
// authenticatorSelection bad attachment values
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachEmptyStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachEmptyObj).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachNull).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is null", new TypeError());
|
||||
// XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelAttachPlatform).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment platform", "NotAllowedError");
|
||||
|
||||
// authenticatorSelection bad requireResidentKey values
|
||||
// XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkTrue).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey true", "NotAllowedError");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkBadString).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey is string", new TypeError());
|
||||
// TODO: not sure if rk is "boolean" or "truthy"; add test cases if it should only accept boolean values
|
||||
|
||||
// authenticatorSelection bad userVerification values
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvEmptyStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvEmptyObj).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification bad value", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvNull).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification null", new TypeError());
|
||||
// XXX: assumes this is a mock authenticator the properly reports that it is not doing userVerfication
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvRequired).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification required", "NotAllowedError");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, cloneObject */
|
||||
</script>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() challenge Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// bad challenge values
|
||||
new CreateCredentialsTest({path: "options.publicKey.challenge", value: undefined}).runTest("Bad challenge: challenge missing", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", "hi mom").runTest("Bad challenge: challenge is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", null).runTest("Bad challenge: challenge is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", {}).runTest("Bad challenge: challenge is empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Array()).runTest("Bad challenge: challenge is empty Array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(0)).runTest("Bad challenge: challenge is empty ArrayBuffer", new TypeError());
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
</script>
|
|
@ -12,29 +12,29 @@ standardSetup(function() {
|
|||
"use strict";
|
||||
|
||||
// rp bad values
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp", value: undefined}).testBadArgs("rp missing");
|
||||
new CreateCredentialsTest("options.publicKey.rp", "hi mom").testBadArgs("rp is string");
|
||||
// new CreateCredentialsTest("options.publicKey.rp", {}).testBadArgs("rp is empty object");
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp", value: undefined}).runTest("Bad rp: rp missing", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp", "hi mom").runTest("Bad rp: rp is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp", {}).runTest("Bad rp: rp is empty object", new TypeError());
|
||||
|
||||
// rp.id
|
||||
// new CreateCredentialsTest({path: "options.publicKey.rp.id", value: undefined}).testBadArgs("rp missing id");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", {}).testBadArgs("Bad rp: id is object");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", null).testBadArgs("Bad rp: id is null");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "").testBadArgs("Bad rp: id is empty String");
|
||||
// // rp.id
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", {}).runTest("Bad rp: id is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", null).runTest("Bad rp: id is null", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "").runTest("Bad rp: id is empty String", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "invalid domain.com").runTest("Bad rp: id is invalid domain (has space)", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "-invaliddomain.com").runTest("Bad rp: id is invalid domain (starts with dash)", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "0invaliddomain.com").runTest("Bad rp: id is invalid domain (starts with number)", "SecurityError");
|
||||
|
||||
// rp.name
|
||||
// new CreateCredentialsTest({path: "options.publicKey.rp.name", value: undefined}).testBadArgs("rp missing name");
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", {}).testBadArgs("Bad rp: name is object");
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", null).testBadArgs("Bad rp: name is null");
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", "").testBadArgs("Bad rp: name is empty String");
|
||||
// // rp.name
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.name", value: undefined}).runTest("rp missing name", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", {}).runTest("Bad rp: name is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", null).runTest("Bad rp: name is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", "").runTest("Bad rp: name is empty String", new TypeError());
|
||||
|
||||
// rp.icon
|
||||
// new CreateCredentialsTest({path: "options.publicKey.rp.icon", value: undefined}).testBadArgs("rp missing icon");
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", {}).testBadArgs("Bad rp: icon is object");
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", null).testBadArgs("Bad rp: icon is null");
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", "").testBadArgs("Bad rp: icon is empty String");
|
||||
// TODO: see https://github.com/w3c/webauthn/issues/587 for the 'undefined' tests that are commented out above
|
||||
// TODO: unicode tests for icon URL (see also: USVString)
|
||||
// // rp.icon
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", {}).runTest("Bad rp: icon is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", null).runTest("Bad rp: icon is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", "").runTest("Bad rp: icon is empty String", new TypeError());
|
||||
// // TODO: unicode tests for icon URL (see also: USVString)
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() user Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// user bad values
|
||||
new CreateCredentialsTest({path: "options.publicKey.user", value: undefined}).runTest("Bad user: user missing", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user", "hi mom").runTest("Bad user: user is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user", {}).runTest("Bad user: user is empty object", new TypeError());
|
||||
|
||||
// // user.id
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.id", value: undefined}).runTest("Bad user: id is undefined", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", {}).runTest("Bad user: id is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", null).runTest("Bad user: id is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", "").runTest("Bad user: id is empty String", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Array()).runTest("Bad user: id is empty Array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(0)).runTest("Bad user: id is empty ArrayBuffer", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(65)).runTest("Bad user: ArrayBuffer id is too long (65 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int16Array(33)).runTest("Bad user: Int16Array id is too long (66 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int32Array(17)).runTest("Bad user: Int32Array id is too long (68 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Float32Array(17)).runTest("Bad user: Float32Array id is too long (68 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Float64Array(9)).runTest("Bad user: Float64Array id is too long (72 bytes)", new TypeError());
|
||||
var buf = new ArrayBuffer(65);
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new DataView(buf)).runTest("Bad user: id is too long (65 bytes)", new TypeError());
|
||||
|
||||
// // user.name
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.name", value: undefined}).runTest("user missing name", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.name", {}).runTest("Bad user: name is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.name", null).runTest("Bad user: name is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.name", "").runTest("Bad user: name is empty String", new TypeError());
|
||||
|
||||
// // user.icon
|
||||
new CreateCredentialsTest("options.publicKey.user.icon", {}).runTest("Bad user: icon is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.icon", null).runTest("Bad user: icon is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.icon", "").runTest("Bad user: icon is empty String", new TypeError());
|
||||
// // TODO: unicode tests for icon URL (see also: USVString)
|
||||
|
||||
// // user.displayName
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.displayName", value: undefined}).runTest("Bad user: displayName is undefined", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.displayName", {}).runTest("Bad user: displayName is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.displayName", null).runTest("Bad user: displayName is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.displayName", "").runTest("Bad user: displayName is empty String", new TypeError());
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
</script>
|
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() excludeCredentials Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// bad excludeCredentials values
|
||||
new CreateCredentialsTest("options.publicKey.excludeCredentials", "hi mom").runTest("Bad excludeCredentials: string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.excludeCredentials", {}).runTest("Bad excludeCredentials: empty object", new TypeError());
|
||||
// TODO: bad excludeCredentials with [{.type}] or [{.id}] or [{.transports}] wrong
|
||||
|
||||
// good excludeCredentials values
|
||||
new CreateCredentialsTest({path: "options.publicKey.excludeCredentials", value: undefined}).runTest("excludeCredentials missing");
|
||||
new CreateCredentialsTest("options.publicKey.excludeCredentials", []).runTest("excludeCredentials empty array");
|
||||
|
||||
// proper excludeCredentials behavior
|
||||
// should error on excluding existing credential
|
||||
promise_test((t) => {
|
||||
var cred1;
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
return createCredential();
|
||||
})
|
||||
.then((cred) => {
|
||||
cred1 = cred;
|
||||
var excludeCred = {
|
||||
id: cred.rawId,
|
||||
type: "public-key"
|
||||
};
|
||||
var args = {
|
||||
options: {
|
||||
publicKey: {
|
||||
excludeCredentials: [excludeCred]
|
||||
}
|
||||
}
|
||||
};
|
||||
var p = createCredential(args);
|
||||
return promise_rejects (t, "NotAllowedError", p, "expected to fail on excluded credenetial");
|
||||
});
|
||||
}, "exclude existing credential");
|
||||
|
||||
// should not error on excluding random credential
|
||||
promise_test(() => {
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
return createCredential();
|
||||
})
|
||||
.then(() => {
|
||||
var randomCredId = new Uint8Array(162);
|
||||
window.crypto.getRandomValues(randomCredId);
|
||||
|
||||
var excludeCred = {
|
||||
id: randomCredId,
|
||||
type: "public-key"
|
||||
};
|
||||
var args = {
|
||||
options: {
|
||||
publicKey: {
|
||||
excludeCredentials: [excludeCred]
|
||||
}
|
||||
}
|
||||
};
|
||||
return createCredential(args);
|
||||
});
|
||||
}, "exclude random (non-existing) credential");
|
||||
|
||||
// TODO: exclude including transport type (USB, BLE, NFC)
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, createCredential, promise_test, promise_rejects */
|
||||
</script>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() extensions Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var dummyExtension = {
|
||||
foo: true,
|
||||
bar: "yup"
|
||||
};
|
||||
|
||||
// bad extension values
|
||||
new CreateCredentialsTest("options.publicKey.extensions", "hi mom").runTest("Bad extensions: extensions is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", null).runTest("Bad extensions: extensions is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", []).runTest("Bad extensions: extensions is empty Array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", new ArrayBuffer(0)).runTest("Bad extensions: extensions is empty ArrayBuffer", new TypeError());
|
||||
var badJson = '{"foo": true, "bar: "yup"}'; // missing quote after "bar"
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: badJson}).runTest("Bad extensions: malformatted JSON", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: dummyExtension}).runTest("Bad extensions: JavaScript object", new TypeError());
|
||||
var badExtId = {};
|
||||
badExtId[createRandomString(65)] = dummyExtension;
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {badExtId: dummyExtension}).runTest("Bad extensions: extension ID too long", new TypeError());
|
||||
|
||||
// phony extensions
|
||||
// TODO: not sure if this should pass or fail
|
||||
// should be clarified as part of https://github.com/w3c/webauthn/pull/765
|
||||
var randomExtId = {};
|
||||
randomExtId[createRandomString(64)] = dummyExtension;
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: JSON.stringify(randomExtId)}).runTest("extensions is a nonsensical JSON string");
|
||||
|
||||
// TODO
|
||||
// defined extensions:
|
||||
// * appid
|
||||
// * txAuthSimple
|
||||
// * txAuthGeneric
|
||||
// * authnSel
|
||||
// * exts
|
||||
// * uvi
|
||||
// * loc
|
||||
// * uvm
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, createRandomString */
|
||||
</script>
|
|
@ -12,9 +12,108 @@ standardSetup(function() {
|
|||
"use strict";
|
||||
|
||||
// CreateCredentialTest passing tests
|
||||
new CreateCredentialsTest().test();
|
||||
|
||||
// default arguments
|
||||
new CreateCredentialsTest().runTest("passing credentials.create() with default arguments");
|
||||
|
||||
// rp
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.id", value: window.location.host}).runTest("passing credentials.create() with rpId (host and port)");
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.id", value: window.location.hostname}).runTest("passing credentials.create() with rpId (hostname)");
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.icon", value: undefined}).runTest("passing credentials.create() without rp.icon");
|
||||
|
||||
// user
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(1)).runTest("very short user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(64)).runTest("max length user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Uint8Array(64)).runTest("Uint8Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int8Array(64)).runTest("Int8Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int16Array(32)).runTest("Int16Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int32Array(16)).runTest("Int32Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Float32Array(16)).runTest("Float32Array user id");
|
||||
var dvBuf1 = new ArrayBuffer(16);
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new DataView(dvBuf1)).runTest("DataView user id");
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.icon", value: undefined}).runTest("passing credentials.create() without user.icon");
|
||||
|
||||
// good challenge values
|
||||
// all these challenges are zero-filled buffers... think anyone will complain?
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Int16Array(33)).runTest("Int16Array challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Int32Array(17)).runTest("Int32Array challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Float32Array(17)).runTest("Float32Array challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Float64Array(9)).runTest("Float64Array challenge");
|
||||
var dvBuf2 = new ArrayBuffer(65);
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new DataView(dvBuf2)).runTest("DataView challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(8192)).runTest("Absurdly large challenge");
|
||||
|
||||
// good pubKeyCredParams values
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", []).runTest("Bad pubKeyCredParams: pubKeyCredParams is empty Array");
|
||||
const pkParamEC256 = {
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA256
|
||||
};
|
||||
const pkParamEC512 = {
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA512
|
||||
};
|
||||
// XXX: presumes all mock authenticators support EC256
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256]).runTest("EC256 pubKeyCredParams");
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
|
||||
.runTest("SelectEC256 pubKeyCredParams from a list");
|
||||
// TODO: currently most browsers are mocking FIDO U2F, which is EC256 only
|
||||
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512]).runTest("EC512 pubKeyCredParams");
|
||||
|
||||
// NOTE: excludeCredentials parameter -- see also: createcredential-excludecredentials.https.html
|
||||
|
||||
// timeout
|
||||
new CreateCredentialsTest({path: "options.publicKey.timeout", value: undefined}).runTest("passing credentials.create() with no timeout");
|
||||
|
||||
// valid authenticatorSelection values
|
||||
var defaultAuthnrSel = {
|
||||
authenticatorAttachment: "cross-platform",
|
||||
requireResidentKey: false,
|
||||
userVerification: "preferred"
|
||||
};
|
||||
// attachment
|
||||
var authnrSelAttachUndef = cloneObject(defaultAuthnrSel);
|
||||
authnrSelAttachUndef.authenticatorAttachment = undefined;
|
||||
// resident key
|
||||
var authnrSelRkUndef = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkUndef.requireResidentKey = undefined;
|
||||
var authnrSelRkFalse = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkFalse.requireResidentKey = false;
|
||||
// user verification
|
||||
var authnrSelUvUndef = cloneObject(defaultAuthnrSel);
|
||||
authnrSelUvUndef.userVerification = undefined;
|
||||
var authnrSelUvDiscouraged = cloneObject(defaultAuthnrSel);
|
||||
authnrSelUvDiscouraged.userVerification = "discouraged";
|
||||
new CreateCredentialsTest({path: "options.publicKey.authenticatorSelection", value: undefined}).runTest("authenticatorSelection is undefined");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", {}).runTest("authenticatorSelection is empty object");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", cloneObject(defaultAuthnrSel)).runTest("authenticatorSelection default values");
|
||||
|
||||
// authnr selection attachment
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelAttachUndef).runTest("authenticatorSelection attachment undefined");
|
||||
|
||||
// authnr selection resident key
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkUndef).runTest("authenticatorSelection residentKey undefined");
|
||||
// XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkFalse).runTest("authenticatorSelection residentKey false");
|
||||
|
||||
// authnr selection user verification
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvUndef).runTest("authenticatorSelection userVerification undefined");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvDiscouraged).runTest("authenticatorSelection userVerification discouraged");
|
||||
|
||||
|
||||
// good attestation values
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "none").runTest("attestation parameter: attestation is \"none\"");
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "indirect").runTest("attestation parameter: attestation is \"indirect\"");
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "direct").runTest("attestation parameter: attestation is \"direct\"");
|
||||
new CreateCredentialsTest({path: "options.publicKey.attestation", value: undefined}).runTest("attestation parameter: attestation is undefined");
|
||||
// TODO: test this with multiple mock authenticators to make sure that the right options are chosen when available?
|
||||
|
||||
// good extension values
|
||||
new CreateCredentialsTest({path: "options.publicKey.extensions", value: undefined}).runTest("extensions undefined");
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {}).runTest("extensions are empty object");
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: "", bar: "", bat: ""}).runTest("extensions are dict of empty strings");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
/* globals standardSetup, CreateCredentialsTest, cose_alg_ECDSA_w_SHA256, cose_alg_ECDSA_w_SHA512, cloneObject */
|
||||
</script>
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() pubKeyCredParams Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var badType = {
|
||||
type: "something-else",
|
||||
alg: cose_alg_ECDSA_w_SHA512
|
||||
};
|
||||
var badTypeEmptyString = cloneObject(badType);
|
||||
badTypeEmptyString.type = "";
|
||||
var badTypeNull = cloneObject(badType);
|
||||
badTypeNull.type = null;
|
||||
var badTypeEmptyObj = cloneObject(badType);
|
||||
badTypeEmptyObj.type = {};
|
||||
|
||||
var badAlg = {
|
||||
type: "public-key",
|
||||
alg: 42
|
||||
};
|
||||
var badAlgZero = cloneObject(badAlg);
|
||||
badAlgZero.alg = 0;
|
||||
|
||||
// bad pubKeyCredParams values
|
||||
new CreateCredentialsTest({path: "options.publicKey.pubKeyCredParams", value: undefined}).runTest("Bad pubKeyCredParams: pubKeyCredParams is undefined", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", "hi mom").runTest("Bad pubKeyCredParams: pubKeyCredParams is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", null).runTest("Bad pubKeyCredParams: pubKeyCredParams is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badType]).runTest("Bad pubKeyCredParams: first param has bad type (\"something-else\")", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyString]).runTest("Bad pubKeyCredParams: first param has bad type (\"\")", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeNull]).runTest("Bad pubKeyCredParams: first param has bad type (null)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyObj]).runTest("Bad pubKeyCredParams: first param has bad type (empty object)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlg]).runTest("Bad pubKeyCredParams: first param has bad alg (42)", "NotSupportedError");
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlgZero]).runTest("Bad pubKeyCredParams: first param has bad alg (0)", "NotSupportedError");
|
||||
|
||||
// TODO: come back to this when mock authenticators support multiple cryptos so that we can test the preference ranking
|
||||
// function verifyEC256(res) {
|
||||
// debug ("verifyEC256 got", res);
|
||||
// debug ("client data JSON", ab2str(res.response.clientDataJSON));
|
||||
// parseAuthenticatorData(res.response.attestationObject);
|
||||
// }
|
||||
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256, pkParamEC512])
|
||||
// .afterTest(verifyEC256)
|
||||
// .runTest("EC256, EC512 pubKeyCredParams");
|
||||
// function verifyEC512(res) {
|
||||
// debug ("verifyEC512 got", res);
|
||||
// debug ("client data JSON", ab2str(res.response.clientDataJSON));
|
||||
// // parseAuthenticatorData(res.response.attestationObject);
|
||||
// printHex ("clientDataJSON", res.response.clientDataJSON);
|
||||
// printHex ("attestationObject", res.response.attestationObject);
|
||||
// }
|
||||
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
|
||||
// .afterTest(verifyEC512)
|
||||
// .runTest("EC512, EC256 pubKeyCredParams");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, cose_alg_ECDSA_w_SHA512, cloneObject */
|
||||
</script>
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() timeout Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// bad timeout values
|
||||
// TODO: there is some debate as to whether MAX_UNSIGNED_LONG + 1 and / or -1 should be disallowed since they get converted to valid values internally
|
||||
// new CreateCredentialsTest({path: "options.publicKey.timeout", value: -1}).runTest("Bad timeout: negative", new TypeError());
|
||||
// new CreateCredentialsTest({path: "options.publicKey.timeout", value: 4294967295 + 1}).runTest("Bad timeout: too big", new TypeError());
|
||||
|
||||
// timeout test
|
||||
// XXX: this probably always passes with most mock authenticators unless
|
||||
// some setup happens right here to make sure they don't return a credential
|
||||
// right away. So... uhh... I guess test this with a real authenticator if you
|
||||
// want to see if it really works.
|
||||
promise_test(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
var args = {
|
||||
options: {
|
||||
publicKey: {
|
||||
timeout: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
reject(new Error ("timed out"));
|
||||
}, 1000);
|
||||
|
||||
createCredential(args).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
}, "ensure create credential times out");
|
||||
// TODO: createCredential.timeout > 1s && setTimeout < 1s
|
||||
// TODO: createCredential.timeout < 5s && setTimeout > 5s
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, createCredential, promise_test */
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn credential.get() rpId Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var credPromise = createCredential();
|
||||
|
||||
new GetCredentialsTest("options.publicKey.rpId", "")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: empty string", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", null)
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: null", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", "invalid domain.com")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: invalid domain (has space)", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", "-invaliddomain.com")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: invalid domain (starts with dash)", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", "0invaliddomain.com")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: invalid domain (starts with number)", "SecurityError");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.get() user verification Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var credPromise = createCredential();
|
||||
|
||||
// authenticatorSelection bad userVerification values
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: empty string", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.userVerification", {})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: empty object", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "requiredshirtshoestshirt")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: bad value", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.userVerification", null)
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: null", new TypeError());
|
||||
// XXX: assumes this is a mock authenticator the properly reports that it is not doing userVerfication
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "required")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: \"required\"", "NotAllowedError");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.get() extensions Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var dummyExtension = {
|
||||
foo: true,
|
||||
bar: "yup"
|
||||
};
|
||||
var credPromise = createCredential();
|
||||
|
||||
// bad extension values
|
||||
new GetCredentialsTest("options.publicKey.extensions", "hi mom")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is string", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", null)
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is null", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", [])
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is empty Array", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", new ArrayBuffer(0))
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is empty ArrayBuffer", new TypeError());
|
||||
var badJson = '{"foo": true, "bar: "yup"}'; // missing quote after "bar"
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: badJson})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: malformatted JSON", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: dummyExtension})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: JavaScript object", new TypeError());
|
||||
var badExtId = {};
|
||||
badExtId[createRandomString(65)] = dummyExtension;
|
||||
new GetCredentialsTest("options.publicKey.extensions", {badExtId: dummyExtension})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extension ID too long", new TypeError());
|
||||
|
||||
// phony extensions
|
||||
// TODO: not sure if this should pass or fail
|
||||
// should be clarified as part of https://github.com/w3c/webauthn/pull/765
|
||||
var randomExtId = {};
|
||||
randomExtId[createRandomString(64)] = dummyExtension;
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: JSON.stringify(randomExtId)})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions is a nonsensical JSON string");
|
||||
|
||||
// TODO
|
||||
// defined extensions:
|
||||
// * appid
|
||||
// * txAuthSimple
|
||||
// * txAuthGeneric
|
||||
// * authnSel
|
||||
// * exts
|
||||
// * uvi
|
||||
// * loc
|
||||
// * uvm
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createRandomString, createCredential */
|
||||
</script>
|
|
@ -11,11 +11,56 @@
|
|||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// GetCredentialsTest passing tests
|
||||
// new GetCredentialsTest().addCredential();
|
||||
new GetCredentialsTest().addCredential().test();
|
||||
var credPromise = createCredential();
|
||||
|
||||
// GetCredentialsTest with default args
|
||||
new GetCredentialsTest()
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.get() with default args");
|
||||
|
||||
// timeout
|
||||
new GetCredentialsTest({path: "options.publicKey.timeout", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.create() with no timeout");
|
||||
|
||||
// rpId
|
||||
new GetCredentialsTest({path: "options.publicKey.rpId", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("rpId undefined");
|
||||
new GetCredentialsTest({path: "options.publicKey.rpId", value: window.location.host})
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.get() with rpId (host and port)");
|
||||
new GetCredentialsTest({path: "options.publicKey.rpId", value: window.location.hostname})
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.get() with rpId (hostname)");
|
||||
|
||||
// allowCredentials
|
||||
new GetCredentialsTest({path: "options.publicKey.allowCredentials", value: undefined})
|
||||
.runTest("no credential specified");
|
||||
|
||||
// authnr selection user verification
|
||||
new GetCredentialsTest({path: "options.publicKey.userVerification", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("authenticatorSelection userVerification undefined");
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "preferred")
|
||||
.addCredential(credPromise)
|
||||
.runTest("authenticatorSelection userVerification preferred");
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "discouraged")
|
||||
.addCredential(credPromise)
|
||||
.runTest("authenticatorSelection userVerification discouraged");
|
||||
|
||||
// good extension values
|
||||
new GetCredentialsTest({path: "options.publicKey.extensions", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions undefined");
|
||||
new GetCredentialsTest("options.publicKey.extensions", {})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions are empty object");
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: "", bar: "", bat: ""})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions are dict of empty strings");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.get() timeout Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var credPromise = createCredential();
|
||||
|
||||
// bad timeout values
|
||||
// TODO: there is some debate as to whether MAX_UNSIGNED_LONG + 1 and / or -1 should be disallowed since they get converted to valid values internally
|
||||
// new GetCredentialsTest({path: "options.publicKey.timeout", value: -1})
|
||||
// .addCredential(credPromise)
|
||||
// .runTest("Bad timeout: negative", new TypeError());
|
||||
// new GetCredentialsTest({path: "options.publicKey.timeout", value: 4294967295 + 1})
|
||||
// .addCredential(credPromise)
|
||||
// .runTest("Bad timeout: too big", new TypeError());
|
||||
|
||||
// timeout test
|
||||
// XXX: this probably always passes with most mock authenticators unless
|
||||
// some setup happens right here to make sure they don't return a credential
|
||||
// right away. So... uhh... I guess test this with a real authenticator if you
|
||||
// want to see if it really works.
|
||||
var timer;
|
||||
function startTimer() {
|
||||
timer = setTimeout(() => {
|
||||
throw new Error("Timer went off before timeout");
|
||||
}, 1000);
|
||||
}
|
||||
function stopTimer() {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
new GetCredentialsTest({path: "options.publicKey.timeout", value: 1})
|
||||
.addCredential(credPromise)
|
||||
.beforeTest(startTimer)
|
||||
.afterTest(stopTimer)
|
||||
.runTest("ensure create credential times out");
|
||||
// TODO: createCredential.timeout > 1s && setTimeout < 1s
|
||||
// TODO: createCredential.timeout < 5s && setTimeout > 5s
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
/* Useful constants for working with COSE key objects */
|
||||
// Useful constants for working with COSE key objects
|
||||
const cose_kty = 1;
|
||||
const cose_kty_ec2 = 2;
|
||||
const cose_alg = 3;
|
||||
|
@ -10,6 +9,117 @@ const cose_crv_P256 = 1;
|
|||
const cose_crv_x = -2;
|
||||
const cose_crv_y = -3;
|
||||
|
||||
/**
|
||||
* These are the default arguments that will be passed to navigator.credentials.create()
|
||||
* unless modified by a specific test case
|
||||
*/
|
||||
var createCredentialDefaultArgs = {
|
||||
options: {
|
||||
publicKey: {
|
||||
// Relying Party:
|
||||
rp: {
|
||||
name: "Acme",
|
||||
icon: "https://www.w3.org/StyleSheets/TR/2016/logos/W3C"
|
||||
},
|
||||
|
||||
// User:
|
||||
user: {
|
||||
id: new Uint8Array(16), // Won't survive the copy, must be rebuilt
|
||||
name: "john.p.smith@example.com",
|
||||
displayName: "John P. Smith",
|
||||
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
|
||||
},
|
||||
|
||||
pubKeyCredParams: [{
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA256,
|
||||
}],
|
||||
|
||||
timeout: 60000, // 1 minute
|
||||
excludeCredentials: [] // No excludeList
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* These are the default arguments that will be passed to navigator.credentials.get()
|
||||
* unless modified by a specific test case
|
||||
*/
|
||||
var getCredentialDefaultArgs = {
|
||||
options: {
|
||||
publicKey: {
|
||||
timeout: 60000
|
||||
// allowCredentials: [newCredential]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function createCredential(opts) {
|
||||
opts = opts || {};
|
||||
|
||||
// set the default options
|
||||
var createArgs = cloneObject(createCredentialDefaultArgs);
|
||||
let challengeBytes = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
createArgs.options.publicKey.challenge = challengeBytes;
|
||||
createArgs.options.publicKey.user.id = new Uint8Array(16);
|
||||
|
||||
// change the defaults with any options that were passed in
|
||||
extendObject (createArgs, opts);
|
||||
|
||||
// create the credential, return the Promise
|
||||
return navigator.credentials.create(createArgs.options);
|
||||
}
|
||||
|
||||
function createRandomString(len) {
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for(var i = 0; i < len; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
function ab2str(buf) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(buf));
|
||||
}
|
||||
|
||||
// Useful constants for working with attestation data
|
||||
const authenticator_data_user_present = 0x01;
|
||||
const authenticator_data_user_verified = 0x04;
|
||||
const authenticator_data_attested_cred_data = 0x40;
|
||||
const authenticator_data_extension_data = 0x80;
|
||||
|
||||
function parseAuthenticatorData(buf) {
|
||||
if (buf.byteLength < 37) {
|
||||
throw new TypeError ("parseAuthenticatorData: buffer must be at least 37 bytes");
|
||||
}
|
||||
|
||||
printHex ("authnrData", buf);
|
||||
|
||||
var authnrData = new DataView(buf);
|
||||
var authnrDataObj = {};
|
||||
authnrDataObj.length = buf.byteLength;
|
||||
|
||||
authnrDataObj.rpIdHash = new Uint8Array (buf.slice (0,32));
|
||||
authnrDataObj.rawFlags = authnrData.getUint8(32);
|
||||
authnrDataObj.counter = authnrData.getUint32(33, false);
|
||||
authnrDataObj.rawCounter = [];
|
||||
authnrDataObj.rawCounter[0] = authnrData.getUint8(33);
|
||||
authnrDataObj.rawCounter[1] = authnrData.getUint8(34);
|
||||
authnrDataObj.rawCounter[2] = authnrData.getUint8(35);
|
||||
authnrDataObj.rawCounter[3] = authnrData.getUint8(36);
|
||||
authnrDataObj.flags = {};
|
||||
|
||||
authnrDataObj.flags.userPresent = (authnrDataObj.rawFlags&authenticator_data_user_present)?true:false;
|
||||
authnrDataObj.flags.userVerified = (authnrDataObj.rawFlags&authenticator_data_user_verified)?true:false;
|
||||
authnrDataObj.flags.attestedCredentialData = (authnrDataObj.rawFlags&authenticator_data_attested_cred_data)?true:false;
|
||||
authnrDataObj.flags.extensionData = (authnrDataObj.rawFlags&authenticator_data_extension_data)?true:false;
|
||||
|
||||
return authnrDataObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* TestCase
|
||||
*
|
||||
|
@ -118,66 +228,127 @@ class TestCase {
|
|||
|
||||
/**
|
||||
* run the test function with the top-level properties of the test object applied as arguments
|
||||
* expects the test to pass, and then validates the results
|
||||
*/
|
||||
test(desc) {
|
||||
promise_test(() => {
|
||||
return this.doIt()
|
||||
.then((ret) => {
|
||||
// check the result
|
||||
this.validateRet(ret);
|
||||
return ret;
|
||||
});
|
||||
}, desc);
|
||||
testPasses(desc) {
|
||||
return this.doIt()
|
||||
.then((ret) => {
|
||||
// check the result
|
||||
this.validateRet(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* run the test function with the top-level properties of the test object applied as arguments
|
||||
* expects the test to fail
|
||||
*/
|
||||
testFails(t, testDesc, expectedErr) {
|
||||
return promise_rejects(t, expectedErr, this.doIt(), "Expected bad parameters to fail");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the test that's implemented by the class by calling the doIt() function
|
||||
* @param {String} desc A description of the test being run
|
||||
* @param [Error|String] expectedErr A string matching an error type, such as "SecurityError" or an object with a .name value that is an error type string
|
||||
*/
|
||||
runTest(desc, expectedErr) {
|
||||
promise_test((t) => {
|
||||
return Promise.resolve().then(() => {
|
||||
return this.testSetup();
|
||||
}).then(() => {
|
||||
if (expectedErr === undefined) {
|
||||
return this.testPasses(desc);
|
||||
} else {
|
||||
return this.testFails(t, desc, expectedErr);
|
||||
}
|
||||
}).then((res) => {
|
||||
return this.testTeardown(res);
|
||||
})
|
||||
}, desc)
|
||||
}
|
||||
|
||||
/**
|
||||
* called before runTest
|
||||
* virtual method expected to be overridden by child class if needed
|
||||
*/
|
||||
testSetup() {
|
||||
if (this.beforeTestFn) {
|
||||
this.beforeTestFn.call(this);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback function that gets called in the TestCase context
|
||||
* and within the testing process.
|
||||
*/
|
||||
beforeTest(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new Error ("Tried to call non-function before test");
|
||||
}
|
||||
|
||||
this.beforeTestFn = fn;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* called after runTest
|
||||
* virtual method expected to be overridden by child class if needed
|
||||
*/
|
||||
testTeardown(res) {
|
||||
if (this.afterTestFn) {
|
||||
this.afterTestFn.call(this, res);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback function that gets called in the TestCase context
|
||||
* and within the testing process. Good for validating results.
|
||||
*/
|
||||
afterTest(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new Error ("Tried to call non-function after test");
|
||||
}
|
||||
|
||||
this.afterTestFn = fn;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the value returned from the test function
|
||||
* virtual method expected to be overridden by child class
|
||||
*/
|
||||
validateRet() {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* calls doIt() with testObject() and expects it to fail with a TypeError()
|
||||
*/
|
||||
testBadArgs(testDesc) {
|
||||
promise_test(function(t) {
|
||||
return promise_rejects(t, new TypeError(), this.doIt(), "Expected bad parameters to fail");
|
||||
}.bind(this), testDesc);
|
||||
}
|
||||
}
|
||||
|
||||
var createCredentialDefaultArgs = {
|
||||
options: {
|
||||
publicKey: {
|
||||
// Relying Party:
|
||||
rp: {
|
||||
name: "Acme"
|
||||
},
|
||||
|
||||
// User:
|
||||
user: {
|
||||
id: new Uint8Array(), // Won't survive the copy, must be rebuilt
|
||||
name: "john.p.smith@example.com",
|
||||
displayName: "John P. Smith",
|
||||
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
|
||||
},
|
||||
|
||||
pubKeyCredParams: [{
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA256,
|
||||
}],
|
||||
|
||||
timeout: 60000, // 1 minute
|
||||
excludeCredentials: [] // No excludeList
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function cloneObject(o) {
|
||||
return JSON.parse(JSON.stringify(o));
|
||||
}
|
||||
|
||||
function extendObject(dst, src) {
|
||||
Object.keys(src).forEach(function(key) {
|
||||
if (isSimpleObject(src[key])) {
|
||||
extendObject (dst[key], src[key]);
|
||||
} else {
|
||||
dst[key] = src[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isSimpleObject(o) {
|
||||
return (typeof o === "object" &&
|
||||
!Array.isArray(o) &&
|
||||
!(o instanceof ArrayBuffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateCredentialTest
|
||||
*
|
||||
|
@ -198,7 +369,7 @@ class CreateCredentialsTest extends TestCase {
|
|||
window.crypto.getRandomValues(challengeBytes);
|
||||
this.testObject = cloneObject(createCredentialDefaultArgs);
|
||||
// cloneObject can't clone the BufferSource in user.id, so let's recreate it.
|
||||
this.testObject.options.publicKey.user.id = new Uint8Array();
|
||||
this.testObject.options.publicKey.user.id = new Uint8Array(16);
|
||||
this.testObject.options.publicKey.challenge = challengeBytes;
|
||||
|
||||
// how to order the properties of testObject when passing them to makeCredential
|
||||
|
@ -235,15 +406,8 @@ class GetCredentialsTest extends TestCase {
|
|||
// default arguments
|
||||
let challengeBytes = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
this.testObject = {
|
||||
options: {
|
||||
publicKey: {
|
||||
challenge: challengeBytes,
|
||||
// timeout: 60000,
|
||||
// allowCredentials: [newCredential]
|
||||
}
|
||||
}
|
||||
};
|
||||
this.testObject = cloneObject(getCredentialDefaultArgs);
|
||||
this.testObject.options.publicKey.challenge = challengeBytes;
|
||||
|
||||
// how to order the properties of testObject when passing them to makeCredential
|
||||
this.argOrder = [
|
||||
|
@ -266,33 +430,28 @@ class GetCredentialsTest extends TestCase {
|
|||
// if a Promise was passed in, add it to the list
|
||||
if (arg instanceof Promise) {
|
||||
this.credentialPromiseList.push(arg);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
// if a credential object was passed in, convert it to a Promise for consistency
|
||||
if (typeof arg === "object") {
|
||||
this.credentialPromiseList.push(Promise.resolve(arg));
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
// if a credential wasn't passed in, create one
|
||||
let challengeBytes = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
var createArgs = cloneObject(createCredentialDefaultArgs);
|
||||
createArgs.options.publicKey.challenge = challengeBytes;
|
||||
createArgs.options.publicKey.user.id = new Uint8Array();
|
||||
var p = navigator.credentials.create(createArgs.options);
|
||||
// if no credential specified then create one
|
||||
var p = createCredential();
|
||||
this.credentialPromiseList.push(p);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
test() {
|
||||
testSetup(desc) {
|
||||
if (!this.credentialPromiseList.length) {
|
||||
throw new Error("Attempting list without defining credential to test");
|
||||
}
|
||||
|
||||
Promise.all(this.credentialPromiseList)
|
||||
return Promise.all(this.credentialPromiseList)
|
||||
.then((credList) => {
|
||||
var idList = credList.map((cred) => {
|
||||
return {
|
||||
|
@ -302,12 +461,15 @@ class GetCredentialsTest extends TestCase {
|
|||
};
|
||||
});
|
||||
this.testObject.options.publicKey.allowCredentials = idList;
|
||||
return super.test();
|
||||
// return super.test(desc);
|
||||
})
|
||||
.catch((err) => {
|
||||
throw Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
validateRet(ret) {
|
||||
validatePublicKeyCredential (ret);
|
||||
validatePublicKeyCredential(ret);
|
||||
validateAuthenticatorAssertionResponse(ret.response);
|
||||
}
|
||||
}
|
||||
|
@ -335,12 +497,16 @@ function validatePublicKeyCredential(cred) {
|
|||
function validateAuthenticatorAttestationResponse(attr) {
|
||||
// class
|
||||
assert_class_string(attr, "AuthenticatorAttestationResponse", "Expected credentials.create() to return instance of 'AuthenticatorAttestationResponse' class");
|
||||
|
||||
// clientDataJSON
|
||||
assert_idl_attribute(attr, "clientDataJSON", "credentials.create() should return AuthenticatorAttestationResponse with clientDataJSON attribute");
|
||||
assert_readonly(attr, "clientDataJSON", "credentials.create() should return AuthenticatorAttestationResponse with readonly clientDataJSON attribute");
|
||||
// TODO: clientDataJSON() and make sure fields are correct
|
||||
|
||||
// attestationObject
|
||||
assert_idl_attribute(attr, "attestationObject", "credentials.create() should return AuthenticatorAttestationResponse with attestationObject attribute");
|
||||
assert_readonly(attr, "attestationObject", "credentials.create() should return AuthenticatorAttestationResponse with readonly attestationObject attribute");
|
||||
// TODO: parseAuthenticatorData() and make sure flags are correct
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -349,15 +515,20 @@ function validateAuthenticatorAttestationResponse(attr) {
|
|||
function validateAuthenticatorAssertionResponse(assert) {
|
||||
// class
|
||||
assert_class_string(assert, "AuthenticatorAssertionResponse", "Expected credentials.create() to return instance of 'AuthenticatorAssertionResponse' class");
|
||||
|
||||
// clientDataJSON
|
||||
assert_idl_attribute(assert, "clientDataJSON", "credentials.get() should return AuthenticatorAssertionResponse with clientDataJSON attribute");
|
||||
assert_readonly(assert, "clientDataJSON", "credentials.get() should return AuthenticatorAssertionResponse with readonly clientDataJSON attribute");
|
||||
// TODO: clientDataJSON() and make sure fields are correct
|
||||
|
||||
// signature
|
||||
assert_idl_attribute(assert, "signature", "credentials.get() should return AuthenticatorAssertionResponse with signature attribute");
|
||||
assert_readonly(assert, "signature", "credentials.get() should return AuthenticatorAssertionResponse with readonly signature attribute");
|
||||
|
||||
// authenticatorData
|
||||
assert_idl_attribute(assert, "authenticatorData", "credentials.get() should return AuthenticatorAssertionResponse with authenticatorData attribute");
|
||||
assert_readonly(assert, "authenticatorData", "credentials.get() should return AuthenticatorAssertionResponse with readonly authenticatorData attribute");
|
||||
// TODO: parseAuthenticatorData() and make sure flags are correct
|
||||
}
|
||||
|
||||
//************* BEGIN DELETE AFTER 1/1/2018 *************** //
|
||||
|
@ -370,8 +541,8 @@ var debug = function() {};
|
|||
// note that the polyfill only gets loaded if navigator.credentials create doesn't exist
|
||||
// AND if the polyfill script is found at the right path (i.e. - the polyfill is opt-in)
|
||||
function ensureInterface() {
|
||||
if (typeof navigator.credentials.create !== "function") {
|
||||
debug = console.log;
|
||||
if (typeof navigator.credentials === "object" && typeof navigator.credentials.create !== "function") {
|
||||
// debug = onsole.log;
|
||||
|
||||
return loadJavaScript("/webauthn/webauthn-polyfill/webauthn-polyfill.js")
|
||||
.then(() => {
|
||||
|
|
|
@ -17,7 +17,7 @@ standardSetup(function() {
|
|||
// Example 1
|
||||
// http://example.com/ opened in a top-level browsing context is not a secure context, as it was not delivered over an authenticated and encrypted channel.
|
||||
test (() => {
|
||||
assert_false (typeof navigator.credentials.create === "function");
|
||||
assert_false (typeof navigator.credentials === "object" && typeof navigator.credentials.create === "function");
|
||||
}, "no navigator.credentials.create in non-secure context");
|
||||
|
||||
// Example 4: TODO
|
||||
|
|
|
@ -17,7 +17,7 @@ standardSetup(function() {
|
|||
// Example 2
|
||||
// https://example.com/ opened in a top-level browsing context is a secure context, as it was delivered over an authenticated and encrypted channel.
|
||||
test (() => {
|
||||
assert_true (typeof navigator.credentials.create === "function");
|
||||
assert_true (typeof navigator.credentials === "object" && typeof navigator.credentials.create === "function");
|
||||
}, "navigator.credentials.create exists in secure context");
|
||||
|
||||
// Example 3: TODO
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue