Bug 1446179 - Update payments tests to use ES modules. r=jaws
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 12 Apr 2018 19:52:05 -0700
changeset 470024 4057d947afae2c4052ac66b8edab87b942eb9f08
parent 470023 64f5c8475f3b3087790dd23acee0e3499126c4fc
child 470025 5fe5bf607ad6e7f6224df2fce1bf58a984978c5c
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1446179
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1446179 - Update payments tests to use ES modules. r=jaws MozReview-Commit-ID: 1cRK5xAEygF
toolkit/components/payments/.eslintrc.js
toolkit/components/payments/test/mochitest/mochitest.ini
toolkit/components/payments/test/mochitest/test_ObservedPropertiesMixin.html
toolkit/components/payments/test/mochitest/test_PaymentStateSubscriberMixin.html
toolkit/components/payments/test/mochitest/test_PaymentsStore.html
toolkit/components/payments/test/mochitest/test_address_picker.html
toolkit/components/payments/test/mochitest/test_basic_card_form.html
toolkit/components/payments/test/mochitest/test_currency_amount.html
toolkit/components/payments/test/mochitest/test_order_details.html
toolkit/components/payments/test/mochitest/test_payer_address_picker.html
toolkit/components/payments/test/mochitest/test_payment_details_item.html
toolkit/components/payments/test/mochitest/test_payment_dialog.html
toolkit/components/payments/test/mochitest/test_payment_method_picker.html
toolkit/components/payments/test/mochitest/test_rich_select.html
toolkit/components/payments/test/mochitest/test_shipping_option_picker.html
toolkit/components/payments/test/unit/test_PaymentsStore.js
toolkit/components/payments/test/unit/xpcshell.ini
--- a/toolkit/components/payments/.eslintrc.js
+++ b/toolkit/components/payments/.eslintrc.js
@@ -3,16 +3,17 @@
 module.exports = {
   overrides: [
     {
       files: [
         "res/components/*.js",
         "res/containers/*.js",
         "res/mixins/*.js",
         "res/PaymentsStore.js",
+        "test/mochitest/test_*.html",
       ],
       parserOptions: {
         sourceType: "module",
       },
     },
   ],
   rules: {
     "mozilla/var-only-at-top-level": "error",
--- a/toolkit/components/payments/test/mochitest/mochitest.ini
+++ b/toolkit/components/payments/test/mochitest/mochitest.ini
@@ -1,47 +1,23 @@
 [DEFAULT]
 prefs =
    dom.webcomponents.customelements.enabled=false
 support-files =
    ../../../../../browser/extensions/formautofill/content/autofillEditForms.js
    ../../../../../testing/modules/sinon-2.3.2.js
-   ../../res/paymentRequest.css
-   ../../res/paymentRequest.js
-   ../../res/paymentRequest.xhtml
-   ../../res/PaymentsStore.js
-   ../../res/unprivileged-fallbacks.js
-   ../../res/components/currency-amount.js
-   ../../res/components/address-option.js
-   ../../res/components/address-option.css
-   ../../res/components/basic-card-option.js
-   ../../res/components/basic-card-option.css
-   ../../res/components/payment-details-item.js
-   ../../res/components/rich-option.js
-   ../../res/components/rich-select.css
-   ../../res/components/rich-select.js
-   ../../res/components/shipping-option.js
-   ../../res/components/shipping-option.css
-   ../../res/containers/address-picker.js
-   ../../res/containers/basic-card-form.js
-   ../../res/containers/shipping-option-picker.js
-   ../../res/containers/order-details.js
-   ../../res/containers/payment-dialog.js
-   ../../res/containers/payment-method-picker.js
-   ../../res/mixins/ObservedPropertiesMixin.js
-   ../../res/mixins/PaymentStateSubscriberMixin.js
-   ../../res/vendor/custom-elements.min.js
-   ../../res/vendor/custom-elements.min.js.map
+   ../../res/**
    payments_common.js
 skip-if = !e10s
 
 [test_address_picker.html]
 [test_basic_card_form.html]
 [test_currency_amount.html]
 [test_order_details.html]
 [test_payer_address_picker.html]
 [test_payment_dialog.html]
 [test_payment_details_item.html]
 [test_payment_method_picker.html]
 [test_rich_select.html]
 [test_shipping_option_picker.html]
 [test_ObservedPropertiesMixin.html]
+[test_PaymentsStore.html]
 [test_PaymentStateSubscriberMixin.html]
--- a/toolkit/components/payments/test/mochitest/test_ObservedPropertiesMixin.html
+++ b/toolkit/components/payments/test/mochitest/test_ObservedPropertiesMixin.html
@@ -4,34 +4,34 @@
 Test the ObservedPropertiesMixin
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the ObservedPropertiesMixin</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <test-element id="el1" one="foo" two-word="bar"></test-element>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the ObservedPropertiesMixin **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/mixins/ObservedPropertiesMixin.js */
+import ObservedPropertiesMixin from "../../res/mixins/ObservedPropertiesMixin.js";
 
 class TestElement extends ObservedPropertiesMixin(HTMLElement) {
   static get observedAttributes() {
     return ["one", "two-word"];
   }
 
   render() {
     this.textContent = JSON.stringify({
--- a/toolkit/components/payments/test/mochitest/test_PaymentStateSubscriberMixin.html
+++ b/toolkit/components/payments/test/mochitest/test_PaymentStateSubscriberMixin.html
@@ -5,36 +5,36 @@ Test the PaymentStateSubscriberMixin
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the PaymentStateSubscriberMixin</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="sinon-2.3.2.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <test-element id="el1"></test-element>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the PaymentStateSubscriberMixin **/
 
 /* global sinon */
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/mixins/PaymentStateSubscriberMixin.js */
+
+import PaymentStateSubscriberMixin from "../../res/mixins/PaymentStateSubscriberMixin.js";
 
 class TestElement extends PaymentStateSubscriberMixin(HTMLElement) {
   render(state) {
     this.textContent = JSON.stringify(state);
   }
 }
 
 // We must spy on the prototype by creating the instance in order to test Custom Element reactions.
rename from toolkit/components/payments/test/unit/test_PaymentsStore.js
rename to toolkit/components/payments/test/mochitest/test_PaymentsStore.html
--- a/toolkit/components/payments/test/unit/test_PaymentsStore.js
+++ b/toolkit/components/payments/test/mochitest/test_PaymentsStore.html
@@ -1,65 +1,104 @@
-"use strict";
+<!DOCTYPE HTML>
+<html>
+<!--
+Test the PaymentsStore
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test the PaymentsStore</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+
+  <script src="sinon-2.3.2.js"></script>
+  <script src="payments_common.js"></script>
+
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  <p id="display">
+  </p>
+<div id="content" style="display: none">
 
-/* import-globals-from ../../res/PaymentsStore.js */
-Services.scriptloader.loadSubScript("resource://payments/PaymentsStore.js", this);
+</div>
+<pre id="test">
+</pre>
+<script type="module">
+/** Test the PaymentsStore **/
+
+/* global sinon */
+
+import PaymentsStore from "../../res/PaymentsStore.js";
+
+function assert_throws(block, expectedError, message) {
+  let actual;
+  try {
+    block();
+  } catch (e) {
+    actual = e;
+  }
+  ok(actual, "Expecting exception: " + message);
+  ok(actual instanceof expectedError,
+     `Check error type is ${expectedError.prototype.name}: ${message}`);
+}
 
 add_task(async function test_defaultState() {
-  Assert.ok(!!PaymentsStore, "Check PaymentsStore import");
+  ok(!!PaymentsStore, "Check PaymentsStore import");
   let ps = new PaymentsStore({
     foo: "bar",
   });
 
   let state = ps.getState();
-  Assert.ok(!!state, "Check state is truthy");
-  Assert.equal(state.foo, "bar", "Check .foo");
+  ok(!!state, "Check state is truthy");
+  is(state.foo, "bar", "Check .foo");
 
-  Assert.throws(() => state.foo = "new", TypeError, "Assigning to existing prop. should throw");
-  Assert.throws(() => state.other = "something", TypeError, "Adding a new prop. should throw");
-  Assert.throws(() => delete state.foo, TypeError, "Deleting a prop. should throw");
+  assert_throws(() => state.foo = "new", TypeError, "Assigning to existing prop. should throw");
+  assert_throws(() => state.other = "something", TypeError, "Adding a new prop. should throw");
+  assert_throws(() => delete state.foo, TypeError, "Deleting a prop. should throw");
 });
 
 add_task(async function test_setState() {
   let ps = new PaymentsStore({});
 
   ps.setState({
     one: "one",
   });
   let state = ps.getState();
-  Assert.equal(Object.keys(state).length, 1, "Should only have 1 prop. set");
-  Assert.equal(state.one, "one", "Check .one");
+  is(Object.keys(state).length, 1, "Should only have 1 prop. set");
+  is(state.one, "one", "Check .one");
 
   ps.setState({
     two: 2,
   });
   state = ps.getState();
-  Assert.equal(Object.keys(state).length, 2, "Should have 2 props. set");
-  Assert.equal(state.one, "one", "Check .one");
-  Assert.equal(state.two, 2, "Check .two");
+  is(Object.keys(state).length, 2, "Should have 2 props. set");
+  is(state.one, "one", "Check .one");
+  is(state.two, 2, "Check .two");
 
   ps.setState({
     one: "a",
     two: "b",
   });
   state = ps.getState();
-  Assert.equal(state.one, "a", "Check .one");
-  Assert.equal(state.two, "b", "Check .two");
+  is(state.one, "a", "Check .one");
+  is(state.two, "b", "Check .two");
 
   info("check consecutive setState for the same prop");
   ps.setState({
     one: "c",
   });
   ps.setState({
     one: "d",
   });
   state = ps.getState();
-  Assert.equal(Object.keys(state).length, 2, "Should have 2 props. set");
-  Assert.equal(state.one, "d", "Check .one");
-  Assert.equal(state.two, "b", "Check .two");
+  is(Object.keys(state).length, 2, "Should have 2 props. set");
+  is(state.one, "d", "Check .one");
+  is(state.two, "b", "Check .two");
 });
 
 add_task(async function test_subscribe_unsubscribe() {
   let ps = new PaymentsStore({});
   let subscriber = {
     stateChangePromise: null,
     _stateChangeResolver: null,
 
@@ -77,50 +116,54 @@ add_task(async function test_subscribe_u
     },
   };
 
   sinon.spy(subscriber, "stateChangeCallback");
   subscriber.reset();
   ps.subscribe(subscriber);
   info("subscribe the same listener twice to ensure it still doesn't call the callback");
   ps.subscribe(subscriber);
-  Assert.ok(subscriber.stateChangeCallback.notCalled,
-            "Check not called synchronously when subscribing");
+  ok(subscriber.stateChangeCallback.notCalled,
+     "Check not called synchronously when subscribing");
 
   let changePromise = subscriber.stateChangePromise;
   ps.setState({
     a: 1,
   });
-  Assert.ok(subscriber.stateChangeCallback.notCalled,
-            "Check not called synchronously for changes");
+  ok(subscriber.stateChangeCallback.notCalled,
+     "Check not called synchronously for changes");
   let state = await changePromise;
-  Assert.equal(state, subscriber.stateChangeCallback.getCall(0).args[0],
-               "Check resolved state is last state");
-  Assert.equal(JSON.stringify(state), `{"a":1}`, "Check callback state");
+  is(state, subscriber.stateChangeCallback.getCall(0).args[0],
+     "Check resolved state is last state");
+  is(JSON.stringify(state), `{"a":1}`, "Check callback state");
 
   info("Testing consecutive setState");
   subscriber.reset();
   subscriber.stateChangeCallback.reset();
   changePromise = subscriber.stateChangePromise;
   ps.setState({
     a: 2,
   });
   ps.setState({
     a: 3,
   });
-  Assert.ok(subscriber.stateChangeCallback.notCalled,
-            "Check not called synchronously for changes");
+  ok(subscriber.stateChangeCallback.notCalled,
+     "Check not called synchronously for changes");
   state = await changePromise;
-  Assert.equal(state, subscriber.stateChangeCallback.getCall(0).args[0],
-               "Check resolved state is last state");
-  Assert.equal(JSON.stringify(subscriber.stateChangeCallback.getCall(0).args[0]), `{"a":3}`,
-               "Check callback state matches second setState");
+  is(state, subscriber.stateChangeCallback.getCall(0).args[0],
+     "Check resolved state is last state");
+  is(JSON.stringify(subscriber.stateChangeCallback.getCall(0).args[0]), `{"a":3}`,
+     "Check callback state matches second setState");
 
   info("test unsubscribe");
   subscriber.stateChangeCallback = function unexpectedChange() {
-    Assert.ok(false, "stateChangeCallback shouldn't be called after unsubscribing");
+    ok(false, "stateChangeCallback shouldn't be called after unsubscribing");
   };
   ps.unsubscribe(subscriber);
   ps.setState({
     a: 4,
   });
   await Promise.resolve("giving a chance for the callback to be called");
 });
+</script>
+
+</body>
+</html>
--- a/toolkit/components/payments/test/mochitest/test_address_picker.html
+++ b/toolkit/components/payments/test/mochitest/test_address_picker.html
@@ -5,43 +5,37 @@ Test the address-picker component
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the address-picker component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
-  <script src="rich-select.js"></script>
-  <script src="address-picker.js"></script>
-  <script src="rich-option.js"></script>
-  <script src="address-option.js"></script>
-  <link rel="stylesheet" type="text/css" href="rich-select.css"/>
-  <link rel="stylesheet" type="text/css" href="address-option.css"/>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
+  <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/address-option.css"/>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <address-picker id="picker1"
                     selected-state-key="selectedShippingAddress"></address-picker>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the address-picker component **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/components/address-option.js */
+import "../../res/containers/address-picker.js";
 
 let picker1 = document.getElementById("picker1");
 
 add_task(async function test_empty() {
   ok(picker1, "Check picker1 exists");
   let {savedAddresses} = picker1.requestStore.getState();
   is(Object.keys(savedAddresses).length, 0, "Check empty initial state");
   is(picker1.dropdown.popupBox.children.length, 0, "Check dropdown is empty");
--- a/toolkit/components/payments/test/mochitest/test_basic_card_form.html
+++ b/toolkit/components/payments/test/mochitest/test_basic_card_form.html
@@ -6,40 +6,39 @@ Test the basic-card-form element
 <head>
   <meta charset="utf-8">
   <title>Test the basic-card-form element</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="sinon-2.3.2.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="unprivileged-fallbacks.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+  <script src="../../res/unprivileged-fallbacks.js"></script>
   <script src="autofillEditForms.js"></script>
-  <script src="basic-card-form.js"></script>
-  <script src="paymentRequest.js"></script>
+  <script src="../../res/paymentRequest.js"></script>
+
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <link rel="stylesheet" type="text/css" href="paymentRequest.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/paymentRequest.css"/>
 </head>
 <body>
   <p id="display">
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the basic-card-form element **/
 
 /* global sinon */
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/mixins/PaymentStateSubscriberMixin.js */
+
+import BasicCardForm from "../../res/containers/basic-card-form.js";
 
 let display = document.getElementById("display");
 
 function checkCCForm(customEl, expectedCard) {
   const CC_PROPERTY_NAMES = [
     "cc-number",
     "cc-name",
     "cc-exp-month",
@@ -49,28 +48,28 @@ function checkCCForm(customEl, expectedC
     let expectedVal = expectedCard[propName] || "";
     is(document.getElementById(propName).value,
        expectedVal.toString(),
        `Check ${propName}`);
   }
 }
 
 add_task(async function test_initialState() {
-  let form = document.createElement("basic-card-form");
+  let form = new BasicCardForm();
   let {page} = form.requestStore.getState();
   is(page.id, "payment-summary", "Check initial page");
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
   is(page.id, "payment-summary", "Check initial page after appending");
   form.remove();
 });
 
 add_task(async function test_backButton() {
-  let form = document.createElement("basic-card-form");
+  let form = new BasicCardForm();
   form.dataset.backButtonLabel = "Back";
   await form.requestStore.setState({
     page: {
       id: "test-page",
     },
   });
   await form.promiseReady;
   display.appendChild(form);
@@ -82,17 +81,17 @@ add_task(async function test_backButton(
 
   let {page} = await stateChangePromise;
   is(page.id, "payment-summary", "Check initial page after appending");
 
   form.remove();
 });
 
 add_task(async function test_saveButton() {
-  let form = document.createElement("basic-card-form");
+  let form = new BasicCardForm();
   form.dataset.saveButtonLabel = "Save";
   form.dataset.errorGenericSave = "Generic error";
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   form.form.querySelector("#cc-number").focus();
   sendString("4111111111111111");
@@ -133,34 +132,34 @@ add_task(async function test_saveButton(
         id: "payment-summary",
       },
     },
   }, "Check event details for the message to chrome");
   form.remove();
 });
 
 add_task(async function test_genericError() {
-  let form = document.createElement("basic-card-form");
+  let form = new BasicCardForm();
   await form.requestStore.setState({
     page: {
       id: "test-page",
       error: "Generic Error",
     },
   });
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   ok(!isHidden(form.genericErrorText), "Error message should be visible");
   is(form.genericErrorText.textContent, "Generic Error", "Check error message");
   form.remove();
 });
 
 add_task(async function test_record() {
-  let form = document.createElement("basic-card-form");
+  let form = new BasicCardForm();
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   info("test year before current");
   let card1 = deepClone(PTU.BasicCards.JohnDoe);
   card1.guid = "9864798564";
   card1["cc-exp-year"] = 2011;
--- a/toolkit/components/payments/test/mochitest/test_currency_amount.html
+++ b/toolkit/components/payments/test/mochitest/test_currency_amount.html
@@ -4,33 +4,34 @@
 Test the currency-amount component
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the currency-amount component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="currency-amount.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <currency-amount id="amount1"></currency-amount>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the currency-amount component **/
 
+import "../../res/components/currency-amount.js";
+
 /* import-globals-from payments_common.js */
 
 let amount1 = document.getElementById("amount1");
 
 add_task(async function test_no_value() {
   ok(amount1, "amount1 exists");
   is(amount1.textContent, "", "Initially empty");
 
--- a/toolkit/components/payments/test/mochitest/test_order_details.html
+++ b/toolkit/components/payments/test/mochitest/test_order_details.html
@@ -4,20 +4,18 @@
   Test the order-details component
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the order-details component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
-  <script src="order-details.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
   <template id="order-details-template">
     <ul class="main-list"></ul>
     <ul class="footer-items-list"></ul>
 
     <div class="details-total">
       <h2 class="label">Total</h2>
@@ -29,22 +27,23 @@
   <p id="display">
     <order-details></order-details>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the order-details component **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/mixins/PaymentStateSubscriberMixin.js */
-/* import-globals-from ../../res/containers/order-details.js */
+
+import OrderDetails from "../../res/containers/order-details.js";
+import {requestStore} from "../../res/mixins/PaymentStateSubscriberMixin.js";
 
 let orderDetails = document.querySelector("order-details");
 let emptyState = requestStore.getState();
 
 function setup() {
   let initialState = deepClone(emptyState);
   requestStore.setState(initialState);
 }
@@ -60,17 +59,17 @@ add_task(async function isFooterItem() {
     amount: { currency: "USD", value: "1" },
   }, "items without type of 'tax' arent footer items"));
 });
 
 add_task(async function test_initial_state() {
   setup();
   is(orderDetails.mainItemsList.childElementCount, 0, "main items list is initially empty");
   is(orderDetails.footerItemsList.childElementCount, 0, "footer items list is initially empty");
-  is(orderDetails.totalAmountElem.value, 0, "total amount is 0");
+  is(orderDetails.totalAmountElem.value, "0", "total amount is 0");
 });
 
 add_task(async function test_list_population() {
   setup();
   let paymentDetails = requestStore.getState().request.paymentDetails;
   paymentDetails.displayItems = [
     {
       label: "One",
@@ -113,16 +112,16 @@ add_task(async function test_list_popula
 });
 
 add_task(async function test_total() {
   let paymentDetails = requestStore.getState().request.paymentDetails;
   paymentDetails.totalItem = { label: "foo", amount: { currency: "JPY", value: 5 }};
   requestStore.setState({ paymentDetails });
   await asyncElementRendered();
 
-  is(orderDetails.totalAmountElem.value, 5, "total amount gets updated");
+  is(orderDetails.totalAmountElem.value, "5", "total amount gets updated");
   is(orderDetails.totalAmountElem.currency, "JPY", "total currency gets updated");
 });
 
 </script>
 
 </body>
 </html>
--- a/toolkit/components/payments/test/mochitest/test_payer_address_picker.html
+++ b/toolkit/components/payments/test/mochitest/test_payer_address_picker.html
@@ -5,46 +5,39 @@ Test the paymentOptions address-picker
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the paymentOptions address-picker</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="payments_common.js"></script>
 
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
-  <script src="payment-dialog.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
 
-  <script src="rich-select.js"></script>
-  <script src="address-picker.js"></script>
-  <script src="rich-option.js"></script>
-  <script src="address-option.js"></script>
-  <script src="currency-amount.js"></script>
-  <link rel="stylesheet" type="text/css" href="rich-select.css"/>
-  <link rel="stylesheet" type="text/css" href="address-option.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/address-option.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/paymentRequest.css"/>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <link rel="stylesheet" type="text/css" href="paymentRequest.css"/>
 </head>
 <body>
   <p id="display">
-    <iframe id="templateFrame" src="paymentRequest.xhtml" width="0" height="0"></iframe>
+    <iframe id="templateFrame" src="../../res/paymentRequest.xhtml" width="0" height="0"></iframe>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the payer requested details functionality **/
 
 /* import-globals-from payments_common.js */
 
+import PaymentDialog from "../../res/containers/payment-dialog.js";
+
 function getVisiblePickerOptions(picker) {
   let select = picker.querySelector(":scope > rich-select");
   let options = select.querySelectorAll("address-option");
   let visibleOptions = Array.from(options).filter(isVisible);
   return visibleOptions;
 }
 
 function isVisible(elem) {
@@ -138,17 +131,17 @@ add_task(async function setup_once() {
 
   let displayEl = document.getElementById("display");
   // Import the templates from the real shipping dialog to avoid duplication.
   for (let template of templateFrame.contentDocument.querySelectorAll("template")) {
     let imported = document.importNode(template, true);
     displayEl.appendChild(imported);
   }
 
-  elDialog = document.createElement("payment-dialog");
+  elDialog = new PaymentDialog();
   displayEl.appendChild(elDialog);
   elPicker = elDialog.querySelector("address-picker.payer-related");
 
   initialState = Object.assign({}, elDialog.requestStore.getState(), {
     changesPrevented: false,
     completionState: "initial",
     orderDetailsShowing: false,
   });
--- a/toolkit/components/payments/test/mochitest/test_payment_details_item.html
+++ b/toolkit/components/payments/test/mochitest/test_payment_details_item.html
@@ -4,37 +4,35 @@
 Test the payment-details-item component
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the payment-details-item component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="currency-amount.js"></script>
-  <script src="payment-details-item.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <payment-details-item id="item1"></payment-details-item>
     <payment-details-item id="item2" label="Some item" amount-value="2" amount-currency="USD"></payment-details-item>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the payment-details-item component **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/components/payment-details-item.js */
+import "../../res/components/payment-details-item.js";
 
 let item1 = document.getElementById("item1");
 let item2 = document.getElementById("item2");
 
 add_task(async function test_no_value() {
   ok(item1, "item1 exists");
   is(item1.textContent, "", "Initially empty");
 
--- a/toolkit/components/payments/test/mochitest/test_payment_dialog.html
+++ b/toolkit/components/payments/test/mochitest/test_payment_dialog.html
@@ -5,39 +5,36 @@ Test the payment-dialog custom element
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the payment-dialog element</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script src="sinon-2.3.2.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
-  <script src="payment-dialog.js"></script>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <link rel="stylesheet" type="text/css" href="paymentRequest.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/paymentRequest.css"/>
 </head>
 <body>
   <p id="display">
-    <iframe id="templateFrame" src="paymentRequest.xhtml" width="0" height="0"></iframe>
+    <iframe id="templateFrame" src="../../res/paymentRequest.xhtml" width="0" height="0"></iframe>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the payment-dialog element **/
 
 /* global sinon */
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/mixins/PaymentStateSubscriberMixin.js */
+
+import PaymentDialog from "../../res/containers/payment-dialog.js";
 
 let el1;
 
 let completionStates = [
     ["processing", "Processing"],
     ["success", "Done"],
     ["fail", "Fail"],
     ["unknown", "Unknown"],
@@ -57,17 +54,17 @@ add_task(async function setup_once() {
 
   let displayEl = document.getElementById("display");
   // Import the templates from the real shipping dialog to avoid duplication.
   for (let template of templateFrame.contentDocument.querySelectorAll("template")) {
     let imported = document.importNode(template, true);
     displayEl.appendChild(imported);
   }
 
-  el1 = document.createElement("payment-dialog");
+  el1 = new PaymentDialog();
   displayEl.appendChild(el1);
 
   sinon.spy(el1, "render");
   sinon.spy(el1, "stateChangeCallback");
 });
 
 async function setup() {
   await el1.requestStore.setState({
--- a/toolkit/components/payments/test/mochitest/test_payment_method_picker.html
+++ b/toolkit/components/payments/test/mochitest/test_payment_method_picker.html
@@ -5,43 +5,38 @@ Test the payment-method-picker component
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the payment-method-picker component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
-  <script src="rich-select.js"></script>
-  <script src="payment-method-picker.js"></script>
-  <script src="rich-option.js"></script>
-  <script src="basic-card-option.js"></script>
-  <link rel="stylesheet" type="text/css" href="rich-select.css"/>
-  <link rel="stylesheet" type="text/css" href="basic-card-option.css"/>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
+  <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/basic-card-option.css"/>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <payment-method-picker id="picker1"
                            selected-state-key="selectedPaymentCard"></payment-method-picker>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the payment-method-picker component **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/components/basic-card-option.js */
+import "../../res/components/basic-card-option.js";
+import "../../res/containers/payment-method-picker.js";
 
 let picker1 = document.getElementById("picker1");
 
 add_task(async function test_empty() {
   ok(picker1, "Check picker1 exists");
   let {savedBasicCards} = picker1.requestStore.getState();
   is(Object.keys(savedBasicCards).length, 0, "Check empty initial state");
   is(picker1.dropdown.popupBox.children.length, 0, "Check dropdown is empty");
--- a/toolkit/components/payments/test/mochitest/test_rich_select.html
+++ b/toolkit/components/payments/test/mochitest/test_rich_select.html
@@ -5,25 +5,21 @@ Test the rich-select component
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the rich-select component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="rich-select.js"></script>
-  <script src="rich-option.js"></script>
-  <script src="address-option.js"></script>
-  <script src="basic-card-option.js"></script>
-  <link rel="stylesheet" type="text/css" href="rich-select.css"/>
-  <link rel="stylesheet" type="text/css" href="address-option.css"/>
-  <link rel="stylesheet" type="text/css" href="basic-card-option.css"/>
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
+  <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/address-option.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/basic-card-option.css"/>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <rich-select id="select1">
       <!-- the class="rich-option" is required to be hard-coded due to a bug with the custom
            elements polyfill causing the address-option constructor to happen too late. -->
       <address-option id="option1"
@@ -77,22 +73,24 @@ Test the rich-select component
                          type="Discover"></basic-card-option>
     </rich-select>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the rich-select address-option component **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/components/address-option.js */
-/* import-globals-from ../../res/components/basic-card-option.js */
+
+import AddressOption from "../../res/components/address-option.js";
+import BasicCardOption from "../../res/components/basic-card-option.js";
+import RichSelect from "../../res/components/rich-select.js";
 
 let select1 = document.getElementById("select1");
 let option1 = document.getElementById("option1");
 let option2 = document.getElementById("option2");
 let option3 = document.getElementById("option3");
 
 function get_selected_clone() {
   return select1.querySelector(".rich-select-selected-clone");
@@ -327,26 +325,26 @@ add_task(async function test_basic_card_
     is(clonedOption.attributes[attrName] && clonedOption.attributes[attrName].value,
        selectedOption.attributes[attrName] && selectedOption.attributes[attrName].value,
        "attributes should have matching value; name=" + attrName);
   }
 });
 
 add_task(async function test_option_appended_after_creation() {
   let select2 = document.getElementById("select2");
-  let select3 = document.createElement("rich-select");
+  let select3 = new RichSelect();
   select3.id = "select3";
   select2.parentNode.insertBefore(select3, select2.nextElementSibling);
 
   is(select3.childElementCount, 2, "There should be a popup child and clone");
   let popupBox = select3.querySelector(".rich-select-popup-box");
   ok(popupBox, "The popup box should exist");
   is(popupBox.childElementCount, 0, "The popup should not have any children");
 
-  let newOption = document.createElement("address-option");
+  let newOption = new AddressOption();
   newOption.name = "Jared FooBar";
   select3.appendChild(newOption);
   await asyncElementRendered();
 
   is(select3.childElementCount, 2, "There should now be two children");
   is(popupBox.childElementCount, 1, "The popup box should have one child");
   ok(!popupBox.children[0].selected, "The only option should not be marked selected");
   is(select3.selectedOption, null, "Check there is no selected option");
--- a/toolkit/components/payments/test/mochitest/test_shipping_option_picker.html
+++ b/toolkit/components/payments/test/mochitest/test_shipping_option_picker.html
@@ -5,43 +5,38 @@ Test the shipping-option-picker componen
 -->
 <head>
   <meta charset="utf-8">
   <title>Test the shipping-option-picker component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script src="payments_common.js"></script>
-  <script src="custom-elements.min.js"></script>
-  <script src="PaymentsStore.js"></script>
-  <script src="ObservedPropertiesMixin.js"></script>
-  <script src="PaymentStateSubscriberMixin.js"></script>
-  <script src="rich-select.js"></script>
-  <script src="shipping-option-picker.js"></script>
-  <script src="rich-option.js"></script>
-  <script src="shipping-option.js"></script>
-  <script src="currency-amount.js"></script>
-  <link rel="stylesheet" type="text/css" href="rich-select.css"/>
-  <link rel="stylesheet" type="text/css" href="shipping-option.css"/>
+
+  <script src="../../res/vendor/custom-elements.min.js"></script>
+
+  <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/>
+  <link rel="stylesheet" type="text/css" href="../../res/components/shipping-option.css"/>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <p id="display">
     <shipping-option-picker id="picker1"></shipping-option-picker>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
-<script type="application/javascript">
+<script type="module">
 /** Test the shipping-option-picker component **/
 
 /* import-globals-from payments_common.js */
-/* import-globals-from ../../res/components/shipping-option.js */
+
+import "../../res/containers/shipping-option-picker.js";
 
 let picker1 = document.getElementById("picker1");
 
 add_task(async function test_empty() {
   ok(picker1, "Check picker1 exists");
   let state = picker1.requestStore.getState();
   let {shippingOptions} = state && state.request && state.request.paymentDetails;
   is(Object.keys(shippingOptions).length, 0, "Check empty initial state");
--- a/toolkit/components/payments/test/unit/xpcshell.ini
+++ b/toolkit/components/payments/test/unit/xpcshell.ini
@@ -1,5 +1,4 @@
 [DEFAULT]
 head = head.js
 
-[test_PaymentsStore.js]
 [test_response_creation.js]