Bug 1300988 - Part 3: XPCShell test for collectFormFields/autofillFormFields. r=MattN draft
authorSteve Chung <schung@mozilla.com>
Thu, 29 Sep 2016 16:31:44 +0800
changeset 426804 8e1ce7951cd1f47731dea9536f519300115e4ebf
parent 426803 bf23ad4432cc9a30fb1295dd6ed688a11ab597e3
child 426922 b6d4c80aaec85c81156fa7c21481cc4aabd38f14
push id32805
push userschung@mozilla.com
push dateWed, 19 Oct 2016 05:07:51 +0000
reviewersMattN
bugs1300988
milestone52.0a1
Bug 1300988 - Part 3: XPCShell test for collectFormFields/autofillFormFields. r=MattN MozReview-Commit-ID: 6SnFxqIksVb
browser/extensions/formautofill/moz.build
browser/extensions/formautofill/test/unit/.eslintrc
browser/extensions/formautofill/test/unit/head.js
browser/extensions/formautofill/test/unit/test_autofillFormFields.js
browser/extensions/formautofill/test/unit/test_collectFormFields.js
browser/extensions/formautofill/test/unit/xpcshell.ini
--- a/browser/extensions/formautofill/moz.build
+++ b/browser/extensions/formautofill/moz.build
@@ -12,10 +12,11 @@ FINAL_TARGET_FILES.features['formautofil
 ]
 
 FINAL_TARGET_PP_FILES.features['formautofill@mozilla.org'] += [
   'install.rdf.in'
 ]
 
 BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
 
+XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
+
 JAR_MANIFESTS += ['jar.mn']
