Bug 906226 - Move shared test code to a single file. r=gwagner
authorReuben Morais <reuben.morais@gmail.com>
Tue, 03 Dec 2013 23:07:59 -0200
changeset 174375 d997913037df89a04960346a36de1860425d6458
parent 174374 7f6a53b49f8e1f9c51fdfd7b89a2d8923141bc22
child 174376 9688476c1544689573c7d3ef805fd61c2fc0f631
child 174388 263f538a5509495d75c5f4e23b61bf0ed8d11b06
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgwagner
bugs906226
milestone28.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 906226 - Move shared test code to a single file. r=gwagner
dom/contacts/tests/mochitest.ini
dom/contacts/tests/shared.js
dom/contacts/tests/test_contacts_basics.html
dom/contacts/tests/test_contacts_basics2.html
dom/contacts/tests/test_contacts_blobs.html
dom/contacts/tests/test_contacts_getall.html
dom/contacts/tests/test_contacts_getall2.html
dom/contacts/tests/test_contacts_international.html
dom/contacts/tests/test_contacts_substringmatching.html
dom/contacts/tests/test_contacts_substringmatchingVE.html
--- a/dom/contacts/tests/mochitest.ini
+++ b/dom/contacts/tests/mochitest.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 
+[shared.js]
 [test_contacts_basics.html]
 [test_contacts_basics2.html]
 [test_contacts_blobs.html]
 [test_contacts_events.html]
 [test_contacts_getall.html]
 [test_contacts_getall2.html]
 [test_contacts_international.html]
 [test_contacts_substringmatching.html]
