Bug 1323339 - Modify WebAuthn mochitests to work with IPC API; r=jcj r=baku
authorKyle Machulis <kyle@nonpolynomial.com>
Thu, 06 Apr 2017 15:44:55 -0700
changeset 357429 2f7004fb4631f356cfaf1c949292430f63f3d4f2
parent 357428 cbf0956298670cd695403c9b3fca98db5f81de39
child 357430 e4c0c46ce1e91cd2859d380539d039150f56330e
push id31792
push usercbook@mozilla.com
push dateWed, 10 May 2017 13:07:59 +0000
treeherdermozilla-central@ebbcdaa5b580 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcj, baku
bugs1323339
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1323339 - Modify WebAuthn mochitests to work with IPC API; r=jcj r=baku Change tests to run serially with async API, since order is no longer enforced by the IPC protocol being synchronous. MozReview-Commit-ID: 9BtnsVhDvPS
dom/webauthn/tests/test_webauthn_get_assertion.html
dom/webauthn/tests/test_webauthn_make_credential.html
dom/webauthn/tests/test_webauthn_no_token.html
dom/webauthn/tests/test_webauthn_sameorigin.html
--- a/dom/webauthn/tests/test_webauthn_get_assertion.html
+++ b/dom/webauthn/tests/test_webauthn_get_assertion.html
@@ -7,85 +7,102 @@
   <script type="text/javascript" src="pkijs/common.js"></script>
   <script type="text/javascript" src="pkijs/asn1.js"></script>
   <script type="text/javascript" src="pkijs/x509_schema.js"></script>
   <script type="text/javascript" src="pkijs/x509_simpl.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 
-<h1>Tests for GetAssertion for W3C Web Authentication</h1>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
+  <h1>Tests for GetAssertion for W3C Web Authentication</h1>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
 
-<script class="testbody" type="text/javascript">
-"use strict";
+  <script class="testbody" type="text/javascript">
+   "use strict";
+
+   // Execute the full-scope test
+   SimpleTest.waitForExplicitFinish();
 
-// Execute the full-scope test
-SimpleTest.waitForExplicitFinish();
+   function arrivingHereIsBad(aResult) {
+     ok(false, "Bad result! Received a: " + aResult);
+     return Promise.resolve();
+   }
 
-function arrivingHereIsBad(aResult) {
-  ok(false, "Bad result! Received a: " + aResult);
-  return Promise.resolve();
-}
+   function expectNotAllowedError(aResult) {
+     ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError");
+     return Promise.resolve();
+   }
 
-function expectNotAllowedError(aResult) {
-  ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError");
-  return Promise.resolve();
-}
+   function expectTypeError(aResult) {
+     ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError");
+     return Promise.resolve();
+   }
 
-function expectTypeError(aResult) {
-  ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError");
-  return Promise.resolve();
-}
+   SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
+                                      ["security.webauth.webauthn_enable_softtoken", true],
+                                      ["security.webauth.webauthn_enable_usbtoken", false]]},
+                             runTests);
 
-SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
-                                   ["security.webauth.webauthn_enable_softtoken", true],
-                                   ["security.webauth.webauthn_enable_usbtoken", false]]},
-function() {
-  isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
-  isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
-  isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
+   function runTests() {
+     isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
+     isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
+     isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
 
-  let authn = navigator.authentication;
+     let authn = navigator.authentication;
 
-  let gAssertionChallenge = new Uint8Array(16);
-  window.crypto.getRandomValues(gAssertionChallenge);
+     let gAssertionChallenge = new Uint8Array(16);
+     window.crypto.getRandomValues(gAssertionChallenge);
+
+     let invalidCred = { type: "Magic", id: base64ToBytes("AAA=") };
+     let unknownCred = { type: "ScopedCred", id: base64ToBytes("AAA=") };
 
-  let invalidCred = { type: "Magic", id: base64ToBytes("AAA=") };
-  let unknownCred = { type: "ScopedCred", id: base64ToBytes("AAA=") };
-
-  Promise.all([
-    // Test basic good call, but without giving a credential so expect failures
-    // this is OK by the standard, but not supported by U2F-backed authenticators
-    // like the soft token in use here.
-    authn.getAssertion(gAssertionChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectNotAllowedError),
-
-    // Test with an unexpected option
-    authn.getAssertion(gAssertionChallenge, { unknownValue: "hi" })
-    .then(arrivingHereIsBad)
-    .catch(expectNotAllowedError),
+     var testFuncs = [
+       function () {
+         // Test basic good call, but without giving a credential so expect failures
+         // this is OK by the standard, but not supported by U2F-backed authenticators
+         // like the soft token in use here.
+         return authn.getAssertion(gAssertionChallenge)
+                     .then(arrivingHereIsBad)
+                     .catch(expectNotAllowedError);
+       },
+       function () {
+         // Test with an unexpected option
+         return authn.getAssertion(gAssertionChallenge, { unknownValue: "hi" })
+                     .then(arrivingHereIsBad)
+                     .catch(expectNotAllowedError);
+       },
+       function () {
+         // Test with an invalid credential
+         return authn.getAssertion(gAssertionChallenge, { allowList: [invalidCred] })
+                     .then(arrivingHereIsBad)
+                     .catch(expectTypeError);
+       },
+       function () {
+         // Test with an unknown credential
+         return authn.getAssertion(gAssertionChallenge, { allowList: [unknownCred] })
+                     .then(arrivingHereIsBad)
+                     .catch(expectNotAllowedError);
+       },
+       function () {
+         // Test with an unexpected option and an invalid credential
+         return authn.getAssertion(gAssertionChallenge, { unknownValue: "hi" })
+                     .then(arrivingHereIsBad)
+                     .catch(expectNotAllowedError);
+       }
+     ];
 
-    // Test with an invalid credential
-    authn.getAssertion(gAssertionChallenge, { allowList: [invalidCred] })
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
-
-    // Test with an unknown credential
-    authn.getAssertion(gAssertionChallenge, { allowList: [unknownCred] })
-    .then(arrivingHereIsBad)
-    .catch(expectNotAllowedError),
+     var i = 0;
+     var runNextTest = () => {
+       if (i == testFuncs.length) {
+         SimpleTest.finish();
+         return;
+       }
+       testFuncs[i]().then(() => { runNextTest(); });
+       i = i + 1;
+     };
+     runNextTest();
 
-    // Test with an unexpected option and an invalid credential
-    authn.getAssertion(gAssertionChallenge, { unknownValue: "hi" })
-    .then(arrivingHereIsBad)
-    .catch(expectNotAllowedError)
-  ])
-  .then(function(){
-    SimpleTest.finish();
-  });
-});
+   }
 
-</script>
+  </script>
 
 </body>
 </html>
--- a/dom/webauthn/tests/test_webauthn_make_credential.html
+++ b/dom/webauthn/tests/test_webauthn_make_credential.html
@@ -7,152 +7,190 @@
   <script type="text/javascript" src="pkijs/common.js"></script>
   <script type="text/javascript" src="pkijs/asn1.js"></script>
   <script type="text/javascript" src="pkijs/x509_schema.js"></script>
   <script type="text/javascript" src="pkijs/x509_simpl.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 
-<h1>Test for MakeCredential for W3C Web Authentication</h1>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
+  <h1>Test for MakeCredential for W3C Web Authentication</h1>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
 
-<script class="testbody" type="text/javascript">
-"use strict";
+  <script class="testbody" type="text/javascript">
+   "use strict";
+
+   // Execute the full-scope test
+   SimpleTest.waitForExplicitFinish();
 
-// Execute the full-scope test
-SimpleTest.waitForExplicitFinish();
+   function arrivingHereIsGood(aResult) {
+     ok(true, "Good result! Received a: " + aResult);
+     return Promise.resolve();
+   }
 
-function arrivingHereIsGood(aResult) {
-  ok(true, "Good result! Received a: " + aResult);
-  return Promise.resolve();
-}
+   function arrivingHereIsBad(aResult) {
+     ok(false, "Bad result! Received a: " + aResult);
+     return Promise.resolve();
+   }
 
-function arrivingHereIsBad(aResult) {
-  ok(false, "Bad result! Received a: " + aResult);
-  return Promise.resolve();
-}
+   function expectNotAllowedError(aResult) {
+     ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError");
+     return Promise.resolve();
+   }
 
-function expectNotAllowedError(aResult) {
-  ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError");
-  return Promise.resolve();
-}
+   function expectTypeError(aResult) {
+     ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError");
+     return Promise.resolve();
+   }
 
