[Payment Request] Import test suite from web-platform-tests
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Aug 2017 03:52:22 +0000 (03:52 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Aug 2017 03:52:22 +0000 (03:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175612
<rdar://problem/33906070>

Reviewed by Tim Horton.

LayoutTests/imported/w3c:

Imported the payment-request test suite using import-w3c-tests. Generated failing expected
results for each test and skipped 5 tests that currently time out.

* resources/import-expectations.json:
* resources/resource-files.json:
* web-platform-tests/payment-request/OWNERS: Added.
* web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/basic.https-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/basic.https.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/common.sub.js: Added.
(window.onmessage):
(string_appeared_here.forEach):
* web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt: Added.
* web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html: Added.
* web-platform-tests/payment-request/allowpaymentrequest/w3c-import.log: Added.
* web-platform-tests/payment-request/historical.https-expected.txt: Added.
* web-platform-tests/payment-request/historical.https.html: Added.
* web-platform-tests/payment-request/interfaces.https-expected.txt: Added.
* web-platform-tests/payment-request/interfaces.https.html: Added.
* web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-abort-method.https.html: Added.
* web-platform-tests/payment-request/payment-request-canmakepayment-method.https.http: Added.
* web-platform-tests/payment-request/payment-request-constructor-crash.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-constructor-crash.https.html: Added.
* web-platform-tests/payment-request/payment-request-constructor.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-constructor.https.html: Added.
* web-platform-tests/payment-request/payment-request-id.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-id.https.html: Added.
* web-platform-tests/payment-request/payment-request-in-iframe-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-in-iframe.html: Added.
* web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html: Added.
* web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html: Added.
* web-platform-tests/payment-request/payment-request-response-id.html: Added.
* web-platform-tests/payment-request/payment-request-show-method.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-show-method.https.html: Added.
* web-platform-tests/payment-request/payment-request-update-event-constructor.http-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-update-event-constructor.http.html: Added.
* web-platform-tests/payment-request/payment-request-update-event-constructor.https-expected.txt: Added.
* web-platform-tests/payment-request/payment-request-update-event-constructor.https.html: Added.
* web-platform-tests/payment-request/w3c-import.log: Added.

LayoutTests:

* TestExpectations: Skipped payment-request tests that currently time out.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220785 268f45cc-cd09-0410-ab3c-d52691b4dbfc

56 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/resources/import-expectations.json
LayoutTests/imported/w3c/resources/resource-files.json
LayoutTests/imported/w3c/web-platform-tests/payment-request/OWNERS [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/w3c-import.log [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method.https.http [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-response-id.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log [new file with mode: 0644]

index a9d944d..359db9e 100644 (file)
@@ -1,3 +1,13 @@
+2017-08-15  Andy Estes  <aestes@apple.com>
+
+        [Payment Request] Import test suite from web-platform-tests
+        https://bugs.webkit.org/show_bug.cgi?id=175612
+        <rdar://problem/33906070>
+
+        Reviewed by Tim Horton.
+
+        * TestExpectations: Skipped payment-request tests that currently time out.
+
 2017-08-15  Ryosuke Niwa  <rniwa@webkit.org>
 
         Make DataTransferItemList work with plain text entries
index f84e378..3794c98 100644 (file)
@@ -1439,3 +1439,9 @@ webkit.org/b/175288 imported/w3c/web-platform-tests/css/css-ui-3/outline-019.htm
 webkit.org/b/175290 imported/w3c/web-platform-tests/css/css-ui-3/text-overflow-005.html [ ImageOnlyFailure ]
 
 webkit.org/b/175597 http/tests/xmlhttprequest/gzip-content-type-no-content-encoding.html [ Failure ]
+
+webkit.org/b/175611 imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html [ Skip ]
+webkit.org/b/175611 imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html [ Skip ]
+webkit.org/b/175611 imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html [ Skip ]
+webkit.org/b/175611 imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html [ Skip ]
+webkit.org/b/175611 imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html [ Skip ]
index 4c5829b..815c9a8 100644 (file)
@@ -1,3 +1,70 @@
+2017-08-15  Andy Estes  <aestes@apple.com>
+
+        [Payment Request] Import test suite from web-platform-tests
+        https://bugs.webkit.org/show_bug.cgi?id=175612
+        <rdar://problem/33906070>
+
+        Reviewed by Tim Horton.
+
+        Imported the payment-request test suite using import-w3c-tests. Generated failing expected
+        results for each test and skipped 5 tests that currently time out.
+
+        * resources/import-expectations.json:
+        * resources/resource-files.json:
+        * web-platform-tests/payment-request/OWNERS: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/basic.https-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/basic.https.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/common.sub.js: Added.
+        (window.onmessage):
+        (string_appeared_here.forEach):
+        * web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html: Added.
+        * web-platform-tests/payment-request/allowpaymentrequest/w3c-import.log: Added.
+        * web-platform-tests/payment-request/historical.https-expected.txt: Added.
+        * web-platform-tests/payment-request/historical.https.html: Added.
+        * web-platform-tests/payment-request/interfaces.https-expected.txt: Added.
+        * web-platform-tests/payment-request/interfaces.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-abort-method.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-canmakepayment-method.https.http: Added.
+        * web-platform-tests/payment-request/payment-request-constructor-crash.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-constructor-crash.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-constructor.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-constructor.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-id.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-id.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-in-iframe-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-in-iframe.html: Added.
+        * web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-response-id.html: Added.
+        * web-platform-tests/payment-request/payment-request-show-method.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-show-method.https.html: Added.
+        * web-platform-tests/payment-request/payment-request-update-event-constructor.http-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-update-event-constructor.http.html: Added.
+        * web-platform-tests/payment-request/payment-request-update-event-constructor.https-expected.txt: Added.
+        * web-platform-tests/payment-request/payment-request-update-event-constructor.https.html: Added.
+        * web-platform-tests/payment-request/w3c-import.log: Added.
+
 2017-08-15  Chris Dumez  <cdumez@apple.com>
 
         Fetch / Beacon: Use "application/octet-stream" Content-Type for payloads of type ArrayBuffer / ArrayBufferView
index ce2abb4..c839b25 100644 (file)
     "web-platform-tests/orientation-event": "skip", 
     "web-platform-tests/orientation-sensor": "skip", 
     "web-platform-tests/page-visibility": "skip", 
-    "web-platform-tests/payment-request": "skip", 
+    "web-platform-tests/payment-request": "import", 
     "web-platform-tests/performance-timeline": "skip", 
     "web-platform-tests/pointerevents": "skip", 
     "web-platform-tests/pointerlock": "skip", 
index c3eb36c..f40684b 100644 (file)
         "web-platform-tests/html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-support.htm",
         "web-platform-tests/html/webappapis/scripting/events/onerroreventhandler-frame.html",
         "web-platform-tests/mathml/relations/html5-tree/unique-identifier-1-iframe.html",
+        "web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html",
+        "web-platform-tests/payment-request/payment-request-response-id.html",
         "web-platform-tests/resource-timing/iframe-setdomain.sub.html",
         "web-platform-tests/secure-contexts/postMessage-helper.html",
         "web-platform-tests/secure-contexts/postMessage-helper.https.html",
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/OWNERS b/LayoutTests/imported/w3c/web-platform-tests/payment-request/OWNERS
new file mode 100644 (file)
index 0000000..ce59356
--- /dev/null
@@ -0,0 +1,3 @@
+@edenchuang
+@alphan102
+@marcoscaceres
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt
new file mode 100644 (file)
index 0000000..87463e7
--- /dev/null
@@ -0,0 +1,7 @@
+Blocked access to external URL https://www1.localhost:9443/common/blank.html
+
+
+FAIL PaymentRequest <iframe allowpaymentrequest> in non-active document (cross-origin) assert_throws: function "() => {
+        new grabbedPaymentRequest(...paymentArgs);
+      }" threw object "TypeError: undefined is not a constructor (evaluating 'new grabbedPaymentRequest(...paymentArgs)')" ("TypeError") expected object "[object Object]" ("SecurityError")
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html
new file mode 100644 (file)
index 0000000..fbb80e3
--- /dev/null
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>PaymentRequest &lt;iframe allowpaymentrequest> in non-active document (cross-origin)</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/utils.js></script>
+<iframe id="iframe" allowpaymentrequest></iframe>
+<script>
+async_test((t) => {
+  const iframe = document.getElementById('iframe');
+  const paymentArgs = [[{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}}];
+
+  onload = () => {
+    const win = window[0];
+    const grabbedPaymentRequest = win.PaymentRequest;
+    win.location.href = make_absolute_url({
+      hostname: '{{domains[www1]}}',
+      path: '/common/blank.html'
+    });
+    iframe.onload = t.step_func_done(() => {
+      assert_throws({name: 'SecurityError'}, () => {
+        new grabbedPaymentRequest(...paymentArgs);
+      });
+    });
+  }
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt
new file mode 100644 (file)
index 0000000..240138c
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+FAIL PaymentRequest <iframe allowpaymentrequest> in non-active document (same-origin) assert_throws: function "() => {
+        new grabbedPaymentRequest(...paymentArgs);
+      }" threw object "TypeError: undefined is not a constructor (evaluating 'new grabbedPaymentRequest(...paymentArgs)')" ("TypeError") expected object "[object Object]" ("SecurityError")
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https.html
new file mode 100644 (file)
index 0000000..69a738a
--- /dev/null
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>PaymentRequest &lt;iframe allowpaymentrequest> in non-active document (same-origin)</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe id="iframe" allowpaymentrequest></iframe>
+<script>
+async_test((t) => {
+  const iframe = document.getElementById('iframe');
+  const paymentArgs = [[{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}}];
+
+  onload = () => {
+    const win = window[0];
+    const grabbedPaymentRequest = win.PaymentRequest;
+    win.location.href = '/common/blank.html';
+    iframe.onload = t.step_func_done(() => {
+      assert_throws({name: 'SecurityError'}, () => {
+        new grabbedPaymentRequest(...paymentArgs);
+      });
+    });
+  }
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt
new file mode 100644 (file)
index 0000000..d097c4f
--- /dev/null
@@ -0,0 +1,9 @@
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?iframe
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?frame
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?object
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?embed
+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 27890)
+FAIL: Timed out waiting for notifyDone to be called
+
+#EOF
+#EOF
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html
new file mode 100644 (file)
index 0000000..1426df1
--- /dev/null
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>PaymentRequest allowpaymentrequest attribute cross-origin browsing context containers</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+const expectSuccess = {'iframe': true, 'frame': false, 'object': false, 'embed': false};
+const setAllowPaymentRequest = true;
+const testCrossOrigin = true;
+</script>
+<script src=common.sub.js></script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt
new file mode 100644 (file)
index 0000000..ac4c612
--- /dev/null
@@ -0,0 +1,6 @@
+
+FAIL iframe assert_equals: expected "Success" but got "Exception"
+FAIL frame assert_equals: expected "Success" but got "Exception"
+FAIL object assert_equals: expected "Success" but got "Exception"
+FAIL embed assert_equals: expected "Success" but got "Exception"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html
new file mode 100644 (file)
index 0000000..b100058
--- /dev/null
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>PaymentRequest allowpaymentrequest attribute same origin browsing context containers</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+const expectSuccess = {'iframe': true, 'frame': true, 'object': true, 'embed': true};
+const setAllowPaymentRequest = true;
+const testCrossOrigin = false;
+</script>
+<script src=common.sub.js></script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https-expected.txt
new file mode 100644 (file)
index 0000000..6287240
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+FAIL PaymentRequest <iframe allowpaymentrequest> basic undefined is not a constructor (evaluating 'new window[0].PaymentRequest(...paymentArgs)')
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https.html
new file mode 100644 (file)
index 0000000..841880e
--- /dev/null
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>PaymentRequest &lt;iframe allowpaymentrequest> basic</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe id="iframe" allowpaymentrequest></iframe>
+<script>
+async_test((t) => {
+  const paymentArgs = [[{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}}];
+
+  onload = t.step_func_done(() => {
+    new window[0].PaymentRequest(...paymentArgs);
+  });
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js
new file mode 100644 (file)
index 0000000..85a0846
--- /dev/null
@@ -0,0 +1,45 @@
+// Test should set these:
+// const expectSuccess = {'iframe': bool, 'frame': bool, 'object': bool, 'embed': bool};
+// const setAllowPaymentRequest = bool;
+// const testCrossOrigin = bool;
+
+const tests = {};
+
+window.onmessage = (e) => {
+  const result = e.data;
+  const tagName = result.urlQuery;
+  const t = tests[tagName];
+  t.step(() => {
+    if (expectSuccess[tagName]) {
+      assert_equals(result.message, 'Success');
+    } else {
+      assert_equals(result.message, 'Exception');
+      assert_array_equals(result.details, [true /*ex instanceof DOMException*/,
+                                           DOMException.SECURITY_ERR /*ex.code*/,
+                                           'SecurityError' /*ex.name*/]);
+    }
+    t.done();
+  });
+};
+
+['iframe', 'frame', 'object', 'embed'].forEach((tagName, i) => {
+  tests[tagName] = async_test((t) => {
+    const elm = document.createElement(tagName);
+    if (setAllowPaymentRequest) {
+      elm.setAttribute('allowpaymentrequest', '');
+    }
+    const path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
+    const url = (testCrossOrigin ? "https://{{domains[www1]}}:{{ports[https][0]}}" : "") +
+                path + "echo-PaymentRequest.html?" + tagName;
+    if (tagName === 'object') {
+      elm.data = url;
+    } else {
+      elm.src = url;
+    }
+    elm.onload = t.step_func(() => {
+      window[i].postMessage('What is the result of new PaymentRequest(...)?', '*');
+    });
+    elm.onerror = t.unreached_func('elm.onerror');
+    document.body.appendChild(elm);
+  }, tagName);
+});
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html
new file mode 100644 (file)
index 0000000..15fa1a1
--- /dev/null
@@ -0,0 +1,23 @@
+<!doctype html>
+<script>
+window.onmessage = (e) => {
+  const paymentArgs = [[{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}}];
+
+  if (e.data === 'What is the result of new PaymentRequest(...)?') {
+    const result = {urlQuery: location.search.substring(1)}; // Used to distinguish subtests
+    try {
+      new PaymentRequest(...paymentArgs);
+      result.message = 'Success';
+      e.source.postMessage(result, '*');
+    } catch(ex) {
+      result.message = 'Exception';
+      result.details = [ex instanceof DOMException, ex.code, ex.name];
+      e.source.postMessage(result, '*');
+    }
+  } else {
+    result.message = 'Incorrect message';
+    e.source.postMessage(result, '*');
+  }
+}
+</script>
+<p>This page echos the result of new PaymentRequest(...).</p>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt
new file mode 100644 (file)
index 0000000..b9ddd8a
--- /dev/null
@@ -0,0 +1,9 @@
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?iframe
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?frame
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?object
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?embed
+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 27905)
+FAIL: Timed out waiting for notifyDone to be called
+
+#EOF
+#EOF
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html
new file mode 100644 (file)
index 0000000..6919a54
--- /dev/null
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>PaymentRequest no attribute cross-origin browsing context containers</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+const expectSuccess = {'iframe': false, 'frame': false, 'object': false, 'embed': false};
+const setAllowPaymentRequest = false;
+const testCrossOrigin = true;
+</script>
+<script src=common.sub.js></script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt
new file mode 100644 (file)
index 0000000..ac4c612
--- /dev/null
@@ -0,0 +1,6 @@
+
+FAIL iframe assert_equals: expected "Success" but got "Exception"
+FAIL frame assert_equals: expected "Success" but got "Exception"
+FAIL object assert_equals: expected "Success" but got "Exception"
+FAIL embed assert_equals: expected "Success" but got "Exception"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html
new file mode 100644 (file)
index 0000000..ea3773b
--- /dev/null
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>PaymentRequest no attribute same origin browsing context containers</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+const expectSuccess = {'iframe': true, 'frame': true, 'object': true, 'embed': true};
+const setAllowPaymentRequest = false;
+const testCrossOrigin = false;
+</script>
+<script src=common.sub.js></script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt
new file mode 100644 (file)
index 0000000..f9d64d3
--- /dev/null
@@ -0,0 +1,6 @@
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html
+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 27916)
+FAIL: Timed out waiting for notifyDone to be called
+
+#EOF
+#EOF
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html
new file mode 100644 (file)
index 0000000..048b93a
--- /dev/null
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>PaymentRequest removing allowpaymentrequest after load and then navigating</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+<script>
+async_test((t) => {
+  const iframe = document.createElement('iframe');
+  iframe.allowPaymentRequest = true;
+
+  let i = 0;
+
+  const path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
+  iframe.src = "https://{{domains[www1]}}:{{ports[https][0]}}" + path + "echo-PaymentRequest.html";
+  iframe.onload = t.step_func(() => {
+    if (i === 0) {
+      iframe.allowPaymentRequest = false;
+    }
+    iframe.contentWindow.postMessage('What is the result of new PaymentRequest(...)?', '*');
+  });
+
+  window.onmessage = t.step_func((e) => {
+    i++;
+    if (i === 1) {
+      assert_equals(e.data.message, 'Success', 'before navigation');
+
+      // Navigate the iframe. This will fire a second 'load' event on the iframe.
+      iframe.contentWindow.location.href = iframe.src + '?2';
+    } else {
+      assert_equals(e.data.message, 'Exception', 'after navigation');
+      assert_array_equals(e.data.details, [true /* ex instanceof DOMException*/, 18 /* ex.code */, 'SecurityError' /* ex.name */], 'after navigation');
+      t.done();
+    }
+  });
+
+  document.body.appendChild(iframe);
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt
new file mode 100644 (file)
index 0000000..6afcb05
--- /dev/null
@@ -0,0 +1,6 @@
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html?pipe=trickle(d3)
+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 27933)
+FAIL: Timed out waiting for notifyDone to be called
+
+#EOF
+#EOF
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html
new file mode 100644 (file)
index 0000000..c7ed3ae
--- /dev/null
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>PaymentRequest setting allowpaymentrequest after document creation, before response</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+<script>
+// Set allowpaymentrequest attribute in a timeout after <iframe> has been inserted to the document.
+// The iframe's response is delayed so it happens after the attribute is set.
+
+async_test((t) => {
+  const iframe = document.createElement('iframe');
+  // no allowpaymentrequest attribute
+
+  const path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
+  iframe.src = "https://{{domains[www1]}}:{{ports[https][0]}}" + path + "echo-PaymentRequest.html?pipe=trickle(d3)";
+  iframe.onload = t.step_func(() => {
+    iframe.contentWindow.postMessage('What is the result of new PaymentRequest(...)?', '*');
+  });
+
+  window.onmessage = t.step_func_done((e) => {
+    assert_equals(e.data.message, 'Exception');
+    assert_array_equals(e.data.details, [true /* ex instanceof DOMException*/, 18 /* ex.code */, 'SecurityError' /* ex.name */]);
+  });
+
+  document.body.appendChild(iframe);
+
+  setTimeout(() => {
+    iframe.allowPaymentRequest = true;
+  }, 10);
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt
new file mode 100644 (file)
index 0000000..0285904
--- /dev/null
@@ -0,0 +1,6 @@
+Blocked access to external URL https://www1.localhost:9443/payment-request/allowpaymentrequest/echo-PaymentRequest.html
+#PID UNRESPONSIVE - com.apple.WebKit.WebContent.Development (pid 27993)
+FAIL: Timed out waiting for notifyDone to be called
+
+#EOF
+#EOF
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html
new file mode 100644 (file)
index 0000000..4564d26
--- /dev/null
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>PaymentRequest setting allowpaymentrequest after load and then navigating</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+<script>
+async_test((t) => {
+  const iframe = document.createElement('iframe');
+  // no allowpaymentrequest attribute
+
+  let i = 0;
+
+  const path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
+  iframe.src = "https://{{domains[www1]}}:{{ports[https][0]}}" + path + "echo-PaymentRequest.html";
+  iframe.onload = t.step_func(() => {
+    if (i === 0) {
+      iframe.allowPaymentRequest = true;
+    }
+    iframe.contentWindow.postMessage('What is the result of new PaymentRequest(...)?', '*');
+  });
+
+  window.onmessage = t.step_func((e) => {
+    i++;
+    if (i === 1) {
+      assert_equals(e.data.message, 'Exception', 'before navigation');
+      assert_array_equals(e.data.details, [true /* ex instanceof DOMException*/, 18 /* ex.code */, 'SecurityError' /* ex.name */], 'before navigation');
+
+      // Navigate the iframe. This will fire a second 'load' event on the iframe.
+      iframe.contentWindow.location.href = iframe.src + '?2';
+    } else {
+      assert_equals(e.data.message, 'Success', 'after navigation');
+      t.done();
+    }
+  });
+
+  document.body.appendChild(iframe);
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/w3c-import.log
new file mode 100644 (file)
index 0000000..4f0acc0
--- /dev/null
@@ -0,0 +1,28 @@
+The tests in this directory were imported from the W3C repository.
+Do NOT modify these tests directly in WebKit.
+Instead, create a pull request on the WPT github:
+       https://github.com/w3c/web-platform-tests
+
+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
+
+Do NOT modify or remove this file.
+
+------------------------------------------------------------------------
+Properties requiring vendor prefixes:
+None
+Property values requiring vendor prefixes:
+None
+------------------------------------------------------------------------
+List of files:
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/active-document-same-origin.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/basic.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https-expected.txt
new file mode 100644 (file)
index 0000000..924e03e
--- /dev/null
@@ -0,0 +1,8 @@
+
+FAIL paymentRequestID in PaymentRequest undefined is not an object (evaluating 'window[interf].prototype')
+FAIL paymentRequestID in PaymentResponse undefined is not an object (evaluating 'window[interf].prototype')
+FAIL careOf in PaymentAddress undefined is not an object (evaluating 'window[interf].prototype')
+FAIL totalAmount in PaymentResponse undefined is not an object (evaluating 'window[interf].prototype')
+FAIL paymentRequestId in PaymentRequest undefined is not an object (evaluating 'window[interf].prototype')
+FAIL paymentRequestId in PaymentResponse undefined is not an object (evaluating 'window[interf].prototype')
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https.html
new file mode 100644 (file)
index 0000000..ba518f4
--- /dev/null
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Historical Payment Request APIs</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+[
+  // https://github.com/w3c/browser-payment-api/pull/419
+  ["paymentRequestID", "PaymentRequest"],
+  ["paymentRequestID", "PaymentResponse"],
+
+  // https://github.com/w3c/browser-payment-api/pull/258
+  ["careOf", "PaymentAddress"],
+
+  // https://github.com/w3c/browser-payment-api/pull/219
+  ["totalAmount", "PaymentResponse"],
+
+  // https://github.com/w3c/browser-payment-api/pull/426
+  ["paymentRequestId", "PaymentRequest"],
+  ["paymentRequestId", "PaymentResponse"],
+
+].forEach(([member, interf]) => {
+  test(() => {
+    assert_false(member in window[interf].prototype);
+  }, member + ' in ' + interf);
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https-expected.txt
new file mode 100644 (file)
index 0000000..81aba81
--- /dev/null
@@ -0,0 +1,61 @@
+
+FAIL PaymentRequest interface: existence and properties of interface object assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface object length assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface object name assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: operation show() assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: operation abort() assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: operation canMakePayment() assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: attribute id assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: attribute shippingAddress assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: attribute shippingOption assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: attribute shippingType assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: attribute onshippingaddresschange assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: attribute onshippingoptionchange assert_own_property: self does not have own property "PaymentRequest" expected property "PaymentRequest" missing
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "show" with the proper type (0) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "abort" with the proper type (1) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "canMakePayment" with the proper type (2) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "id" with the proper type (3) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingAddress" with the proper type (4) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingOption" with the proper type (5) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingType" with the proper type (6) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingaddresschange" with the proper type (7) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingoptionchange" with the proper type (8) assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL PaymentAddress interface: existence and properties of interface object assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface object length assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface object name assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: existence and properties of interface prototype object assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute country assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute addressLine assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute region assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute city assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute dependentLocality assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute postalCode assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute sortingCode assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute languageCode assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute organization assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute recipient assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentAddress interface: attribute phone assert_own_property: self does not have own property "PaymentAddress" expected property "PaymentAddress" missing
+FAIL PaymentResponse interface: existence and properties of interface object assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface object length assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface object name assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: existence and properties of interface prototype object assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute requestId assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute methodName assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute details assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute shippingAddress assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute shippingOption assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute payerName assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute payerEmail assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: attribute payerPhone assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentResponse interface: operation complete(PaymentComplete) assert_own_property: self does not have own property "PaymentResponse" expected property "PaymentResponse" missing
+FAIL PaymentRequestUpdateEvent interface: existence and properties of interface object assert_own_property: self does not have own property "PaymentRequestUpdateEvent" expected property "PaymentRequestUpdateEvent" missing
+FAIL PaymentRequestUpdateEvent interface object length assert_own_property: self does not have own property "PaymentRequestUpdateEvent" expected property "PaymentRequestUpdateEvent" missing
+FAIL PaymentRequestUpdateEvent interface object name assert_own_property: self does not have own property "PaymentRequestUpdateEvent" expected property "PaymentRequestUpdateEvent" missing
+FAIL PaymentRequestUpdateEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "PaymentRequestUpdateEvent" expected property "PaymentRequestUpdateEvent" missing
+FAIL PaymentRequestUpdateEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "PaymentRequestUpdateEvent" expected property "PaymentRequestUpdateEvent" missing
+FAIL PaymentRequestUpdateEvent interface: operation updateWith([object Object]) assert_own_property: self does not have own property "PaymentRequestUpdateEvent" expected property "PaymentRequestUpdateEvent" missing
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https.html
new file mode 100644 (file)
index 0000000..bca60a6
--- /dev/null
@@ -0,0 +1,140 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Payment Request interface IDL tests</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/WebIDLParser.js></script>
+<script src=/resources/idlharness.js></script>
+<script type=text/plain class=untested>
+interface EventHandler {};
+interface Event {};
+interface EventInit {};
+interface EventTarget {};
+</script>
+<script type=text/plain>
+[Constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options),
+ SecureContext]
+interface PaymentRequest : EventTarget {
+    Promise<PaymentResponse> show();
+    Promise<void>            abort();
+    Promise<boolean>         canMakePayment();
+
+    readonly attribute DOMString            id;
+    readonly attribute PaymentAddress?      shippingAddress;
+    readonly attribute DOMString?           shippingOption;
+    readonly attribute PaymentShippingType? shippingType;
+
+             attribute EventHandler         onshippingaddresschange;
+
+             attribute EventHandler         onshippingoptionchange;
+};
+dictionary PaymentMethodData {
+    required sequence<DOMString> supportedMethods;
+             object              data;
+};
+dictionary PaymentCurrencyAmount {
+    required DOMString currency;
+    required DOMString value;
+             DOMString currencySystem = "urn:iso:std:iso:4217";
+};
+dictionary PaymentDetailsBase {
+    sequence<PaymentItem>            displayItems;
+    sequence<PaymentShippingOption>  shippingOptions;
+    sequence<PaymentDetailsModifier> modifiers;
+};
+dictionary PaymentDetailsInit : PaymentDetailsBase {
+             DOMString   id;
+    required PaymentItem total;
+};
+dictionary PaymentDetailsUpdate : PaymentDetailsBase {
+    DOMString   error;
+    PaymentItem total;
+};
+dictionary PaymentDetailsModifier {
+    required sequence<DOMString>   supportedMethods;
+             PaymentItem           total;
+             sequence<PaymentItem> additionalDisplayItems;
+             object                data;
+};
+enum PaymentShippingType {
+    "shipping",
+    "delivery",
+    "pickup"
+};
+dictionary PaymentOptions {
+    boolean             requestPayerName = false;
+    boolean             requestPayerEmail = false;
+    boolean             requestPayerPhone = false;
+    boolean             requestShipping = false;
+    PaymentShippingType shippingType = "shipping";
+};
+dictionary PaymentItem {
+    required DOMString             label;
+    required PaymentCurrencyAmount amount;
+             boolean               pending = false;
+};
+[SecureContext]
+interface PaymentAddress {
+    serializer = {attribute};
+    readonly attribute DOMString              country;
+    readonly attribute FrozenArray<DOMString> addressLine;
+    readonly attribute DOMString              region;
+    readonly attribute DOMString              city;
+    readonly attribute DOMString              dependentLocality;
+    readonly attribute DOMString              postalCode;
+    readonly attribute DOMString              sortingCode;
+    readonly attribute DOMString              languageCode;
+    readonly attribute DOMString              organization;
+    readonly attribute DOMString              recipient;
+    readonly attribute DOMString              phone;
+};
+dictionary PaymentShippingOption {
+    required DOMString             id;
+    required DOMString             label;
+    required PaymentCurrencyAmount amount;
+             boolean               selected = false;
+};
+enum PaymentComplete {
+    "fail",
+    "success",
+    "unknown"
+};
+[SecureContext]
+interface PaymentResponse {
+    serializer = {attribute};
+
+    readonly attribute DOMString       requestId;
+    readonly attribute DOMString       methodName;
+    readonly attribute object          details;
+    readonly attribute PaymentAddress? shippingAddress;
+    readonly attribute DOMString?      shippingOption;
+    readonly attribute DOMString?      payerName;
+    readonly attribute DOMString?      payerEmail;
+    readonly attribute DOMString?      payerPhone;
+
+    Promise<void> complete(optional PaymentComplete result = "unknown");
+};
+[Constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict),
+ SecureContext]
+interface PaymentRequestUpdateEvent : Event {
+    void updateWith(Promise<PaymentDetailsUpdate> detailsPromise);
+};
+dictionary PaymentRequestUpdateEventInit : EventInit {
+};
+</script>
+
+<script>
+"use strict";
+var idlArray = new IdlArray();
+[].forEach.call(document.querySelectorAll("script[type=text\\/plain]"), function(node) {
+  if (node.className == "untested") {
+    idlArray.add_untested_idls(node.textContent);
+  } else {
+    idlArray.add_idls(node.textContent);
+  }
+});
+idlArray.add_objects({
+  PaymentRequest: ["new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}})"]
+});
+idlArray.test();
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https-expected.txt
new file mode 100644 (file)
index 0000000..405a6c5
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL Throws if the promise [[state]] is not "interactive" promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL Calling abort must not change the [[state]] until after "interactive" promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL calling .abort() causes acceptPromise to reject and closes the request. promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: PaymentRequest"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html
new file mode 100644 (file)
index 0000000..4dd9ffd
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for PaymentRequest.abort() method</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#abort-method">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+"use strict";
+setup(() => {}, {
+  // Ignore unhandled rejections resulting from .show()'s acceptPromise
+  // not being explicitly handled.
+  allow_uncaught_exception: 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 => {
+  // 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 => {
+  // 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.".
+  request.show();
+  // Let's set request the state to "closed" by calling .abort()
+  try {
+    await request.abort();
+  } catch (err) {
+    assert_true(false, "Unexpected promise rejection: " + err.message);
+  }
+  // The request is now "closed", so...
+  await promise_rejects(t, "InvalidStateError", request.abort());
+}, `Calling abort must not change the [[state]] until after "interactive"`);
+
+promise_test(async t => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const acceptPromise = request.show();
+  try {
+    await request.abort();
+  } catch (err) {
+    assert_true(false, "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());
+}, "calling .abort() causes acceptPromise to reject and closes the request.");
+
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method.https.http b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method.https.http
new file mode 100644 (file)
index 0000000..86fae2e
--- /dev/null
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<!-- Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<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>
+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_equal(
+      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);
+  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(async t => {
+  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_equal(
+      err.name,
+      "InvalidStateError",
+      "must be an InvalidStateError."
+    );
+  }
+}, `If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.`);
+
+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",
+    "basic-card?not-really",
+    "basic-card://not-ok",
+    "basic card",
+    "/basic card/",
+    "BaSicCarD",
+    "BASIC-CARD",
+    " basic-card ",
+    "this is not supported",
+    " ",
+  ];
+  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_true(
+        false,
+        `Unexpected exception testing method ${method}, expected false. See error console.`
+      );
+    }
+  }
+}, `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_equal(
+        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_equal(
+        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.`);
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https-expected.txt
new file mode 100644 (file)
index 0000000..92dc5dc
--- /dev/null
@@ -0,0 +1,42 @@
+
+FAIL Don't crash if there is a abusive number of payment methods in the methodData sequence assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:81:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:77:5 expected true got false
+FAIL Don't crash if there is a abusive number of supported methods in one sequence assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:101:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:97:5 expected true got false
+FAIL Don't crash if the request id has an abusive length assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:123:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:119:5 expected true got false
+FAIL Don't crash if PaymentDetailsInit.total.label is an abusive length assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:147:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:143:5 expected true got false
+FAIL Don't crash if total.amount.value is an abusive length assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:168:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:164:5 expected true got false
+FAIL Don't crash if details.displayItems has an abusive number of items assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:191:25
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:186:7 expected true got false
+FAIL Don't crash if details.shippingOptions has an abusive number of items assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:191:25
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:186:7 expected true got false
+FAIL Don't crash if PaymentShippingOptions.label is an abusive length assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:214:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:208:5 expected true got false
+FAIL Don't crash if the PaymentShippingOptions.amount.value is an abusive length assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:234:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:228:5 expected true got false
+FAIL Don't crash if PaymentItem.label is an abusive length assert_true: failed smoke test: https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:254:23
+step@https://localhost:9443/resources/testharness.js:1409:30
+test@https://localhost:9443/resources/testharness.js:498:22
+global code@https://localhost:9443/payment-request/payment-request-constructor-crash.https.html:248:5 expected true got false
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https.html
new file mode 100644 (file)
index 0000000..8ca0a47
--- /dev/null
@@ -0,0 +1,269 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Crash tests PaymentRequest Constructor</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+/**
+    dictionary PaymentItem {
+        required DOMString             label;
+        required PaymentCurrencyAmount amount;
+                boolean               pending = false;
+    };
+
+    dictionary PaymentDetailsBase {
+        sequence<PaymentItem>            displayItems;
+        sequence<PaymentShippingOption>  shippingOptions;
+        sequence<PaymentDetailsModifier> modifiers;
+    };
+
+    dictionary PaymentCurrencyAmount {
+        required DOMString currency;
+        required DOMString value;
+    };
+**/
+
+"use strict";
+const ABUSIVE_AMOUNT = 100000;
+
+const basicCard = Object.freeze({
+  supportedMethods: ["basic-card"],
+});
+
+const defaultAmount = Object.freeze({
+  currency: "USD",
+  value: "1.00",
+});
+
+const evilAmount = Object.freeze({
+  currency: "USD",
+  value: "1".repeat(ABUSIVE_AMOUNT),
+});
+
+const defaultMethods = Object.freeze([basicCard]);
+
+const defaultTotal = Object.freeze({
+  label: "label",
+  amount: defaultAmount,
+});
+
+const evilTotal = Object.freeze({
+  label: "a".repeat(ABUSIVE_AMOUNT),
+  amount: evilAmount,
+});
+
+const defaultDetails = Object.freeze({
+  total: defaultTotal,
+  get id() {
+    return Math.random();
+  },
+});
+
+const defaultPaymentItem = Object.freeze({
+  label: "label",
+  amount: defaultAmount,
+});
+
+const defaultShippingOption = {
+  get id() {
+    return "shipping option " + Math.random();
+  },
+  amount: defaultAmount,
+  label: "shipping option label",
+};
+
+// First argument is sequence<PaymentMethodData> methodData
+test(() => {
+  let evilMethods = [Object.assign({}, basicCard)];
+  // smoke test
+  try {
+    new PaymentRequest(evilMethods, defaultDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, let's add an abusive amount of methods.
+  while (evilMethods.length < ABUSIVE_AMOUNT) {
+    evilMethods = evilMethods.concat(evilMethods);
+  }
+  try {
+    new PaymentRequest(evilMethods, defaultDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if there is a abusive number of payment methods in the methodData sequence");
+
+test(() => {
+  let supportedMethods = ["basic-card"];
+  // Smoke test
+  try {
+    new PaymentRequest([{ supportedMethods }], defaultDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, let's add an abusive number of supportedMethods to a single PaymentMethodData
+  for (let i = 0; i < ABUSIVE_AMOUNT; i++) {
+    supportedMethods.push(`https://example.com/${i}/evil_${Math.random()}`);
+  }
+  const evilMethodData = [{ supportedMethods }];
+  try {
+    new PaymentRequest(evilMethodData, defaultDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if there is a abusive number of supported methods in one sequence");
+
+// PaymentDetailsInit.id
+test(() => {
+  const id = "abc";
+  // Smoke Test
+  try {
+    new PaymentRequest(
+      defaultMethods,
+      Object.assign({}, defaultDetails, { id })
+    );
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, we make the id super large;
+  const evilDetails = Object.assign({}, defaultDetails, {
+    id: id.repeat(ABUSIVE_AMOUNT),
+  });
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if the request id has an abusive length");
+
+// PaymentDetailsInit.total.label
+test(() => {
+  const evilDetails = Object.assign({}, defaultDetails);
+  // Smoke Test
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, we make the label super large;
+  evilDetails.total = {
+    label: "l".repeat(ABUSIVE_AMOUNT),
+    amount: defaultAmount,
+  };
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if PaymentDetailsInit.total.label is an abusive length");
+
+test(() => {
+  const evilDetails = Object.assign({}, defaultDetails);
+  // Smoke Test
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, we can use evilAmount
+  evilDetails.total = evilAmount;
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if total.amount.value is an abusive length");
+
+for (const [prop, defaultValue] of [
+  ["displayItems", defaultPaymentItem],
+  ["shippingOptions", defaultShippingOption],
+]) {
+  test(() => {
+    const evilDetails = Object.assign({}, defaultDetails);
+    evilDetails[prop] = [defaultValue];
+    // Smoke Test
+    try {
+      new PaymentRequest(defaultMethods, evilDetails);
+    } catch (err) {
+      assert_true(false, "failed smoke test: " + err.stack);
+    }
+    while (evilDetails[prop].length < ABUSIVE_AMOUNT) {
+      evilDetails[prop] = evilDetails[prop].concat(evilDetails[prop]);
+    }
+    // Now, construct with evil items!
+    try {
+      new PaymentRequest(defaultMethods, evilDetails);
+    } catch (err) {
+      assert_equals(err.name, "TypeError", "must be a TypeError");
+    }
+    assert_true(true, "Didn't crash");
+  }, `Don't crash if details.${prop} has an abusive number of items`);
+}
+
+test(() => {
+  const evilDetails = Object.assign({}, defaultDetails);
+  const evilShippingOption = Object.assign({}, defaultShippingOption);
+  evilDetails.shippingOptions = [evilShippingOption];
+  // Smoke Test
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, we make the label super large;
+  evilShippingOption.label = "l".repeat(ABUSIVE_AMOUNT);
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if PaymentShippingOptions.label is an abusive length");
+
+test(() => {
+  const evilDetails = Object.assign({}, defaultDetails);
+  const evilShippingOption = Object.assign({}, defaultShippingOption);
+  evilDetails.shippingOptions = [evilShippingOption];
+  // Smoke Test
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, we make use of evilAmount;
+  evilShippingOption.amount = evilAmount;
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if the PaymentShippingOptions.amount.value is an abusive length");
+
+test(() => {
+  const evilDetails = Object.assign({}, defaultDetails);
+  const evilDisplayItem = Object.assign({}, defaultPaymentItem);
+  evilDetails.displayItems = [evilDisplayItem];
+  // Smoke Test
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_true(false, "failed smoke test: " + err.stack);
+  }
+  // Now, we make the label super large;
+  evilDisplayItem.label = "l".repeat(ABUSIVE_AMOUNT);
+  try {
+    new PaymentRequest(defaultMethods, evilDetails);
+  } catch (err) {
+    assert_equals(err.name, "TypeError", "must be a TypeError");
+  }
+  assert_true(true, "Didn't crash");
+}, "Don't crash if PaymentItem.label is an abusive length");
+
+
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https-expected.txt
new file mode 100644 (file)
index 0000000..37c37c5
--- /dev/null
@@ -0,0 +1,2678 @@
+
+FAIL If details.id is missing, assign a identifier Can't find variable: PaymentRequest
+FAIL If details.id is missing, assign a unique identifier Can't find variable: PaymentRequest
+FAIL If the same id is provided, then use it Can't find variable: PaymentRequest
+FAIL Use ids even if they are strange Can't find variable: PaymentRequest
+FAIL Use provided request ID Can't find variable: PaymentRequest
+FAIL If the length of the methodData sequence is zero, then throw a TypeError assert_throws: function "() => {
+      new PaymentRequest([], {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+      });
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If the length of the paymentMethod.supportedMethods sequence is zero, then throw a TypeError assert_throws: function "() => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: [],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        }
+      );
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL Method data must be JSON-serializable object (a list in this case) assert_false: shouldn't throw when using a list expected false got true
+FAIL Method data must be JSON-serializable object (an object in this case) Can't find variable: PaymentRequest
+FAIL Rethrow any exceptions of JSON-serializing paymentMethod.data into a string assert_throws: function "() => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+            data: recursiveDictionary,
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        }
+      );
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-1"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-1.00"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If details.total.amount.value is not a valid decimal monetary value (in this case "-1000.000"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL PaymentDetailsBase.0 can be 0 length assert_true: 0 can be zero length expected true got false
+FAIL PaymentDetailsBase.1 can be 0 length assert_true: 1 can be zero length expected true got false
+FAIL PaymentDetailsBase.2 can be 0 length assert_true: 2 can be zero length expected true got false
+FAIL If the first character of details.total.amount.value is U+002D HYPHEN-MINUS, then throw a TypeError assert_throws: function "() => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "-1.00",
+            },
+          },
+        }
+      );
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError assert_throws: function "() => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL Negative values are allowed for displayItems.amount.value, irrespective of total amount assert_false: shouldn't throw when given a negative value expected false got true
+FAIL it handles high precision currency values without throwing assert_false: shouldn't throw when given absurd monetary values expected false got true
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If there is no selected shipping option, then PaymentRequest.shippingOption remains null Can't find variable: PaymentRequest
+FAIL If there is a selected shipping option, then it becomes synchronously selected Can't find variable: PaymentRequest
+FAIL If there is a multiple selected shipping options, only the last is selected Can't find variable: PaymentRequest
+FAIL If there are any duplicate shipping option ids, then there are no shipping options Can't find variable: PaymentRequest
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1.00"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1000.000"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "-"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "10."), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case ".99"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "-10."), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "10-"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case ""), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "null"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError assert_throws: function "() => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL Modifier data must be JSON-serializable object (a list in this case) assert_false: shouldn't throw when given a list expected false got true
+FAIL Modifier data must be JSON-serializable object (a object in this case) assert_false: shouldn't throw when given an object value expected false got true
+FAIL Rethrow any exceptions of JSON-serializing modifier.data into a string assert_throws: function "() => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+          modifiers: [
+            {
+              supportedMethods: ["basic-card"],
+              data: recursiveDictionary,
+            },
+          ],
+        }
+      );
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL Shipping type should be valid assert_throws: function "() => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        },
+        {
+          shippingType: "invalid",
+        }
+      );
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("TypeError")
+FAIL PaymentRequest.shippingAddress must initially be null Can't find variable: PaymentRequest
+FAIL If options.requestShipping is not set, then request.shippingType attribute is null. Can't find variable: PaymentRequest
+FAIL If options.requestShipping is true, request.shippingType will be options.shippingType. Can't find variable: PaymentRequest
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https.html
new file mode 100644 (file)
index 0000000..bd3dc25
--- /dev/null
@@ -0,0 +1,861 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for PaymentRequest Constructor</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+"use strict";
+const basicCard = Object.freeze({ supportedMethods: ["basic-card"] });
+const defaultMethods = Object.freeze([basicCard]);
+const defaultDetails = Object.freeze({
+  total: {
+    label: "",
+    amount: {
+      currency: "USD",
+      value: "1.00",
+    },
+  },
+});
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  assert_true(!!request.id, "must be some truthy value");
+}, "If details.id is missing, assign a identifier");
+
+test(() => {
+  const request1 = new PaymentRequest(defaultMethods, defaultDetails);
+  const request2 = new PaymentRequest(defaultMethods, defaultDetails);
+  assert_not_equals(request1.id, request2.id, "UA generated ID must be unique");
+}, "If details.id is missing, assign a unique identifier");
+
+test(() => {
+  const newDetails = Object.assign({}, defaultDetails, { id: "test123" });
+  const request1 = new PaymentRequest(defaultMethods, newDetails);
+  const request2 = new PaymentRequest(defaultMethods, newDetails);
+  assert_equals(request1.id, newDetails.id, `id must be ${newDetails.id}`);
+  assert_equals(request2.id, newDetails.id, `id must be ${newDetails.id}`);
+  assert_equals(request1.id, request2.id, "ids need to be the same");
+}, "If the same id is provided, then use it");
+
+test(() => {
+  const newDetails = Object.assign({}, defaultDetails, {
+    id: "".padStart(1024, "a"),
+  });
+  const request = new PaymentRequest(defaultMethods, newDetails);
+  assert_equals(
+    request.id,
+    newDetails.id,
+    `id must be provided value, even if very long and contain spaces`
+  );
+}, "Use ids even if they are strange");
+
+test(() => {
+  assert_equals(
+    new PaymentRequest(
+      [
+        {
+          supportedMethods: ["basic-card"],
+        },
+      ],
+      {
+        id: "foo",
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+      }
+    ).id,
+    "foo"
+  );
+}, "Use provided request ID");
+
+test(() => {
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest([], {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+      });
+    }
+  );
+}, "If the length of the methodData sequence is zero, then throw a TypeError");
+
+test(() => {
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: [],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        }
+      );
+    }
+  );
+}, "If the length of the paymentMethod.supportedMethods sequence is zero, " + "then throw a TypeError");
+
+test(() => {
+  let itThrows = false;
+  try {
+    new PaymentRequest(
+      [
+        {
+          supportedMethods: ["basic-card"],
+          data: ["some-data"],
+        },
+      ],
+      {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+      }
+    );
+  } catch (err) {
+    itThrows = true;
+  }
+  assert_false(itThrows, "shouldn't throw when using a list");
+}, "Method data must be JSON-serializable object (a list in this case)");
+
+test(() => {
+  new PaymentRequest(
+    [
+      {
+        supportedMethods: ["basic-card"],
+        data: {
+          some: "data",
+        },
+      },
+    ],
+    {
+      total: {
+        label: "",
+        amount: {
+          currency: "USD",
+          value: "1.00",
+        },
+      },
+    }
+  );
+}, "Method data must be JSON-serializable object (an object in this case)");
+
+test(() => {
+  const recursiveDictionary = {};
+  recursiveDictionary.foo = recursiveDictionary;
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+            data: recursiveDictionary,
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        }
+      );
+    }
+  );
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+            data: "a string",
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        }
+      );
+    }
+  );
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+            data: null,
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        }
+      );
+    },
+    "Even though null is JSON-serializable, it's not type 'Object' per ES spec"
+  );
+}, "Rethrow any exceptions of JSON-serializing paymentMethod.data into a string");
+
+// process total
+const invalidAmounts = [
+  "-",
+  "notdigits",
+  "ALSONOTDIGITS",
+  "10.",
+  ".99",
+  "-10.",
+  "-.99",
+  "10-",
+  "1-0",
+  "1.0.0",
+  "1/3",
+  "",
+  null,
+  " 1.0  ",
+  " 1.0 ",
+  "1.0 ",
+  "USD$1.0",
+  "$1.0",
+  {
+    toString() {
+      return " 1.0";
+    },
+  },
+];
+const invalidTotalAmounts = invalidAmounts.concat([
+  "-1",
+  "-1.0",
+  "-1.00",
+  "-1000.000",
+]);
+for (const amount of invalidTotalAmounts) {
+  test(() => {
+    assert_throws(
+      {
+        name: "TypeError",
+      },
+      () => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          }
+        );
+      }
+    );
+  }, `If details.total.amount.value is not a valid decimal monetary value (in this case "${amount}"), then throw a TypeError`);
+}
+
+for (const prop in ["displayItems", "shippingOptions", "modifiers"]) {
+  test(() => {
+    try {
+      const details = Object.assign({}, defaultDetails, { [prop]: [] });
+      new PaymentRequest(defaultMethods, details);
+    } catch (err) {
+      assert_true(false, `${prop} can be zero length`);
+    }
+  }, `PaymentDetailsBase.${prop} can be 0 length`);
+}
+
+test(() => {
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "-1.00",
+            },
+          },
+        }
+      );
+    }
+  );
+}, "If the first character of details.total.amount.value is U+002D HYPHEN-MINUS, then throw a TypeError");
+
+for (const amount of invalidAmounts) {
+  test(() => {
+    assert_throws(
+      {
+        name: "TypeError",
+      },
+      () => {
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.00",
+              },
+            },
+            displayItems: [
+              {
+                label: "",
+                amount: {
+                  currency: "USD",
+                  value: amount,
+                },
+              },
+            ],
+          }
+        );
+      }
+    );
+  }, "For each item in details.displayItems: if item.amount.value is not " + 'a valid decimal monetary value (in this case "' + amount + '"), then throw a TypeError');
+}
+
+test(() => {
+  let itThrows = false;
+  try {
+    new PaymentRequest(
+      [
+        {
+          supportedMethods: ["basic-card"],
+          data: {
+            supportedTypes: ["debit"],
+          },
+        },
+      ],
+      {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+        displayItems: [
+          {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "-1000",
+            },
+          },
+          {
+            label: "",
+            amount: {
+              currency: "AUD",
+              value: "-2000.00",
+            },
+          },
+        ],
+      }
+    );
+  } catch (err) {
+    itThrows = true;
+  }
+  assert_false(itThrows, "shouldn't throw when given a negative value");
+}, "Negative values are allowed for displayItems.amount.value, irrespective of total amount");
+
+test(() => {
+  let itThrows = false;
+  const largeMoney = "1".repeat(510);
+
+  try {
+    new PaymentRequest(
+      [
+        {
+          supportedMethods: ["basic-card"],
+        },
+      ],
+      {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: `${largeMoney}.${largeMoney}`,
+          },
+        },
+        displayItems: [
+          {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: `-${largeMoney}`,
+            },
+          },
+          {
+            label: "",
+            amount: {
+              currency: "AUD",
+              value: `-${largeMoney}.${largeMoney}`,
+            },
+          },
+        ],
+      }
+    );
+  } catch (err) {
+    itThrows = true;
+  }
+  assert_false(itThrows, "shouldn't throw when given absurd monetary values");
+}, "it handles high precision currency values without throwing");
+
+// Process shipping options:
+const defaultAmount = Object.freeze({
+  currency: "USD",
+  value: "0.0",
+});
+const defaultShippingOption = Object.freeze({
+  id: "default",
+  label: "",
+  amount: defaultAmount,
+  selected: false,
+});
+const defaultShippingOptions = Object.freeze([
+  Object.assign({}, defaultShippingOption),
+]);
+
+for (const amount of invalidAmounts) {
+  test(() => {
+    assert_throws(
+      {
+        name: "TypeError",
+      },
+      () => {
+        const invalidAmount = Object.assign({}, defaultAmount, {
+          value: amount,
+        });
+        const invalidShippingOption = Object.assign({}, defaultShippingOption, {
+          amount: invalidAmount,
+        });
+        const details = Object.assign({}, defaultDetails, {
+          shippingOptions: [invalidShippingOption],
+        });
+        new PaymentRequest(defaultMethods, details);
+      }
+    );
+  }, "For each option in details.shippingOptions: if option.amount.value is not " + 'a valid decimal monetary value (in this case "' + amount + '"), then throw a TypeError');
+}
+
+test(() => {
+  const shippingOptions = [defaultShippingOption];
+  const details = Object.assign({}, defaultDetails, { shippingOptions });
+  const request = new PaymentRequest(defaultMethods, details);
+  assert_equals(
+    request.shippingOption,
+    null,
+    "request.shippingOption must be null"
+  );
+}, "If there is no selected shipping option, then PaymentRequest.shippingOption remains null");
+
+test(() => {
+  const selectedOption = Object.assign({}, defaultShippingOption, {
+    selected: true,
+    id: "PASS",
+  });
+  const shippingOptions = [selectedOption];
+  const details = Object.assign({}, defaultDetails, { shippingOptions });
+  const request = new PaymentRequest(defaultMethods, details);
+  assert_equals(request.shippingOption, "PASS", "selected option must be PASS");
+}, "If there is a selected shipping option, then it becomes synchronously selected");
+
+test(() => {
+  const failOption1 = Object.assign({}, defaultShippingOption, {
+    selected: true,
+    id: "FAIL1",
+  });
+  const failOption2 = Object.assign({}, defaultShippingOption, {
+    selected: false,
+    id: "FAIL2",
+  });
+  const passOption = Object.assign({}, defaultShippingOption, {
+    selected: true,
+    id: "PASS",
+  });
+  const shippingOptions = [failOption1, failOption2, passOption];
+  const details = Object.assign({}, defaultDetails, { shippingOptions });
+  const request = new PaymentRequest(defaultMethods, details);
+  assert_equals(request.shippingOption, "PASS", "selected option must PASS");
+}, "If there is a multiple selected shipping options, only the last is selected");
+
+test(() => {
+  const selectedOption = Object.assign({}, defaultShippingOption, {
+    selected: true,
+  });
+  const unselectedOption = Object.assign({}, defaultShippingOption, {
+    selected: false,
+  });
+  const shippingOptions = [selectedOption, unselectedOption];
+  const details = Object.assign({}, defaultDetails, { shippingOptions });
+  const request = new PaymentRequest(defaultMethods, details);
+  assert_equals(request.shippingOption, null, "selected option must be null");
+}, "If there are any duplicate shipping option ids, then there are no shipping options");
+
+// Process payment details modifiers:
+for (const amount of invalidTotalAmounts) {
+  test(() => {
+    assert_throws(
+      {
+        name: "TypeError",
+      },
+      () => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: amount,
+            },
+          },
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }
+    );
+  }, `If modifier.total.amount.value is not a valid decimal monetary value (in this case "${amount}"), then throw a TypeError`);
+}
+
+for (const amount of invalidAmounts) {
+  test(() => {
+    assert_throws(
+      {
+        name: "TypeError",
+      },
+      () => {
+        const invalidModifier = {
+          supportedMethods: ["basic-card"],
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.0",
+            },
+          },
+          additionalDisplayItems: [
+            {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: amount,
+              },
+            },
+          ],
+        };
+        new PaymentRequest(
+          [
+            {
+              supportedMethods: ["basic-card"],
+            },
+          ],
+          {
+            modifiers: [invalidModifier],
+            total: {
+              label: "",
+              amount: {
+                currency: "USD",
+                value: "1.0",
+              },
+            },
+          }
+        );
+      }
+    );
+  }, `If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "${amount}"), then throw a TypeError`);
+}
+
+test(() => {
+  let itThrows = false;
+  try {
+    new PaymentRequest(
+      [
+        {
+          supportedMethods: ["basic-card"],
+        },
+      ],
+      {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+        modifiers: [
+          {
+            supportedMethods: ["basic-card"],
+            data: ["some-data"],
+          },
+        ],
+      }
+    );
+  } catch (err) {
+    itThrows = true;
+  }
+  assert_false(itThrows, "shouldn't throw when given a list");
+}, "Modifier data must be JSON-serializable object (a list in this case)");
+
+test(() => {
+  let itThrows = false;
+  try {
+    new PaymentRequest(
+      [
+        {
+          supportedMethods: ["basic-card"],
+        },
+      ],
+      {
+        total: {
+          label: "",
+          amount: {
+            currency: "USD",
+            value: "1.00",
+          },
+        },
+        modifiers: [
+          {
+            supportedMethods: ["basic-card"],
+            data: {
+              some: "data",
+            },
+          },
+        ],
+      }
+    );
+  } catch (err) {
+    itThrows = true;
+  }
+  assert_false(itThrows, "shouldn't throw when given an object value");
+}, "Modifier data must be JSON-serializable object (a object in this case)");
+
+test(() => {
+  const recursiveDictionary = {};
+  recursiveDictionary.foo = recursiveDictionary;
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+          modifiers: [
+            {
+              supportedMethods: ["basic-card"],
+              data: recursiveDictionary,
+            },
+          ],
+        }
+      );
+    }
+  );
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+          modifiers: [
+            {
+              supportedMethods: ["basic-card"],
+              data: "a string",
+            },
+          ],
+        }
+      );
+    }
+  );
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+          modifiers: [
+            {
+              supportedMethods: ["basic-card"],
+              data: null,
+            },
+          ],
+        }
+      );
+    }
+  );
+}, "Rethrow any exceptions of JSON-serializing modifier.data into a string");
+
+//Setting ShippingType attribute during construction
+test(() => {
+  assert_throws(
+    {
+      name: "TypeError",
+    },
+    () => {
+      new PaymentRequest(
+        [
+          {
+            supportedMethods: ["basic-card"],
+          },
+        ],
+        {
+          total: {
+            label: "",
+            amount: {
+              currency: "USD",
+              value: "1.00",
+            },
+          },
+        },
+        {
+          shippingType: "invalid",
+        }
+      );
+    }
+  );
+}, "Shipping type should be valid");
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails, {});
+  assert_equals(request.shippingAddress, null, "must be null");
+}, "PaymentRequest.shippingAddress must initially be null");
+
+test(() => {
+  const request1 = new PaymentRequest(defaultMethods, defaultDetails, {});
+  assert_equals(request1.shippingType, null, "must be null");
+  const request2 = new PaymentRequest(defaultMethods, defaultDetails, {
+    requestShipping: false,
+  });
+  assert_equals(request2.shippingType, null, "must be null");
+}, "If options.requestShipping is not set, then request.shippingType attribute is null.");
+
+test(() => {
+  // option.shippingType defaults to 'shipping'
+  const request1 = new PaymentRequest(defaultMethods, defaultDetails, {
+    requestShipping: true,
+  });
+  assert_equals(request1.shippingType, "shipping", "must be shipping");
+  const request2 = new PaymentRequest(defaultMethods, defaultDetails, {
+    requestShipping: true,
+    shippingType: "delivery",
+  });
+  assert_equals(request2.shippingType, "delivery", "must be delivery");
+}, "If options.requestShipping is true, request.shippingType will be options.shippingType.");
+
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https-expected.txt
new file mode 100644 (file)
index 0000000..5179e95
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+FAIL Test for PaymentRequest identifier usage undefined is not a constructor (evaluating 'new window[0].PaymentRequest([{supportedMethods: ['foo']}], {id: 'my_payment_id', total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}})')
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https.html
new file mode 100644 (file)
index 0000000..c639f39
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for PaymentRequest identifier usage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="iframe" allowpaymentrequest></iframe>
+<script>
+async_test((t) => {
+  onload = t.step_func_done(() => {
+    var request = new window[0].PaymentRequest([{supportedMethods: ['foo']}], {id: 'my_payment_id', total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}});
+    assert_equals(request.id, 'my_payment_id', 'Payment identifier is not reflected correctly in PaymentRequest.id');
+
+    request = new window[0].PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}});
+    assert_equals(request.id.length, 36, 'Generated payment identifier is not of correct length.');
+  });
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe-expected.txt
new file mode 100644 (file)
index 0000000..c23cb1a
--- /dev/null
@@ -0,0 +1,7 @@
+
+
+FAIL Test for PaymentRequest in an iframe (see also
+https://github.com/w3c/browser-payment-api/issues/2) assert_throws: If the browsing context of the script calling the constructor is not a top-level browsing context, then throw a SecurityError. function "function () {
+        new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}});
+    }" threw object "ReferenceError: Can't find variable: PaymentRequest" ("ReferenceError") expected object "[object Object]" ("SecurityError")
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe.html
new file mode 100644 (file)
index 0000000..c3798f7
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for PaymentRequest in an iframe (see also
+https://github.com/w3c/browser-payment-api/issues/2)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe srcdoc="
+<!DOCTYPE html>
+<meta charset='utf-8'>
+<script>
+window.top.test(function() {
+    window.top.assert_throws({name: 'SecurityError'}, function() {
+        new PaymentRequest([{supportedMethods: ['foo']}], {total: {label: 'label', amount: {currency: 'USD', value: '5.00'}}});
+    }, 'If the browsing context of the script calling the constructor is not a top-level browsing context, then throw a SecurityError.');
+});
+</script>
+"></iframe>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt
new file mode 100644 (file)
index 0000000..80bad3e
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL onshippingaddresschange attribute is a generic handler for "shippingaddresschange" Can't find variable: PaymentRequest
+FAIL onshippingaddresschange attribute is a handler for PaymentRequestUpdateEvent Can't find variable: PaymentRequest
+FAIL onshippingaddresschange attribute and listeners both work Can't find variable: PaymentRequest
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html
new file mode 100644 (file)
index 0000000..a07ca2a
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for onshippingaddresschange attribute</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#onshippingaddresschange-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+"use strict";
+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",
+    },
+  },
+});
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new Event("shippingaddresschange");
+  let didHandle = false;
+  request.onshippingaddresschange = evt => {
+    assert_equals(ev, evt, "must be same event");
+    didHandle = true;
+  };
+  request.dispatchEvent(ev);
+  assert_true(didHandle, "event did not fire");
+}, `onshippingaddresschange attribute is a generic handler for "shippingaddresschange"`);
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new PaymentRequestUpdateEvent("shippingaddresschange");
+  let didHandle = false;
+  request.onshippingaddresschange = evt => {
+    assert_equals(ev, evt, "must be same event");
+    didHandle = true;
+  };
+  request.dispatchEvent(ev);
+  assert_true(didHandle, "event did not fire");
+}, `onshippingaddresschange attribute is a handler for PaymentRequestUpdateEvent`);
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new PaymentRequestUpdateEvent("shippingaddresschange");
+  let didHandle = false;
+  let didListen = false;
+  request.onshippingaddresschange = evt => {
+    assert_equals(ev, evt, "must be same event");
+    didHandle = true;
+  };
+  request.addEventListener("shippingaddresschange", evt => {
+    assert_equals(ev, evt, "must be same event");
+    didListen = true;
+  });
+  request.dispatchEvent(ev);
+  assert_true(didHandle, "onshippingaddresschange did not receive the event");
+  assert_true(didListen, "addEventListener did not receive the event");
+}, `onshippingaddresschange attribute and listeners both work`);
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt
new file mode 100644 (file)
index 0000000..f785267
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL onshippingoptionchange attribute is a generic handler for "shippingoptionchange" Can't find variable: PaymentRequest
+FAIL onshippingoptionchange attribute is a handler for PaymentRequestUpdateEvent Can't find variable: PaymentRequest
+FAIL onshippingoptionchange attribute and listeners both work Can't find variable: PaymentRequest
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html
new file mode 100644 (file)
index 0000000..b954337
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for onshippingoptionchange attribute</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#onshippingoptionchange-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+"use strict";
+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",
+    },
+  },
+});
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new Event("shippingoptionchange");
+  let didHandle = false;
+  request.onshippingoptionchange = evt => {
+    assert_equals(ev, evt, "must be same event");
+    didHandle = true;
+  };
+  request.dispatchEvent(ev);
+  assert_true(didHandle, "event did not fire");
+}, `onshippingoptionchange attribute is a generic handler for "shippingoptionchange"`);
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new PaymentRequestUpdateEvent("shippingoptionchange");
+  let didHandle = false;
+  request.onshippingoptionchange = evt => {
+    assert_equals(ev, evt, "must be same event");
+    didHandle = true;
+  };
+  request.dispatchEvent(ev);
+  assert_true(didHandle, "event did not fire");
+}, `onshippingoptionchange attribute is a handler for PaymentRequestUpdateEvent`);
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new PaymentRequestUpdateEvent("shippingoptionchange");
+  let didHandle = false;
+  let didListen = false;
+  request.onshippingoptionchange = evt => {
+    assert_equals(ev, evt, "must be same event");
+    didHandle = true;
+  };
+  request.addEventListener("shippingoptionchange", evt => {
+    assert_equals(ev, evt, "must be same event");
+    didListen = true;
+  });
+  request.dispatchEvent(ev);
+  assert_true(didHandle, "onshippingoptionchange did not receive the event");
+  assert_true(didListen, "addEventListener did not receive the event");
+}, `onshippingoptionchange attribute and listeners both work`);
+
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-response-id.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-response-id.html
new file mode 100644 (file)
index 0000000..a28f3b2
--- /dev/null
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>PaymentRequest identifier manual test</title>
+</head>
+<body>
+  <div id="contents">
+    <h1>PaymentRequest identifier manual test</h1>
+    <p>Perform the following steps:</p>
+    <ul>
+      <li>Press 'Buy'</li>
+      <li>In the payment dialog make sure a payment app is selected</li>
+      <li>In the payment dialog press 'Pay'</li>
+      <li>In the launched payment app perform steps to do the payment</li>
+      <li>The response will be processed and below should display 'my_payment_id'</li>
+    </ul>
+    <p>No payment will be processed.</p>
+    <p>Price: USD <strong>$55.00</strong></p>
+    <p><button onclick="onBuyClicked()">Buy</button></p>
+  </div>
+  <pre id="msg"></pre>
+  <script>
+    /**
+      * Initializes the payment request object.
+      * @return {PaymentRequest} The payment request object.
+      */
+     function buildPaymentRequest() {
+       if (!window.PaymentRequest) {
+         return null;
+       }
+
+       const supportedInstruments = [{
+         supportedMethods: ['https://android.com/pay'],
+         data: {
+           merchantName: 'Rouslan Solomakhin',
+           merchantId: '00184145120947117657',
+           allowedCardNetworks: ['AMEX', 'MASTERCARD', 'VISA', 'DISCOVER'],
+           paymentMethodTokenizationParameters: {
+             tokenizationType: 'GATEWAY_TOKEN',
+             parameters: {
+               'gateway': 'stripe',
+               'stripe:publishableKey': 'pk_live_lNk21zqKM2BENZENh3rzCUgo',
+               'stripe:version': '2016-07-06',
+             },
+           },
+         },
+       }, {
+         supportedMethods: ['basic-card'],
+         data: {
+           supportedNetworks: ['unionpay', 'visa', 'mastercard', 'amex', 'discover',
+             'diners', 'jcb', 'mir',
+           ],
+           supportedTypes: ['prepaid', 'debit', 'credit'],
+         },
+       }];
+
+       const details = {
+         id: 'my_payment_id',
+         total: {
+           label: 'Donation',
+           amount: {
+             currency: 'USD',
+             value: '55.00',
+           },
+         },
+         displayItems: [{
+           label: 'Original donation amount',
+           amount: {
+             currency: 'USD',
+             value: '65.00',
+           },
+         }, {
+           label: 'Friends and family discount',
+           amount: {
+             currency: 'USD',
+             value: '-10.00',
+           },
+         }],
+       };
+
+       let request = null;
+
+       try {
+         request = new PaymentRequest(supportedInstruments, details);
+         if (request.canMakePayment) {
+           request.canMakePayment().then(function(result) {
+             console.log(result ? 'Can make payment' : 'Cannot make payment');
+           }).catch(function(err) {
+             console.log(err);
+           });
+         }
+       } catch (e) {
+         console.log('Developer mistake: \'' + e + '\'');
+       }
+
+       return request;
+     }
+
+     let request = buildPaymentRequest();
+
+     /**
+      * Launches payment request that does not require shipping.
+      */
+     function onBuyClicked() { // eslint-disable-line no-unused-vars
+       if (!window.PaymentRequest || !request) {
+         console.log('PaymentRequest API is not supported.');
+         return;
+       }
+
+       try {
+         request.show()
+           .then(function(instrumentResponse) {
+             window.setTimeout(function() {
+               instrumentResponse.complete('success')
+                 .then(function() {
+                    let element = document.createElement('pre');
+                    element.innerHTML = instrumentResponse.requestId;
+                    document.getElementById('msg').appendChild(element);
+                 })
+                 .catch(function(err) {
+                   console.log(err);
+                   request = buildPaymentRequest();
+                 });
+             }, 2000);
+           })
+           .catch(function(err) {
+             console.log(err);
+             request = buildPaymentRequest();
+           });
+       } catch (e) {
+         console.log('Developer mistake: \'' + e + '\'');
+         request = buildPaymentRequest();
+       }
+     }
+  </script>
+</body>
+</html>
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https-expected.txt
new file mode 100644 (file)
index 0000000..2c9f786
--- /dev/null
@@ -0,0 +1,4 @@
+
+FAIL Throws if the promise [[state]] is not "created" promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: PaymentRequest"
+FAIL If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException. promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: PaymentRequest"
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html
new file mode 100644 (file)
index 0000000..542408d
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<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>
+'use strict';
+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);
+  const acceptPromise = request.show(); // Sets state to "interactive"
+  await promise_rejects(t, "InvalidStateError", request.show());
+  await request.abort();
+  await promise_rejects(t, "AbortError", acceptPromise);
+}, `Throws if the promise [[state]] is not "created"`);
+
+promise_test(async t => {
+  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);
+}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
+
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http-expected.txt
new file mode 100644 (file)
index 0000000..9561a32
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL PaymentRequestUpdateEvent constructor throws in a non-secure context assert_throws: function "() => {
+    new PaymentRequestUpdateEvent("test");
+  }" threw object "ReferenceError: Can't find variable: PaymentRequestUpdateEvent" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http.html
new file mode 100644 (file)
index 0000000..120c3c8
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for PaymentRequestUpdateEvent Constructor</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+  assert_throws("SecurityError", () => {
+    new PaymentRequestUpdateEvent("test");
+  });
+}, "PaymentRequestUpdateEvent constructor throws in a non-secure context");
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https-expected.txt
new file mode 100644 (file)
index 0000000..78520b9
--- /dev/null
@@ -0,0 +1,5 @@
+
+FAIL PaymentRequestUpdateEvent can be constructed in secure-context assert_true: Unexpected exception: Can't find variable: PaymentRequestUpdateEvent expected true got false
+FAIL PaymentRequestUpdateEvent can be constructed with an EventInitDict, even if not trusted Can't find variable: PaymentRequestUpdateEvent
+FAIL PaymentRequestUpdateEvent can be dispatched, even if not trusted Can't find variable: PaymentRequest
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https.html b/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https.html
new file mode 100644 (file)
index 0000000..d28fa85
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Test for PaymentRequestUpdateEvent Constructor</title>
+<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.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",
+    },
+  },
+});
+
+test(() => {
+  try {
+    new PaymentRequestUpdateEvent("test");
+  } catch (err) {
+    assert_true(false, `Unexpected exception: ${err.message}`);
+  }
+}, "PaymentRequestUpdateEvent can be constructed in secure-context");
+
+test(() => {
+  const ev = new PaymentRequestUpdateEvent("test", {
+    bubbles: true,
+    cancelable: true,
+    composed: true,
+  });
+  assert_false(ev.isTrusted, "constructed in script, so not be trusted");
+  assert_true(ev.bubbles, "set by EventInitDict");
+  assert_true(ev.cancelable, "set by EventInitDict");
+  assert_true(ev.composed, "set by EventInitDict");
+  assert_equals(ev.type, "test");
+}, "PaymentRequestUpdateEvent can be constructed with an EventInitDict, even if not trusted");
+
+test(() => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const ev = new PaymentRequestUpdateEvent("test");
+  request.addEventListener("test", evt => {
+    assert_equals(ev, evt);
+  });
+  request.dispatchEvent(ev);
+}, "PaymentRequestUpdateEvent can be dispatched, even if not trusted");
+
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/payment-request/w3c-import.log
new file mode 100644 (file)
index 0000000..3de8ccd
--- /dev/null
@@ -0,0 +1,31 @@
+The tests in this directory were imported from the W3C repository.
+Do NOT modify these tests directly in WebKit.
+Instead, create a pull request on the WPT github:
+       https://github.com/w3c/web-platform-tests
+
+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
+
+Do NOT modify or remove this file.
+
+------------------------------------------------------------------------
+Properties requiring vendor prefixes:
+None
+Property values requiring vendor prefixes:
+None
+------------------------------------------------------------------------
+List of files:
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/OWNERS
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/historical.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/interfaces.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-abort-method.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-canmakepayment-method.https.http
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-constructor.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-id.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-in-iframe.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingaddresschange-attribute.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-onshippingoptionchange-attribute.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-response-id.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-show-method.https.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.http.html
+/LayoutTests/imported/w3c/web-platform-tests/payment-request/payment-request-update-event-constructor.https.html