new file mode 100644
--- /dev/null
+++ b/dom/contacts/tests/shared.js
@@ -0,0 +1,416 @@
+"use strict";
+
+// Fix the environment to run Contacts tests
+if (SpecialPowers.isMainProcess()) {
+  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
+  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
+}
+
+SpecialPowers.addPermission("contacts-write", true, document);
+SpecialPowers.addPermission("contacts-read", true, document);
+SpecialPowers.addPermission("contacts-create", true, document);
+
+// Some helpful global vars
+var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
+
+var defaultOptions = {
+  sortBy: "givenName",
+};
+
+var mozContacts = navigator.mozContacts;
+
+// To test sorting
+var c1 = {
+  name: ["a a"],
+  familyName: ["a"],
+  givenName: ["a"],
+};
+
+var c2 = {
+  name: ["b b"],
+  familyName: ["b"],
+  givenName: ["b"],
+};
+
+var c3 = {
+  name: ["c c", "a a", "b b"],
+  familyName: ["c","a","b"],
+  givenName: ["c","a","b"],
+};
+
+var c4 = {
+  name: ["c c", "a a", "c c"],
+  familyName: ["c","a","c"],
+  givenName: ["c","a","c"],
+};
+
+var c5 = {
+  familyName: [],
+  givenName: [],
+};
+
+var c6 = {
+  name: ["e"],
+  familyName: ["e","e","e"],
+  givenName: ["e","e","e"],
+};
+
+var c7 = {
+  name: ["e"],
+  familyName: ["e","e","e"],
+  givenName: ["e","e","e"],
+};
+
+var c8 = {
+  name: ["e"],
+  familyName: ["e","e","e"],
+  givenName: ["e","e","e"],
+};
+
+var adr1 = {
+  type: ["work"],
+  streetAddress: "street 1",
+  locality: "locality 1",
+  region: "region 1",
+  postalCode: "postal code 1",
+  countryName: "country 1"
+};
+
+var adr2 = {
+  type: ["home, fax"],
+  streetAddress: "street2",
+  locality: "locality2",
+  region: "region2",
+  postalCode: "postal code2",
+  countryName: "country2"
+};
+
+var properties1 = {
+  // please keep capital letters at the start of these names
+  name: ["Test1 TestFamilyName", "Test2 Wagner"],
+  familyName: ["TestFamilyName","Wagner"],
+  givenName: ["Test1","Test2"],
+  nickname: ["nicktest"],
+  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
+  adr: [adr1],
+  email: [{type: ["work"], value: "x@y.com"}],
+};
+
+var properties2 = {
+  name: ["dummyHonorificPrefix dummyGivenName dummyFamilyName dummyHonorificSuffix", "dummyHonorificPrefix2"],
+  familyName: ["dummyFamilyName"],
+  givenName: ["dummyGivenName"],
+  honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
+  honorificSuffix: ["dummyHonorificSuffix"],
+  additionalName: ["dummyadditionalName"],
+  nickname: ["dummyNickname"],
+  tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
+  email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
+  adr: [adr1, adr2],
+  impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
+  org: ["org1", "org2"],
+  jobTitle: ["boss", "superboss"],
+  note: ["test note"],
+  category: ["cat1", "cat2"],
+  url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
+  bday: new Date("1980, 12, 01"),
+  anniversary: new Date("2000, 12, 01"),
+  sex: "male",
+  genderIdentity: "test",
+  key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
+};
+
+var sample_id1;
+var sample_id2;
+
+var createResult1;
+var createResult2;
+
+var findResult1;
+var findResult2;
+
+// DOMRequest helper functions
+function onUnwantedSuccess() {
+  ok(false, "onUnwantedSuccess: shouldn't get here");
+}
+
+function onFailure() {
+  ok(false, "in on Failure!");
+  next();
+}
+
+// Validation helper functions
+function checkStr(str1, str2, msg) {
+  if (str1 ^ str2) {
+    ok(false, "Expected both strings to be either present or absent");
+    return;
+  }
+  if (!str1 || str1 == "null") {
+    str1 = null;
+  }
+  if (!str2 || str2 == "null") {
+    str2 = null;
+  }
+  is(str1, str2, msg);
+}
+
+function checkStrArray(str1, str2, msg) {
+  function normalize_falsy(v) {
+    if (!v || v == "null" || v == "undefined") {
+      return "";
+    }
+    return v;
+  }
+  function optArray(val) {
+    return Array.isArray(val) ? val : [val];
+  }
+  str1 = optArray(str1).map(normalize_falsy).filter(v => v != "");
+  str2 = optArray(str2).map(normalize_falsy).filter(v => v != "");
+  ise(JSON.stringify(str1), JSON.stringify(str2), msg);
+}
+
+function checkPref(pref1, pref2) {
+  // If on Android treat one preference as 0 and the other as undefined as matching
+  if (isAndroid) {
+    if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
+      pref1 = false;
+      pref2 = false;
+    }
+  }
+  ise(!!pref1, !!pref2, "Same pref");
+}
+
+function checkAddress(adr1, adr2) {
+  if (adr1 ^ adr2) {
+    ok(false, "Expected both adrs to be either present or absent");
+    return;
+  }
+  checkStrArray(adr1.type, adr2.type, "Same type");
+  checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
+  checkStr(adr1.locality, adr2.locality, "Same locality");
+  checkStr(adr1.region, adr2.region, "Same region");
+  checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
+  checkStr(adr1.countryName, adr2.countryName, "Same countryName");
+  checkPref(adr1.pref, adr2.pref);
+}
+
+function checkField(field1, field2) {
+  if (field1 ^ field2) {
+    ok(false, "Expected both fields to be either present or absent");
+    return;
+  }
+  checkStrArray(field1.type, field2.type, "Same type");
+  checkStr(field1.value, field2.value, "Same value");
+  checkPref(field1.pref, field2.pref);
+}
+
+function checkTel(tel1, tel2) {
+  if (tel1 ^ tel2) {
+    ok(false, "Expected both tels to be either present or absent");
+    return;
+  }
+  checkField(tel1, tel2);
+  checkStr(tel1.carrier, tel2.carrier, "Same carrier");
+}
+
+function checkCategory(category1, category2) {
+  // Android adds contacts to the a default category. This should be removed from the
+  // results before comparing them
+  if (isAndroid) {
+    category1 = removeAndroidDefaultCategory(category1);
+    category2 = removeAndroidDefaultCategory(category2);
+  }
+  checkStrArray(category1, category2, "Same Category")
+}
+
+function removeAndroidDefaultCategory(category) {
+  if (!category) {
+    return category;
+  }
+
+  var result = [];
+
+  for (var i of category) {
+    // Some devices may return the full group name (prefixed with "System Group: ")
+    if (i != "My Contacts" && i != "System Group: My Contacts") {
+      result.push(i);
+    }
+  }
+
+  return result;
+}
+
+function checkArrayField(array1, array2, func, msg) {
+  if (!!array1 ^ !!array2) {
+    ok(false, "Expected both arrays to be either present or absent: " + JSON.stringify(array1) + " vs. " + JSON.stringify(array2) + ". (" + msg + ")");
+    return;
+  }
+  if (!array1 && !array2)  {
+    ok(true, msg);
+    return;
+  }
+  ise(array1.length, array2.length, "Same length");
+  for (var i = 0; i < array1.length; ++i) {
+    func(array1[i], array2[i], msg);
+  }
+}
+
+function checkContacts(contact1, contact2) {
+  if (!!contact1 ^ !!contact2) {
+    ok(false, "Expected both contacts to be either present or absent");
+    return;
+  }
+  checkStrArray(contact1.name, contact2.name, "Same name");
+  checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
+  checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
+  checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
+  checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
+  checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
+  checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
+  checkCategory(contact1.category, contact2.category);
+  checkStrArray(contact1.org, contact2.org, "Same org");
+  checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
+  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
+  checkStrArray(contact1.note, contact2.note, "Same note");
+  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
+  checkStr(contact1.sex, contact2.sex, "Same sex");
+  checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
+  checkStrArray(contact1.key, contact2.key, "Same key");
+
+  checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
+  checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
+  checkArrayField(contact1.email, contact2.email, checkField, "Same email");
+  checkArrayField(contact1.url, contact2.url, checkField, "Same url");
+  checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
+}
+
+function addContacts() {
+  ok(true, "Adding 40 contacts");
+  let req;
+  for (let i = 0; i < 39; ++i) {
+    properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
+    properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
+    createResult1 = new mozContact(properties1);
+    req = mozContacts.save(createResult1);
+    req.onsuccess = function() {
+      ok(createResult1.id, "The contact now has an ID.");
+    };
+    req.onerror = onFailure;
+  };
+  properties1.familyName[0] = "Testname39";
+  properties1.name = [properties1.givenName[0] + " Testname39"];
+  createResult1 = new mozContact(properties1);
+  req = mozContacts.save(createResult1);
+  req.onsuccess = function() {
+    ok(createResult1.id, "The contact now has an ID.");
+    checkStrArray(createResult1.name, properties1.name, "Same Name");
+    next();
+  };
+  req.onerror = onFailure;
+}
+
+function getOne(msg) {
+  return function() {
+    ok(true, msg || "Retrieving one contact with getAll");
+    let req = mozContacts.getAll({});
+
+    let count = 0;
+    req.onsuccess = function(event) {
+      ok(true, "on success");
+      if (req.result) {
+        ok(true, "result is valid");
+        count++;
+        req.continue();
+      } else {
+        is(count, 1, "last contact - only one contact returned");
+        next();
+      }
+    };
+    req.onerror = onFailure;
+  };
+}
+
+function getAll(msg) {
+  return function() {
+    ok(true, msg || "Retrieving 40 contacts with getAll");
+    let req = mozContacts.getAll({
+      sortBy: "familyName",
+      sortOrder: "ascending"
+    });
+    let count = 0;
+    let result;
+    let props;
+    req.onsuccess = function(event) {
+      if (req.result) {
+        ok(true, "result is valid");
+        result = req.result;
+        properties1.familyName[0] = "Testname" + (count < 10 ? "0" + count : count);
+        is(result.familyName[0], properties1.familyName[0], "Same familyName");
+        count++;
+        req.continue();
+      } else {
+        is(count, 40, "last contact - 40 contacts returned");
+        next();
+      }
+    };
+    req.onerror = onFailure;
+  };
+}
+
+function clearTemps() {
+  sample_id1 = null;
+  sample_id2 = null;
+  createResult1 = null;
+  createResult2 = null;
+  findResult1 = null;
+  findResult2 = null;
+}
+
+function clearDatabase() {
+  ok(true, "Deleting database");
+  let req = mozContacts.clear()
+  req.onsuccess = function () {
+    ok(true, "Deleted the database");
+    next();
+  }
+  req.onerror = onFailure;
+}
+
+function checkCount(count, msg, then) {
+  var request = mozContacts.getCount();
+  request.onsuccess = function(e) {
+    is(e.target.result, count, msg);
+    then();
+  };
+  request.onerror = onFailure;
+}
+
+// Helper functions to run tests
+var index = 0;
+
+function next() {
+  ok(true, "Begin!");
+  if (index >= steps.length) {
+    ok(false, "Shouldn't get here!");
+    return;
+  }
+  try {
+    var i = index++;
+    steps[i]();
+  } catch(ex) {
+    ok(false, "Caught exception", ex);
+  }
+}
+
+function start_tests() {
+  // Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
+  let androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
+                                    .getService(SpecialPowers.Ci.nsIPropertyBag2)
+                                    .getProperty('version');
+  if (!isAndroid || androidVersion >= 14) {
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(next);
+  } else {
+    ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
+  }
+}
--- a/dom/contacts/tests/test_contacts_basics.html
+++ b/dom/contacts/tests/test_contacts_basics.html
@@ -12,341 +12,40 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=674720">Mozilla Bug 674720</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
 <script class="testbody" type="text/javascript">
