Update web-platform-tests to revision 6d85a3b422cab97d032ad3db47cb741ca364185f

This commit is contained in:
WPT Sync Bot 2018-02-08 20:20:17 -05:00
parent cd663ea332
commit b524b7c279
37 changed files with 1446 additions and 178 deletions

View file

@ -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

View file

@ -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": [

View file

@ -1,3 +1,3 @@
[attachment-local-clipping-color-4.html]
type: reftest
expected: FAIL
expected: TIMEOUT

View file

@ -1,3 +1,3 @@
[box-shadow-syntax-001.xht]
type: reftest
expected: TIMEOUT
expected: FAIL

View file

@ -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

View file

@ -2,6 +2,3 @@
[elementsFromPoint on the root document for points in iframe elements]
expected: FAIL
[elementsFromPoint on inner documents]
expected: FAIL

View file

@ -1,2 +0,0 @@
[Create-blocked-port.htm]
expected: CRASH

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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");

View file

@ -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>

View file

@ -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("")

View file

@ -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>

View file

@ -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 {};

View file

@ -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 {
};

View file

@ -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/*

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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 */

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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(() => {

View file

@ -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

View file

@ -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