Bug 1473359 [wpt PR 11775] - Check [NewObject] on show(), use webdriver, a=testonly
authorMarcos Cáceres <marcos@marcosc.com>
Mon, 13 Aug 2018 18:24:32 +0000
changeset 431524 a52201915f4071a4cc605003c24b88286766ec61
parent 431523 f66f84b4eae08de13a511bad81e4b644ec6bfaa7
child 431525 86ac39eb681388ba4dc94b1febf06a2891bd7329
push id34443
push usercsabou@mozilla.com
push dateWed, 15 Aug 2018 00:53:32 +0000
treeherdermozilla-central@b80906e2fbc9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1473359, 11775
milestone63.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 1473359 [wpt PR 11775] - Check [NewObject] on show(), use webdriver, a=testonly Automatic update from web-platform-testsCheck [NewObject] on show(), use webdriver (#11775) -- wpt-commits: f69ed366b8c028c882a4fb582b20d6982577c00f wpt-pr: 11775
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/payment-request/payment-request-abort-method.https.html
testing/web-platform/tests/payment-request/payment-request-canmakepayment-method-manual.https.html
testing/web-platform/tests/payment-request/payment-request-canmakepayment-method.https.html
testing/web-platform/tests/payment-request/payment-request-show-method.https.html
testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -13262,22 +13262,16 @@
     ]
    ],
    "payment-request/change-shipping-option-select-last-manual.https.html": [
     [
      "/payment-request/change-shipping-option-select-last-manual.https.html",
      {}
     ]
    ],