-
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
-}
-
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
-// For Sorting
-var c1 = {
-  name: ["a a"],
-  familyName: ["a"],
-  givenName: ["a"],
-};
-
-var c2 = {
-  name: ["b b"],
-  familyName: ["b"],
-  givenName: ["b"],
-};
-
-var c3 = {
-  name: ["c c", "a a", "b b"],
-  familyName: ["c","a","b"],
-  givenName: ["c","a","b"],
-};
-
-var c4 = {
-  name: ["c c", "a a", "c c"],
-  familyName: ["c","a","c"],
-  givenName: ["c","a","c"],
-};
-
-var c5 = {
-  familyName: [],
-  givenName: [],
-};
-
-var c6 = {
-  name: ["e"],
-  familyName: ["e","e","e"],
-  givenName: ["e","e","e"],
-};
-
-var c7 = {
-  name: ["e"],
-  familyName: ["e","e","e"],
-  givenName: ["e","e","e"],
-};
-
-var c8 = {
-  name: ["e"],
-  familyName: ["e","e","e"],
-  givenName: ["e","e","e"],
-};
-
-var adr1 = {
-  type: ["work"],
-  streetAddress: "street 1",
-  locality: "locality 1",
-  region: "region 1",
-  postalCode: "postal code 1",
-  countryName: "country 1"
-};
-
-var adr2 = {
-  type: ["home, fax"],
-  streetAddress: "street2",
-  locality: "locality2",
-  region: "region2",
-  postalCode: "postal code2",
-  countryName: "country2"
-};
-
-var properties1 = {
-  // please keep capital letters at the start of these names
-  name: ["Test1 TestFamilyName", "Test2 Wagner"],
-  familyName: ["TestFamilyName","Wagner"],
-  givenName: ["Test1","Test2"],
-  nickname: ["nicktest"],
-  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
-  adr: [adr1],
-  email: [{type: ["work"], value: "x@y.com"}],
-};
-
-var properties2 = {
-  name: ["dummyHonorificPrefix dummyGivenName dummyFamilyName dummyHonorificSuffix", "dummyHonorificPrefix2"],
-  familyName: ["dummyFamilyName"],
-  givenName: ["dummyGivenName"],
-  honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
-  honorificSuffix: ["dummyHonorificSuffix"],
-  additionalName: ["dummyadditionalName"],
-  nickname: ["dummyNickname"],
-  tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
-  email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
-  adr: [adr1, adr2],
-  impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
-  org: ["org1", "org2"],
-  jobTitle: ["boss", "superboss"],
-  note: ["test note"],
-  category: ["cat1", "cat2"],
-  url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
-  bday: new Date("1980, 12, 01"),
-  anniversary: new Date("2000, 12, 01"),
-  sex: "male",
-  genderIdentity: "test",
-  key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
-};
-
-var sample_id1;
-var sample_id2;
-
-var createResult1;
-var createResult2;
-
-var findResult1;
-var findResult2;
-
-function clearTemps() {
-  sample_id1 = null;
-  sample_id2 = null;
-  createResult1 = null;
-  createResult2 = null;
-  findResult1 = null;
-  findResult2 = null;
-}
-
-function onUnwantedSuccess() {
-  ok(false, "onUnwantedSuccess: shouldn't get here");
-}
-
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-
-function checkStr(str1, str2, msg) {
-  if (str1 ^ str2) {
-    ok(false, "Expected both strings to be either present or absent");
-    return;
-  }
-  if (!str1 || str1 == "null") {
-    str1 = null;
-  }
-  if (!str2 || str2 == "null") {
-    str2 = null;
-  }
-  is(str1, str2, msg);
-}
-
-function checkStrArray(str1, str2, msg) {
-  function normalize_falsy(v) {
-    if (!v || v == "null" || v == "undefined") {
-      return "";
-    }
-    return v;
-  }
-  function optArray(val) {
-    return Array.isArray(val) ? val : [val];
-  }
-  str1 = optArray(str1).map(normalize_falsy).filter(v => v != "");
-  str2 = optArray(str2).map(normalize_falsy).filter(v => v != "");
-  ise(JSON.stringify(str1), JSON.stringify(str2), msg);
-}
-
-function checkPref(pref1, pref2) {
-  // If on Android treat one preference as 0 and the other as undefined as matching
-  if (isAndroid) {
-    if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
-      pref1 = false;
-      pref2 = false;
-    }
-  }
-  ise(!!pref1, !!pref2, "Same pref");
-}
-
-function checkAddress(adr1, adr2) {
-  if (adr1 ^ adr2) {
-    ok(false, "Expected both adrs to be either present or absent");
-    return;
-  }
-  checkStrArray(adr1.type, adr2.type, "Same type");
-  checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
-  checkStr(adr1.locality, adr2.locality, "Same locality");
-  checkStr(adr1.region, adr2.region, "Same region");
-  checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
-  checkStr(adr1.countryName, adr2.countryName, "Same countryName");
-  checkPref(adr1.pref, adr2.pref);
-}
-
-function checkField(field1, field2) {
-  if (field1 ^ field2) {
-    ok(false, "Expected both fields to be either present or absent");
-    return;
-  }
-  checkStrArray(field1.type, field2.type, "Same type");
-  checkStr(field1.value, field2.value, "Same value");
-  checkPref(field1.pref, field2.pref);
-}
-
-function checkTel(tel1, tel2) {
-  if (tel1 ^ tel2) {
-    ok(false, "Expected both tels to be either present or absent");
-    return;
-  }
-  checkField(tel1, tel2);
-  checkStr(tel1.carrier, tel2.carrier, "Same carrier");
-}
-
-function checkCategory(category1, category2) {
-  // Android adds contacts to the a default category. This should be removed from the
-  // results before comparing them
-  if (isAndroid) {
-    category1 = removeAndroidDefaultCategory(category1);
-    category2 = removeAndroidDefaultCategory(category2);
-  }
-  checkStrArray(category1, category2, "Same Category")
-}
-
-function removeAndroidDefaultCategory(category) {
-  if (!category) {
-    return category;
-  }
-
-  var result = [];
-
-  for (var i of category) {
-    // Some devices may return the full group name (prefixed with "System Group: ")
-    if (i != "My Contacts" && i != "System Group: My Contacts") {
-      result.push(i);
-    }
-  }
-
-  return result;
-}
-
-function checkArrayField(array1, array2, func, msg) {
-  if (!!array1 ^ !!array2) {
-    ok(false, "Expected both arrays to be either present or absent: " + JSON.stringify(array1) + " vs. " + JSON.stringify(array2) + ". (" + msg + ")");
-    return;
-  }
-  if (!array1 && !array2)  {
-    ok(true, msg);
-    return;
-  }
-  ise(array1.length, array2.length, "Same length");
-  for (var i = 0; i < array1.length; ++i) {
-    func(array1[i], array2[i], msg);
-  }
-}
-
-function checkContacts(contact1, contact2) {
-  if (!!contact1 ^ !!contact2) {
-    ok(false, "Expected both contacts to be either present or absent");
-    return;
-  }
-  checkStrArray(contact1.name, contact2.name, "Same name");
-  checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
-  checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
-  checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
-  checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
-  checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
-  checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
-  checkCategory(contact1.category, contact2.category);
-  checkStrArray(contact1.org, contact2.org, "Same org");
-  checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
-  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
-  checkStrArray(contact1.note, contact2.note, "Same note");
-  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
-  checkStr(contact1.sex, contact2.sex, "Same sex");
-  checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
-  checkStrArray(contact1.key, contact2.key, "Same key");
-
-  checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
-  checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
-  checkArrayField(contact1.email, contact2.email, checkField, "Same email");
-  checkArrayField(contact1.url, contact2.url, checkField, "Same url");
-  checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
-}
-
-var req;
-var index = 0;
-
 var initialRev;
 
