Bug 1328338 - Fix more no-undef eslint issues in toolkit/ and browser/. r?Mossop draft
authorMark Banner <standard8@mozilla.com>
Tue, 03 Jan 2017 11:55:24 +0000
changeset 455602 c555e54196242c5ded6c4dccba6be23258ca675a
parent 455536 57ac9f63fc6953f4efeb0cc84a60192d3721251f
child 456042 021b4d638c0f5395b9e65457ba1feb3c01885214
push id40303
push userbmo:standard8@mozilla.com
push dateWed, 04 Jan 2017 09:57:55 +0000
reviewersMossop
bugs1328338
milestone53.0a1
Bug 1328338 - Fix more no-undef eslint issues in toolkit/ and browser/. r?Mossop MozReview-Commit-ID: 78dXLYVW1gC
browser/base/content/test/captivePortal/.eslintrc.js
browser/base/content/test/general/browser_contextmenu.js
browser/base/content/test/general/browser_contextmenu_input.js
browser/base/content/test/general/browser_save_link-perwindowpb.js
browser/base/content/test/general/browser_save_link_when_window_navigates.js
browser/base/content/test/general/browser_save_private_link_perwindowpb.js
browser/base/content/test/general/browser_save_video.js
browser/base/content/test/general/browser_save_video_frame.js
browser/base/content/test/general/test_offlineNotification.html
browser/base/content/test/plugins/head.js
browser/base/content/test/tabcrashed/.eslintrc.js
browser/components/feeds/WebContentConverter.js
browser/components/preferences/in-content/tests/browser_advanced_siteData.js
browser/components/preferences/in-content/tests/browser_privacypane_1.js
browser/components/preferences/in-content/tests/browser_privacypane_3.js
browser/components/preferences/in-content/tests/browser_privacypane_4.js
browser/components/preferences/in-content/tests/browser_privacypane_5.js
browser/components/preferences/in-content/tests/browser_privacypane_8.js
browser/components/preferences/permissions.js
browser/components/preferences/selectBookmark.js
testing/mochitest/browser.eslintrc.js
testing/mochitest/chrome.eslintrc.js
testing/mochitest/mochitest.eslintrc.js
testing/xpcshell/xpcshell.eslintrc.js
toolkit/.eslintrc.js
toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js
toolkit/components/contentprefs/tests/unit/xpcshell.ini
toolkit/components/crashes/tests/xpcshell/test_crash_store.js
toolkit/components/ctypes/tests/unit/head.js
toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js
toolkit/components/ctypes/tests/unit/test_jsctypes.js
toolkit/components/downloads/test/unit/head_download_manager.js
toolkit/components/downloads/test/unit/tail_download_manager.js
toolkit/components/downloads/test/unit/test_app_rep.js
toolkit/components/downloads/test/unit/test_app_rep_maclinux.js
toolkit/components/downloads/test/unit/test_app_rep_windows.js
toolkit/components/downloads/test/unit/xpcshell.ini
toolkit/components/formautofill/test/.eslintrc.js
toolkit/components/formautofill/test/browser/head.js
toolkit/components/formautofill/test/browser/loader.js
toolkit/components/formautofill/test/chrome/head.js
toolkit/components/formautofill/test/chrome/loader.js
toolkit/components/formautofill/test/chrome/loader_parent.js
toolkit/components/formautofill/test/chrome/test_infrastructure.js
toolkit/components/formautofill/test/chrome/test_requestAutocomplete_cancel.js
toolkit/components/formautofill/test/head_common.js
toolkit/components/formautofill/test/loader_common.js
toolkit/components/places/tests/head_common.js
toolkit/components/printing/content/printjoboptions.js
toolkit/components/viewsource/content/viewPartialSource.js
toolkit/content/tests/mochitest/.eslintrc.js
toolkit/crashreporter/test/unit/head_crashreporter.js
toolkit/crashreporter/test/unit/test_crash_AsyncShutdown.js
toolkit/crashreporter/test/unit_ipc/test_content_annotation.js
toolkit/crashreporter/test/unit_ipc/test_content_exception_time_annotation.js
toolkit/crashreporter/test/unit_ipc/test_content_memory_list.js
toolkit/crashreporter/test/unit_ipc/test_content_oom_annotation_windows.js
toolkit/forgetaboutsite/ForgetAboutSite.jsm
toolkit/forgetaboutsite/test/unit/head_forgetaboutsite.js
toolkit/modules/Log.jsm
toolkit/modules/SpatialNavigation.jsm
toolkit/modules/tests/xpcshell/test_JSONFile.js
toolkit/modules/tests/xpcshell/test_Log.js
toolkit/xre/test/test_fpuhandler.html
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/captivePortal/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
--- a/browser/base/content/test/general/browser_contextmenu.js
+++ b/browser/base/content/test/general/browser_contextmenu.js
@@ -11,16 +11,17 @@ let LOGIN_FILL_ITEMS = [
     ], null,
 ];
 let hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
 let hasContainers = Services.prefs.getBoolPref("privacy.userContext.enabled");
 
 const example_base = "http://example.com/browser/browser/base/content/test/general/";
 const chrome_base = "chrome://mochitests/content/browser/browser/base/content/test/general/";
 
+/* import-globals-from contextmenu_common.js */
 Services.scriptloader.loadSubScript(chrome_base + "contextmenu_common.js", this);
 
 // Below are test cases for XUL element
 add_task(function* test_xul_text_link_label() {
   let url = chrome_base + "subtst_contextmenu_xul.xul";
 
   yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
 
--- a/browser/base/content/test/general/browser_contextmenu_input.js
+++ b/browser/base/content/test/general/browser_contextmenu_input.js
@@ -5,16 +5,17 @@ let hasPocket = Services.prefs.getBoolPr
 
 add_task(function* test_setup() {
   const example_base = "http://example.com/browser/browser/base/content/test/general/";
   const url = example_base + "subtst_contextmenu_input.html";
   yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
 
   const chrome_base = "chrome://mochitests/content/browser/browser/base/content/test/general/";
   const contextmenu_common = chrome_base + "contextmenu_common.js";
+  /* import-globals-from contextmenu_common.js */
   Services.scriptloader.loadSubScript(contextmenu_common, this);
 });
 
 add_task(function* test_text_input() {
   yield test_contextmenu("#input_text",
     ["context-undo",        false,
      "---",                 null,
      "context-cut",         true,
--- a/browser/base/content/test/general/browser_save_link-perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_link-perwindowpb.js
@@ -175,16 +175,17 @@ function test() {
           is(gNumSet, 2, "2 cookies should be set");
           finish();
         });
       });
     });
   });
 }
 
+/* import-globals-from ../../../../../toolkit/content/tests/browser/common/mockTransfer.js */
 Cc["@mozilla.org/moz/jssubscript-loader;1"]
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                  this);
 
 function createTemporarySaveDirectory() {
   var saveDir = Cc["@mozilla.org/file/directory_service;1"]
                   .getService(Ci.nsIProperties)
--- a/browser/base/content/test/general/browser_save_link_when_window_navigates.js
+++ b/browser/base/content/test/general/browser_save_link_when_window_navigates.js
@@ -3,16 +3,17 @@
 
 var MockFilePicker = SpecialPowers.MockFilePicker;
 MockFilePicker.init(window);
 
 const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite";
 const ALWAYS_DOWNLOAD_DIR_PREF = "browser.download.useDownloadDir";
 const UCT_URI = "chrome://mozapps/content/downloads/unknownContentType.xul";
 
+/* import-globals-from ../../../../../toolkit/content/tests/browser/common/mockTransfer.js */
 Cc["@mozilla.org/moz/jssubscript-loader;1"]
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                  this);
 
 function createTemporarySaveDirectory() {
   var saveDir = Cc["@mozilla.org/file/directory_service;1"]
                   .getService(Ci.nsIProperties)
@@ -165,9 +166,8 @@ function test() {
         Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, false);
         testOnWindow(undefined, function(win2) {
           triggerSave(win2, finish);
         });
       });
     });
   });
 }