-
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/unit/.eslintrc
@@ -0,0 +1,5 @@
+{
+  "extends": [
+    "../../../../../testing/xpcshell/xpcshell.eslintrc"
+  ],
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/unit/head.js
@@ -0,0 +1,26 @@
+/**
+ * Provides infrastructure for automated login components tests.
+ */
+
+ /* exported importAutofillModule */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://testing-common/MockDocument.jsm");
+
+// Load the module by Service newFileURI API for running extension's XPCShell test
+function importAutofillModule(module) {
+  return Cu.import(Services.io.newFileURI(do_get_file(module)).spec);
+}
+
+add_task(function* test_common_initialize() {
+  Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", true);
+
+  // Clean up after every test.
+  do_register_cleanup(() => {
+    Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", false);
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
@@ -0,0 +1,200 @@
+/*
+ * Test for form auto fill content helper fill all inputs function.
+ */
+
+"use strict";
+
+let {FormAutofillHandler} = importAutofillModule("FormAutofillContent.jsm");
+
+const TESTCASES = [
+  {
+    description: "Form without autocomplete property",
+    document: `<form><input id="given-name"><input id="family-name">
+               <input id="street-addr"><input id="city"><input id="country">
+               <input id='email'><input id="tel"></form>`,
+    fieldDetails: [],
+    profileData: [],
+    expectedResult: {
+      "given-name": "",
+      "family-name": "",
+      "street-addr": "",
+      "city": "",
+      "country": "",
+      "email": "",
+      "tel": "",
+    },
+  },
+  {
+    description: "Form with autocomplete properties and 1 token",
+    document: `<form><input id="given-name" autocomplete="given-name">
+               <input id="family-name" autocomplete="family-name">
+               <input id="street-addr" autocomplete="street-address">
+               <input id="city" autocomplete="address-level2">
+               <input id="country" autocomplete="country">
+               <input id="email" autocomplete="email">
+               <input id="tel" autocomplete="tel"></form>`,
+    fieldDetails: [
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+    profileData: [
+      {"section": "", "addressType": "", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
+      {"section": "", "addressType": "", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
+      {"section": "", "addressType": "", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
+      {"section": "", "addressType": "", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
+      {"section": "", "addressType": "", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
+      {"section": "", "addressType": "", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
+      {"section": "", "addressType": "", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
+    ],
+    expectedResult: {
+      "given-name": "foo",
+      "family-name": "bar",
+      "street-addr": "2 Harrison St",
+      "city": "San Francisco",
+      "country": "US",
+      "email": "foo@mozilla.com",
+      "tel": "1234567",
+    },
+  },
+  {
+    description: "Form with autocomplete properties and 2 tokens",
+    document: `<form><input id="given-name" autocomplete="shipping given-name">
+               <input id="family-name" autocomplete="shipping family-name">
+               <input id="street-addr" autocomplete="shipping street-address">
+               <input id="city" autocomplete="shipping address-level2">
+               <input id="country" autocomplete="shipping country">
+               <input id='email' autocomplete="shipping email">
+               <input id="tel" autocomplete="shipping tel"></form>`,
+    fieldDetails: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+    profileData: [
+      {"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
+      {"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
+      {"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
+      {"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
+      {"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
+      {"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
+      {"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
+    ],
+    expectedResult: {
+      "given-name": "foo",
+      "family-name": "bar",
+      "street-addr": "2 Harrison St",
+      "city": "San Francisco",
+      "country": "US",
+      "email": "foo@mozilla.com",
+      "tel": "1234567",
+    },
+  },
+  {
+    description: "Form with autocomplete properties and profile is partly matched",
+    document: `<form><input id="given-name" autocomplete="shipping given-name">
+               <input id="family-name" autocomplete="shipping family-name">
+               <input id="street-addr" autocomplete="shipping street-address">
+               <input id="city" autocomplete="shipping address-level2">
+               <input id="country" autocomplete="shipping country">
+               <input id='email' autocomplete="shipping email">
+               <input id="tel" autocomplete="shipping tel"></form>`,
+    fieldDetails: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+    profileData: [
+      {"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
+      {"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
+      {"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
+      {"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
+      {"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
+      {"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5},
+      {"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6},
+    ],
+    expectedResult: {
+      "given-name": "foo",
+      "family-name": "bar",
+      "street-addr": "2 Harrison St",
+      "city": "San Francisco",
+      "country": "US",
+      "email": "",
+      "tel": "",
+    },
+  },
+  {
+    description: "Form with autocomplete properties but mismatched",
+    document: `<form><input id="given-name" autocomplete="shipping given-name">
+               <input id="family-name" autocomplete="shipping family-name">
+               <input id="street-addr" autocomplete="billing street-address">
+               <input id="city" autocomplete="billing address-level2">
+               <input id="country" autocomplete="billing country">
+               <input id='email' autocomplete="shipping email">
+               <input id="tel" autocomplete="shipping tel"></form>`,
+    fieldDetails: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+    profileData: [
+      {"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
+      {"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
+      {"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
+      {"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
+      {"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
+      {"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
+      {"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
+    ],
+    expectedResult: {
+      "given-name": "foo",
+      "family-name": "bar",
+      "street-addr": "",
+      "city": "",
+      "country": "",
+      "email": "foo@mozilla.com",
+      "tel": "1234567",
+    },
+  },
+];
+
+for (let tc of TESTCASES) {
+  (function() {
+    let testcase = tc;
+    add_task(function* () {
+      do_print("Starting testcase: " + testcase.description);
+
+      let doc = MockDocument.createTestDocument("http://localhost:8080/test/",
+                                                testcase.document);
+      let form = doc.querySelector("form");
+      let handler = new FormAutofillHandler(form);
+
+      handler.fieldDetails = testcase.fieldDetails;
+      handler.fieldDetails.forEach((field, index) => {
+        field.element = doc.querySelectorAll("input")[index];
+      });
+
+      handler.autofillFormFields(testcase.profileData);
+      for (let id in testcase.expectedResult) {
+        Assert.equal(doc.getElementById(id).value, testcase.expectedResult[id],
+                    "Check the " + id + " fields were filled with correct data");
+      }
+    });
+  })();
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/unit/test_collectFormFields.js
@@ -0,0 +1,122 @@
+/*
+ * Test for form auto fill content helper collectFormFields functions.
+ */
+
+"use strict";
+
+let {FormAutofillHandler} = importAutofillModule("FormAutofillContent.jsm");
+
+const TESTCASES = [
+  {
+    description: "Form without autocomplete property",
+    document: `<form><input id="given-name"><input id="family-name">
+               <input id="street-addr"><input id="city"><input id="country">
+               <input id='email'><input id="tel"></form>`,
+    returnedFormat: [],
+    fieldDetails: [],
+  },
+  {
+    description: "Form with autocomplete properties and 1 token",
+    document: `<form><input id="given-name" autocomplete="given-name">
+               <input id="family-name" autocomplete="family-name">
+               <input id="street-addr" autocomplete="street-address">
+               <input id="city" autocomplete="address-level2">
+               <input id="country" autocomplete="country">
+               <input id="email" autocomplete="email">
+               <input id="tel" autocomplete="tel"></form>`,
+    returnedFormat: [
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name", "index": 0},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name", "index": 1},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "index": 2},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "index": 3},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "country", "index": 4},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "email", "index": 5},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "index": 6},
+    ],
+    fieldDetails: [
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+  },
+  {
+    description: "Form with autocomplete properties and 2 tokens",
+    document: `<form><input id="given-name" autocomplete="shipping given-name">
+               <input id="family-name" autocomplete="shipping family-name">
+               <input id="street-addr" autocomplete="shipping street-address">
+               <input id="city" autocomplete="shipping address-level2">
+               <input id="country" autocomplete="shipping country">
+               <input id='email' autocomplete="shipping email">
+               <input id="tel" autocomplete="shipping tel"></form>`,
+    returnedFormat: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "index": 0},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "index": 1},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "index": 2},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "index": 3},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "index": 4},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "index": 5},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "index": 6},
+    ],
+    fieldDetails: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+  },
+  {
+    description: "Form with autocomplete properties and profile is partly matched",
+    document: `<form><input id="given-name" autocomplete="shipping given-name">
+               <input id="family-name" autocomplete="shipping family-name">
+               <input id="street-addr" autocomplete="shipping street-address">
+               <input id="city" autocomplete="shipping address-level2">
+               <input id="country" autocomplete="shipping country">
+               <input id='email' autocomplete="shipping email">
+               <input id="tel" autocomplete="shipping tel"></form>`,
+    returnedFormat: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "index": 0},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "index": 1},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "index": 2},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "index": 3},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "index": 4},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "index": 5},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "index": 6},
+    ],
+    fieldDetails: [
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
+      {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
+    ],
+  },
+];
+
+for (let tc of TESTCASES) {
+  (function() {
+    let testcase = tc;
+    add_task(function* () {
+      do_print("Starting testcase: " + testcase.description);
+
+      let doc = MockDocument.createTestDocument("http://localhost:8080/test/",
+                                                testcase.document);
+      let form = doc.querySelector("form");
+      let handler = new FormAutofillHandler(form);
+
+      Assert.deepEqual(handler.collectFormFields(), testcase.returnedFormat,
+                         "Check the format of form autofill were returned correctly");
+
+      Assert.deepEqual(handler.fieldDetails, testcase.fieldDetails,
+                         "Check the fieldDetails were set correctly");
+    });
+  })();
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/unit/xpcshell.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+head = head.js
+tail =
+support-files = ../../content/FormAutofillContent.jsm
+
+[test_autofillFormFields.js]
+[test_collectFormFields.js]