-var defaultOptions = {
-  sortBy: "givenName",
-};
-
 function checkRevision(revision, msg, then) {
   var revReq = mozContacts.getRevision();
   revReq.onsuccess = function(e) {
     is(e.target.result, initialRev+revision, msg);
     then();
   };
   // The revision function isn't supported on Android so treat on failure as success
   if (isAndroid) {
     revReq.onerror = function(e) {
       then();
     };
   } else {
     revReq.onerror = onFailure;
   }
 }
 
-function checkCount(count, msg, then) {
-  var request = navigator.mozContacts.getCount();
-  request.onsuccess = function(e) {
-    is(e.target.result, count, msg);
-    then();
-  };
-  request.onerror = onFailure;
-}
+var req;
 
-var mozContacts = window.navigator.mozContacts;
 var steps = [
   function() {
     req = mozContacts.getRevision();
     req.onsuccess = function(e) {
       initialRev = e.target.result;
       next();
     };
 
@@ -1063,34 +762,13 @@ var steps = [
   function () {
     ok(true, "all done!\n");
     clearTemps();
 
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  try {
-    var i = index++;
-    steps[i]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_basics2.html
+++ b/dom/contacts/tests/test_contacts_basics2.html
@@ -12,341 +12,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=674720">Mozilla Bug 674720</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
 <script class="testbody" type="text/javascript">
-
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
-}
-
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
-// For Sorting
-var c1 = {
-  name: ["a a"],
-  familyName: ["a"],
-  givenName: ["a"],
-};
-
-var c2 = {
-  name: ["b b"],
-  familyName: ["b"],
-  givenName: ["b"],
-};
-
-var c3 = {
-  name: ["c c", "a a", "b b"],
-  familyName: ["c","a","b"],
-  givenName: ["c","a","b"],
-};
-
-var c4 = {
-  name: ["c c", "a a", "c c"],
-  familyName: ["c","a","c"],
-  givenName: ["c","a","c"],
-};
-
-var c5 = {
-  familyName: [],
-  givenName: [],
-};
-
-var c6 = {
-  name: ["e"],
-  familyName: ["e","e","e"],
-  givenName: ["e","e","e"],
-};
-
-var c7 = {
-  name: ["e"],
-  familyName: ["e","e","e"],
-  givenName: ["e","e","e"],
-};
-
-var c8 = {
-  name: ["e"],
-  familyName: ["e","e","e"],
-  givenName: ["e","e","e"],
-};
-
-var adr1 = {
-  type: ["work"],
-  streetAddress: "street 1",
-  locality: "locality 1",
-  region: "region 1",
-  postalCode: "postal code 1",
-  countryName: "country 1"
-};
-
-var adr2 = {
-  type: ["home, fax"],
-  streetAddress: "street2",
-  locality: "locality2",
-  region: "region2",
-  postalCode: "postal code2",
-  countryName: "country2"
-};
-
-var properties1 = {
-  // please keep capital letters at the start of these names
-  name: ["Test1 TestFamilyName", "Test2 Wagner"],
-  familyName: ["TestFamilyName","Wagner"],
-  givenName: ["Test1","Test2"],
-  nickname: ["nicktest"],
-  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
-  adr: [adr1],
-  email: [{type: ["work"], value: "x@y.com"}],
-};
-
-var properties2 = {
-  name: ["dummyHonorificPrefix dummyGivenName dummyFamilyName dummyHonorificSuffix", "dummyHonorificPrefix2"],
-  familyName: ["dummyFamilyName"],
-  givenName: ["dummyGivenName"],
-  honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
-  honorificSuffix: ["dummyHonorificSuffix"],
-  additionalName: ["dummyadditionalName"],
-  nickname: ["dummyNickname"],
-  tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
-  email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
-  adr: [adr1, adr2],
-  impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
-  org: ["org1", "org2"],
-  jobTitle: ["boss", "superboss"],
-  note: ["test note"],
-  category: ["cat1", "cat2"],
-  url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
-  bday: new Date("1980, 12, 01"),
-  anniversary: new Date("2000, 12, 01"),
-  sex: "male",
-  genderIdentity: "test",
-  key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
-};
-
-var sample_id1;
-var sample_id2;
-
-var createResult1;
-var createResult2;
-
-var findResult1;
-var findResult2;
-
-function clearTemps() {
-  sample_id1 = null;
-  sample_id2 = null;
-  createResult1 = null;
-  createResult2 = null;
-  findResult1 = null;
-  findResult2 = null;
-}
-
-function onUnwantedSuccess() {
-  ok(false, "onUnwantedSuccess: shouldn't get here");
-}
-
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-
-function checkStr(str1, str2, msg) {
-  if (str1 ^ str2) {
-    ok(false, "Expected both strings to be either present or absent");
-    return;
-  }
-  if (!str1 || str1 == "null") {
-    str1 = null;
-  }
-  if (!str2 || str2 == "null") {
-    str2 = null;
-  }
-  is(str1, str2, msg);
-}
+var req;
 
-function checkStrArray(str1, str2, msg) {
-  function normalize_falsy(v) {
-    if (!v || v == "null" || v == "undefined") {
-      return "";
-    }
-    return v;
-  }
-  function optArray(val) {
-    return Array.isArray(val) ? val : [val];
-  }
-  str1 = optArray(str1).map(normalize_falsy).filter(v => v != "");
-  str2 = optArray(str2).map(normalize_falsy).filter(v => v != "");
-  ise(JSON.stringify(str1), JSON.stringify(str2), msg);
-}
-
-function checkPref(pref1, pref2) {
-  // If on Android treat one preference as 0 and the other as undefined as matching
-  if (isAndroid) {
-    if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
-      pref1 = false;
-      pref2 = false;
-    }
-  }
-  ise(!!pref1, !!pref2, "Same pref");
-}
-
-function checkAddress(adr1, adr2) {
-  if (adr1 ^ adr2) {
-    ok(false, "Expected both adrs to be either present or absent");
-    return;
-  }
-  checkStrArray(adr1.type, adr2.type, "Same type");
-  checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
-  checkStr(adr1.locality, adr2.locality, "Same locality");
-  checkStr(adr1.region, adr2.region, "Same region");
-  checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
-  checkStr(adr1.countryName, adr2.countryName, "Same countryName");
-  checkPref(adr1.pref, adr2.pref);
-}
-
-function checkField(field1, field2) {
-  if (field1 ^ field2) {
-    ok(false, "Expected both fields to be either present or absent");
-    return;
-  }
-  checkStrArray(field1.type, field2.type, "Same type");
-  checkStr(field1.value, field2.value, "Same value");
-  checkPref(field1.pref, field2.pref);
-}
-
-function checkTel(tel1, tel2) {
-  if (tel1 ^ tel2) {
-    ok(false, "Expected both tels to be either present or absent");
-    return;
-  }
-  checkField(tel1, tel2);
-  checkStr(tel1.carrier, tel2.carrier, "Same carrier");
-}
-
-function checkCategory(category1, category2) {
-  // Android adds contacts to the a default category. This should be removed from the
-  // results before comparing them
-  if (isAndroid) {
-    category1 = removeAndroidDefaultCategory(category1);
-    category2 = removeAndroidDefaultCategory(category2);
-  }
-  checkStrArray(category1, category2, "Same Category")
-}
-
-function removeAndroidDefaultCategory(category) {
-  if (!category) {
-    return category;
-  }
-
-  var result = [];
-
-  for (var i of category) {
-    // Some devices may return the full group name (prefixed with "System Group: ")
-    if (i != "My Contacts" && i != "System Group: My Contacts") {
-      result.push(i);
-    }
-  }
-
-  return result;
-}
-
-function checkArrayField(array1, array2, func, msg) {
-  if (!!array1 ^ !!array2) {
-    ok(false, "Expected both arrays to be either present or absent: " + JSON.stringify(array1) + " vs. " + JSON.stringify(array2) + ". (" + msg + ")");
-    return;
-  }
-  if (!array1 && !array2)  {
-    ok(true, msg);
-    return;
-  }
-  ise(array1.length, array2.length, "Same length");
-  for (var i = 0; i < array1.length; ++i) {
-    func(array1[i], array2[i], msg);
-  }
-}
-
-function checkContacts(contact1, contact2) {
-  if (!!contact1 ^ !!contact2) {
-    ok(false, "Expected both contacts to be either present or absent");
-    return;
-  }
-  checkStrArray(contact1.name, contact2.name, "Same name");
-  checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
-  checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
-  checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
-  checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
-  checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
-  checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
-  checkCategory(contact1.category, contact2.category);
-  checkStrArray(contact1.org, contact2.org, "Same org");
-  checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
-  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
-  checkStrArray(contact1.note, contact2.note, "Same note");
-  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
-  checkStr(contact1.sex, contact2.sex, "Same sex");
-  checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
-  checkStrArray(contact1.key, contact2.key, "Same key");
-
-  checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
-  checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
-  checkArrayField(contact1.email, contact2.email, checkField, "Same email");
-  checkArrayField(contact1.url, contact2.url, checkField, "Same url");
-  checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
-}
-
-var req;
-var index = 0;
-
-var initialRev;
-
-var defaultOptions = {
-  sortBy: "givenName",
-};
-
-function checkRevision(revision, msg, then) {
-  var revReq = mozContacts.getRevision();
-  revReq.onsuccess = function(e) {
-    is(e.target.result, initialRev+revision, msg);
-    then();
-  };
-  // The revision function isn't supported on Android so treat on failure as success
-  if (isAndroid) {
-    revReq.onerror = function(e) {
-      then();
-    };
-  } else {
-    revReq.onerror = onFailure;
-  }
-}
-
-function checkCount(count, msg, then) {
-  var request = navigator.mozContacts.getCount();
-  request.onsuccess = function(e) {
-    is(e.target.result, count, msg);
-    then();
-  };
-  request.onerror = onFailure;
-}
-
-var mozContacts = window.navigator.mozContacts;
 var steps = [
   function () {
     ok(true, "Adding a new contact");
     createResult1 = new mozContact(properties1);
     req = mozContacts.save(createResult1)
     req.onsuccess = function () {
       ok(createResult1.id, "The contact now has an ID.");
       sample_id1 = createResult1.id;
@@ -434,17 +115,16 @@ var steps = [
       next();
     }
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Deleting database");
     req = mozContacts.clear();
     req.onsuccess = function () {
-      clearTemps();
       next();
     }
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Adding 20 contacts");
     for (var i=0; i<19; i++) {
       createResult1 = new mozContact(properties1);
@@ -519,17 +199,16 @@ var steps = [
       next();
     }
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Deleting database");
     req = mozContacts.clear();
     req.onsuccess = function () {
-      clearTemps();
       next();
     }
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Testing clone contact");
     createResult1 = new mozContact(properties1);
     req = mozContacts.save(createResult1);
@@ -1039,18 +718,16 @@ var steps = [
     testArrayProp("adr");
     testArrayProp("tel");
     testArrayProp("impp");
     testArrayProp("url");
     next();
   },
   function () {
     ok(true, "all done!\n");
-    clearTemps();
-
     SimpleTest.finish();
   }
 ];
 
 function next() {
   ok(true, "Begin!");
   if (index >= steps.length) {
     ok(false, "Shouldn't get here!");
@@ -1059,20 +736,13 @@ function next() {
   try {
     var i = index++;
     steps[i]();
   } catch(ex) {
     ok(false, "Caught exception", ex);
   }
 }
 
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_blobs.html
+++ b/dom/contacts/tests/test_contacts_blobs.html
@@ -12,34 +12,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=674720">Mozilla Bug 674720</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
 <script class="testbody" type="text/javascript">
-
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
-}
-
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
 var utils = SpecialPowers.getDOMWindowUtils(window);
 
 function getView(size)
 {
  var buffer = new ArrayBuffer(size);
  var view = new Uint8Array(buffer);
  is(buffer.byteLength, size, "Correct byte length");
  return view;
@@ -100,25 +86,16 @@ var properties2 = {
   givenName: ["yTestname2"],
   photo: [randomBlob, randomBlob2]
 };
 
 var sample_id1;
 var createResult1;
 var findResult1;
 
-function onUnwantedSuccess() {
-  ok(false, "onUnwantedSuccess: shouldn't get here");
-}
-
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-
 function verifyBlob(blob1, blob2, isLast)
 {
   is(blob1 instanceof SpecialPowers.Ci.nsIDOMBlob, true,
      "Instance of nsIDOMBlob");
   is(blob1 instanceof SpecialPowers.Ci.nsIDOMFile,
      blob2 instanceof SpecialPowers.Ci.nsIDOMFile,
      "Instance of nsIDOMFile");
   is(blob1.size, blob2.size, "Correct size");
@@ -156,19 +133,16 @@ function verifyBlobArray(blobs1, blobs2)
     return;
   }
 
   for (var i = 0; i < blobs1.length; i++)
     verifyBlob(blobs1[i], blobs2[i], i == blobs1.length - 1);
 }
 
 var req;
-var index = 0;
-
-var mozContacts = window.navigator.mozContacts
 
 var steps = [
   function () {
     ok(true, "Deleting database");
     req = mozContacts.clear();
     req.onsuccess = function () {
       ok(true, "Deleted the database");
       next();
@@ -236,34 +210,13 @@ var steps = [
   },
   function () {
     ok(true, "all done!\n");
 
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  try {
-    steps[index]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-  index += 1;
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_getall.html
+++ b/dom/contacts/tests/test_contacts_getall.html
@@ -12,277 +12,21 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836519">Mozilla Bug 836519</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
-<script class="testbody" type="text/javascript;version=1.7">
-
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
+<script class="testbody" type="text/javascript;version=1.8">
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
-}
-
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
-let adr1 = {
-  type: ["work"],
-  streetAddress: "street 1",
-  locality: "locality 1",
-  region: "region 1",
-  postalCode: "postal code 1",
-  countryName: "country 1"
-};
-
-let properties1 = {
-  name: ["Testname1 TestFamilyName"],
-  familyName: ["TestFamilyName","Wagner"],
-  givenName: ["Test1","Test2"],
-  nickname: ["nicktest"],
-  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
-  adr: [adr1],
-  email: [{type: ["work"], value: "x@y.com"}]
-};
-
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-function checkStr(str1, str2, msg) {
-  if (str1 ^ str2) {
-    ok(false, "Expected both strings to be either present or absent");
-    return;
-  }
-  is(str1, str2, msg);
-}
-
-function checkStrArray(str1, str2, msg) {
-  function normalize_falsy(k, v) {
-    if (!v || v == "null" || v == "undefined") {
-      return "";
-    }
-    return v;
-  }
-  ise(JSON.stringify(str1, normalize_falsy), JSON.stringify(str2, normalize_falsy), msg);
-}
-
-function checkPref(pref1, pref2) {
-  // If on Android treat one preference as 0 and the other as undefined as matching
-  if (isAndroid) {
-    if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
-      pref1 = false;
-      pref2 = false;
-    }
-  }
-  ise(!!pref1, !!pref2, "Same pref");
-}
-
-function checkAddress(adr1, adr2) {
-  if (adr1 ^ adr2) {
-    ok(false, "Expected both adrs to be either present or absent");
-    return;
-  }
-  checkStrArray(adr1.type, adr2.type, "Same type");
-  checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
-  checkStrArray(adr1.locality, adr2.locality, "Same locality");
-  checkStrArray(adr1.region, adr2.region, "Same region");
-  checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
-  checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
-  checkPref(adr1.pref, adr2.pref);
-}
-
-function checkField(field1, field2) {
-  if (field1 ^ field2) {
-    ok(false, "Expected both fields to be either present or absent");
-    return;
-  }
-  checkStrArray(field1.type, field2.type, "Same type");
-  checkStrArray(field1.value, field2.value, "Same value");
-  checkPref(field1.pref, field2.pref);
-}
-
-function checkTel(tel1, tel2) {
-  if (tel1 ^ tel2) {
-    ok(false, "Expected both tels to be either present or absent");
-    return;
-  }
-  checkField(tel1, tel2);
-  checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
-}
-
-function checkCategory(category1, category2) {
-  // Android adds contacts to the a default category. This should be removed from the
-  // results before comparing them
-  if (isAndroid) {
-    category1 = removeAndroidDefaultCategory(category1);
-    category2 = removeAndroidDefaultCategory(category2);
-  }
-  checkStrArray(category1, category2, "Same Category")
-}
-
-function removeAndroidDefaultCategory(category) {
-  if (!category) {
-    return category;
-  }
-
-  var result = [];
-
-  for (var i of category) {
-    // Some devices may return the full group name (prefixed with "System Group: ")
-    if (i != "My Contacts" && i != "System Group: My Contacts") {
-      result.push(i);
-    }
-  }
-
-  return result;
-}
-
-function checkArrayField(array1, array2, func, msg) {
-  if (!!array1 ^ !!array2) {
-    ok(false, "Expected both arrays to be either present or absent");
-    return;
-  }
-  if (!array1 && !array2)  {
-    ok(true, msg);
-    return;
-  }
-  ise(array1.length, array2.length, "Same length");
-  for (var i = 0; i < array1.length; ++i) {
-    func(array1[i], array2[i], msg);
-  }
-}
-
-function checkContacts(contact1, contact2) {
-  if (!!contact1 ^ !!contact2) {
-    ok(false, "Expected both contacts to be either present or absent");
-    return;
-  }
-  checkStrArray(contact1.name, contact2.name, "Same name");
-  checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
-  checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
-  checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
-  checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
-  checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
-  checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
-  checkCategory(contact1.category, contact2.category);
-  checkStrArray(contact1.org, contact2.org, "Same org");
-  checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
-  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
-  checkStrArray(contact1.note, contact2.note, "Same note");
-  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
-  checkStr(contact1.sex, contact2.sex, "Same sex");
-  checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
-  checkStrArray(contact1.key, contact2.key, "Same key");
-
-  checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
-  checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
-  checkArrayField(contact1.email, contact2.email, checkField, "Same email");
-  checkArrayField(contact1.url, contact2.url, checkField, "Same url");
-  checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
-}
-
-function clearDatabase() {
-  ok(true, "Clearing database");
-  req = mozContacts.clear();
-  req.onsuccess = function() {
-    ok(true, "Cleared the database");
-    next();
-  };
-  req.onerror = onFailure;
-}
-
-function addContacts() {
-  ok(true, "Adding 40 contacts");
-  for (let i = 0; i < 39; ++i) {
-    properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
-    properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
-    createResult1 = new mozContact(properties1);
-    req = mozContacts.save(createResult1);
-    req.onsuccess = function() {
-      ok(createResult1.id, "The contact now has an ID.");
-    };
-    req.onerror = onFailure;
-  };
-  properties1.familyName[0] = "Testname39";
-  properties1.name = [properties1.givenName[0] + " Testname39"];
-  createResult1 = new mozContact(properties1);
-  req = mozContacts.save(createResult1);
-  req.onsuccess = function() {
-    ok(createResult1.id, "The contact now has an ID.");
-    checkStrArray(createResult1.name, properties1.name, "Same Name");
-    next();
-  };
-  req.onerror = onFailure;
-}
-
-let createResult1;
-
-let index = 0;
 let req;
-let mozContacts = window.navigator.mozContacts;
-
-function getOne(msg) {
-  return function() {
-    ok(true, msg || "Retrieving one contact with getAll");
-    req = mozContacts.getAll({});
-
-    let count = 0;
-    req.onsuccess = function(event) {
-      ok(true, "on success");
-      if (req.result) {
-        ok(true, "result is valid");
-        count++;
-        req.continue();
-      } else {
-        is(count, 1, "last contact - only one contact returned");
-        next();
-      }
-    };
-    req.onerror = onFailure;
-  };
-}
-
-function getAll(msg) {
-  return function() {
-    ok(true, msg || "Retrieving 40 contacts with getAll");
-    req = mozContacts.getAll({
-      sortBy: "familyName",
-      sortOrder: "ascending"
-    });
-    let count = 0;
-    let result;
-    let props;
-    req.onsuccess = function(event) {
-      if (req.result) {
-        ok(true, "result is valid");
-        result = req.result;
-        properties1.familyName[0] = "Testname" + (count < 10 ? "0" + count : count);
-        is(result.familyName[0], properties1.familyName[0], "Same familyName");
-        count++;
-        req.continue();
-      } else {
-        is(count, 40, "last contact - 40 contacts returned");
-        next();
-      }
-    };
-    req.onerror = onFailure;
-  }
-}
 
 let steps = [
   function start() {
     SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_START");
     next();
   },
   clearDatabase,
   addContacts,
@@ -396,34 +140,13 @@ let steps = [
 
   function() {
     ok(true, "all done!\n");
     SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_END");
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  let i = index++;
-  try {
-    steps[i]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_getall2.html
+++ b/dom/contacts/tests/test_contacts_getall2.html
@@ -12,283 +12,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836519">Mozilla Bug 836519</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
-<script class="testbody" type="text/javascript;version=1.7">
-
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
+<script class="testbody" type="text/javascript;version=1.8">
 "use strict";
-
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
-}
-
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
-let adr1 = {
-  type: ["work"],
-  streetAddress: "street 1",
-  locality: "locality 1",
-  region: "region 1",
-  postalCode: "postal code 1",
-  countryName: "country 1"
-};
-
-let properties1 = {
-  name: ["Testname1 TestFamilyName"],
-  familyName: ["TestFamilyName","Wagner"],
-  givenName: ["Test1","Test2"],
-  nickname: ["nicktest"],
-  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
-  adr: [adr1],
-  email: [{type: ["work"], value: "x@y.com"}]
-};
-
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-function checkStr(str1, str2, msg) {
-  if (str1 ^ str2) {
-    ok(false, "Expected both strings to be either present or absent");
-    return;
-  }
-  is(str1, str2, msg);
-}
-
-function checkStrArray(str1, str2, msg) {
-  function normalize_falsy(k, v) {
-    if (!v || v == "null" || v == "undefined") {
-      return "";
-    }
-    return v;
-  }
-  ise(JSON.stringify(str1, normalize_falsy), JSON.stringify(str2, normalize_falsy), msg);
-}
-
-function checkPref(pref1, pref2) {
-  // If on Android treat one preference as 0 and the other as undefined as matching
-  if (isAndroid) {
-    if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
-      pref1 = false;
-      pref2 = false;
-    }
-  }
-  ise(!!pref1, !!pref2, "Same pref");
-}
-
-function checkAddress(adr1, adr2) {
-  if (adr1 ^ adr2) {
-    ok(false, "Expected both adrs to be either present or absent");
-    return;
-  }
-  checkStrArray(adr1.type, adr2.type, "Same type");
-  checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
-  checkStrArray(adr1.locality, adr2.locality, "Same locality");
-  checkStrArray(adr1.region, adr2.region, "Same region");
-  checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
-  checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
-  checkPref(adr1.pref, adr2.pref);
-}
-
-function checkField(field1, field2) {
-  if (field1 ^ field2) {
-    ok(false, "Expected both fields to be either present or absent");
-    return;
-  }
-  checkStrArray(field1.type, field2.type, "Same type");
-  checkStrArray(field1.value, field2.value, "Same value");
-  checkPref(field1.pref, field2.pref);
-}
-
-function checkTel(tel1, tel2) {
-  if (tel1 ^ tel2) {
-    ok(false, "Expected both tels to be either present or absent");
-    return;
-  }
-  checkField(tel1, tel2);
-  checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
-}
-
-function checkCategory(category1, category2) {
-  // Android adds contacts to the a default category. This should be removed from the
-  // results before comparing them
-  if (isAndroid) {
-    category1 = removeAndroidDefaultCategory(category1);
-    category2 = removeAndroidDefaultCategory(category2);
-  }
-  checkStrArray(category1, category2, "Same Category")
-}
-
-function removeAndroidDefaultCategory(category) {
-  if (!category) {
-    return category;
-  }
-
-  var result = [];
-
-  for (var i of category) {
-    // Some devices may return the full group name (prefixed with "System Group: ")
-    if (i != "My Contacts" && i != "System Group: My Contacts") {
-      result.push(i);
-    }
-  }
-
-  return result;
-}
-
-function checkArrayField(array1, array2, func, msg) {
-  if (!!array1 ^ !!array2) {
-    ok(false, "Expected both arrays to be either present or absent");
-    return;
-  }
-  if (!array1 && !array2)  {
-    ok(true, msg);
-    return;
-  }
-  ise(array1.length, array2.length, "Same length");
-  for (var i = 0; i < array1.length; ++i) {
-    func(array1[i], array2[i], msg);
-  }
-}
-
-function checkContacts(contact1, contact2) {
-  if (!!contact1 ^ !!contact2) {
-    ok(false, "Expected both contacts to be either present or absent");
-    return;
-  }
-  checkStrArray(contact1.name, contact2.name, "Same name");
-  checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
-  checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
-  checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
-  checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
-  checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
-  checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
-  checkCategory(contact1.category, contact2.category);
-  checkStrArray(contact1.org, contact2.org, "Same org");
-  checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
-  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
-  checkStrArray(contact1.note, contact2.note, "Same note");
-  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
-  checkStr(contact1.sex, contact2.sex, "Same sex");
-  checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
-  checkStrArray(contact1.key, contact2.key, "Same key");
-
-  checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
-  checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
-  checkArrayField(contact1.email, contact2.email, checkField, "Same email");
-  checkArrayField(contact1.url, contact2.url, checkField, "Same url");
-  checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
-}
-
-function clearDatabase() {
-  ok(true, "Clearing database");
-  req = mozContacts.clear();
-  req.onsuccess = function() {
-    ok(true, "Cleared the database");
-    next();
-  };
-  req.onerror = onFailure;
-}
-
-function addContacts() {
-  ok(true, "Adding 40 contacts");
-  for (let i = 0; i < 39; ++i) {
-    properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
-    properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
-    createResult1 = new mozContact(properties1);
-    req = mozContacts.save(createResult1);
-    req.onsuccess = function() {
-      ok(createResult1.id, "The contact now has an ID.");
-    };
-    req.onerror = onFailure;
-  };
-  properties1.familyName[0] = "Testname39";
-  properties1.name = [properties1.givenName[0] + " Testname39"];
-  createResult1 = new mozContact(properties1);
-  req = mozContacts.save(createResult1);
-  req.onsuccess = function() {
-    ok(createResult1.id, "The contact now has an ID.");
-    checkStrArray(createResult1.name, properties1.name, "Same Name");
-    next();
-  };
-  req.onerror = onFailure;
-}
-
-let createResult1;
-
-let index = 0;
 let req;
-let mozContacts = window.navigator.mozContacts;
-
-function getOne(msg) {
-  return function() {
-    ok(true, msg || "Retrieving one contact with getAll");
-    req = mozContacts.getAll({});
-
-    let count = 0;
-    req.onsuccess = function(event) {
-      ok(true, "on success");
-      if (req.result) {
-        ok(true, "result is valid");
-        count++;
-        req.continue();
-      } else {
-        is(count, 1, "last contact - only one contact returned");
-        next();
-      }
-    };
-    req.onerror = onFailure;
-  };
-}
-
-function getAll(msg) {
-  return function() {
-    ok(true, msg || "Retrieving 40 contacts with getAll");
-    req = mozContacts.getAll({
-      sortBy: "familyName",
-      sortOrder: "ascending"
-    });
-    let count = 0;
-    let result;
-    let props;
-    req.onsuccess = function(event) {
-      if (req.result) {
-        ok(true, "result is valid");
-        result = req.result;
-        properties1.familyName[0] = "Testname" + (count < 10 ? "0" + count : count);
-        is(result.familyName[0], properties1.familyName[0], "Same familyName");
-        count++;
-        req.continue();
-      } else {
-        is(count, 40, "last contact - 40 contacts returned");
-        next();
-      }
-    };
-    req.onerror = onFailure;
-  }
-}
 
 let steps = [
-  function start() {
-    SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_START");
-    next();
-  },
   clearDatabase,
   function() {
     // add a contact
     createResult1 = new mozContact({});
     req = navigator.mozContacts.save(createResult1);
     req.onsuccess = function() {
       next();
     };
@@ -365,39 +104,17 @@ let steps = [
       };
     };
   },
 
   clearDatabase,
 
   function() {
     ok(true, "all done!\n");
-    SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_END");
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  let i = index++;
-  try {
-    steps[i]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_international.html
+++ b/dom/contacts/tests/test_contacts_international.html
@@ -12,39 +12,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815833">Mozilla Bug 815833</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
 <script class="testbody" type="text/javascript">
-
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
-}
-
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-
 var number1 = {
   local: "7932012345",
   international: "+557932012345"
 };
 
 var number2 = {
   local: "7932012346",
   international: "+557932012346"
@@ -67,23 +48,20 @@ var number3 = {
 };
 
 var properties3 = {
   name: ["Testname2"],
   tel: [{value: number3.international2}]
 };
 
 var req;
-var index = 0;
 var createResult1;
 var findResult1;
 var sample_id1;
 
-var mozContacts = window.navigator.mozContacts;
-
 var steps = [
   function () {
     ok(true, "Deleting database");
     req = mozContacts.clear();
     req.onsuccess = function () {
       ok(true, "Deleted the database");
       next();
     };
@@ -280,34 +258,13 @@ var steps = [
     req.onerror = onFailure;
   },
   function () {
     ok(true, "all done!\n");
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  try {
-    steps[index]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-  index += 1;
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_substringmatching.html
+++ b/dom/contacts/tests/test_contacts_substringmatching.html
@@ -12,69 +12,45 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=877302">Mozilla Bug 877302</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
 <script class="testbody" type="text/javascript">
-
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-}
-
 var substringLength = 8;
 SpecialPowers.setIntPref("dom.phonenumber.substringmatching.BR", substringLength);
 SpecialPowers.setCharPref("ril.lastKnownSimMcc", "724");
 
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
 var sample_id1;
 var createResult1;
 var findResult1;
 
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-
 var prop = {
   tel: [{value: "7932012345" }, {value: "7932012346"}]
 };
 
 var prop2 = {
   tel: [{value: "01187654321" }]
 };
 
 var prop3 = {
   tel: [{ value: "+43332112346" }]
 };
 
 var prop4 = {
   tel: [{ value: "(0414) 233-9888" }]
 };
 
-
 var req;
-var index = 0;
-
-var mozContacts = window.navigator.mozContacts;
-ok(mozContacts, "mozContacts exists");
-ok("mozContact" in window, "mozContact exists");
 var steps = [
   function () {
     ok(true, "Deleting database");
     req = mozContacts.clear()
     req.onsuccess = function () {
       ok(true, "Deleted the database");
       next();
     }
@@ -319,34 +295,13 @@ var steps = [
   },
   function () {
     ok(true, "all done!\n");
     SpecialPowers.setIntPref("dom.phonenumber.substringmatching.BR", -1);
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  try {
-    steps[index]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-  index += 1;
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>
--- a/dom/contacts/tests/test_contacts_substringmatchingVE.html
+++ b/dom/contacts/tests/test_contacts_substringmatchingVE.html
@@ -12,60 +12,37 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=877302">Mozilla Bug 877302</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
+<script type="text/javascript;version=1.8" src="http://mochi.test:8888/tests/dom/contacts/tests/shared.js"></script>
 <script class="testbody" type="text/javascript">
-
 "use strict";
 
-if (SpecialPowers.isMainProcess()) {
-  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
-}
-
 var substringLength = 7;
 SpecialPowers.setIntPref("dom.phonenumber.substringmatching.VE", substringLength);
 SpecialPowers.setCharPref("ril.lastKnownSimMcc", "734");
 
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
-var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
-var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                  .getProperty('version');
-
 var sample_id1;
 var createResult1;
 var findResult1;
 
-function onFailure() {
-  ok(false, "in on Failure!");
-  next();
-}
-
 var prop = {
   tel: [{value: "7932012345" }, {value: "7704143727591"}]
 };
 
 var prop2 = {
   tel: [{value: "7932012345" }, {value: "+58 212 5551212"}]
 };
 
 var req;
-var index = 0;
-
-var mozContacts = window.navigator.mozContacts;
-ok(mozContacts, "mozContacts exists");
-ok("mozContact" in window, "mozContact exists");
 var steps = [
   function () {
     ok(true, "Deleting database");
     req = mozContacts.clear()
     req.onsuccess = function () {
       ok(true, "Deleted the database");
       next();
     }
@@ -147,34 +124,13 @@ var steps = [
   },
   function () {
     ok(true, "all done!\n");
     SpecialPowers.setIntPref("dom.phonenumber.substringmatching.VE", -1);
     SimpleTest.finish();
   }
 ];
 
-function next() {
-  ok(true, "Begin!");
-  if (index >= steps.length) {
-    ok(false, "Shouldn't get here!");
-    return;
-  }
-  try {
-    steps[index]();
-  } catch(ex) {
-    ok(false, "Caught exception", ex);
-  }
-  index += 1;
-}
-
-// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
-if (!isAndroid || androidVersion >= 14) {
-  SimpleTest.waitForExplicitFinish();
-  addLoadEvent(next);
-} else {
-  ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
-}
-
+start_tests();
 </script>
 </pre>
 </body>
 </html>