-   "payment-request/payment-request-canmakepayment-method-manual.https.html": [
-    [
-     "/payment-request/payment-request-canmakepayment-method-manual.https.html",
-     {}
-    ]
-   ],
    "payment-request/payment-response/complete-method-manual.https.html": [
     [
      "/payment-request/payment-response/complete-method-manual.https.html",
      {}
     ]
    ],
    "payment-request/payment-response/methodName-attribute-manual.https.html": [
     [
@@ -377495,16 +377489,24 @@
    "payment-request/payment-request-abort-method.https.html": [
     [
      "/payment-request/payment-request-abort-method.https.html",
      {
       "testdriver": true
      }
     ]
    ],
+   "payment-request/payment-request-canmakepayment-method.https.html": [
+    [
+     "/payment-request/payment-request-canmakepayment-method.https.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "payment-request/payment-request-constructor-crash.https.html": [
     [
      "/payment-request/payment-request-constructor-crash.https.html",
      {
       "timeout": "long"
      }
     ]
    ],
@@ -615901,22 +615903,22 @@
    "d15c1940959f85bff499a11408bbd99287bfd0e4",
    "testharness"
   ],
   "payment-request/onpaymentmenthodchange-attribute.https.html": [
    "0484eb868f983e3cdb0efceab5fe2b3c6084b4ab",
    "testharness"
   ],
   "payment-request/payment-request-abort-method.https.html": [
-   "d1f693a6ceff90e50a4f4db2f4d8bbe1d32cac88",
-   "testharness"
-  ],
-  "payment-request/payment-request-canmakepayment-method-manual.https.html": [
-   "5ea639b7073629e819d9b1e695fc2572a20b7707",
-   "manual"
+   "522411b542a6d3a8a6a9e6488ab11a29454840d9",
+   "testharness"
+  ],
+  "payment-request/payment-request-canmakepayment-method.https.html": [
+   "617bd6e4834011937915e8e22bbf18b3af217c78",
+   "testharness"
   ],
   "payment-request/payment-request-constructor-crash.https.html": [
    "1325681a4acf6841b67b2dd40d20cf0dcc449d8f",
    "testharness"
   ],
   "payment-request/payment-request-constructor.https.html": [
    "b5997a0c9be55e2b3b135a4471aa2abc5e7440af",
    "testharness"
@@ -615957,21 +615959,21 @@
    "b5f9ea65c6c8e0deff02f12e529f09ba96720571",
    "testharness"
   ],
   "payment-request/payment-request-shippingType-attribute.https.html": [
    "b1ed0d028860ea9c98dd1a61ba239db75a7e3864",
    "testharness"
   ],
   "payment-request/payment-request-show-method.https.html": [
-   "38ab786b431ebed917daa39c428e6db4e727b95a",
+   "c6e69d4c587602d51602aea41224731e692af2ae",
    "testharness"
   ],
   "payment-request/payment-response/complete-method-manual.https.html": [
-   "64d5c537ed9de230efde592e77d5ca6c0d53093e",
+   "a9da9eed9cbaed0540ef542f75896f532a60d13e",
    "manual"
   ],
   "payment-request/payment-response/helpers.js": [
    "bf938c5edba56a1acdf22a3596a34c02dfd49a51",
    "support"
   ],
   "payment-request/payment-response/methodName-attribute-manual.https.html": [
    "0a8ef6c77e87e68a1b7f9aa28588be4de3da98f0",
--- a/testing/web-platform/tests/payment-request/payment-request-abort-method.https.html
+++ b/testing/web-platform/tests/payment-request/payment-request-abort-method.https.html
@@ -10,69 +10,72 @@
 "use strict";
 setup({
   // Ignore unhandled rejections resulting from .show()'s acceptPromise
   // not being explicitly handled.
   allow_uncaught_exception: true,
   explicit_timeout: true,
 });
 const basicCard = Object.freeze({ supportedMethods: "basic-card" });
-const defaultMethods = Object.freeze([basicCard]);
+const applePay = Object.freeze({
+  supportedMethods: "https://apple.com/apple-pay",
+});
+const defaultMethods = Object.freeze([basicCard, applePay]);
 const defaultDetails = Object.freeze({
   total: {
     label: "Total",
     amount: {
       currency: "USD",
       value: "1.00",
     },
   },
 });
 
-window.onload = async () => {
-  promise_test(async t => {
-    // request is in "created" state
+promise_test(async t => {
+  // request is in "created" state
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  await promise_rejects(t, "InvalidStateError", request.abort());
+}, `Throws if the promise [[state]] is not "interactive"`);
+
+promise_test(async t => {
+  return test_driver.bless("show payment request", async () => {
+    const request = new PaymentRequest(defaultMethods, defaultDetails);
+    const acceptPromise = request.show();
+    try {
+      await request.abort();
+    } catch (err) {
+      assert_unreached("Unexpected promise rejection: " + err.message);
+    }
+    await promise_rejects(t, "AbortError", acceptPromise);
+    // As request is now "closed", trying to show it will fail
+    await promise_rejects(t, "InvalidStateError", request.show());
+  });
+});
+
+promise_test(async t => {
+  return test_driver.bless("show payment request", async () => {
+    // request is in "created" state.
     const request = new PaymentRequest(defaultMethods, defaultDetails);
     await promise_rejects(t, "InvalidStateError", request.abort());
-  }, `Throws if the promise [[state]] is not "interactive"`);
-
-  const button = document.getElementById("button");
-
-  promise_test(async t => {
-    button.onclick = async () => {
-      const request = new PaymentRequest(defaultMethods, defaultDetails);
-      const acceptPromise = request.show();
-      try {
-        await request.abort();
-      } catch (err) {
-        assert_unreached("Unexpected promise rejection: " + err.message);
-      }
-      await promise_rejects(t, "AbortError", acceptPromise);
-      // As request is now "closed", trying to show it will fail
-      await promise_rejects(t, "InvalidStateError", request.show());
-    };
-    await test_driver.click(button);
+    // Call it again, for good measure.
+    await promise_rejects(t, "InvalidStateError", request.abort());
+    // The request's state is "created", so let's show it
+    // which changes the state to "interactive.".
+    const acceptPromise = request.show();
+    // Let's set request the state to "closed" by calling .abort()
+    try {
+      await request.abort();
+    } catch (err) {
+      assert_unreached("Unexpected promise rejection: " + err.message);
+    }
+    // The request is now "closed", so...
+    await promise_rejects(t, "InvalidStateError", request.abort());
+    await promise_rejects(t, "AbortError", acceptPromise);
   });
+});
 
-  promise_test(async t => {
-    button.onclick = async () => {
-      // request is in "created" state.
-      const request = new PaymentRequest(defaultMethods, defaultDetails);
-      await promise_rejects(t, "InvalidStateError", request.abort());
-      // Call it again, for good measure.
-      await promise_rejects(t, "InvalidStateError", request.abort());
-      // The request's state is "created", so let's show it
-      // which changes the state to "interactive.".
-      const acceptPromise = request.show();
-      // Let's set request the state to "closed" by calling .abort()
-      try {
-        await request.abort();
-      } catch (err) {
-        assert_unreached("Unexpected promise rejection: " + err.message);
-      }
-      // The request is now "closed", so...
-      await promise_rejects(t, "InvalidStateError", request.abort());
-      await promise_rejects(t, "AbortError", acceptPromise);
-    };
-    await test_driver.click(button);
-  });
-};
+promise_test(async t => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const promises = new Set([request.abort(), request.abort(), request.abort()]);
+  assert_equals(promises.size, 3, "Must have three unique objects");
+}, "Calling abort() multiple times is always a new object.");
 </script>
-<button id="button"></button>
+
deleted file mode 100644
--- a/testing/web-platform/tests/payment-request/payment-request-canmakepayment-method-manual.https.html
+++ /dev/null
@@ -1,202 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Tests for PaymentRequest.canMakePayment() method</title>
-<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-setup({
-  explicit_done: true,
-  explicit_timeout: true,
-});
-
-const basicCard = Object.freeze({ supportedMethods: "basic-card" });
-const defaultMethods = Object.freeze([basicCard]);
-const defaultDetails = Object.freeze({
-  total: {
-    label: "Total",
-    amount: {
-      currency: "USD",
-      value: "1.00",
-    },
-  },
-});
-
-promise_test(async t => {
-  const request = new PaymentRequest(defaultMethods, defaultDetails);
-  try {
-    assert_true(
-      await request.canMakePayment(),
-      `canMakePaymentPromise should be true`
-    );
-    assert_true(
-      await request.canMakePayment(),
-      `canMakePaymentPromise should be true`
-    );
-  } catch (err) {
-    assert_equals(
-      err.name,
-      "NotAllowedError",
-      "if it throws, then it must be a NotAllowedError."
-    );
-  }
-}, `If request.[[state]] is "created", then return a promise that resolves to true for known method.`);
-
-promise_test(async t => {
-  const request = new PaymentRequest(defaultMethods, defaultDetails);
-  assert_true(await request.canMakePayment(), "basic-card should be supported");
-}, `If payment method identifier and serialized parts are supported, resolve promise with true.`);
-
-promise_test(async t => {
-  const unsupportedMethods = [
-    "this-is-not-supported",
-    "https://not.supported",
-    "e",
-    "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa",
-    "a-b-q-n-s-pw0",
-    "m-u",
-    "s-l5",
-    "k9-f",
-    "m-l",
-    "u4-n-t",
-    "i488jh6-g18-fck-yb-v7-i",
-    "x-x-t-t-c34-o",
-    "https://wpt",
-    "https://wpt.fyi/",
-    "https://wpt.fyi/payment",
-    "https://wpt.fyi/payment-request",
-    "https://wpt.fyi/payment-request?",
-    "https://wpt.fyi/payment-request?this=is",
-    "https://wpt.fyi/payment-request?this=is&totally",
-    "https://wpt.fyi:443/payment-request?this=is&totally",
-    "https://wpt.fyi:443/payment-request?this=is&totally#fine",
-    "https://:@wpt.fyi:443/payment-request?this=is&totally#👍",
-    " \thttps://wpt\n ",
-    "https://xn--c1yn36f",
-    "https://點看",
-  ];
-  for (const method of unsupportedMethods) {
-    try {
-      const request = new PaymentRequest(
-        [{ supportedMethods: method }],
-        defaultDetails
-      );
-      assert_false(
-        await request.canMakePayment(),
-        `method "${method}" must not be supported`
-      );
-    } catch (err) {
-      assert_equals(
-        err.name,
-        "NotAllowedError",
-        "if it throws, then it must be a NotAllowedError."
-      );
-    }
-  }
-}, `If payment method identifier is unknown, resolve promise with false.`);
-
-promise_test(async t => {
-  // This test might never actually hit its assertion, but that's allowed.
-  const request = new PaymentRequest(defaultMethods, defaultDetails);
-  for (let i = 0; i < 1000; i++) {
-    try {
-      await request.canMakePayment();
-    } catch (err) {
-      assert_equals(
-        err.name,
-        "NotAllowedError",
-        "if it throws, then it must be a NotAllowedError."
-      );
-      break;
-    }
-  }
-  for (let i = 0; i < 1000; i++) {
-    try {
-      await new PaymentRequest(defaultMethods, defaultDetails).canMakePayment();
-    } catch (err) {
-      assert_equals(
-        err.name,
-        "NotAllowedError",
-        "if it throws, then it must be a NotAllowedError."
-      );
-      break;
-    }
-  }
-}, `Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.`);
-
-function manualTest1(elem){
-  elem.disabled = true;
-
-  // NB: request.show has to be called outside of promise_test to ensure the
-  // user's click is still visible to PaymentRequest.show.
-  const request = new PaymentRequest(defaultMethods, defaultDetails);
-  const acceptPromise = request.show(); // Sets state to "interactive"
-  promise_test(async t => {
-    const canMakePaymentPromise = request.canMakePayment();
-    try {
-      const result = await canMakePaymentPromise;
-      assert_true(
-        false,
-        `canMakePaymentPromise should have thrown InvalidStateError`
-      );
-    } catch (err) {
-      await promise_rejects(t, "InvalidStateError", canMakePaymentPromise);
-    } finally {
-      await request.abort();
-      await promise_rejects(t, "AbortError", acceptPromise);
-    }
-    // The state should be "closed"
-    await promise_rejects(t, "InvalidStateError", request.canMakePayment());
-  }, elem.textContent.trim());
-}
-
-function manualTest2(elem){
-  elem.disabled = true;
-
-  // See above for why it's important for these lines to be outside of
-  // promise_test.
-  const request = new PaymentRequest(defaultMethods, defaultDetails);
-  const acceptPromise = request.show(); // The state is now "interactive"
-  acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools.
-  promise_test(async t => {
-    await request.abort(); // The state is now "closed"
-    await promise_rejects(t, "InvalidStateError", request.canMakePayment());
-    try {
-      const result = await request.canMakePayment();
-      assert_true(
-        false,
-        `should have thrown InvalidStateError, but instead returned "${result}"`
-      );
-    } catch (err) {
-      assert_equals(
-        err.name,
-        "InvalidStateError",
-        "must be an InvalidStateError."
-      );
-    }
-  }, elem.textContent.trim());
-  done();
-}
-</script>
-
-<h2>Tests for PaymentRequest.canMakePayment() method</h2>
-<p>
-  Click on each button in sequence from top to bottom without refreshing the page.
-  No payment sheet will be shown, but the tests will run in the background.
-</p>
-<ol>
-  <li>
-    <button onclick="manualTest1(this)">
-      If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.
-    </button>
-  </li>
-  <li>
-    <button onclick="manualTest2(this)">
-      If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.
-    </button>
-  </li>
-</ol>
-<small>
-  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
-  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
-</small>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-request-canmakepayment-method.https.html
@@ -0,0 +1,186 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Tests for PaymentRequest.canMakePayment() method</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/resources/testdriver-vendor.js'></script>
+<script src="/resources/testdriver.js"></script>
+<script>
+const basicCard = Object.freeze({ supportedMethods: "basic-card" });
+const defaultMethods = Object.freeze([basicCard]);
+const defaultDetails = Object.freeze({
+  total: {
+    label: "Total",
+    amount: {
+      currency: "USD",
+      value: "1.00",
+    },
+  },
+});
+
+promise_test(async t => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  try {
+    assert_true(
+      await request.canMakePayment(),
+      `canMakePaymentPromise should be true`
+    );
+    assert_true(
+      await request.canMakePayment(),
+      `canMakePaymentPromise should be true`
+    );
+  } catch (err) {
+    assert_equals(
+      err.name,
+      "NotAllowedError",
+      "if it throws, then it must be a NotAllowedError."
+    );
+  }
+}, `If request.[[state]] is "created", then return a promise that resolves to true for known method.`);
+
+promise_test(async t => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  assert_true(await request.canMakePayment(), "basic-card should be supported");
+}, `If payment method identifier and serialized parts are supported, resolve promise with true.`);
+
+promise_test(async t => {
+  const unsupportedMethods = [
+    "this-is-not-supported",
+    "https://not.supported",
+    "e",
+    "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa",
+    "a-b-q-n-s-pw0",
+    "m-u",
+    "s-l5",
+    "k9-f",
+    "m-l",
+    "u4-n-t",
+    "i488jh6-g18-fck-yb-v7-i",
+    "x-x-t-t-c34-o",
+    "https://wpt",
+    "https://wpt.fyi/",
+    "https://wpt.fyi/payment",
+    "https://wpt.fyi/payment-request",
+    "https://wpt.fyi/payment-request?",
+    "https://wpt.fyi/payment-request?this=is",
+    "https://wpt.fyi/payment-request?this=is&totally",
+    "https://wpt.fyi:443/payment-request?this=is&totally",
+    "https://wpt.fyi:443/payment-request?this=is&totally#fine",
+    "https://:@wpt.fyi:443/payment-request?this=is&totally#👍",
+    " \thttps://wpt\n ",
+    "https://xn--c1yn36f",
+    "https://點看",
+  ];
+  for (const method of unsupportedMethods) {
+    try {
+      const request = new PaymentRequest(
+        [{ supportedMethods: method }],
+        defaultDetails
+      );
+      assert_false(
+        await request.canMakePayment(),
+        `method "${method}" must not be supported`
+      );
+    } catch (err) {
+      assert_equals(
+        err.name,
+        "NotAllowedError",
+        "if it throws, then it must be a NotAllowedError."
+      );
+    }
+  }
+}, `If payment method identifier is unknown, resolve promise with false.`);
+
+promise_test(async t => {
+  // This test might never actually hit its assertion, but that's allowed.
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  for (let i = 0; i < 1000; i++) {
+    try {
+      await request.canMakePayment();
+    } catch (err) {
+      assert_equals(
+        err.name,
+        "NotAllowedError",
+        "if it throws, then it must be a NotAllowedError."
+      );
+      break;
+    }
+  }
+  for (let i = 0; i < 1000; i++) {
+    try {
+      await new PaymentRequest(defaultMethods, defaultDetails).canMakePayment();
+    } catch (err) {
+      assert_equals(
+        err.name,
+        "NotAllowedError",
+        "if it throws, then it must be a NotAllowedError."
+      );
+      break;
+    }
+  }
+}, `Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.`);
+
+promise_test(t => {
+  return test_driver.bless("show payment request", async () => {
+    const request = new PaymentRequest(defaultMethods, defaultDetails);
+    const acceptPromise = request.show(); // Sets state to "interactive"
+    const canMakePaymentPromise = request.canMakePayment();
+    try {
+      const result = await canMakePaymentPromise;
+      assert_true(
+        false,
+        `canMakePaymentPromise should have thrown InvalidStateError`
+      );
+    } catch (err) {
+      await promise_rejects(t, "InvalidStateError", canMakePaymentPromise);
+    } finally {
+      await request.abort();
+      await promise_rejects(t, "AbortError", acceptPromise);
+    }
+    // The state should be "closed"
+    await promise_rejects(t, "InvalidStateError", request.canMakePayment());
+  });
+}, 'If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.');
+
+promise_test(t => {
+  return test_driver.bless("show payment request", async () => {
+    const request = new PaymentRequest(defaultMethods, defaultDetails);
+    const acceptPromise = request.show(); // The state is now "interactive"
+    acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools.
+    await request.abort(); // The state is now "closed"
+    await promise_rejects(t, "InvalidStateError", request.canMakePayment());
+    try {
+      const result = await request.canMakePayment();
+      assert_true(
+        false,
+        `should have thrown InvalidStateError, but instead returned "${result}"`
+      );
+    } catch (err) {
+      assert_equals(
+        err.name,
+        "InvalidStateError",
+        "must be an InvalidStateError."
+      );
+    }
+  });
+}, 'If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.');
+
+test(() => {
+  const request = new PaymentRequest(
+    [{ supportedMethods: "basic-card" }],
+    defaultDetails
+  );
+  const promises = new Set([
+    request.canMakePayment(),
+    request.canMakePayment(),
+    request.canMakePayment(),
+  ]);
+  assert_equals(promises.size, 3, "Must have three unique objects");
+}, "Calling canMakePayment() multiple times is always a new object.");
+</script>
+
+<small>
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
+  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
+</small>
--- a/testing/web-platform/tests/payment-request/payment-request-show-method.https.html
+++ b/testing/web-platform/tests/payment-request/payment-request-show-method.https.html
@@ -1,23 +1,21 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>Test for PaymentRequest.show() method</title>
 <link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
-<button id="button"></button>
 <script>
-'use strict';
-const button = document.getElementById("button");
+"use strict";
 const defaultMethods = Object.freeze([
   { supportedMethods: "basic-card" },
-  { supportedMethods: "https://apple.com/apple-pay" }
+  { supportedMethods: "https://apple.com/apple-pay" },
 ]);
 
 const defaultDetails = Object.freeze({
   total: {
     label: "Total",
     amount: {
       currency: "USD",
       value: "1.00",
@@ -26,44 +24,57 @@ const defaultDetails = Object.freeze({
 });
 
 promise_test(async t => {
   const request = new PaymentRequest(defaultMethods, defaultDetails);
   const acceptPromise = request.show();
   await promise_rejects(t, "SecurityError", acceptPromise);
 }, `Calling show() without being triggered by user interaction throws`);
 
-promise_test(async t => {
-  button.onclick = async () => {
+promise_test(t => {
+  return test_driver.bless("show payment request", async () => {
     const request = new PaymentRequest(defaultMethods, defaultDetails);
     const acceptPromise = request.show(); // Sets state to "interactive"
     await promise_rejects(t, "InvalidStateError", request.show());
     await request.abort();
     await promise_rejects(t, "AbortError", acceptPromise);
-  };
-  await test_driver.click(button);
+  });
 }, "Throws if the promise [[state]] is not 'created'.");
 
-promise_test(async t => {
-  button.onclick = async () => {
+promise_test(t => {
+  return test_driver.bless("show payment request", async () => {
     const request1 = new PaymentRequest(defaultMethods, defaultDetails);
     const request2 = new PaymentRequest(defaultMethods, defaultDetails);
     const acceptPromise1 = request1.show();
     const acceptPromise2 = request2.show();
     await promise_rejects(t, "AbortError", acceptPromise2);
     await request1.abort();
     await promise_rejects(t, "AbortError", acceptPromise1);
-  };
-  await test_driver.click(button);
+  });
 }, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
 
-promise_test(async t => {
-  button.onclick = async () => {
+promise_test(t => {
+  return test_driver.bless("show payment request", async () => {
     const request = new PaymentRequest(
       [{ supportedMethods: "this-is-not-supported" }],
       defaultDetails
     );
     const acceptPromise = request.show();
     await promise_rejects(t, "NotSupportedError", acceptPromise);
-  };
-  await test_driver.click(button);
+  });
 }, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);
+
+promise_test(t => {
+  return test_driver.bless("show payment request", async () => {
+    const request = new PaymentRequest(
+      [{ supportedMethods: "basic-card" }],
+      defaultDetails
+    );
+    const promises = new Set([request.show(), request.show(), request.show()]);
+    await request.abort();
+    assert_equals(promises.size, 3, "Must have three unique objects");
+  });
+}, "Calling show() multiple times is always a new object.");
 </script>
+<small>
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
+  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
+</small>
--- a/testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html
+++ b/testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html
@@ -9,35 +9,47 @@
 <script src="helpers.js"></script>
 <script>
 async function runManualTest({ completeWith: result }, button) {
   button.disabled = true;
   const { response, request } = await getPaymentRequestResponse();
   promise_test(async t => {
     try {
       // We .complete() as normal, using the passed test value
-      const promise = response.complete(result);
-      assert_true(promise instanceof Promise, "returns a promise");
+      const completePromise = response.complete(result);
+      assert_true(completePromise instanceof Promise, "returns a promise");
       // Immediately calling complete() again yields a rejected promise.
-      await promise_rejects(t, "InvalidStateError", response.complete(result));
+      const invalidComplete = response.complete(result);
+      await promise_rejects(t, "InvalidStateError", invalidComplete);
       // but the original promise is unaffected
-      const returnedValue = await promise;
+      const returnedValue = await completePromise;
       assert_equals(
         returnedValue,
         undefined,
         "Returned value must always be undefined"
       );
       // We now call .complete() again, to force an exception
       // because [[complete]] is true.
-      await promise_rejects(t, "InvalidStateError", response.complete(result));
+      const afterComplete = response.complete(result);
+      await promise_rejects(t, "InvalidStateError", afterComplete);
       button.innerHTML = `✅  ${button.textContent}`;
     } catch (err) {
       button.innerHTML = `❌  ${button.textContent}`;
       assert_unreached("Unexpected exception: " + err.message);
     }
+    const allPromises = new Set([
+      completePromise,
+      invalidComplete,
+      afterComplete,
+    ]);
+    assert_equals(
+      allPromises.length,
+      3,
+      "Calling complete() multiple times is always a new object."
+    );
   }, button.textContent.trim());
 }
 </script>
 
 <h2>
     Manual Tests for PaymentResponse.complete() - Please run in order!
 </h2>
 <p>