-
--- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
@@ -102,12 +102,13 @@ add_task(function* () {
 
   // wait for image download
   let fileName = yield imageDownloaded;
   yield promiseNoCacheEntry(fileName);
 
   yield BrowserTestUtils.closeWindow(privateWindow);
 });
 
+/* import-globals-from ../../../../../toolkit/content/tests/browser/common/mockTransfer.js */
 Cc["@mozilla.org/moz/jssubscript-loader;1"]
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                  this);
--- a/browser/base/content/test/general/browser_save_video.js
+++ b/browser/base/content/test/general/browser_save_video.js
@@ -65,17 +65,17 @@ add_task(function* () {
   let contextMenu = document.getElementById("contentAreaContextMenu");
   let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
   contextMenu.hidePopup();
   yield popupHiddenPromise;
 
   yield transferCompletePromise;
 });
 
-
+/* import-globals-from ../../../../../toolkit/content/tests/browser/common/mockTransfer.js */
 Cc["@mozilla.org/moz/jssubscript-loader;1"]
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                  this);
 
 function createTemporarySaveDirectory() {
   var saveDir = Cc["@mozilla.org/file/directory_service;1"]
                   .getService(Ci.nsIProperties)
--- a/browser/base/content/test/general/browser_save_video_frame.js
+++ b/browser/base/content/test/general/browser_save_video_frame.js
@@ -2,16 +2,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const VIDEO_URL = "http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html";
 
 /**
  * mockTransfer.js provides a utility that lets us mock out
  * the "Save File" dialog.
  */
+/* import-globals-from ../../../../../toolkit/content/tests/browser/common/mockTransfer.js */
 Cc["@mozilla.org/moz/jssubscript-loader;1"]
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                  this);
 
 /**
  * Creates and returns an nsIFile for a new temporary save
  * directory.
--- a/browser/base/content/test/general/test_offlineNotification.html
+++ b/browser/base/content/test/general/test_offlineNotification.html
@@ -20,17 +20,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <iframe name="testFrame3" src="http://example.com/tests/browser/base/content/test/general/offlineChild.html"></iframe>
 
 <iframe id="eventsTestFrame" src="offlineEvent.html"></iframe>
 
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
-
+/* import-globals-from offlineByDefault.js */
 SimpleTest.waitForExplicitFinish();
 const Cc = SpecialPowers.Cc;
 
 var numFinished = 0;
 
 window.addEventListener("message", function(event) {
     is(event.data, "success", "Child was successfully cached.");
 
--- a/browser/base/content/test/plugins/head.js
+++ b/browser/base/content/test/plugins/head.js
@@ -2,16 +2,20 @@ Components.utils.import("resource://gre/
 
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
   "resource://gre/modules/PromiseUtils.jsm");
 
+// Various tests in this directory may define gTestBrowser, to use as the
+// default browser under test in some of the functions below.
+/* global gTestBrowser */
+
 // The blocklist shim running in the content process does not initialize at
 // start up, so it's not active until we load content that needs to do a
 // check. This helper bypasses the delay to get the svc up and running
 // immediately. Note, call this after remote content has loaded.
 function promiseInitContentBlocklistSvc(aBrowser) {
   return ContentTask.spawn(aBrowser, {}, function* () {
     try {
       Cc["@mozilla.org/extensions/blocklist;1"]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabcrashed/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
--- a/browser/components/feeds/WebContentConverter.js
+++ b/browser/components/feeds/WebContentConverter.js
@@ -903,17 +903,17 @@ WebContentConverterRegistrarContent.prot
     // first get the numbers of the providers by getting all ###.uri prefs
     let nums = children.map((child) => {
       let match = /^(\d+)\.uri$/.exec(child);
       return match ? match[1] : "";
     }).filter(child => !!child)
       .sort();
 
     // now register them
-    for (num of nums) {
+    for (let num of nums) {
       let branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + num + ".");
       try {
         this._registerContentHandlerHavingBranch(branch);
       } catch (ex) {
         // do nothing, the next branch might have values
       }
     }
   },
--- a/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
@@ -1,16 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+/* import-globals-from ../../../../../testing/modules/sinon-1.16.1.js */
 Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
 
 const TEST_HOST = "example.com";
 const TEST_ORIGIN = "http://" + TEST_HOST;
 const TEST_BASE_URL = TEST_ORIGIN + "/browser/browser/components/preferences/in-content/tests/";
 
 const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const { SiteDataManager } = Cu.import("resource:///modules/SiteDataManager.jsm", {});
--- a/browser/components/preferences/in-content/tests/browser_privacypane_1.js
+++ b/browser/components/preferences/in-content/tests/browser_privacypane_1.js
@@ -2,16 +2,17 @@ let loader = Cc["@mozilla.org/moz/jssubs
              getService(Ci.mozIJSSubScriptLoader);
 
 let rootDir = getRootDirectory(gTestPath);
 let jar = getJar(rootDir);
 if (jar) {
   let tmpdir = extractJarToTmp(jar);
   rootDir = "file://" + tmpdir.path + '/';
 }
+/* import-globals-from privacypane_tests_perwindow.js */
 loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
 
 run_test_subset([
   test_pane_visibility,
   test_dependent_elements,
   test_dependent_cookie_elements,
   test_dependent_clearonclose_elements,
   test_dependent_prefs,
--- a/browser/components/preferences/in-content/tests/browser_privacypane_3.js
+++ b/browser/components/preferences/in-content/tests/browser_privacypane_3.js
@@ -1,16 +1,17 @@
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
              getService(Ci.mozIJSSubScriptLoader);
 let rootDir = getRootDirectory(gTestPath);
 let jar = getJar(rootDir);
 if (jar) {
   let tmpdir = extractJarToTmp(jar);
   rootDir = "file://" + tmpdir.path + '/';
 }
+/* import-globals-from privacypane_tests_perwindow.js */
 loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
 
 run_test_subset([
   test_custom_retention("rememberHistory", "remember"),
   test_custom_retention("rememberHistory", "custom"),
   test_custom_retention("rememberForms", "custom"),
   test_custom_retention("rememberForms", "custom"),
   test_historymode_retention("remember", "custom"),
--- a/browser/components/preferences/in-content/tests/browser_privacypane_4.js
+++ b/browser/components/preferences/in-content/tests/browser_privacypane_4.js
@@ -3,16 +3,17 @@ requestLongerTimeout(2);
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
              getService(Ci.mozIJSSubScriptLoader);
 let rootDir = getRootDirectory(gTestPath);
 let jar = getJar(rootDir);
 if (jar) {
   let tmpdir = extractJarToTmp(jar);
   rootDir = "file://" + tmpdir.path + '/';
 }
+/* import-globals-from privacypane_tests_perwindow.js */
 loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
 let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
 
 run_test_subset([
   test_custom_retention("acceptCookies", "remember"),
   test_custom_retention("acceptCookies", "custom"),
   test_custom_retention("acceptThirdPartyMenu", "custom", "visited"),
   test_custom_retention("acceptThirdPartyMenu", "custom", "always"),
--- a/browser/components/preferences/in-content/tests/browser_privacypane_5.js
+++ b/browser/components/preferences/in-content/tests/browser_privacypane_5.js
@@ -1,16 +1,17 @@
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
              getService(Ci.mozIJSSubScriptLoader);
 let rootDir = getRootDirectory(gTestPath);
 let jar = getJar(rootDir);
 if (jar) {
   let tmpdir = extractJarToTmp(jar);
   rootDir = "file://" + tmpdir.path + '/';
 }
+/* import-globals-from privacypane_tests_perwindow.js */
 loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
 
 run_test_subset([
   test_locbar_suggestion_retention("history", true),
   test_locbar_suggestion_retention("bookmark", true),
   test_locbar_suggestion_retention("openpage", false),
   test_locbar_suggestion_retention("history", true),
   test_locbar_suggestion_retention("history", false),
--- a/browser/components/preferences/in-content/tests/browser_privacypane_8.js
+++ b/browser/components/preferences/in-content/tests/browser_privacypane_8.js
@@ -1,16 +1,17 @@
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
              getService(Ci.mozIJSSubScriptLoader);
 let rootDir = getRootDirectory(gTestPath);
 let jar = getJar(rootDir);
 if (jar) {
   let tmpdir = extractJarToTmp(jar);
   rootDir = "file://" + tmpdir.path + '/';
 }
+/* import-globals-from privacypane_tests_perwindow.js */
 loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
 
 run_test_subset([
   // history mode should be initialized to remember
   test_historymode_retention("remember", undefined),
 
   // history mode should remain remember; toggle acceptCookies checkbox
   test_custom_retention("acceptCookies", "remember"),
--- a/browser/components/preferences/permissions.js
+++ b/browser/components/preferences/permissions.js
@@ -1,12 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// Imported via permissions.xul.
+/* import-globals-from ../../../toolkit/content/treeUtils.js */
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
 const nsICookiePermission = Components.interfaces.nsICookiePermission;
 
 const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions";
 
 function Permission(principal, type, capability) {
--- a/browser/components/preferences/selectBookmark.js
+++ b/browser/components/preferences/selectBookmark.js
@@ -1,13 +1,16 @@
 //* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// These globals are imported via placesOverlay.xul.
+/* globals PlacesUIUtils, PlacesUtils, NS_ASSERT */
+
 /**
  * SelectBookmarkDialog controls the user interface for the "Use Bookmark for
  * Home Page" dialog.
  *
  * The caller (gMainPane.setHomePageToBookmark in main.js) invokes this dialog
  * with a single argument - a reference to an object with a .urls property and
  * a .names property.  This dialog is responsible for updating the contents of
  * the .urls property with an array of URLs to use as home pages and for
--- a/testing/mochitest/browser.eslintrc.js
+++ b/testing/mochitest/browser.eslintrc.js
@@ -9,16 +9,17 @@ module.exports = {
   "env": {
     "browser": true,
     //"node": true
   },
 
   // All globals made available in the test environment.
   "globals": {
     "add_task": false,
+    "addLoadEvent": false,
     "Assert": false,
     "BrowserTestUtils": false,
     "content": false,
     "ContentTask": false,
     "ContentTaskUtils": false,
     "EventUtils": false,
     "executeSoon": false,
     "expectUncaughtException": false,
@@ -29,16 +30,17 @@ module.exports = {
     "getRootDirectory": false,
     "getTestFilePath": false,
     "gTestPath": false,
     "info": false,
     "ignoreAllUncaughtExceptions": false,
     "is": false,
     "isnot": false,
     "ok": false,
+    "privateNoteIntentionalCrash": false,
     "registerCleanupFunction": false,
     "requestLongerTimeout": false,
     "SimpleTest": false,
     "SpecialPowers": false,
     "TestUtils": false,
     "thisTestLeaksUncaughtRejectionsAndShouldBeFixed": false,
     "todo": false,
     "todo_is": false,
--- a/testing/mochitest/chrome.eslintrc.js
+++ b/testing/mochitest/chrome.eslintrc.js
@@ -7,28 +7,30 @@ module.exports = {
 
   "env": {
     "browser": true,
   },
 
   // All globals made available in the test environment.
   "globals": {
     "add_task": false,
+    "addLoadEvent": false,
     "Assert": false,
     "EventUtils": false,
     "executeSoon": false,
     "export_assertions": false,
     "finish": false,
     "getRootDirectory": false,
     "getTestFilePath": false,
     "gTestPath": false,
     "info": false,
     "is": false,
     "isnot": false,
     "ok": false,
+    "privateNoteIntentionalCrash": false,
     "promise": false,
     "registerCleanupFunction": false,
     "requestLongerTimeout": false,
     "SimpleTest": false,
     "SpecialPowers": false,
     "todo": false,
     "todo_is": false,
     "todo_isnot": false,
--- a/testing/mochitest/mochitest.eslintrc.js
+++ b/testing/mochitest/mochitest.eslintrc.js
@@ -10,16 +10,17 @@ module.exports = {
     "browser": true,
   },
 
   // All globals made available in the test environment.
   "globals": {
     // $ is defined in SimpleTest.js
     "$": false,
     "add_task": false,
+    "addLoadEvent": false,
     "Assert": false,
     "EventUtils": false,
     "executeSoon": false,
     "export_assertions": false,
     "finish": false,
     "getRootDirectory": false,
     "getTestFilePath": false,
     "gTestPath": false,
--- a/testing/xpcshell/xpcshell.eslintrc.js
+++ b/testing/xpcshell/xpcshell.eslintrc.js
@@ -11,26 +11,28 @@ module.exports = {
     "_TEST_FILE": false,
     "add_task": false,
     "add_test": false,
     "Assert": false,
     "deepEqual": false,
     "do_await_remote_message": false,
     "do_check_eq": false,
     "do_check_false": false,
+    "do_check_instanceof": false,
     "do_check_matches": false,
     "do_check_neq": false,
     "do_check_null": false,
     "do_check_true": false,
     "do_execute_soon": false,
     "do_get_cwd": false,
     "do_get_file": false,
     "do_get_idle": false,
     "do_get_profile": false,
     "do_get_tempdir": false,
+    "do_load_child_test_harness": false,
     "do_load_manifest": false,
     "do_load_module": false,
     "do_parse_document": false,
     "do_print": false,
     "do_register_cleanup": false,
     "do_report_unexpected_exception": false,
     "do_send_remote_message": false,
     "do_test_finished": false,
@@ -47,16 +49,18 @@ module.exports = {
     "notDeepEqual": false,
     "notEqual": false,
     "notStrictEqual": false,
     "ok": false,
     "runningInParent": false,
     "run_next_test": false,
     "run_test": false,
     "run_test_in_child": false,
+    // Defined in XPCShellImpl.
+    "sendCommand": false,
     "strictEqual": false,
     "throws": false,
     "todo": false,
     "todo_check_false": false,
     "todo_check_true": false,
     // Firefox specific function.
     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval
     "uneval": false,
--- a/toolkit/.eslintrc.js
+++ b/toolkit/.eslintrc.js
@@ -202,15 +202,18 @@ module.exports = {
     // Only check typeof against valid results
     "valid-typeof": "error",
   },
   "env": {
     "es6": true,
     "browser": true,
   },
   "globals": {
+    "ChromeWorker": false,
+    "ChromeUtils": false,
     "Components": false,
     "dump": true,
+    "KeyEvent": false,
     "openDialog": false,
     "sizeToContent": false,
-    "ChromeWorker": false,
+    "SharedArrayBuffer": false,
   }
 };
--- a/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
+++ b/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
@@ -63,16 +63,17 @@ function frameScript() {
     Services.obs.notifyObservers(null, "test-about:performance-test-driver", JSON.stringify(options));
   });
 
   addMessageListener("aboutperformance-test:checkSanity", ({data: options}) => {
     let exn = null;
     try {
       let reFullname = /Full name: (.+)/;
       let reFps = /Impact on framerate: (\d+)\/10( \((\d+) alerts\))?/;
+      let reCPU = /CPU usage: (\d+)%/;
       let reCpow = /Blocking process calls: (\d+)%( \((\d+) alerts\))?/;
 
       let getContentOfSelector = function(eltContainer, selector, re) {
         let elt = eltContainer.querySelector(selector);
         if (!elt) {
           throw new Error(`No item ${selector}`);
         }
 
--- a/toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
+++ b/toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
@@ -137,16 +137,21 @@ function enterPBMode() {
 }
 function exitPBMode() {
   gInPrivateBrowsing = false;
   Services.obs.notifyObservers(null, "last-pb-context-exited", null);
 }
 
 ContentPrefTest.deleteDatabase();
 
+do_register_cleanup(function() {
+  ContentPrefTest.deleteDatabase();
+  ContentPrefTest.__dirSvc = null;
+});
+
 function inChildProcess() {
   var appInfo = Cc["@mozilla.org/xre/app-info;1"];
   if (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType ==
       Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
     return false;
   }
   return true;
 }
@@ -154,9 +159,8 @@ function inChildProcess() {
 // Turn on logging for the content preferences service so we can troubleshoot
 // problems with the tests. Note that we cannot do this in a child process
 // without crashing (but we don't need it anyhow)
 if (!inChildProcess()) {
   var prefBranch = Cc["@mozilla.org/preferences-service;1"].
                    getService(Ci.nsIPrefBranch);
   prefBranch.setBoolPref("browser.preferences.content.log", true);
 }
-
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-ContentPrefTest.deleteDatabase();
-ContentPrefTest.__dirSvc = null;
--- a/toolkit/components/contentprefs/tests/unit/xpcshell.ini
+++ b/toolkit/components/contentprefs/tests/unit/xpcshell.ini
@@ -1,11 +1,11 @@
 [DEFAULT]
 head = head_contentPrefs.js
-tail = tail_contentPrefs.js
+tail =
 
 [test_bug248970.js]
 [test_bug503971.js]
 [test_bug679784.js]
 [test_contentPrefs.js]
 [test_contentPrefsCache.js]
 [test_getPrefAsync.js]
 [test_stringGroups.js]
--- a/toolkit/components/crashes/tests/xpcshell/test_crash_store.js
+++ b/toolkit/components/crashes/tests/xpcshell/test_crash_store.js
@@ -579,9 +579,8 @@ add_task(function* test_setRemoteCrashID
   let s = yield getStore();
 
   Assert.ok(s.addCrash(PROCESS_TYPE_MAIN, CRASH_TYPE_CRASH, "crash1",
                        new Date()));
   Assert.equal(s.crashes[0].remoteID, null);
   Assert.ok(s.setRemoteCrashID("crash1", "bp-1"));
   Assert.equal(s.crashes[0].remoteID, "bp-1");
 });
-
--- a/toolkit/components/ctypes/tests/unit/head.js
+++ b/toolkit/components/ctypes/tests/unit/head.js
@@ -1,8 +1,10 @@
+/* global ThreadSafeChromeUtils */
+
 try {
   // We might be running without privileges, in which case it's up to the
   // harness to give us the 'ctypes' object.
   Components.utils.import("resource://gre/modules/ctypes.jsm");
 } catch (e) {
 }
 
 function open_ctypes_test_lib() {
@@ -107,21 +109,24 @@ function structural_check_eq_aux(a, b) {
   );
 }
 
 function trigger_gc() {
   dump("Triggering garbage-collection");
   Components.utils.forceGC();
 }
 
-function must_throw(f) {
+function must_throw(f, expected) {
   let has_thrown = false;
   try {
     f();
   } catch (x) {
+    if (expected) {
+      do_check_eq(x.toString(), expected);
+    }
     has_thrown = true;
   }
   do_check_true(has_thrown);
 }
 
 function get_os() {
   return Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
 }
--- a/toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js
+++ b/toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js
@@ -58,30 +58,33 @@ function run_test() {
  * Testing construction of finalizers with wrong arguments.
  */
 function test_finalize_bad_construction() {
   // First argument does not match second
   must_throw(function() { ctypes.CDataFinalizer({}, dispose); });
   must_throw(function() { ctypes.CDataFinalizer(dispose, dispose); });
 
   // Not enough arguments
-  must_throw(function() { ctypes.CDataFinalizer(init(0)); });
+  must_throw(function() { ctypes.CDataFinalizer(dispose); },
+             "TypeError: CDataFinalizer constructor takes two arguments");
 
   // Too many arguments
-  must_throw(function() { ctypes.CDataFinalizer(init(0), dispose, dispose); });
+  must_throw(function() { ctypes.CDataFinalizer(dispose, dispose, dispose); },
+             "TypeError: CDataFinalizer constructor takes two arguments");
 
   // Second argument is null
-  must_throw(function() { ctypes.CDataFinalizer(init(0), null); });
+  must_throw(function() { ctypes.CDataFinalizer(dispose, null); },
+             "TypeError: expected _a CData object_ of a function pointer type, got null");
 
   // Second argument is undefined
   must_throw(function() {
     let a;
-    ctypes.CDataFinalizer(init(0), a);
-  });
-
+    ctypes.CDataFinalizer(dispose, a);
+  },
+  "TypeError: expected _a CData object_ of a function pointer type, got undefined");
 }
 
 /**
  * Test that forget/dispose can only take place once.
  */
 function test_double_dispose() {
   function test_one_combination(i, a, b) {
     let v = ctypes.CDataFinalizer(acquire(i), dispose);
--- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js
+++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js
@@ -944,17 +944,17 @@ function run_float_tests(library, t, nam
               {toString() { return 7; }},
               {valueOf() { return 7; }}];
   for (let i = 0; i < vals.length; i++)
     do_check_throws(function() { d.value = vals[i]; }, TypeError);
 
   // Check that values roundtrip through toSource() correctly.
   function test_roundtrip(tFn, val) {
     let f1 = tFn(val);
-    eval("var f2 = " + f1.toSource());
+    var f2 = eval(f1.toSource());
     do_check_eq(f1.value, f2.value);
   }
   vals = [Infinity, -Infinity, -0, 0, 1, -1, 1 / 3, -1 / 3, 1 / 4, -1 / 4,
           1e-14, -1e-14, 0xfffffffffffff000, -0xfffffffffffff000];
   for (let i = 0; i < vals.length; i++)
     test_roundtrip(t, vals[i]);
   do_check_eq(t(NaN).toSource(), t.toSource() + "(NaN)");
 
@@ -1538,17 +1538,17 @@ function run_StructType_tests() {
   do_check_true(g_a.constructor === g_t.ptr);
   do_check_eq(g_a.contents.a, s.b.a);
   do_check_throws(function() { s.addressOfField(); }, TypeError);
   do_check_throws(function() { s.addressOfField("d"); }, TypeError);
   do_check_throws(function() { s.addressOfField("a", 2); }, TypeError);
 
   do_check_eq(s.toSource(), "s_t(4, {\"a\": 7, \"b\": 2}, 10)");
   do_check_eq(s.toSource(), s.toString());
-  eval("var s2 = " + s.toSource());
+  var s2 = eval(s.toSource());
   do_check_true(s2.constructor === s_t);
   do_check_eq(s.b.b, s2.b.b);
 
   // Test that structs can be set from an object using 'value'.
   do_check_throws(function() { s.value; }, TypeError);
   let s_init = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13 };
   s.value = s_init;
   do_check_eq(s.b.a, 9);
@@ -2036,17 +2036,17 @@ function run_ArrayType_tests() {
   do_check_eq(ptrValue(b.addressOfElement(0)), ptrValue(p));
 
   // Test that arrays can be constructed through ImplicitConvert.
   let c_t = ctypes.int32_t.array(6);
   let c = c_t();
   c.value = [1, 2, 3, 4, 5, 6];
   do_check_eq(c.toSource(), "ctypes.int32_t.array(6)([1, 2, 3, 4, 5, 6])");
   do_check_eq(c.toSource(), c.toString());
-  eval("var c2 = " + c.toSource());
+  var c2 = eval(c.toSource());
   do_check_eq(c2.constructor.name, "int32_t[6]");
   do_check_eq(c2.length, 6);
   do_check_eq(c2[3], c[3]);
 
   c.value = c;
   do_check_eq(c[3], 4);
   do_check_throws(function() { c.value; }, TypeError);
   do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, TypeError);
--- a/toolkit/components/downloads/test/unit/head_download_manager.js
+++ b/toolkit/components/downloads/test/unit/head_download_manager.js
@@ -11,15 +11,17 @@ var Cr = Components.results;
 
 do_get_profile();
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://testing-common/httpd.js");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Task",
+                                  "resource://gre/modules/Task.jsm");
 
 function createURI(aObj) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) :
                                         ios.newURI(aObj, null, null);
 }
deleted file mode 100644
--- a/toolkit/components/downloads/test/unit/tail_download_manager.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Provides infrastructure for automated download components tests.
- */
-
-"use strict";
-
-// Termination functions common to all tests
-
-add_task(function* test_common_terminate() {
-  // Stop the HTTP server.  We must do this inside a task in "tail.js" until the
-  // xpcshell testing framework supports asynchronous termination functions.
-  let deferred = Promise.defer();
-  gHttpServer.stop(deferred.resolve);
-  yield deferred.promise;
-});
-
--- a/toolkit/components/downloads/test/unit/test_app_rep.js
+++ b/toolkit/components/downloads/test/unit/test_app_rep.js
@@ -84,16 +84,24 @@ add_task(function* test_setup() {
   });
 
   gHttpServ = new HttpServer();
   gHttpServ.registerDirectory("/", do_get_cwd());
   gHttpServ.registerPathHandler("/download", function(request, response) {
     do_throw("This test should never make a remote lookup");
   });
   gHttpServ.start(4444);
+
+  do_register_cleanup(function() {
+    return Task.spawn(function* () {
+      yield new Promise(resolve => {
+        gHttpServ.stop(resolve);
+      });
+    });
+  });
 });
 
 function run_test() {
   run_next_test();
 }
 
 function check_telemetry(aCount,
                          aShouldBlockCount,
--- a/toolkit/components/downloads/test/unit/test_app_rep_maclinux.js
+++ b/toolkit/components/downloads/test/unit/test_app_rep_maclinux.js
@@ -136,16 +136,24 @@ add_task(function test_setup() {
     } else if (buf.length == 73) {
       // mozilla.com
       blob = createVerdict(false);
     }
     response.bodyOutputStream.write(blob, blob.length);
   });
 
   gHttpServer.start(4444);
+
+  do_register_cleanup(function() {
+    return Task.spawn(function* () {
+      yield new Promise(resolve => {
+        gHttpServer.stop(resolve);
+      });
+    });
+  });
 });
 
 // Construct a response with redirect urls.
 function processUpdateRequest() {
   let response = "n:1000\n";
   for (let table in gTables) {
     response += "i:" + table + "\n";
     for (let i = 0; i < gTables[table].length; ++i) {
--- a/toolkit/components/downloads/test/unit/test_app_rep_windows.js
+++ b/toolkit/components/downloads/test/unit/test_app_rep_windows.js
@@ -13,18 +13,16 @@
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
-                                  "resource://gre/modules/Task.jsm");
 
 const BackgroundFileSaverOutputStream = Components.Constructor(
       "@mozilla.org/network/background-file-saver;1?mode=outputstream",
       "nsIBackgroundFileSaver");
 
 const StringInputStream = Components.Constructor(
       "@mozilla.org/io/string-input-stream;1",
       "nsIStringInputStream",
@@ -117,17 +115,17 @@ function promiseCopyToSaver(aSourceStrin
   copier.init(inputStream, aSaverOutputStream, null, false, true, 0x8000, true,
               aCloseWhenDone);
   copier.asyncCopy({
     onStartRequest() { },
     onStopRequest(aRequest, aContext, aStatusCode) {
       if (Components.isSuccessCode(aStatusCode)) {
         deferred.resolve();
       } else {
-        deferred.reject(new Components.Exception(aResult));
+        deferred.reject(new Components.Exception(aStatusCode));
       }
     },
   }, null);
   return deferred.promise;
 }
 
 // Registers a table for which to serve update chunks.
 function registerTableUpdate(aTable, aFilename) {
@@ -233,16 +231,24 @@ add_task(function* test_setup() {
     } else if (buf.length == 73) {
       // mozilla.com
       blob = createVerdict(false);
     }
     response.bodyOutputStream.write(blob, blob.length);
   });
 
   gHttpServer.start(4444);
+
+  do_register_cleanup(function() {
+    return Task.spawn(function* () {
+      yield new Promise(resolve => {
+        gHttpServer.stop(resolve);
+      });
+    });
+  });
 });
 
 // Construct a response with redirect urls.
 function processUpdateRequest() {
   let response = "n:1000\n";
   for (let table in gTables) {
     response += "i:" + table + "\n";
     for (let i = 0; i < gTables[table].length; ++i) {
--- a/toolkit/components/downloads/test/unit/xpcshell.ini
+++ b/toolkit/components/downloads/test/unit/xpcshell.ini
@@ -1,11 +1,10 @@
 [DEFAULT]
 head = head_download_manager.js
-tail = tail_download_manager.js
 skip-if = toolkit == 'android'
 support-files =
   data/digest.chunk
   data/block_digest.chunk
   data/signed_win.exe
 
 [test_app_rep.js]
 [test_app_rep_windows.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/formautofill/test/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
--- a/toolkit/components/formautofill/test/browser/head.js
+++ b/toolkit/components/formautofill/test/browser/head.js
@@ -1,15 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*
  * Initialization specific to Form Autofill mochitest-browser tests.
  */
 
+/* import-globals-from loader.js */
+
 "use strict";
 
 // We cannot start initialization from "loader.js" like we do in the xpcshell
 // and mochitest-chrome frameworks, thus we load the script here.
 Services.scriptloader.loadSubScript(getRootDirectory(gTestPath) + "loader.js",
                                     this);
 
 // The testing framework is fully initialized at this point, you can add
--- a/toolkit/components/formautofill/test/browser/loader.js
+++ b/toolkit/components/formautofill/test/browser/loader.js
@@ -7,16 +7,22 @@
  * See "loader_common.js" in the parent folder for a general overview.
  *
  * Unless you are adding new features to the framework, you shouldn't have to
  * modify this file.  Use "head_common.js" or "head.js" for shared code.
  */
 
 "use strict";
 
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+Cu.import("resource://gre/modules/Services.jsm", this);
+
+/* import-globals-from ../loader_common.js */
 Services.scriptloader.loadSubScript(getRootDirectory(gTestPath) +
                                     "loader_common.js", this);
 
 // Define output functions so they look the same across all frameworks.
 var Output = {
   print: info,
 };
 
@@ -26,13 +32,14 @@ var Assert = {
   equal: _mochitestAssert.equal,
 };
 
 // Define task registration functions, see description in "loader_common.js".
 var add_task_in_parent_process = add_task;
 var add_task_in_child_process = function() {};
 var add_task_in_both_processes = add_task;
 
+/* import-globals-from ../head_common.js */
 Services.scriptloader.loadSubScript(getRootDirectory(gTestPath) +
                                     "head_common.js", this);
 
 // Reminder: unless you are adding new features to the framework, you shouldn't
 // have to modify this file.  Use "head_common.js" or "head.js" for shared code.
--- a/toolkit/components/formautofill/test/chrome/head.js
+++ b/toolkit/components/formautofill/test/chrome/head.js
@@ -2,14 +2,16 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*
  * Initialization specific to Form Autofill mochitest-chrome tests.
  *
  * This file is loaded by "loader.js".
  */
 
+/* import-globals-from loader.js */
+
 "use strict";
 
 // The testing framework is fully initialized at this point, you can add
 // mochitest-chrome specific test initialization here.  If you need shared
 // functions or initialization that are not specific to mochitest-chrome,
 // consider adding them to "head_common.js" in the parent folder instead.
--- a/toolkit/components/formautofill/test/chrome/loader.js
+++ b/toolkit/components/formautofill/test/chrome/loader.js
@@ -15,16 +15,17 @@
 var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 Services.scriptloader.loadSubScript(
   "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js", this);
 
+/* import-globals-from ../loader_common.js */
 var sharedUrl = SimpleTest.getTestFileURL("loader_common.js");
 Services.scriptloader.loadSubScript(sharedUrl, this);
 
 var parentScript = SpecialPowers.loadChromeScript(
                                  SimpleTest.getTestFileURL("loader_parent.js"));
 
 // Replace the extension of the loaded HTML file with ".js"
 var testUrl = location.href.replace(/\.\w+$/, ".js");
@@ -95,16 +96,17 @@ window.addEventListener("load", function
 });
 
 // Wait for the test script to be loaded in the parent process.  This means that
 // test tasks are registered and ready, but have not been executed yet.
 add_task(function* wait_loading_in_parent_process() {
   yield promiseParentInitFinished;
 });
 
+/* import-globals-from ../head_common.js */
 var headUrl = SimpleTest.getTestFileURL("head_common.js");
 Services.scriptloader.loadSubScript(headUrl, this);
 
 Output.print("Loading test file: " + testUrl);
 Services.scriptloader.loadSubScript(testUrl, this);
 
 // Register the execution of termination tasks after all other tasks.
 add_task(terminationTaskFn);
--- a/toolkit/components/formautofill/test/chrome/loader_parent.js
+++ b/toolkit/components/formautofill/test/chrome/loader_parent.js
@@ -13,16 +13,17 @@
 
 "use strict";
 
 var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 
+/* import-globals-from ../loader_common.js */
 var sharedUrl = "chrome://mochitests/content/chrome/" +
                 "toolkit/components/formautofill/test/chrome/loader_common.js";
 Services.scriptloader.loadSubScript(sharedUrl, this);
 
 // Define output functions so they look the same across all frameworks.  Since
 // we don't have an output function available here, we report as TEST-PASS.
 var Output = {
   print: message => assert.ok(true, message),
@@ -55,16 +56,17 @@ var add_task = function() {};
 var add_task_in_child_process = function() {};
 var add_task_in_both_processes = add_task_in_parent_process;
 
 // We need to wait for the child process to send us the path of the test file
 // to load before we can actually start loading it.
 var context = this;
 addMessageListener("start_load_in_parent", function(message) {
   Output.print("Starting loading infrastructure in parent process.");
+  /* import-globals-from ../head_common.js */
   let headUrl = "chrome://mochitests/content/chrome/" +
                 "toolkit/components/formautofill/test/chrome/head_common.js";
   Services.scriptloader.loadSubScript(headUrl, context);
 
   Services.scriptloader.loadSubScript(message.testUrl, context);
 
   // Register the execution of termination tasks after all other tasks.
   add_task_in_parent_process(terminationTaskFn, terminationTaskFn.name);
--- a/toolkit/components/formautofill/test/chrome/test_infrastructure.js
+++ b/toolkit/components/formautofill/test/chrome/test_infrastructure.js
@@ -2,16 +2,18 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*
  * Tests the local testing infrastructure.
  */
 
 "use strict";
 
+/* import-globals-from loader.js */
+
 /**
  * Tests the truth assertion function.
  */
 add_task(function* test_assert_truth() {
   Assert.ok(1 != 2);
 });
 
 /**
--- a/toolkit/components/formautofill/test/chrome/test_requestAutocomplete_cancel.js
+++ b/toolkit/components/formautofill/test/chrome/test_requestAutocomplete_cancel.js
@@ -2,16 +2,18 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*
  * Tests the response sent when requestAutocomplete is canceled by the user.
  */
 
 "use strict";
 
+/* import-globals-from loader.js */
+
 /**
  * The requestAutocomplete UI will not be displayed during these tests.
  */
 add_task_in_parent_process(function* test_cancel_init() {
   FormAutofillTest.requestAutocompleteResponse = { canceled: true };
 });
 
 /**
--- a/toolkit/components/formautofill/test/head_common.js
+++ b/toolkit/components/formautofill/test/head_common.js
@@ -2,18 +2,24 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*
  * Initialization of Form Autofill tests shared between all frameworks.
  *
  * A copy of this file is installed in each of the framework subfolders, this
  * means it becomes a sibling of the test files in the final layout.  This is
  * determined by how manifest "support-files" installation works.
+ *
+ * This file expects the globals below to be defined in the scope it is
+ * imported into.
  */
 
+ /* global add_termination_task, add_task_in_both_processes,
+           add_task_in_parent_process, Output */
+
 "use strict";
 
 // The requestAutocomplete framework is available at this point, you can add
 // mochitest-chrome specific test initialization here.  If you need shared
 // functions or initialization that are not specific to mochitest-chrome,
 // consider adding them to "head_common.js" in the parent folder instead.
 
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths",
--- a/toolkit/components/formautofill/test/loader_common.js
+++ b/toolkit/components/formautofill/test/loader_common.js
@@ -6,20 +6,25 @@
  *
  * A copy of this file is installed in each of the framework subfolders, this
  * means it becomes a sibling of the test files in the final layout.  This is
  * determined by how manifest "support-files" installation works.
  *
  * Unless you are adding new features to the framework, you shouldn't have to
  * modify this file.  Use "head_common.js" or the "head.js" file of each
  * framework for shared code.
+ *
+ * This file expects Services & XPCOMUtils to be defined in the scope it is imported
+ * into. Additionally, it expects "Output" to be defined as well.
  */
 
 "use strict";
 
+/* global XPCOMUtils, Services, Output */
+
 /*
  * --------------------
  *  FRAMEWORK OVERVIEW
  * --------------------
  *
  * This framework is designed in such a way that test can be written in similar
  * ways in the xpcshell, mochitest-chrome, and mochitest-browser frameworks,
  * both when tests are running in the parent process or in a content process.
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -1,13 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// It is expected that the test files importing this file define Cu etc.
+/* global Cu, Ci, Cc, Cr */
+
 const CURRENT_SCHEMA_VERSION = 36;
 const FIRST_UPGRADABLE_SCHEMA_VERSION = 11;
 
 const NS_APP_USER_PROFILE_50_DIR = "ProfD";
 const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
 
 // Shortcuts to transitions type.
 const TRANSITION_LINK = Ci.nsINavHistoryService.TRANSITION_LINK;
--- a/toolkit/components/printing/content/printjoboptions.js
+++ b/toolkit/components/printing/content/printjoboptions.js
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var dialog;
 var gPrintBundle;
 var gPrintSettings = null;
 var gPrintSettingsInterface  = Components.interfaces.nsIPrintSettings;
 var gPaperArray;
 var gPrefs;
+var gParamBlock;
 
 var gPrintSetInterface = Components.interfaces.nsIPrintSettings;
 var doDebug            = true;
 
 // ---------------------------------------------------
 function checkDouble(element, maxVal) {
   var value = element.value;
   if (value && value.length > 0) {
@@ -305,25 +306,25 @@ function loadDialog() {
 }
 
 // ---------------------------------------------------
 function onLoad() {
   // Init dialog.
   initDialog();
 
   gPrintSettings = window.arguments[0].QueryInterface(gPrintSetInterface);
-  paramBlock = window.arguments[1].QueryInterface(Components.interfaces.nsIDialogParamBlock);
+  gParamBlock = window.arguments[1].QueryInterface(Components.interfaces.nsIDialogParamBlock);
 
   if (doDebug) {
     if (gPrintSettings == null) alert("PrintSettings is null!");
-    if (paramBlock == null) alert("nsIDialogParam is null!");
+    if (gParamBlock == null) alert("nsIDialogParam is null!");
   }
 
   // default return value is "cancel"
-  paramBlock.SetInt(0, 0);
+  gParamBlock.SetInt(0, 0);
 
   loadDialog();
 }
 
 // ---------------------------------------------------
 function onAccept() {
   var print_paper_unit        = gPrintSettingsInterface.kPaperSizeInches;
   var print_paper_width       = 0.0;
@@ -363,17 +364,17 @@ function onAccept() {
       dump("paperName       '" + print_paper_name + "'\n");
 
       dump("printInColor     " + gPrintSettings.printInColor + "\n");
     }
   } else {
     dump("************ onAccept gPrintSettings: " + gPrintSettings + "\n");
   }
 
-  if (paramBlock) {
+  if (gParamBlock) {
     // set return value to "ok"
-    paramBlock.SetInt(0, 1);
+    gParamBlock.SetInt(0, 1);
   } else {
     dump("*** FATAL ERROR: paramBlock missing\n");
   }
 
   return true;
 }
--- a/toolkit/components/viewsource/content/viewPartialSource.js
+++ b/toolkit/components/viewsource/content/viewPartialSource.js
@@ -1,14 +1,16 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* import-globals-from viewSource.js */
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function onLoadViewPartialSource() {
   // check the view_source.wrap_long_lines pref
   // and set the menuitem's checked attribute accordingly
   let wrapLongLines = Services.prefs.getBoolPref("view_source.wrap_long_lines");
   document.getElementById("menu_wrapLongLines")
           .setAttribute("checked", wrapLongLines);
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/mochitest/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../testing/mochitest/mochitest.eslintrc.js"
+  ]
+};
--- a/toolkit/crashreporter/test/unit/head_crashreporter.js
+++ b/toolkit/crashreporter/test/unit/head_crashreporter.js
@@ -151,16 +151,19 @@ function do_content_crash(setup, callbac
 
   // Setting the minidump path won't work in the child, so we need to do
   // that here.
   let crashReporter =
       Components.classes["@mozilla.org/toolkit/crash-reporter;1"]
                 .getService(Components.interfaces.nsICrashReporter);
   crashReporter.minidumpPath = do_get_tempdir();
 
+  /* import-globals-from ../unit/crasher_subprocess_head.js */
+  /* import-globals-from ../unit/crasher_subprocess_tail.js */
+
   let headfile = do_get_file("../unit/crasher_subprocess_head.js");
   let tailfile = do_get_file("../unit/crasher_subprocess_tail.js");
   if (setup) {
     if (typeof(setup) == "function") {
       // funky, but convenient
       setup = "(" + setup.toSource() + ")();";
     }
   }
--- a/toolkit/crashreporter/test/unit/test_crash_AsyncShutdown.js
+++ b/toolkit/crashreporter/test/unit/test_crash_AsyncShutdown.js
@@ -1,14 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that AsyncShutdown report errors correctly
 
+// Note: these functions are evaluated in their own process, hence the need
+// to import modules into each function.
+
 function setup_crash() {
+  /* global AsyncShutdown */
   Components.utils.import("resource://gre/modules/AsyncShutdown.jsm", this);
   Components.utils.import("resource://gre/modules/Services.jsm", this);
   Components.utils.import("resource://gre/modules/Promise.jsm", this);
 
   Services.prefs.setBoolPref("toolkit.asyncshutdown.testing", true);
   Services.prefs.setIntPref("toolkit.asyncshutdown.crash_timeout", 10);
 
   let TOPIC = "testing-async-shutdown-crash";
--- a/toolkit/crashreporter/test/unit_ipc/test_content_annotation.js
+++ b/toolkit/crashreporter/test/unit_ipc/test_content_annotation.js
@@ -1,8 +1,9 @@
+/* import-globals-from ../unit/head_crashreporter.js */
 load("../unit/head_crashreporter.js");
 
 function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
     dump("INFO | test_content_annotation.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
--- a/toolkit/crashreporter/test/unit_ipc/test_content_exception_time_annotation.js
+++ b/toolkit/crashreporter/test/unit_ipc/test_content_exception_time_annotation.js
@@ -1,8 +1,9 @@
+/* import-globals-from ../unit/head_crashreporter.js */
 load("../unit/head_crashreporter.js");
 
 function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
     dump("INFO | test_content_annotation.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
--- a/toolkit/crashreporter/test/unit_ipc/test_content_memory_list.js
+++ b/toolkit/crashreporter/test/unit_ipc/test_content_memory_list.js
@@ -1,11 +1,12 @@
 // Any copyright is dedicated to the Public Domain.
 // http://creativecommons.org/publicdomain/zero/1.0/
 
+/* import-globals-from ../unit/head_crashreporter.js */
 load("../unit/head_crashreporter.js");
 
 function run_test() {
   var is_win7_or_newer = false;
   var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"]
              .getService(Components.interfaces.nsIHttpProtocolHandler);
   var match = ph.userAgent.match(/Windows NT (\d+).(\d+)/);
   if (match && (parseInt(match[1]) > 6 ||
--- a/toolkit/crashreporter/test/unit_ipc/test_content_oom_annotation_windows.js
+++ b/toolkit/crashreporter/test/unit_ipc/test_content_oom_annotation_windows.js
@@ -1,8 +1,9 @@
+/* import-globals-from ../unit/head_crashreporter.js */
 load("../unit/head_crashreporter.js");
 
 function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
     dump("INFO | test_content_annotation.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
--- a/toolkit/forgetaboutsite/ForgetAboutSite.jsm
+++ b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
@@ -180,17 +180,17 @@ this.ForgetAboutSite = {
 
     // Predictive network data - like cache, no way to clear this per
     // domain, so just trash it all
     let np = Cc["@mozilla.org/network/predictor;1"].
              getService(Ci.nsINetworkPredictor);
     np.reset();
 
     // Push notifications.
-    promises.push(new Promise(resolve => {
+    promises.push(new Promise((resolve, reject) => {
       var push = Cc["@mozilla.org/push/Service;1"]
                   .getService(Ci.nsIPushService);
       push.clearForDomain(aDomain, status => {
         (Components.isSuccessCode(status) ? resolve : reject)(status);
       });
     }).catch(e => {
       Cu.reportError("Exception thrown while clearing Push notifications: " +
                      e.toString());
--- a/toolkit/forgetaboutsite/test/unit/head_forgetaboutsite.js
+++ b/toolkit/forgetaboutsite/test/unit/head_forgetaboutsite.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* import-globals-from ../../../../dom/push/test/xpcshell/head.js */
+
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 
 var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
 var profileDir = do_get_profile();
 
 /**
--- a/toolkit/modules/Log.jsm
+++ b/toolkit/modules/Log.jsm
@@ -92,33 +92,33 @@ this.Log = {
 
   ParameterFormatter,
   // Logging helper:
   // let logger = Log.repository.getLogger("foo");
   // logger.info(Log.enumerateInterfaces(someObject).join(","));
   enumerateInterfaces: function Log_enumerateInterfaces(aObject) {
     let interfaces = [];
 
-    for (i in Ci) {
+    for (let i in Ci) {
       try {
         aObject.QueryInterface(Ci[i]);
         interfaces.push(i);
       } catch (ex) {}
     }
 
     return interfaces;
   },
 
   // Logging helper:
   // let logger = Log.repository.getLogger("foo");
   // logger.info(Log.enumerateProperties(someObject).join(","));
   enumerateProperties(aObject, aExcludeComplexTypes) {
     let properties = [];
 
-    for (p in aObject) {
+    for (let p in aObject) {
       try {
         if (aExcludeComplexTypes &&
             (typeof(aObject[p]) == "object" || typeof(aObject[p]) == "function"))
           continue;
         properties.push(p + " = " + aObject[p]);
       } catch (ex) {
         properties.push(p + " = " + ex);
       }
@@ -956,9 +956,8 @@ BoundedFileAppender.prototype = {
 
     return fileClosePromise.then(_ => {
       this._size = 0;
       this._file = null;
       return OS.File.remove(this._path);
     });
   }
 };
-
--- a/toolkit/modules/SpatialNavigation.jsm
+++ b/toolkit/modules/SpatialNavigation.jsm
@@ -30,17 +30,17 @@ var SpatialNavigation = {
 };
 
 // Private stuff
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-Cu["import"]("resource://gre/modules/Services.jsm", this);
+Cu.import("resource://gre/modules/Services.jsm", this);
 
 var eventListenerService = Cc["@mozilla.org/eventlistenerservice;1"]
                              .getService(Ci.nsIEventListenerService);
 var focusManager         = Cc["@mozilla.org/focus-manager;1"]
                              .getService(Ci.nsIFocusManager);
 var windowMediator       = Cc['@mozilla.org/appshell/window-mediator;1']
                              .getService(Ci.nsIWindowMediator);
 
--- a/toolkit/modules/tests/xpcshell/test_JSONFile.js
+++ b/toolkit/modules/tests/xpcshell/test_JSONFile.js
@@ -292,12 +292,12 @@ add_task(function* test_beforeSave_rejec
   let promiseSave = new Promise((resolve, reject) => {
     let save = storeForSave._save.bind(storeForSave);
     storeForSave._save = () => {
       save().then(resolve, reject);
     };
     storeForSave.saveSoon();
   });
 
-  yield rejects(promiseSave, function(ex) {
+  yield Assert.rejects(promiseSave, function(ex) {
     return ex.message == "oops";
   });
 });
--- a/toolkit/modules/tests/xpcshell/test_Log.js
+++ b/toolkit/modules/tests/xpcshell/test_Log.js
@@ -500,17 +500,17 @@ add_task(function* test_log_err_only() {
    * log.error(null, err) by the logMessage constructor; the formatMessage()
    * tests above ensure that the combination of null text and an error object
    * is formatted correctly.
    */
   try {
     eval("javascript syntax error");
   } catch (e) {
     log.error(e);
-    msg = appender.messages.pop();
+    let msg = appender.messages.pop();
     do_check_eq(msg.message, null);
     do_check_eq(msg.params, e);
   }
 });
 
 /*
  * Test logStructured() messages through basic formatter.
  */
@@ -562,18 +562,18 @@ add_task(function* log_message_with_para
 
 /*
  * Check that we format JS Errors reasonably.
  */
 add_task(function* format_errors() {
   let pFormat = new Log.ParameterFormatter();
 
   // Test that subclasses of Error are recognized as errors.
-  err = new ReferenceError("Ref Error", "ERROR_FILE", 28);
-  str = pFormat.format(err);
+  let err = new ReferenceError("Ref Error", "ERROR_FILE", 28);
+  let str = pFormat.format(err);
   do_check_true(str.includes("ReferenceError"));
   do_check_true(str.includes("ERROR_FILE:28"));
   do_check_true(str.includes("Ref Error"));
 
   // Test that JS-generated Errors are recognized and formatted.
   try {
     yield Promise.resolve();  // Scrambles the stack
     eval("javascript syntax error");
--- a/toolkit/xre/test/test_fpuhandler.html
+++ b/toolkit/xre/test/test_fpuhandler.html
@@ -7,17 +7,17 @@
 
   <script class="testbody" type="application/javascript">
   SimpleTest.waitForExplicitFinish();
 
   function doDiv(x, y) {
     var z;
     z = x / y;
 
-    for (i = 0 + x; i < 1000; ++i)
+    for (let i = 0 + x; i < 1000; ++i)
       z = y / x;
 
     z = x / y;
     return z;
   }
 
   function runTest() {
     ok(isNaN(doDiv(0.0, 0.0)), "Undefined division-by-zero doesn't crash");