-function expectTypeError(aResult) {
-  ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError");
-  return Promise.resolve();
-}
+   function expectNotSupportedError(aResult) {
+     ok(aResult.toString().startsWith("NotSupportedError"), "Expecting a NotSupportedError");
+     return Promise.resolve();
+   }
 
-function expectNotSupportedError(aResult) {
-  ok(aResult.toString().startsWith("NotSupportedError"), "Expecting a NotSupportedError");
-  return Promise.resolve();
-}
+   SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
+                                      ["security.webauth.webauthn_enable_softtoken", true],
+                                      ["security.webauth.webauthn_enable_usbtoken", false]]}, runTests);
+   function runTests() {
+     isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
+     isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
+     isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
+
+     let authn = navigator.authentication;
 
-SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
-                                   ["security.webauth.webauthn_enable_softtoken", true],
-                                   ["security.webauth.webauthn_enable_usbtoken", false]]},
-function() {
-  isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
-  isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
-  isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
+     let gCredentialChallenge = new Uint8Array(16);
+     window.crypto.getRandomValues(gCredentialChallenge);
+
+     let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
+     let param = {type: "ScopedCred", algorithm: "p-256"};
+     let unsupportedParam = {type: "ScopedCred", algorithm: "3DES"};
+     let badParam = {type: "SimplePassword", algorithm: "MaxLength=2"};
 
-  let authn = navigator.authentication;
-
-  let gCredentialChallenge = new Uint8Array(16);
-  window.crypto.getRandomValues(gCredentialChallenge);
+     var testFuncs = [
+       // Test basic good call
+       function() {
+         return authn.makeCredential(acct, [param], gCredentialChallenge)
+              .then(arrivingHereIsGood)
+              .catch(arrivingHereIsBad);
+       },
 
-  let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
-  let param = {type: "ScopedCred", algorithm: "p-256"};
-  let unsupportedParam = {type: "ScopedCred", algorithm: "3DES"};
-  let badParam = {type: "SimplePassword", algorithm: "MaxLength=2"};
+       // Test empty account
+       function() {
+         return authn.makeCredential({}, [param], gCredentialChallenge)
+                     .then(arrivingHereIsBad)
+                     .catch(expectTypeError);
+       },
+
+       // Test without a parameter
+       function() {
+         return authn.makeCredential(acct, [], gCredentialChallenge)
+                     .then(arrivingHereIsBad)
+                     .catch(expectNotSupportedError);
+       },
 
-  Promise.all([
-    // Test basic good call
-    authn.makeCredential(acct, [param], gCredentialChallenge)
-    .then(arrivingHereIsGood)
-    .catch(arrivingHereIsBad),
+       // Test without a parameter array at all
+       function() {
+         return authn.makeCredential(acct, null, gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test empty account
-    authn.makeCredential({}, [param], gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
-
-    // Test without a parameter
-    authn.makeCredential(acct, [], gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectNotSupportedError),
+       // Test with an unsupported parameter
+       function() {
+         return authn.makeCredential(acct, [unsupportedParam], gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectNotSupportedError);
+       },
 
-    // Test without a parameter array at all
-    authn.makeCredential(acct, null, gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       // Test with an unsupported parameter and a good one
+       function() {
+         return authn.makeCredential(acct, [unsupportedParam, param], gCredentialChallenge)
+              .then(arrivingHereIsGood)
+              .catch(arrivingHereIsBad);
+       },
 
-    // Test with an unsupported parameter
-    authn.makeCredential(acct, [unsupportedParam], gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectNotSupportedError),
+       // Test with a bad parameter
+       function() {
+         return authn.makeCredential(acct, [badParam], gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test with an unsupported parameter and a good one
-    authn.makeCredential(acct, [unsupportedParam, param], gCredentialChallenge)
-    .then(arrivingHereIsGood)
-    .catch(arrivingHereIsBad),
+       // Test with an unsupported parameter, and a bad one
+       function() {
+         return authn.makeCredential(acct, [unsupportedParam, badParam],
+                              gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test with a bad parameter
-    authn.makeCredential(acct, [badParam], gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       // Test with an unsupported parameter, a bad one, and a good one. This
+       // should still fail, as anything with a badParam should fail.
+       function() {
+         return authn.makeCredential(acct, [unsupportedParam, badParam, param],
+                              gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test with an unsupported parameter, and a bad one
-    authn.makeCredential(acct, [unsupportedParam, badParam],
-                         gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       // Test without a challenge
+       function() {
+         return authn.makeCredential(acct, [param], null)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test with an unsupported parameter, a bad one, and a good one. This
-    // should still fail, as anything with a badParam should fail.
-    authn.makeCredential(acct, [unsupportedParam, badParam, param],
-                         gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       // Test with an invalid challenge
+       function() {
+         return authn.makeCredential(acct, [param], "begone, thou ill-fitting moist glove!")
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test without a challenge
-    authn.makeCredential(acct, [param], null)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
-
-    // Test with an invalid challenge
-    authn.makeCredential(acct, [param], "begone, thou ill-fitting moist glove!")
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       // Test with duplicate parameters
+       function() {
+         return authn.makeCredential(acct, [param, param, param], gCredentialChallenge)
+              .then(arrivingHereIsGood)
+              .catch(arrivingHereIsBad);
+       },
 
-    // Test with duplicate parameters
-    authn.makeCredential(acct, [param, param, param], gCredentialChallenge)
-    .then(arrivingHereIsGood)
-    .catch(arrivingHereIsBad),
+       // Test an incomplete account
+       function() {
+         return authn.makeCredential({id: "none"
+         }, [param], gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    // Test an incomplete account
-    authn.makeCredential({id: "none"}, [param], gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       function() {
+         return authn.makeCredential({name: "none", imageURL: "http://example.com/404"},
+                              [param], gCredentialChallenge)
+              .then(arrivingHereIsBad)
+              .catch(expectTypeError);
+       },
 
-    authn.makeCredential({name: "none", imageURL: "http://example.com/404"},
-                         [param], gCredentialChallenge)
-    .then(arrivingHereIsBad)
-    .catch(expectTypeError),
+       // Test a complete account
+       function() {
+         return authn.makeCredential({rpDisplayName: "Foxxy", displayName: "Foxxy V",
+                                      id: "foxes_are_the_best@example.com",
+                                      name: "Fox F. Foxington",
+                                      imageURL: "https://example.com/fox.svg"},
+                                     [param], gCredentialChallenge)
+                     .then(arrivingHereIsGood)
+                     .catch(arrivingHereIsBad);
+       }];
 
-    // Test a complete account
-    authn.makeCredential({rpDisplayName: "Foxxy", displayName: "Foxxy V",
-                          id: "foxes_are_the_best@example.com",
-                          name: "Fox F. Foxington",
-                          imageURL: "https://example.com/fox.svg"},
-                         [param], gCredentialChallenge)
-    .then(arrivingHereIsGood)
-    .catch(arrivingHereIsBad)
-  ])
-  .then(function() {
-    SimpleTest.finish();
-  });
-});
+     var i = 0;
+     var runNextTest = () => {
+       if (i == testFuncs.length) {
+         SimpleTest.finish();
+         return;
+       }
+       testFuncs[i]().then(() => { runNextTest(); });
+       i = i + 1;
+     };
+     runNextTest();
+   };
 
-</script>
+  </script>
 
 </body>
 </html>
--- a/dom/webauthn/tests/test_webauthn_no_token.html
+++ b/dom/webauthn/tests/test_webauthn_no_token.html
@@ -16,16 +16,17 @@
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
 
 <script class="testbody" type="text/javascript">
 "use strict";
 
 // Execute the full-scope test
 SimpleTest.waitForExplicitFinish();
 
+// Turn off all tokens. This should result in "not allowed" failures
 SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
                                    ["security.webauth.webauthn_enable_softtoken", false],
                                    ["security.webauth.webauthn_enable_usbtoken", false]]},
 function() {
   isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
   isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
   isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
 
--- a/dom/webauthn/tests/test_webauthn_sameorigin.html
+++ b/dom/webauthn/tests/test_webauthn_sameorigin.html
@@ -7,156 +7,180 @@
   <script type="text/javascript" src="pkijs/common.js"></script>
   <script type="text/javascript" src="pkijs/asn1.js"></script>
   <script type="text/javascript" src="pkijs/x509_schema.js"></script>
   <script type="text/javascript" src="pkijs/x509_simpl.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 
-<h1>Test Same Origin Policy for W3C Web Authentication</h1>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
+  <h1>Test Same Origin Policy for W3C Web Authentication</h1>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
 
-<script class="testbody" type="text/javascript">
-"use strict";
+  <script class="testbody" type="text/javascript">
+   "use strict";
 
-// Execute the full-scope test
-SimpleTest.waitForExplicitFinish();
+   // Execute the full-scope test
+   SimpleTest.waitForExplicitFinish();
 
-var gTrackedCredential = {};
+   var gTrackedCredential = {};
 
-function arrivingHereIsGood(aResult) {
-  ok(true, "Good result! Received a: " + aResult);
-  return Promise.resolve();
-}
+   function arrivingHereIsGood(aResult) {
+     ok(true, "Good result! Received a: " + aResult);
+     return Promise.resolve();
+   }
 
-function arrivingHereIsBad(aResult) {
-  // TODO: Change to `ok` when Bug 1329764 lands
-  todo(false, "Bad result! Received a: " + aResult);
-  return Promise.resolve();
-}
+   function arrivingHereIsBad(aResult) {
+     // TODO: Change to `ok` when Bug 1329764 lands
+     todo(false, "Bad result! Received a: " + aResult);
+     return Promise.resolve();
+   }
 
-function expectSecurityError(aResult) {
-  // TODO: Change to `ok` when Bug 1329764 lands
-  todo(aResult.toString().startsWith("SecurityError"), "Expecting a SecurityError");
-  return Promise.resolve();
-}
+   function expectSecurityError(aResult) {
+     // TODO: Change to `ok` when Bug 1329764 lands
+     todo(aResult.toString().startsWith("SecurityError"), "Expecting a SecurityError");
+     return Promise.resolve();
+   }
 
-function keepThisScopedCredential(aScopedCredInfo) {
-  gTrackedCredential = {
-    type: aScopedCredInfo.credential.type,
-    id: Uint8Array.from(aScopedCredInfo.credential.id),
-    transports: [ "usb" ],
-  }
-  return Promise.resolve(aScopedCredInfo);
-}
+   function keepThisScopedCredential(aScopedCredInfo) {
+     gTrackedCredential = {
+       type: aScopedCredInfo.credential.type,
+       id: Uint8Array.from(aScopedCredInfo.credential.id),
+       transports: [ "usb" ],
+     }
+     return Promise.resolve(aScopedCredInfo);
+   }
 
-SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
-                                   ["security.webauth.webauthn_enable_softtoken", true],
-                                   ["security.webauth.webauthn_enable_usbtoken", false]]},
-function() {
-  isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
-  isnot(navigator.authentication.makeCredential, undefined,
-        "WebAuthn makeCredential API endpoint must exist");
-  isnot(navigator.authentication.getAssertion, undefined,
-        "WebAuthn getAssertion API endpoint must exist");
-
-  let authn = navigator.authentication;
+   function runTests() {
+     isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
+     isnot(navigator.authentication.makeCredential, undefined,
+           "WebAuthn makeCredential API endpoint must exist");
+     isnot(navigator.authentication.getAssertion, undefined,
+           "WebAuthn getAssertion API endpoint must exist");
 
-  let chall = new Uint8Array(16);
-  window.crypto.getRandomValues(chall);
+     let authn = navigator.authentication;
 
-  let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
-  let param = {type: "ScopedCred", algorithm: "p-256"};
+     let chall = new Uint8Array(16);
+     window.crypto.getRandomValues(chall);
+
+     let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
+     let param = {type: "ScopedCred", algorithm: "p-256"};
 
-  Promise.all([
-    // Test basic good call
-    authn.makeCredential(acct, [param], chall, {rpId: document.origin})
-    .then(keepThisScopedCredential)
-    .then(arrivingHereIsGood)
-    .catch(arrivingHereIsBad),
-
-    // Test rpId being unset
-    authn.makeCredential(acct, [param], chall, {})
-    .then(arrivingHereIsGood)
-    .catch(arrivingHereIsBad),
-
-    // Test this origin with optional fields
-    authn.makeCredential(acct, [param], chall,
-                         {rpId: "user:pass@" + document.origin + ":8888"})
-    .then(arrivingHereIsBad)
-    .catch(expectSecurityError),
+     var testFuncs = [
+       function() {
+         // Test basic good call
+         return authn.makeCredential(acct, [param], chall, {rpId: document.origin})
+                     .then(keepThisScopedCredential)
+                     .then(arrivingHereIsGood)
+                     .catch(arrivingHereIsBad);
+       },
 
-    // Test blank rpId
-    authn.makeCredential(acct, [param], chall, {rpId: ""})
-    .then(arrivingHereIsBad)
-    .catch(expectSecurityError),
-
-    // Test subdomain of this origin
-    authn.makeCredential(acct, [param], chall,
-                         {rpId: "subdomain." + document.origin})
-    .then(arrivingHereIsBad)
-    .catch(expectSecurityError),
-
-    // Test another origin
-    authn.makeCredential(acct, [param], chall, {rpId: "example.com"})
-    .then(arrivingHereIsBad)
-    .catch(expectSecurityError),
-
-    // est a different domain within the same TLD
-    authn.makeCredential(acct, [param], chall, {rpId: "alt.test"})
-    .then(arrivingHereIsBad)
-    .catch(expectSecurityError)
-
-  ])
-  .then(function(){
-    return Promise.all([
-      // Test basic good call
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
-                                 rpId: document.origin})
-      .then(arrivingHereIsGood)
-      .catch(arrivingHereIsBad),
-
-      // Test rpId being unset
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ]})
-      .then(arrivingHereIsGood)
-      .catch(arrivingHereIsBad),
+       function() {
+         // Test rpId being unset
+         return authn.makeCredential(acct, [param], chall, {})
+                     .then(arrivingHereIsGood)
+                     .catch(arrivingHereIsBad);
+       },
+       function() {
+         // Test this origin with optional fields
+         return authn.makeCredential(acct, [param], chall,
+                                     {rpId: "user:pass@" + document.origin + ":8888"})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function() {
+         // Test blank rpId
+         return authn.makeCredential(acct, [param], chall, {rpId: ""})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function() {
+         // Test subdomain of this origin
+         return authn.makeCredential(acct, [param], chall,
+                                     {rpId: "subdomain." + document.origin})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function() {
+         // Test another origin
+         return authn.makeCredential(acct, [param], chall, {rpId: "example.com"})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function () {
+         // est a different domain within the same TLD
+         return authn.makeCredential(acct, [param], chall, {rpId: "alt.test"})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function () {
+         // Test basic good call
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
+                                           rpId: document.origin})
+                     .then(arrivingHereIsGood)
+                     .catch(arrivingHereIsBad);
+       },
+       function () {
+         // Test rpId being unset
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ]})
+                     .then(arrivingHereIsGood)
+                     .catch(arrivingHereIsBad);
+       },
+       function () {
+         // Test this origin with optional fields
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
+                                           rpId: "user:pass@" + document.origin + ":8888"})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function () {
+         // Test blank rpId
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
+                                           rpId: ""})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function () {
+         // Test subdomain of this origin
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
+                                           rpId: "subdomain." + document.origin})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function () {
+         // Test another origin
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
+                                           rpId: "example.com"})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError);
+       },
+       function () {
+         // Test a different domain within the same TLD
+         return authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
+                                           rpId: "alt.test"})
+                     .then(arrivingHereIsBad)
+                     .catch(expectSecurityError)
+       },
+       function () {
+         SimpleTest.finish();
+       }
+     ];
+     var i = 0;
+     var runNextTest = () => {
+       if (i == testFuncs.length) {
+         SimpleTest.finish();
+         return;
+       }
+       console.log(i);
+       testFuncs[i]().then(() => { runNextTest(); });
+       i = i + 1;
+     };
+     runNextTest();
+   };
+   SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
+                                      ["security.webauth.webauthn_enable_softtoken", true],
+                                      ["security.webauth.webauthn_enable_usbtoken", false]]},
+                             runTests);
 
-      // Test this origin with optional fields
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
-                                 rpId: "user:pass@" + document.origin + ":8888"})
-      .then(arrivingHereIsBad)
-      .catch(expectSecurityError),
-
-      // Test blank rpId
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
-                                 rpId: ""})
-      .then(arrivingHereIsBad)
-      .catch(expectSecurityError),
-
-      // Test subdomain of this origin
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
-                                 rpId: "subdomain." + document.origin})
-      .then(arrivingHereIsBad)
-      .catch(expectSecurityError),
-
-      // Test another origin
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
-                                 rpId: "example.com"})
-      .then(arrivingHereIsBad)
-      .catch(expectSecurityError),
-
-      // Test a different domain within the same TLD
-      authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
-                                 rpId: "alt.test"})
-      .then(arrivingHereIsBad)
-      .catch(expectSecurityError)
-    ]);
-  })
-  .then(function(){
-    SimpleTest.finish();
-  });
-});
-
-</script>
+  </script>
 
 </body>
 </html>