Merge inbound to mozilla-central. a=merge
authorBogdan Tara <btara@mozilla.com>
Thu, 20 Sep 2018 00:58:18 +0300
changeset 493067 9812141ec782
parent 493020 e04795eb82f2 (current diff)
parent 493066 c6289939c72c (diff)
child 493068 d2e41f2f964d
child 493086 e64c21de36b7
child 493103 b37e4fe538bf
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
9812141ec782 / 64.0a1 / 20180919220108 / files
nightly linux64
9812141ec782 / 64.0a1 / 20180919220108 / files
nightly mac
9812141ec782 / 64.0a1 / 20180919220108 / files
nightly win32
9812141ec782 / 64.0a1 / 20180919220108 / files
nightly win64
9812141ec782 / 64.0a1 / 20180919220108 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
browser/components/newtab/lib/SnippetsFeed.jsm
testing/web-platform/tests/webdriver/tests/actions/bounds.py
--- a/accessible/generic/HyperTextAccessible-inl.h
+++ b/accessible/generic/HyperTextAccessible-inl.h
@@ -51,30 +51,28 @@ HyperTextAccessible::AddToSelection(int3
   dom::Selection* domSel = DOMSelection();
   return domSel &&
     SetSelectionBoundsAt(domSel->RangeCount(), aStartOffset, aEndOffset);
 }
 
 inline void
 HyperTextAccessible::ReplaceText(const nsAString& aText)
 {
-  // We need to call DeleteText() even if there is no contents because we need
-  // to ensure to move focus to the editor via SetSelectionRange() called in
-  // DeleteText().
-  DeleteText(0, CharacterCount());
+  if (aText.Length() == 0) {
+    DeleteText(0, CharacterCount());
+    return;
+  }
+
+  SetSelectionRange(0, CharacterCount());
 
   RefPtr<TextEditor> textEditor = GetEditor();
   if (!textEditor) {
     return;
   }
 
-  // DeleteText() may cause inserting <br> element in some cases. Let's
-  // select all again and replace whole contents.
-  textEditor->SelectAll();
-
   DebugOnly<nsresult> rv = textEditor->InsertTextAsAction(aText);
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert the new text");
 }
 
 inline void
 HyperTextAccessible::InsertText(const nsAString& aText, int32_t aPosition)
 {
   RefPtr<TextEditor> textEditor = GetEditor();
--- a/accessible/tests/browser/events/browser_test_focus_browserui.js
+++ b/accessible/tests/browser/events/browser_test_focus_browserui.js
@@ -11,18 +11,20 @@ loadScripts({ name: "states.js", dir: MO
 
 async function runTests(browser, accDoc) {
   let onFocus = waitForEvent(EVENT_FOCUS, "input");
   EventUtils.synthesizeKey("VK_TAB", {}, browser.ownerGlobal);
   let evt = await onFocus;
   testStates(evt.accessible, STATE_FOCUSED);
 
   onFocus = waitForEvent(EVENT_FOCUS, "buttonInputDoc");
-  browser.loadURI(snippetToURL(
-    `<input id="input" type="button" value="button">`, { id: "buttonInputDoc" }));
+  let url = snippetToURL(`<input id="input" type="button" value="button">`, { id: "buttonInputDoc" });
+  browser.loadURI(url, {
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
+  });
   evt = await onFocus;
   testStates(evt.accessible, STATE_FOCUSED);
 
   onFocus = waitForEvent(EVENT_FOCUS, "input");
   browser.goBack();
   evt = await onFocus;
   testStates(evt.accessible, STATE_FOCUSED);
 
--- a/accessible/tests/browser/events/browser_test_textcaret.js
+++ b/accessible/tests/browser/events/browser_test_textcaret.js
@@ -11,17 +11,17 @@ function caretMoveChecker(target, caretO
     let cmEvent = event.QueryInterface(nsIAccessibleCaretMoveEvent);
     return cmEvent.accessible == getAccessible(target) && cmEvent.caretOffset == caretOffset;
   };
 }
 
 async function checkURLBarCaretEvents() {
   const kURL = "about:mozilla";
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
-  newWin.gBrowser.selectedBrowser.loadURI(kURL);
+  BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, kURL);
 
   await waitForEvent(
     EVENT_DOCUMENT_LOAD_COMPLETE,
     event => {
       try {
         return event.accessible.QueryInterface(nsIAccessibleDocument).URL == kURL;
       } catch (e) {
         return false;
--- a/accessible/tests/mochitest/events/test_scroll.xul
+++ b/accessible/tests/mochitest/events/test_scroll.xul
@@ -38,17 +38,19 @@
     {
       this.eventSeq = [
         new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
         new asyncInvokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument)
       ];
 
       this.invoke = function loadTab_invoke()
       {
-        tabBrowser().loadURI(aURL);
+        tabBrowser().loadURI(aURL, {
+          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        });
       }
 
       this.getID = function loadTab_getID()
       {
         return "load tab: " + aURL;
       }
     }
 
--- a/accessible/tests/mochitest/events/test_scroll_caret.xul
+++ b/accessible/tests/mochitest/events/test_scroll_caret.xul
@@ -38,17 +38,19 @@
     {
       this.eventSeq = [
         new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
         new asyncCaretMoveChecker(0, getAnchorJumpInTabDocument)
       ];
 
       this.invoke = function loadTab_invoke()
       {
-        tabBrowser().loadURI(aURL);
+        tabBrowser().loadURI(aURL, {
+          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        });
       }
 
       this.getID = function loadTab_getID()
       {
         return "load tab: " + aURL;
       }
     }
 
--- a/accessible/tests/mochitest/relations/test_embeds.xul
+++ b/accessible/tests/mochitest/relations/test_embeds.xul
@@ -28,17 +28,19 @@
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
 
     function loadURI(aURI)
     {
       this.invoke = function loadURI_invoke()
       {
-        tabBrowser().loadURI(aURI);
+        tabBrowser().loadURI(aURI, {
+          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        });
       }
 
       this.eventSeq = [
         new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
       ];
 
       this.finalCheck = function loadURI_finalCheck()
       {
--- a/accessible/tests/mochitest/text/a11y.ini
+++ b/accessible/tests/mochitest/text/a11y.ini
@@ -7,10 +7,11 @@ support-files = doc.html
 [test_doc.html]
 [test_dynamic.html]
 [test_general.xul]
 [test_gettext.html]
 [test_hypertext.html]
 [test_lineboundary.html]
 [test_passwords.html]
 [test_selection.html]
+[test_settext_input_event.html]
 [test_wordboundary.html]
 [test_words.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_settext_input_event.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test that setTextContents only sends one DOM input event</title>
+  <meta charset="utf-8" />
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript">
+    async function doTest() {
+      let input = getAccessible("input", [nsIAccessibleEditableText]);
+      let eventPromise = new Promise(resolve =>
+        document.getElementById("input").addEventListener(
+          "input", resolve, { once: true }));
+
+      input.setTextContents("goodbye");
+      let inputEvent = await eventPromise;
+      is(inputEvent.target.value, "goodbye", "input set to new value.");
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="HyperTextAccessible::ReplaceText causes two distinct DOM 'input' events"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=1490840">Mozilla Bug 1490840</a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <input id="input" value="hello">
+</body>
+</html>
--- a/browser/actors/BlockedSiteChild.jsm
+++ b/browser/actors/BlockedSiteChild.jsm
@@ -3,16 +3,18 @@
  * 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/. */
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var EXPORTED_SYMBOLS = ["BlockedSiteChild"];
 
 ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
+ChromeUtils.defineModuleGetter(this, "Utils",
+  "resource://gre/modules/sessionstore/Utils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "SafeBrowsing",
                                "resource://gre/modules/SafeBrowsing.jsm");
 
 function getSiteBlockedErrorDetails(docShell) {
   let blockedInfo = {};
   if (docShell.failedChannel) {
     let classifiedChannel = docShell.failedChannel.
@@ -24,17 +26,19 @@ function getSiteBlockedErrorDetails(docS
 
       // Remove the query to avoid leaking sensitive data
       if (reportUri instanceof Ci.nsIURL) {
         reportUri = reportUri.mutate()
                              .setQuery("")
                              .finalize();
       }
 
+      let triggeringPrincipal = docShell.failedChannel.loadInfo ? Utils.serializePrincipal(docShell.failedChannel.loadInfo.triggeringPrincipal) : null;
       blockedInfo = { list: classifiedChannel.matchedList,
+                      triggeringPrincipal,
                       provider: classifiedChannel.matchedProvider,
                       uri: reportUri.asciiSpec };
     }
   }
   return blockedInfo;
 }
 
 class BlockedSiteChild extends ActorChild {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1004,16 +1004,28 @@ function handleUriInChrome(aBrowser, aUr
     } catch (e) {
       return false;
     }
   }
 
   return false;
 }
 
+/* Creates a null principal using the userContextId
+   from the current selected tab or a passed in tab argument */
+function _createNullPrincipalFromTabUserContextId(tab = gBrowser.selectedTab) {
+  let userContextId;
+  if (tab.hasAttribute("usercontextid")) {
+    userContextId = tab.getAttribute("usercontextid");
+  }
+  return Services.scriptSecurityManager.createNullPrincipal({
+    userContextId,
+  });
+}
+
 // A shared function used by both remote and non-remote browser XBL bindings to
 // load a URI or redirect it to the correct process.
 function _loadURI(browser, uri, params = {}) {
   let tab = gBrowser.getTabForBrowser(browser);
   // Preloaded browsers don't have tabs, so we ignore those.
   if (tab) {
     maybeRecordAbandonmentTelemetry(tab, "newURI");
   }
@@ -1026,16 +1038,20 @@ function _loadURI(browser, uri, params =
     flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
     referrerURI,
     referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
     triggeringPrincipal,
     postData,
     userContextId,
   } = params || {};
 
+  if (!triggeringPrincipal) {
+    throw new Error("Must load with a triggering Principal");
+  }
+
   let {
     uriObject,
     requiredRemoteType,
     mustChangeProcess,
     newFrameloader,
   } = E10SUtils.shouldLoadURIInBrowser(browser, uri, gMultiProcessBrowser,
                                        flags);
   if (uriObject && handleUriInChrome(browser, uriObject)) {
@@ -2394,16 +2410,20 @@ function BrowserCloseTabOrWindow(event) 
 function BrowserTryToCloseWindow() {
   if (WindowIsClosing())
     window.close(); // WindowIsClosing does all the necessary checks
 }
 
 function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
                  userContextId, originPrincipal, forceAboutBlankViewerInCurrent,
                  triggeringPrincipal, allowInheritPrincipal = false) {
+  if (!triggeringPrincipal) {
+    throw new Error("Must load with a triggering Principal");
+  }
+
   try {
     openLinkIn(uri, "current",
                { referrerURI: referrer,
                  referrerPolicy,
                  postData,
                  allowThirdPartyFixup,
                  userContextId,
                  originPrincipal,
@@ -3135,20 +3155,22 @@ var BrowserOnClick = {
           }
           this.ignoreWarningLink(reason, blockedInfo);
         }
         break;
     }
   },
 
   ignoreWarningLink(reason, blockedInfo) {
+    let triggeringPrincipal = Utils.deserializePrincipal(blockedInfo.triggeringPrincipal) || _createNullPrincipalFromTabUserContextId();
     // Allow users to override and continue through to the site,
     // but add a notify bar as a reminder, so that they don't lose
     // track after, e.g., tab switching.
     gBrowser.loadURI(gBrowser.currentURI.spec, {
+      triggeringPrincipal,
       flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
     });
 
     Services.perms.add(gBrowser.currentURI, "safe-browsing",
                        Ci.nsIPermissionManager.ALLOW_ACTION,
                        Ci.nsIPermissionManager.EXPIRE_SESSION);
 
     let buttons = [{
@@ -3203,33 +3225,37 @@ var BrowserOnClick = {
 /**
  * Re-direct the browser to a known-safe page.  This function is
  * used when, for example, the user browses to a known malware page
  * and is presented with about:blocked.  The "Get me out of here!"
  * button should take the user to the default start page so that even
  * when their own homepage is infected, we can get them somewhere safe.
  */
 function getMeOutOfHere() {
-  gBrowser.loadURI(getDefaultHomePage());
+  gBrowser.loadURI(getDefaultHomePage(), {
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), // Also needs to load homepage
+  });
 }
 
 /**
  * Re-direct the browser to the previous page or a known-safe page if no
  * previous page is found in history.  This function is used when the user
  * browses to a secure page with certificate issues and is presented with
  * about:certerror.  The "Go Back" button should take the user to the previous
  * or a default start page so that even when their own homepage is on a server
  * that has certificate errors, we can get them somewhere safe.
  */
 function goBackFromErrorPage() {
   let state = JSON.parse(SessionStore.getTabState(gBrowser.selectedTab));
   if (state.index == 1) {
     // If the unsafe page is the first or the only one in history, go to the
     // start page.
-    gBrowser.loadURI(getDefaultHomePage());
+    gBrowser.loadURI(getDefaultHomePage(), {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
   } else {
     BrowserBack();
   }
 }
 
 /**
  * Return the default start page for the cases when the user's own homepage is
  * infected, so we can get them somewhere safe.
@@ -3255,17 +3281,20 @@ function getWebNavigation() {
 }
 
 function BrowserReloadWithFlags(reloadFlags) {
   let url = gBrowser.currentURI.spec;
   if (gBrowser.updateBrowserRemotenessByURL(gBrowser.selectedBrowser, url)) {
     // If the remoteness has changed, the new browser doesn't have any
     // information of what was loaded before, so we need to load the previous
     // URL again.
-    gBrowser.loadURI(url, { flags: reloadFlags });
+    gBrowser.loadURI(url, {
+      flags: reloadFlags,
+      triggeringPrincipal: gBrowser.selectedBrowser.contentPrincipal,
+    });
     return;
   }
 
   // Do this after the above case where we might flip remoteness.
   // Unfortunately, we'll count the remoteness flip case as a
   // "newURL" load, since we're using loadURI, but hopefully
   // that's rare enough to not matter.
   maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "reload");
@@ -7661,17 +7690,19 @@ function switchToTabHavingURI(aURI, aOpe
             window.gBrowser.tabContainer.selectedIndex + 1,
             /* aSelectTab = */ true
           );
         } else {
           aWindow.focus();
         }
 
         if (ignoreFragment == "whenComparingAndReplace" || replaceQueryString) {
-          browser.loadURI(aURI.spec);
+          browser.loadURI(aURI.spec, {
+            triggeringPrincipal: aOpenParams.triggeringPrincipal || _createNullPrincipalFromTabUserContextId(),
+          });
         }
 
         if (!doAdopt) {
           aWindow.gBrowser.tabContainer.selectedIndex = i;
         }
 
         return true;
       }
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -1787,17 +1787,19 @@ window._gBrowser = {
 
     if (remoteType != E10SUtils.NOT_REMOTE) {
       // For remote browsers, we need to make sure that the webProgress is
       // instantiated, otherwise the parent won't get informed about the state
       // of the preloaded browser until it gets attached to a tab.
       browser.webProgress;
     }
 
-    browser.loadURI(BROWSER_NEW_TAB_URL);
+    browser.loadURI(BROWSER_NEW_TAB_URL, {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
     browser.docShellIsActive = false;
     browser._urlbarFocused = true;
 
     // Make sure the preloaded browser is loaded with desired zoom level
     let tabURI = Services.io.newURI(BROWSER_NEW_TAB_URL);
     FullZoom.onLocationChange(tabURI, false, browser);
   },
 
--- a/browser/base/content/test/favicons/browser_favicon_change.js
+++ b/browser/base/content/test/favicons/browser_favicon_change.js
@@ -5,17 +5,17 @@
 
 const TEST_ROOT = "http://mochi.test:8888/browser/browser/base/content/test/favicons/";
 const TEST_URL = TEST_ROOT + "file_favicon_change.html";
 
 add_task(async function() {
   let extraTab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   let haveChanged = waitForFavicon(extraTab.linkedBrowser, TEST_ROOT + "file_bug970276_favicon1.ico");
 
-  extraTab.linkedBrowser.loadURI(TEST_URL);
+  BrowserTestUtils.loadURI(extraTab.linkedBrowser, TEST_URL);
   await BrowserTestUtils.browserLoaded(extraTab.linkedBrowser);
   await haveChanged;
 
   haveChanged = waitForFavicon(extraTab.linkedBrowser, TEST_ROOT + "moz.png");
 
   ContentTask.spawn(extraTab.linkedBrowser, null, function() {
     let ev = new content.CustomEvent("PleaseChangeFavicon", {});
     content.dispatchEvent(ev);
--- a/browser/base/content/test/favicons/browser_favicon_change_not_in_document.js
+++ b/browser/base/content/test/favicons/browser_favicon_change_not_in_document.js
@@ -22,17 +22,17 @@ add_task(async function() {
   const linkAddedHandler = event => domLinkAddedFired++;
   const linkChangedhandler = event => domLinkChangedFired++;
   BrowserTestUtils.addContentEventListener(gBrowser.selectedBrowser, "DOMLinkAdded", linkAddedHandler);
   BrowserTestUtils.addContentEventListener(gBrowser.selectedBrowser, "DOMLinkChanged", linkChangedhandler);
 
   let expectedFavicon = TEST_ROOT + "file_generic_favicon.ico";
   let faviconPromise = waitForFavicon(extraTab.linkedBrowser, expectedFavicon);
 
-  extraTab.linkedBrowser.loadURI(TEST_URL);
+  BrowserTestUtils.loadURI(extraTab.linkedBrowser, TEST_URL);
   await BrowserTestUtils.browserLoaded(extraTab.linkedBrowser);
 
   await faviconPromise;
 
   is(domLinkAddedFired, 2, "Should fire the correct number of DOMLinkAdded event.");
   is(domLinkChangedFired, 0, "Should not fire any DOMLinkChanged event.");
 
   gBrowser.removeTab(extraTab);
--- a/browser/base/content/test/general/browser_alltabslistener.js
+++ b/browser/base/content/test/general/browser_alltabslistener.js
@@ -92,27 +92,27 @@ function test() {
   gBrowser.selectedTab = gForegroundTab;
 
   // We must wait until a page has completed loading before
   // starting tests or we get notifications from that
   let promises = [
     BrowserTestUtils.browserStopped(gBackgroundBrowser, kBasePage),
     BrowserTestUtils.browserStopped(gForegroundBrowser, kBasePage),
   ];
-  gBackgroundBrowser.loadURI(kBasePage);
-  gForegroundBrowser.loadURI(kBasePage);
+  BrowserTestUtils.loadURI(gBackgroundBrowser, kBasePage);
+  BrowserTestUtils.loadURI(gForegroundBrowser, kBasePage);
   Promise.all(promises).then(startTest1);
 }
 
 function runTest(browser, url, next) {
   gFrontNotificationsPos = 0;
   gAllNotificationsPos = 0;
   gNextTest = next;
   gTestBrowser = browser;
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 }
 
 function startTest1() {
   info("\nTest 1");
   gBrowser.addProgressListener(gFrontProgressListener);
   gBrowser.addTabsProgressListener(gAllProgressListener);
 
   gAllNotifications = [
--- a/browser/base/content/test/general/browser_bug417483.js
+++ b/browser/base/content/test/general/browser_bug417483.js
@@ -1,12 +1,12 @@
 add_task(async function() {
   let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, true);
   const htmlContent = "data:text/html, <iframe src='data:text/html,text text'></iframe>";
-  gBrowser.loadURI(htmlContent);
+  BrowserTestUtils.loadURI(gBrowser, htmlContent);
   await loadedPromise;
 
   await ContentTask.spawn(gBrowser.selectedBrowser, { }, async function(arg) {
     let frame = content.frames[0];
     let sel = frame.getSelection();
     let range = frame.document.createRange();
     let tn = frame.document.body.childNodes[0];
     range.setStart(tn, 4);
--- a/browser/base/content/test/general/browser_bug431826.js
+++ b/browser/base/content/test/general/browser_bug431826.js
@@ -1,17 +1,17 @@
 function remote(task) {
   return ContentTask.spawn(gBrowser.selectedBrowser, null, task);
 }
 
 add_task(async function() {
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   let promise = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser);
-  gBrowser.loadURI("https://nocert.example.com/");
+  BrowserTestUtils.loadURI(gBrowser, "https://nocert.example.com/");
   await promise;
 
   await remote(() => {
     // Confirm that we are displaying the contributed error page, not the default
     let uri = content.document.documentURI;
     Assert.ok(uri.startsWith("about:certerror"), "Broken page should go to about:certerror, not about:neterror");
   });
 
--- a/browser/base/content/test/general/browser_bug519216.js
+++ b/browser/base/content/test/general/browser_bug519216.js
@@ -1,14 +1,14 @@
 function test() {
   waitForExplicitFinish();
   gBrowser.addProgressListener(progressListener1);
   gBrowser.addProgressListener(progressListener2);
   gBrowser.addProgressListener(progressListener3);
-  gBrowser.loadURI("data:text/plain,bug519216");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/plain,bug519216");
 }
 
 var calledListener1 = false;
 var progressListener1 = {
   onLocationChange: function onLocationChange() {
     calledListener1 = true;
     gBrowser.removeProgressListener(this);
   },
--- a/browser/base/content/test/general/browser_bug567306.js
+++ b/browser/base/content/test/general/browser_bug567306.js
@@ -10,17 +10,19 @@ add_task(async function() {
   let selectedBrowser = newwindow.gBrowser.selectedBrowser;
   await new Promise((resolve, reject) => {
     BrowserTestUtils.waitForContentEvent(selectedBrowser, "pageshow", true, (event) => {
       return content.location.href != "about:blank";
     }).then(function pageshowListener() {
       ok(true, "pageshow listener called: " + newwindow.gBrowser.currentURI.spec);
       resolve();
     });
-    selectedBrowser.loadURI("data:text/html,<h1 id='h1'>Select Me</h1>");
+    selectedBrowser.loadURI("data:text/html,<h1 id='h1'>Select Me</h1>", {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
   });
 
   await SimpleTest.promiseFocus(newwindow);
 
   ok(!newwindow.gFindBarInitialized, "find bar is not yet initialized");
   let findBar = await newwindow.gFindBarPromise;
 
   await ContentTask.spawn(selectedBrowser, { }, async function() {
--- a/browser/base/content/test/general/browser_bug579872.js
+++ b/browser/base/content/test/general/browser_bug579872.js
@@ -19,10 +19,10 @@ function test() {
 
     openTrustedLinkIn("http://example.org/", "current");
     is(gBrowser.tabs.length, 3, "Should open in new tab");
 
     gBrowser.removeTab(newTab);
     gBrowser.removeTab(gBrowser.tabs[1]); // example.org tab
     finish();
   }
-  newTab.linkedBrowser.loadURI("http://example.com");
+  BrowserTestUtils.loadURI(newTab.linkedBrowser, "http://example.com");
 }
--- a/browser/base/content/test/general/browser_bug581253.js
+++ b/browser/base/content/test/general/browser_bug581253.js
@@ -19,17 +19,17 @@ add_task(async function test_remove_book
   await PlacesUtils.bookmarks.insert({
     parentGuid: PlacesUtils.bookmarks.unfiledGuid,
     title: "",
     url: testURL,
   });
 
   Assert.ok(await PlacesUtils.bookmarks.fetch({url: testURL}), "the test url is bookmarked");
 
-  gBrowser.loadURI(testURL);
+  BrowserTestUtils.loadURI(gBrowser, testURL);
 
   await BrowserTestUtils.waitForCondition(
     () => BookmarkingUI.status == BookmarkingUI.STATUS_STARRED,
     "star button indicates that the page is bookmarked");
 
   PlacesUtils.tagging.tagURI(makeURI(testURL), [testTag]);
 
   let popupShownPromise = BrowserTestUtils.waitForEvent(StarUI.panel, "popupshown");
--- a/browser/base/content/test/general/browser_bug624734.js
+++ b/browser/base/content/test/general/browser_bug624734.js
@@ -25,10 +25,10 @@ function test() {
     if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING) {
       waitForCondition(() => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING, finishTest, "BookmarkingUI was updating for too long");
     } else {
       CustomizableUI.removeWidgetFromArea("bookmarks-menu-button");
       finishTest();
     }
   });
 
-  tab.linkedBrowser.loadURI("http://example.com/browser/browser/base/content/test/general/dummy_page.html");
+  BrowserTestUtils.loadURI(tab.linkedBrowser, "http://example.com/browser/browser/base/content/test/general/dummy_page.html");
 }
--- a/browser/base/content/test/general/browser_bug734076.js
+++ b/browser/base/content/test/general/browser_bug734076.js
@@ -86,17 +86,17 @@ add_task(async function() {
       },
     },
   ];
 
   let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
 
   for (let test of tests) {
     let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-    gBrowser.loadURI(test.url);
+    BrowserTestUtils.loadURI(gBrowser, test.url);
     await loadedPromise;
 
     info("Run subtest " + test.name);
     let commandToRun = await test.go();
 
     let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
     await BrowserTestUtils.synthesizeMouse(test.element, 3, 3,
           { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
--- a/browser/base/content/test/general/browser_documentnavigation.js
+++ b/browser/base/content/test/general/browser_documentnavigation.js
@@ -77,17 +77,17 @@ async function expectFocusOnF6(backward,
   if (onContent) {
     window.messageManager.removeMessageListener("BrowserTest:FocusChanged", focusChangedListener);
   }
 }
 
 // Load a page and navigate between it and the chrome window.
 add_task(async function() {
   let page1Promise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.selectedBrowser.loadURI(testPage1);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPage1);
   await page1Promise;
 
   // When the urlbar is focused, pressing F6 should focus the root of the content page.
   gURLBar.focus();
   await expectFocusOnF6(false, "html1", "html1",
                                 true, "basic focus content page");
 
   // When the content is focused, pressing F6 should focus the urlbar.
--- a/browser/base/content/test/general/browser_e10s_chrome_process.js
+++ b/browser/base/content/test/general/browser_e10s_chrome_process.js
@@ -9,17 +9,17 @@ function makeTest(name, startURL, startP
     // In non-e10s nothing should be remote
     if (!gMultiProcessBrowser) {
       startProcessIsRemote = false;
       endProcessIsRemote = false;
     }
 
     // Load the initial URL and make sure we are in the right initial process
     info("Loading initial URL");
-    browser.loadURI(startURL);
+    BrowserTestUtils.loadURI(browser, startURL);
     await BrowserTestUtils.browserLoaded(browser);
 
     is(browser.currentURI.spec, startURL, "Shouldn't have been redirected");
     is(browser.isRemoteBrowser, startProcessIsRemote, "Should be displayed in the right process");
 
     let docLoadedPromise = BrowserTestUtils.browserLoaded(browser);
     let expectSyncChange = await transitionTask(browser, endURL);
     if (expectSyncChange) {
--- a/browser/base/content/test/general/browser_e10s_switchbrowser.js
+++ b/browser/base/content/test/general/browser_e10s_switchbrowser.js
@@ -43,16 +43,17 @@ var check_history = async function() {
   let sessionHistory = await get_remote_history(gBrowser.selectedBrowser);
 
   let count = sessionHistory.entries.length;
   is(count, gExpectedHistory.entries.length, "Should have the right number of history entries");
   is(sessionHistory.index, gExpectedHistory.index, "Should have the right history index");
 
   for (let i = 0; i < count; i++) {
     let entry = sessionHistory.entries[i];
+    info("Checking History Entry:", entry.uri);
     is(entry.uri, gExpectedHistory.entries[i].uri, "Should have the right URI");
     is(entry.title, gExpectedHistory.entries[i].title, "Should have the right title");
   }
 };
 
 function clear_history() {
   gExpectedHistory.index = -1;
   gExpectedHistory.entries = [];
@@ -72,17 +73,20 @@ var waitForLoad = async function(uri) {
     uri: gBrowser.currentURI.spec,
     title: gBrowser.contentTitle,
   });
 };
 
 // Waits for a load and updates the known history
 var waitForLoadWithFlags = async function(uri, flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE) {
   info("Loading " + uri + " flags = " + flags);
-  gBrowser.selectedBrowser.loadURI(uri, { flags });
+  gBrowser.selectedBrowser.loadURI(uri, {
+    flags,
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+  });
 
   await BrowserTestUtils.browserStopped(gBrowser);
   if (!(flags & Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY)) {
 
     if (flags & Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY) {
       gExpectedHistory.entries.pop();
     } else {
       gExpectedHistory.index++;
--- a/browser/base/content/test/general/browser_findbarClose.js
+++ b/browser/base/content/test/general/browser_findbarClose.js
@@ -7,17 +7,17 @@ var newTab;
 
 add_task(async function findbar_test() {
   waitForExplicitFinish();
   newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
 
   let promise = ContentTask.spawn(newTab.linkedBrowser, null, async function() {
     await ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", false);
   });
-  newTab.linkedBrowser.loadURI("http://example.com/browser/" +
+  BrowserTestUtils.loadURI(newTab.linkedBrowser, "http://example.com/browser/" +
     "browser/base/content/test/general/test_bug628179.html");
   await promise;
 
   await gFindBarPromise;
   gFindBar.open();
 
   await new ContentTask.spawn(newTab.linkedBrowser, null, async function() {
     let iframe = content.document.getElementById("iframe");
--- a/browser/base/content/test/general/browser_refreshBlocker.js
+++ b/browser/base/content/test/general/browser_refreshBlocker.js
@@ -86,17 +86,17 @@ add_task(async function test_can_enable_
  */
 async function testRealRefresh(refreshPage, delay) {
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: "about:blank",
   }, async function(browser) {
     await pushPrefs(["accessibility.blockautorefresh", true]);
 
-    browser.loadURI(refreshPage + "?p=" + TARGET_PAGE + "&d=" + delay);
+    BrowserTestUtils.loadURI(browser, refreshPage + "?p=" + TARGET_PAGE + "&d=" + delay);
     await BrowserTestUtils.browserLoaded(browser);
 
     // Once browserLoaded resolves, all nsIWebProgressListener callbacks
     // should have fired, so the notification should be visible.
     let notificationBox = gBrowser.getNotificationBox(browser);
     let notification = notificationBox.currentNotification;
 
     ok(notification, "Notification should be visible");
--- a/browser/base/content/test/general/browser_restore_isAppTab.js
+++ b/browser/base/content/test/general/browser_restore_isAppTab.js
@@ -57,31 +57,31 @@ add_task(async function navigate() {
   loadFrameScript(browser);
   let isAppTab = await isBrowserAppTab(browser);
   ok(!isAppTab, "Docshell shouldn't think it is an app tab");
 
   gBrowser.pinTab(tab);
   isAppTab = await isBrowserAppTab(browser);
   ok(isAppTab, "Docshell should think it is an app tab");
 
-  gBrowser.loadURI(DUMMY);
+  BrowserTestUtils.loadURI(gBrowser, DUMMY);
   await BrowserTestUtils.browserStopped(gBrowser);
   loadFrameScript(browser);
   isAppTab = await isBrowserAppTab(browser);
   ok(isAppTab, "Docshell should think it is an app tab");
 
   gBrowser.unpinTab(tab);
   isAppTab = await isBrowserAppTab(browser);
   ok(!isAppTab, "Docshell shouldn't think it is an app tab");
 
   gBrowser.pinTab(tab);
   isAppTab = await isBrowserAppTab(browser);
   ok(isAppTab, "Docshell should think it is an app tab");
 
-  gBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser, "about:robots");
   await BrowserTestUtils.browserStopped(gBrowser);
   loadFrameScript(browser);
   isAppTab = await isBrowserAppTab(browser);
   ok(isAppTab, "Docshell should think it is an app tab");
 
   gBrowser.removeCurrentTab();
 });
 
--- a/browser/base/content/test/general/browser_save_link-perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_link-perwindowpb.js
@@ -9,17 +9,17 @@ MockFilePicker.init(window);
 // the first by checking that cookies set by the first response are not sent
 // during the second request.
 function triggerSave(aWindow, aCallback) {
   info("started triggerSave");
   var fileName;
   let testBrowser = aWindow.gBrowser.selectedBrowser;
   // This page sets a cookie if and only if a cookie does not exist yet
   let testURI = "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517-2.html";
-  testBrowser.loadURI(testURI);
+  BrowserTestUtils.loadURI(testBrowser, testURI);
   BrowserTestUtils.browserLoaded(testBrowser, false, testURI)
                   .then(() => {
     waitForFocus(function() {
       info("register to handle popupshown");
       aWindow.document.addEventListener("popupshown", contextMenuOpened);
 
       BrowserTestUtils.synthesizeMouseAtCenter("#fff", {type: "contextmenu", button: 2}, testBrowser);
       info("right clicked!");
--- 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
@@ -24,17 +24,17 @@ function createTemporarySaveDirectory() 
 }
 
 function triggerSave(aWindow, aCallback) {
   info("started triggerSave, persite downloads: " + (Services.prefs.getBoolPref(SAVE_PER_SITE_PREF) ? "on" : "off"));
   var fileName;
   let testBrowser = aWindow.gBrowser.selectedBrowser;
   let testURI = "http://mochi.test:8888/browser/browser/base/content/test/general/navigating_window_with_download.html";
   windowObserver.setCallback(onUCTDialog);
-  testBrowser.loadURI(testURI);
+  BrowserTestUtils.loadURI(testBrowser, testURI);
 
   // Create the folder the link will be saved into.
   var destDir = createTemporarySaveDirectory();
   var destFile = destDir.clone();
 
   MockFilePicker.displayDirectory = destDir;
   MockFilePicker.showCallback = function(fp) {
     info("showCallback");
--- a/browser/base/content/test/general/browser_save_video.js
+++ b/browser/base/content/test/general/browser_save_video.js
@@ -7,17 +7,17 @@ MockFilePicker.init(window);
 /**
  * TestCase for bug 564387
  * <https://bugzilla.mozilla.org/show_bug.cgi?id=564387>
  */
 add_task(async function() {
   var fileName;
 
   let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.loadURI("http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html");
+  BrowserTestUtils.loadURI(gBrowser, "http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html");
   await loadPromise;
 
   let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
 
   await BrowserTestUtils.synthesizeMouseAtCenter("#video1",
                                                  { type: "contextmenu", button: 2 },
                                                  gBrowser.selectedBrowser);
   info("context menu click on video1");
--- a/browser/base/content/test/general/browser_ssl_error_reports.js
+++ b/browser/base/content/test/general/browser_ssl_error_reports.js
@@ -59,17 +59,17 @@ async function testSendReportAutomatical
   Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
 
   // Add a tab and wait until it's loaded.
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
 
   // Load the page and wait for the error report submission.
   let promiseStatus = createReportResponseStatusPromise(URL_REPORTS + suffix);
-  browser.loadURI(testURL);
+  BrowserTestUtils.loadURI(browser, testURL);
   await BrowserTestUtils.waitForErrorPage(browser);
 
   ok(!isErrorStatus(await promiseStatus),
      "SSL error report submitted successfully");
 
   // Check that we loaded the right error page.
   await checkErrorPage(browser, errorURISuffix);
 
@@ -83,17 +83,17 @@ async function testSetAutomatic(testURL,
   Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, false);
   Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
 
   // Add a tab and wait until it's loaded.
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
 
   // Load the page.
-  browser.loadURI(testURL);
+  BrowserTestUtils.loadURI(browser, testURL);
   await BrowserTestUtils.waitForErrorPage(browser);
 
   // Check that we loaded the right error page.
   await checkErrorPage(browser, errorURISuffix);
 
   let statusPromise = createReportResponseStatusPromise(URL_REPORTS + suffix);
 
   // Click the checkbox, enable automatic error reports.
@@ -124,17 +124,17 @@ async function testSetAutomatic(testURL,
 }
 
 async function testSendReportDisabled(testURL, errorURISuffix) {
   // Add a tab and wait until it's loaded.
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
 
   // Load the page.
-  browser.loadURI(testURL);
+  BrowserTestUtils.loadURI(browser, testURL);
   await BrowserTestUtils.waitForErrorPage(browser);
 
   // Check that we loaded the right error page.
   await checkErrorPage(browser, errorURISuffix);
 
   // Check that the error reporting section is hidden.
   await ContentTask.spawn(browser, null, async function() {
     let section = content.document.getElementById("certificateErrorReporting");
--- a/browser/base/content/test/general/browser_star_hsts.js
+++ b/browser/base/content/test/general/browser_star_hsts.js
@@ -63,11 +63,11 @@ function promiseStarState(aValue) {
  *        The url to wait for, same as aURL if not defined.
  * @return {Promise} resolved when the event is handled.
  */
 function promiseTabLoadEvent(aTab, aURL, aFinalURL) {
   if (!aFinalURL)
     aFinalURL = aURL;
 
   info("Wait for load tab event");
-  aTab.linkedBrowser.loadURI(aURL);
+  BrowserTestUtils.loadURI(aTab.linkedBrowser, aURL);
   return BrowserTestUtils.browserLoaded(aTab.linkedBrowser, false, aFinalURL);
 }
--- a/browser/base/content/test/general/browser_tab_detach_restore.js
+++ b/browser/base/content/test/general/browser_tab_detach_restore.js
@@ -5,17 +5,17 @@ const {TabStateFlusher} = ChromeUtils.im
 add_task(async function() {
   let uri = "http://example.com/browser/browser/base/content/test/general/dummy_page.html";
 
   // Clear out the closed windows set to start
   while (SessionStore.getClosedWindowCount() > 0)
     SessionStore.forgetClosedWindow(0);
 
   let tab = BrowserTestUtils.addTab(gBrowser);
-  tab.linkedBrowser.loadURI(uri);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, uri);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   await TabStateFlusher.flush(tab.linkedBrowser);
 
   let key = tab.linkedBrowser.permanentKey;
   let win = gBrowser.replaceTabWithWindow(tab);
   await new Promise(resolve => whenDelayedStartupFinished(win, resolve));
 
   is(win.gBrowser.selectedBrowser.permanentKey, key, "Should have properly copied the permanentKey");
--- a/browser/base/content/test/general/browser_tab_dragdrop.js
+++ b/browser/base/content/test/general/browser_tab_dragdrop.js
@@ -22,17 +22,17 @@ var clickTest = async function(tab) {
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
 
   let newClicks = await getClicks(tab);
   is(newClicks, clicks + 1, "adding 1 more click on BODY");
 };
 
 function loadURI(tab, url) {
-  tab.linkedBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, url);
   return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 }
 
 // Creates a framescript which caches the current object value from the plugin
 // in the page. checkObjectValue below verifies that the framescript is still
 // active for the browser and that the cached value matches that from the plugin
 // in the page which tells us the plugin hasn't been reinitialized.
 async function cacheObjectValue(browser) {
--- a/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
+++ b/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
@@ -20,17 +20,17 @@ function frame_script() {
 
 /**
  * Takes some browser in some window, and forces that browser
  * to become non-remote, and then navigates it to a page that
  * we're not supposed to be displaying remotely. Returns a
  * Promise that resolves when the browser is no longer remote.
  */
 function prepareNonRemoteBrowser(aWindow, browser) {
-  browser.loadURI(NON_REMOTE_PAGE);
+  BrowserTestUtils.loadURI(browser, NON_REMOTE_PAGE);
   return BrowserTestUtils.browserLoaded(browser);
 }
 
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref(OPEN_LOCATION_PREF);
 });
 
 /**
--- a/browser/base/content/test/general/browser_typeAheadFind.js
+++ b/browser/base/content/test/general/browser_typeAheadFind.js
@@ -1,16 +1,16 @@
 /* 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/. */
 
 add_task(async function() {
   let testWindow = await BrowserTestUtils.openNewBrowserWindow();
 
-  testWindow.gBrowser.loadURI("data:text/html,<h1>A Page</h1>");
+  BrowserTestUtils.loadURI(testWindow.gBrowser, "data:text/html,<h1>A Page</h1>");
   await BrowserTestUtils.browserLoaded(testWindow.gBrowser.selectedBrowser);
 
   await SimpleTest.promiseFocus(testWindow.gBrowser.selectedBrowser);
 
   ok(!testWindow.gFindBarInitialized, "find bar is not initialized");
 
   let findBarOpenPromise = promiseWaitForEvent(testWindow.gBrowser, "findbaropen");
   EventUtils.synthesizeKey("/", {}, testWindow);
--- a/browser/base/content/test/general/browser_unknownContentType_title.js
+++ b/browser/base/content/test/general/browser_unknownContentType_title.js
@@ -16,17 +16,17 @@ function waitForNewWindow() {
 
 add_task(async function() {
   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, url);
   let browser = tab.linkedBrowser;
   await promiseTabLoaded(gBrowser.selectedTab);
 
   is(gBrowser.contentTitle, "Test Page", "Should have the right title.");
 
-  browser.loadURI(unknown_url);
+  BrowserTestUtils.loadURI(browser, unknown_url);
   let win = await waitForNewWindow();
   is(win.location, "chrome://mozapps/content/downloads/unknownContentType.xul",
      "Should have seen the unknown content dialog.");
   is(gBrowser.contentTitle, "Test Page", "Should still have the right title.");
 
   win.close();
   await promiseWaitForFocus(window);
   gBrowser.removeCurrentTab();
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -298,17 +298,17 @@ var FullZoomHelper = {
       }, true);
 
       this.waitForLocationChange().then(function() {
         didZoom = true;
         if (didLoad)
           resolve();
       });
 
-      tab.linkedBrowser.loadURI(url);
+      BrowserTestUtils.loadURI(tab.linkedBrowser, url);
     });
   },
 
   zoomTest: function zoomTest(tab, val, msg) {
     is(ZoomManager.getZoomForBrowser(tab.linkedBrowser), val, msg);
   },
 
   enlarge: function enlarge() {
--- a/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
@@ -69,17 +69,17 @@ async function test() {
   Services.prefs.setBoolPref("privacy.firstparty.isolate", true);
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("privacy.firstparty.isolate");
   });
 
   let url = "https://example.com/browser/browser/base/content/test/pageinfo/image.html";
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, url);
-  gBrowser.selectedBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
   await loadPromise;
 
   // Pass a dummy imageElement, if there isn't an imageElement, pageInfo.js
   // will do a preview, however this sometimes will cause intermittent failures,
   // see bug 1403365.
   let pageInfo = BrowserPageInfo(url, "mediaTab", {});
   info("waitForEvent pageInfo");
   await waitForEvent(pageInfo, "load");
--- a/browser/base/content/test/pageinfo/browser_pageinfo_image_info.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_image_info.js
@@ -41,10 +41,10 @@ function test() {
           pageInfo.close();
           gBrowser.removeCurrentTab();
           finish();
         });
       });
     }, {capture: true, once: true});
   });
 
-  gBrowser.loadURI(URI);
+  BrowserTestUtils.loadURI(gBrowser, URI);
 }
--- a/browser/base/content/test/pageinfo/browser_pageinfo_images.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_images.js
@@ -23,17 +23,17 @@ function test() {
           pageInfo.close();
           gBrowser.removeCurrentTab();
           finish();
         });
       });
     }, {capture: true, once: true});
   });
 
-  gBrowser.selectedBrowser.loadURI(
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser,
     "data:text/html," +
     "<html>" +
     "  <head>" +
     "    <title>Test for media tab</title>" +
     "    <link rel='shortcut icon' href='file:///dummy_icon.ico'>" + // Icon
     "  </head>" +
     "  <body style='background-image:url(about:logo?a);'>" + // Background
     "    <img src='file:///dummy_image.gif'>" + // Image
--- a/browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js
@@ -30,10 +30,10 @@ function test() {
           pageInfo.close();
           gBrowser.removeCurrentTab();
           finish();
         });
       });
     }, {capture: true, once: true});
   });
 
-  gBrowser.selectedBrowser.loadURI(URI);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, URI);
 }
--- a/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js
+++ b/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js
@@ -131,17 +131,17 @@ add_task(async function testChromeHearsP
   // Setup the crash observer promise
   crashDeferred = PromiseUtils.defer();
 
   // Open a remote window so that we can run this test even if e10s is not
   // enabled by default.
   let win = await BrowserTestUtils.openNewBrowserWindow({remote: true});
   let browser = win.gBrowser.selectedBrowser;
 
-  browser.loadURI(CRASH_URL);
+  BrowserTestUtils.loadURI(browser, CRASH_URL);
   await BrowserTestUtils.browserLoaded(browser);
 
   // In this case, we want the <object> to match the -moz-handler-crashed
   // pseudoselector, but we want it to seem still active, because the
   // content process is not yet supposed to know that the plugin has
   // crashed.
   let runID = await preparePlugin(browser,
                                   Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE);
@@ -200,17 +200,17 @@ add_task(async function testContentHears
   // Setup the crash observer promise
   crashDeferred = PromiseUtils.defer();
 
   // Open a remote window so that we can run this test even if e10s is not
   // enabled by default.
   let win = await BrowserTestUtils.openNewBrowserWindow({remote: true});
   let browser = win.gBrowser.selectedBrowser;
 
-  browser.loadURI(CRASH_URL);
+  BrowserTestUtils.loadURI(browser, CRASH_URL);
   await BrowserTestUtils.browserLoaded(browser);
 
   // In this case, we want the <object> to match the -moz-handler-crashed
   // pseudoselector, and we want the plugin to seem crashed, since the
   // content process in this case has heard about the crash first.
   let runID = await preparePlugin(browser,
                                   Ci.nsIObjectLoadingContent.PLUGIN_CRASHED);
 
--- a/browser/base/content/test/popupNotifications/head.js
+++ b/browser/base/content/test/popupNotifications/head.js
@@ -31,17 +31,17 @@ async function waitForWindowReadyForPopu
  * @return {Promise} resolved when the event is handled.
  * @resolves to the received event
  * @rejects if a valid load event is not received within a meaningful interval
  */
 function promiseTabLoadEvent(tab, url) {
   let browser = tab.linkedBrowser;
 
   if (url) {
-    browser.loadURI(url);
+    BrowserTestUtils.loadURI(browser, url);
   }
 
   return BrowserTestUtils.browserLoaded(browser, false, url);
 }
 
 const PREF_SECURITY_DELAY_INITIAL = Services.prefs.getIntPref("security.notification_enable_delay");
 
 // Tests that call setup() should have a `tests` array defined for the actual
--- a/browser/base/content/test/siteIdentity/browser_check_identity_state.js
+++ b/browser/base/content/test/siteIdentity/browser_check_identity_state.js
@@ -270,17 +270,17 @@ add_task(async function test_resource_ur
 
 async function noCertErrorTest(secureCheck) {
   let oldTab = gBrowser.selectedTab;
   await SpecialPowers.pushPrefEnv({set: [[INSECURE_ICON_PREF, secureCheck]]});
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
 
   let promise = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser);
-  gBrowser.loadURI("https://nocert.example.com/");
+  BrowserTestUtils.loadURI(gBrowser, "https://nocert.example.com/");
   await promise;
   is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
   is(getConnectionState(), "not-secure", "Connection should be file");
 
   gBrowser.selectedTab = oldTab;
   is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
 
   gBrowser.selectedTab = newTab;
--- a/browser/base/content/test/siteIdentity/browser_csp_block_all_mixedcontent.js
+++ b/browser/base/content/test/siteIdentity/browser_csp_block_all_mixedcontent.js
@@ -35,17 +35,17 @@ function runTests() {
   var newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   newTab.linkedBrowser.stop();
 
   // Starting the test
   var url = PRE_PATH + "file_csp_block_all_mixedcontent.html";
   BrowserTestUtils.browserLoaded(gTestBrowser, false, url).then(verifyUInotDegraded);
-  gTestBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(gTestBrowser, url);
 }
 
 // ------------------------------------------------------
 function test() {
   // Performing async calls, e.g. 'onload', we have to wait till all of them finished
   waitForExplicitFinish();
 
   SpecialPowers.pushPrefEnv(
--- a/browser/base/content/test/tabs/browser_abandonment_telemetry.js
+++ b/browser/base/content/test/tabs/browser_abandonment_telemetry.js
@@ -72,17 +72,17 @@ const PROBE_TESTS = [
 
   // Test going back to a previous page
   {
     name: "Going back to a previous page",
 
     category: "back",
 
     async prepare(browser) {
-      browser.loadURI(PAGE_2);
+      BrowserTestUtils.loadURI(browser, PAGE_2);
       await BrowserTestUtils.browserLoaded(browser);
     },
 
     async doAction(browser) {
       let pageShow =
         BrowserTestUtils.waitForContentEvent(browser, "pageshow");
       document.getElementById("Browser:Back").doCommand();
       await pageShow;
@@ -91,17 +91,17 @@ const PROBE_TESTS = [
 
   // Test going forward to a previous page
   {
     name: "Going forward to the next page",
 
     category: "forward",
 
     async prepare(browser) {
-      browser.loadURI(PAGE_2);
+      BrowserTestUtils.loadURI(browser, PAGE_2);
       await BrowserTestUtils.browserLoaded(browser);
       let pageShow =
         BrowserTestUtils.waitForContentEvent(browser, "pageshow");
       browser.goBack();
       await pageShow;
     },
 
     async doAction(browser) {
@@ -114,19 +114,19 @@ const PROBE_TESTS = [
 
   // Test going backwards more than one page back via gotoIndex
   {
     name: "Going backward to a previous page via gotoIndex",
 
     category: "historyNavigation",
 
     async prepare(browser) {
-      browser.loadURI(PAGE_2);
+      BrowserTestUtils.loadURI(browser, PAGE_2);
       await BrowserTestUtils.browserLoaded(browser);
-      browser.loadURI("http://example.com");
+      BrowserTestUtils.loadURI(browser, "http://example.com");
       await BrowserTestUtils.browserLoaded(browser);
       await TabStateFlusher.flush(browser);
     },
 
     async doAction(browser) {
       let pageShow =
         BrowserTestUtils.waitForContentEvent(browser, "pageshow");
       synthesizeHistoryNavigationToIndex(0);
@@ -136,19 +136,19 @@ const PROBE_TESTS = [
 
   // Test going forwards more than one page back via gotoIndex
   {
     name: "Going forward to a previous page via gotoIndex",
 
     category: "historyNavigation",
 
     async prepare(browser) {
-      browser.loadURI(PAGE_2);
+      BrowserTestUtils.loadURI(browser, PAGE_2);
       await BrowserTestUtils.browserLoaded(browser);
-      browser.loadURI("http://example.com");
+      BrowserTestUtils.loadURI(browser, "http://example.com");
       await BrowserTestUtils.browserLoaded(browser);
       let pageShow =
         BrowserTestUtils.waitForContentEvent(browser, "pageshow");
       browser.gotoIndex(0);
       await pageShow;
       await TabStateFlusher.flush(browser);
     },
 
--- a/browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js
+++ b/browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js
@@ -21,13 +21,13 @@ add_task(async function() {
 
   let dummyPage = getChromeDir(getResolvedURI(gTestPath));
   dummyPage.append(DUMMY_FILE);
   const uriString = Services.io.newFileURI(dummyPage).spec;
 
   let viewSourceBrowser = viewSourceTab.linkedBrowser;
   let promiseLoad =
     BrowserTestUtils.browserLoaded(viewSourceBrowser, false, uriString);
-  viewSourceBrowser.loadURI(uriString);
+  BrowserTestUtils.loadURI(viewSourceBrowser, uriString);
   let href = await promiseLoad;
   is(href, uriString,
     "Check file:// URI loads in a browser that was previously for view-source");
 });
--- a/browser/base/content/test/tabs/browser_audioTabIcon.js
+++ b/browser/base/content/test/tabs/browser_audioTabIcon.js
@@ -364,17 +364,17 @@ async function test_cross_process_load()
     //   Start playback and wait for it to finish.
     await play(tab);
 
     let soundPlayingStoppedPromise = BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false,
       event => event.detail.changed.includes("soundplaying")
     );
 
     // Go to a different process.
-    browser.loadURI("about:mozilla");
+    BrowserTestUtils.loadURI(browser, "about:mozilla");
     await BrowserTestUtils.browserLoaded(browser);
 
     await soundPlayingStoppedPromise;
 
     ok(!tab.hasAttribute("soundplaying"), "Tab should not be playing sound any more");
     ok(!tab.soundPlaying, "Tab should not be playing sound any more");
   }
 
--- a/browser/base/content/test/tabs/browser_contextmenu_openlink_after_tabnavigated.js
+++ b/browser/base/content/test/tabs/browser_contextmenu_openlink_after_tabnavigated.js
@@ -12,17 +12,17 @@ add_task(async function test_contextmenu
   await BrowserTestUtils.synthesizeMouse("a", 0, 0, {
     type: "contextmenu",
     button: 2,
   }, gBrowser.selectedBrowser);
   await awaitPopupShown;
   info("Popup Shown");
 
   info("Navigate the tab with the opened context menu");
-  gBrowser.selectedBrowser.loadURI("about:blank");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   let awaitNewTabOpen = BrowserTestUtils.waitForNewTab(gBrowser, "http://example.com/");
 
   info("Click the 'open link in new tab' menu item");
   let openLinkMenuItem = contextMenu.querySelector("#context-openlinkintab");
   openLinkMenuItem.click();
 
--- a/browser/base/content/test/tabs/browser_new_web_tab_in_file_process_pref.js
+++ b/browser/base/content/test/tabs/browser_new_web_tab_in_file_process_pref.js
@@ -57,17 +57,17 @@ add_task(async function() {
     let promiseLoad = BrowserTestUtils.browserLoaded(httpBrowser, false, TEST_HTTP);
     document.getElementById("reload-button").doCommand();
     await promiseLoad;
     await CheckBrowserInPid(httpBrowser, filePid,
       "Check that http tab still in file content process after reload.");
 
     // Check that same-origin load doesn't break the affinity.
     promiseLoad = BrowserTestUtils.browserLoaded(httpBrowser, false, TEST_HTTP + "foo");
-    httpBrowser.loadURI(TEST_HTTP + "foo");
+    BrowserTestUtils.loadURI(httpBrowser, TEST_HTTP + "foo");
     await promiseLoad;
     await CheckBrowserInPid(httpBrowser, filePid,
       "Check that http tab still in file content process after same origin load.");
 
     // Check that history back doesn't break the affinity.
     let promiseLocation =
       BrowserTestUtils.waitForLocationChange(gBrowser, TEST_HTTP);
     httpBrowser.goBack();
@@ -88,33 +88,33 @@ add_task(async function() {
     promiseLocation = BrowserTestUtils.waitForLocationChange(gBrowser, TEST_HTTP);
     httpBrowser.gotoIndex(0);
     await promiseLocation;
     await CheckBrowserInPid(httpBrowser, filePid,
       "Check that http tab still in file content process after history gotoIndex.");
 
     // Check that file:// URI load doesn't break the affinity.
     promiseLoad = BrowserTestUtils.browserLoaded(httpBrowser, false, uriString);
-    httpBrowser.loadURI(uriString);
+    BrowserTestUtils.loadURI(httpBrowser, uriString);
     await promiseLoad;
     await CheckBrowserInPid(httpBrowser, filePid,
       "Check that http tab still in file content process after file:// load.");
 
     // Check that location change doesn't break the affinity.
     promiseLoad = BrowserTestUtils.browserLoaded(httpBrowser, false, TEST_HTTP);
     await ContentTask.spawn(httpBrowser, TEST_HTTP, uri => {
       content.location = uri;
     });
     await promiseLoad;
     await CheckBrowserInPid(httpBrowser, filePid,
       "Check that http tab still in file content process after location change.");
 
     // Check that cross-origin load does break the affinity.
     promiseLoad = BrowserTestUtils.browserLoaded(httpBrowser, false, TEST_CROSS_ORIGIN);
-    httpBrowser.loadURI(TEST_CROSS_ORIGIN);
+    BrowserTestUtils.loadURI(httpBrowser, TEST_CROSS_ORIGIN);
     await promiseLoad;
     await CheckBrowserNotInPid(httpBrowser, filePid,
       "Check that http tab not in file content process after cross origin load.");
     is(httpBrowser.remoteType, E10SUtils.WEB_REMOTE_TYPE,
       "Check that tab now has web remote type.");
 
     // Check that history back now remains in the web content process.
     let httpPid = await ContentTask.spawn(httpBrowser, null, () => {
--- a/browser/base/content/test/tabs/browser_opened_file_tab_navigated_to_web.js
+++ b/browser/base/content/test/tabs/browser_opened_file_tab_navigated_to_web.js
@@ -31,13 +31,13 @@ add_task(async function() {
   let openedTab = await promiseTabOpened;
   registerCleanupFunction(async function() {
     BrowserTestUtils.removeTab(openedTab);
   });
 
   let openedBrowser = openedTab.linkedBrowser;
 
   // Ensure that new file:// tab can be navigated to web content.
-  openedBrowser.loadURI(WEB_ADDRESS);
+  BrowserTestUtils.loadURI(openedBrowser, "http://example.org/");
   let href = await BrowserTestUtils.browserLoaded(openedBrowser, false, WEB_ADDRESS);
   is(href, WEB_ADDRESS,
      "Check that new file:// page has navigated successfully to web content");
 });
--- a/browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js
+++ b/browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js
@@ -15,17 +15,17 @@ add_task(async function() {
   await BrowserTestUtils.withNewTab(uriString, async function(fileBrowser) {
     let filePid = await ContentTask.spawn(fileBrowser, null, () => {
       return Services.appinfo.processID;
     });
 
     // Navigate to data URI.
     let promiseLoad = BrowserTestUtils.browserLoaded(fileBrowser, false,
                                                      DATA_URI);
-    fileBrowser.loadURI(DATA_URI);
+    BrowserTestUtils.loadURI(fileBrowser, DATA_URI);
     let href = await promiseLoad;
     is(href, DATA_URI, "Check data URI loaded.");
     let dataPid = await ContentTask.spawn(fileBrowser, null, () => {
       return Services.appinfo.processID;
     });
     is(dataPid, filePid, "Check that data URI loaded in file content process.");
 
     // Make sure we can view-source on the data URI page.
--- a/browser/base/content/test/urlbar/browser_URLBarSetURI.js
+++ b/browser/base/content/test/urlbar/browser_URLBarSetURI.js
@@ -50,17 +50,17 @@ var tests = [
         }, win);
       });
     });
   },
   function pageloaderror(next) {
     loadTabInWindow(window, function(tab) {
       // Load a new URL and then immediately stop it, to simulate a page load
       // error.
-      tab.linkedBrowser.loadURI("http://test1.example.com");
+      BrowserTestUtils.loadURI(tab.linkedBrowser, "http://test1.example.com");
       tab.linkedBrowser.stop();
       is(gURLBar.textValue, "example.com", "URL bar had user/pass stripped after load error");
       gBrowser.removeTab(tab);
       next();
     });
   },
 ];
 
--- a/browser/base/content/test/urlbar/browser_bug304198.js
+++ b/browser/base/content/test/urlbar/browser_bug304198.js
@@ -9,19 +9,19 @@ add_task(async function() {
   deletedURLTab = BrowserTestUtils.addTab(gBrowser);
   fullURLTab = BrowserTestUtils.addTab(gBrowser);
   partialURLTab = BrowserTestUtils.addTab(gBrowser);
   testURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
 
   let loaded1 = BrowserTestUtils.browserLoaded(deletedURLTab.linkedBrowser, false, testURL);
   let loaded2 = BrowserTestUtils.browserLoaded(fullURLTab.linkedBrowser, false, testURL);
   let loaded3 = BrowserTestUtils.browserLoaded(partialURLTab.linkedBrowser, false, testURL);
-  deletedURLTab.linkedBrowser.loadURI(testURL);
-  fullURLTab.linkedBrowser.loadURI(testURL);
-  partialURLTab.linkedBrowser.loadURI(testURL);
+  BrowserTestUtils.loadURI(deletedURLTab.linkedBrowser, testURL);
+  BrowserTestUtils.loadURI(fullURLTab.linkedBrowser, testURL);
+  BrowserTestUtils.loadURI(partialURLTab.linkedBrowser, testURL);
   await Promise.all([loaded1, loaded2, loaded3]);
 
   testURL = gURLBar.trimValue(testURL);
   testPartialURL = testURL.substr(0, (testURL.length - charsToDelete));
 
   function cleanUp() {
     gBrowser.removeTab(fullURLTab);
     gBrowser.removeTab(partialURLTab);
--- a/browser/base/content/test/urlbar/browser_bug623155.js
+++ b/browser/base/content/test/urlbar/browser_bug623155.js
@@ -104,17 +104,17 @@ function delayed(aIsSelectedTab) {
   let currentURI = gBrowser.selectedBrowser.currentURI.spec;
   ok(isRedirectedURISpec(currentURI),
      "The content area is redirected. aIsSelectedTab:" + aIsSelectedTab);
   is(gURLBar.value, currentURI,
      "The URL bar shows the content URI. aIsSelectedTab:" + aIsSelectedTab);
 
   if (!aIsSelectedTab) {
     // If this was a background request, go on a foreground request.
-    gBrowser.selectedBrowser.loadURI(REDIRECT_FROM + "#FG");
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, REDIRECT_FROM + "#FG");
   } else {
     // Othrewise, nothing to do remains.
     finish();
   }
 }
 
 /* Cleanup */
 registerCleanupFunction(function() {
--- a/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar.js
+++ b/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar.js
@@ -54,17 +54,17 @@ add_task(async function step_3() {
 
   await Promise.all(promises);
   await ensure_opentabs_match_db();
 });
 
 add_task(async function step_4() {
   info("Running step 4 - ensure we don't register subframes as open pages");
   let tab = BrowserTestUtils.addTab(gBrowser);
-  tab.linkedBrowser.loadURI('data:text/html,<body><iframe src=""></iframe></body>');
+  BrowserTestUtils.loadURI(tab.linkedBrowser, 'data:text/html,<body><iframe src=""></iframe></body>');
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
     let iframe_loaded = ContentTaskUtils.waitForEvent(content.document, "load", true);
     content.document.querySelector("iframe").src = "http://test2.example.org/";
     await iframe_loaded;
   });
 
@@ -77,17 +77,17 @@ add_task(async function step_5() {
   BrowserTestUtils.removeTab(tab);
   await ensure_opentabs_match_db();
 });
 
 add_task(async function step_6() {
   info("Running step 6 - check swapBrowsersAndCloseOther preserves registered switch-to-tab result");
   let tabToKeep = BrowserTestUtils.addTab(gBrowser);
   let tab = BrowserTestUtils.addTab(gBrowser);
-  tab.linkedBrowser.loadURI("about:mozilla");
+  BrowserTestUtils.loadURI(tab.linkedBrowser, "about:mozilla");
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   gBrowser.updateBrowserRemoteness(tabToKeep.linkedBrowser, tab.linkedBrowser.isRemoteBrowser);
   gBrowser.swapBrowsersAndCloseOther(tabToKeep, tab);
 
   await ensure_opentabs_match_db();
 
   BrowserTestUtils.removeTab(tabToKeep);
@@ -127,17 +127,17 @@ function loadTab(tab, url) {
         Services.obs.removeObserver(observer, aTopic);
         resolve();
       },
       "uri-visit-saved"
     );
   });
 
   info("Loading page: " + url);
-  tab.linkedBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, url);
   return Promise.all([ loaded, visited ]);
 }
 
 function ensure_opentabs_match_db() {
   var tabs = {};
 
   for (let browserWin of Services.wm.getEnumerator("navigator:browser")) {
     // skip closed-but-not-destroyed windows
--- a/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
+++ b/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
@@ -28,17 +28,17 @@ add_task(async function clearURLBarAfter
  */
 add_task(async function clearURLBarAfterParentProcessURLInExistingTab() {
   let tab = await new Promise(resolve => {
     gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
     let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
     newTabBrowser.addEventListener("Initialized", async function() {
       resolve(gBrowser.selectedTab);
     }, {capture: true, once: true});
-    newTabBrowser.loadURI("about:preferences");
+    BrowserTestUtils.loadURI(newTabBrowser, "about:preferences");
   });
   document.getElementById("home-button").click();
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, HomePage.get());
   is(gURLBar.value, "", "URL bar should be empty");
   is(tab.linkedBrowser.userTypedValue, null, "The browser should have no recorded userTypedValue");
   BrowserTestUtils.removeTab(tab);
 });
 
--- a/browser/base/content/test/urlbar/browser_urlbarTrimURLs.js
+++ b/browser/base/content/test/urlbar/browser_urlbarTrimURLs.js
@@ -64,17 +64,17 @@ add_task(async function() {
   Services.prefs.setBoolPref(PREF_TRIMURLS, false);
 
   testVal("http://mozilla.org/");
 
   Services.prefs.setBoolPref(PREF_TRIMURLS, true);
 
   let promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser,
                                                      false, "http://example.com/");
-  gBrowser.loadURI("http://example.com/");
+  BrowserTestUtils.loadURI(gBrowser, "http://example.com/");
   await promiseLoaded;
 
   await testCopy("example.com", "http://example.com/");
 
   SetPageProxyState("invalid");
   gURLBar.valueIsTyped = true;
   await testCopy("example.com", "example.com");
 });
--- a/browser/base/content/test/webextensions/browser_extension_sideloading.js
+++ b/browser/base/content/test/webextensions/browser_extension_sideloading.js
@@ -95,22 +95,22 @@ add_task(async function() {
     // clear out ExtensionsUI state about sideloaded extensions so
     // subsequent tests don't get confused.
     ExtensionsUI.sideloaded.clear();
     ExtensionsUI.emit("change");
   };
 
   // Navigate away from the starting page to force about:addons to load
   // in a new tab during the tests below.
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   registerCleanupFunction(async function() {
     // Return to about:blank when we're done
-    gBrowser.selectedBrowser.loadURI("about:blank");
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank");
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   });
 
   hookExtensionsTelemetry();
 
   let changePromise = new Promise(resolve => {
     ExtensionsUI.on("change", function listener() {
       ExtensionsUI.off("change", listener);
--- a/browser/base/content/test/webextensions/browser_extension_update_background.js
+++ b/browser/base/content/test/webextensions/browser_extension_update_background.js
@@ -36,22 +36,22 @@ add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({set: [
     // We don't have pre-pinned certificates for the local mochitest server
     ["extensions.install.requireBuiltInCerts", false],
     ["extensions.update.requireBuiltInCerts", false],
   ]});
 
   // Navigate away from the initial page so that about:addons always
   // opens in a new tab during tests
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   registerCleanupFunction(async function() {
     // Return to about:blank when we're done
-    gBrowser.selectedBrowser.loadURI("about:blank");
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank");
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   });
 });
 
 hookExtensionsTelemetry();
 
 // Helper function to test background updates.
 async function backgroundUpdateTest(url, id, checkIconFn) {
--- a/browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js
+++ b/browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js
@@ -16,22 +16,22 @@ add_task(async function setup() {
     ["extensions.install.requireBuiltInCerts", false],
     ["extensions.update.requireBuiltInCerts", false],
     // Don't require the extensions to be signed
     ["xpinstall.signatures.required", false],
   ]});
 
   // Navigate away from the initial page so that about:addons always
   // opens in a new tab during tests
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   registerCleanupFunction(async function() {
     // Return to about:blank when we're done
-    gBrowser.selectedBrowser.loadURI("about:blank");
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank");
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   });
 });
 
 hookExtensionsTelemetry();
 
 // Helper function to test an upgrade that should not show a prompt
 async function testNoPrompt(origUrl, id) {
--- a/browser/base/content/test/webextensions/browser_permissions_installTrigger.js
+++ b/browser/base/content/test/webextensions/browser_permissions_installTrigger.js
@@ -1,14 +1,14 @@
 "use strict";
 
 const INSTALL_PAGE = `${BASE}/file_install_extensions.html`;
 
 async function installTrigger(filename) {
-  gBrowser.selectedBrowser.loadURI(INSTALL_PAGE);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, INSTALL_PAGE);
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   ContentTask.spawn(gBrowser.selectedBrowser, `${BASE}/${filename}`, async function(url) {
     content.wrappedJSObject.installTrigger(url);
   });
 }
 
 add_task(() => testInstallMethod(installTrigger, "installAmo"));
--- a/browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js
+++ b/browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js
@@ -1,14 +1,14 @@
 "use strict";
 
 const INSTALL_PAGE = `${BASE}/file_install_extensions.html`;
 
 async function installMozAM(filename) {
-  gBrowser.selectedBrowser.loadURI(INSTALL_PAGE);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, INSTALL_PAGE);
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   await ContentTask.spawn(gBrowser.selectedBrowser, `${BASE}/${filename}`, async function(url) {
     await content.wrappedJSObject.installMozAM(url);
   });
 }
 
 add_task(() => testInstallMethod(installMozAM, "installAmo"));
--- a/browser/base/content/test/webextensions/browser_permissions_unsigned.js
+++ b/browser/base/content/test/webextensions/browser_permissions_unsigned.js
@@ -10,17 +10,17 @@ add_task(async function test_unsigned() 
   ]});
 
   let testURI = makeURI("https://example.com/");
   Services.perms.add(testURI, "install", Services.perms.ALLOW_ACTION);
   registerCleanupFunction(() => Services.perms.remove(testURI, "install"));
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
 
-  gBrowser.selectedBrowser.loadURI(`${BASE}/file_install_extensions.html`);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, `${BASE}/file_install_extensions.html`);
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   ContentTask.spawn(gBrowser.selectedBrowser, `${BASE}/browser_webext_unsigned.xpi`, async function(url) {
     content.wrappedJSObject.installTrigger(url);
   });
 
   let panel = await promisePopupNotificationShown("addon-webext-permissions");
 
--- a/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
+++ b/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
@@ -14,17 +14,17 @@ add_task(async function setup() {
   ]});
 });
 
 // Helper to test that an update of a given extension does not
 // generate any permission prompts.
 async function testUpdateNoPrompt(filename, id,
                                   initialVersion = "1.0", updateVersion = "2.0") {
   // Navigate away to ensure that BrowserOpenAddonMgr() opens a new tab
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   // Install initial version of the test extension
   let addon = await promiseInstallAddon(`${BASE}/${filename}`);
   ok(addon, "Addon was installed");
   is(addon.version, initialVersion, "Version 1 of the addon is installed");
 
   // Go to Extensions in about:addons
--- a/browser/base/content/test/webextensions/head.js
+++ b/browser/base/content/test/webextensions/head.js
@@ -396,17 +396,17 @@ async function interactiveUpdateTest(aut
       EventUtils.synthesizeMouseAtCenter(item._updateBtn, {}, win);
     }
 
     return {promise};
   }
 
   // Navigate away from the starting page to force about:addons to load
   // in a new tab during the tests below.
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   // Install version 1.0 of the test extension
   let addon = await promiseInstallAddon(`${BASE}/browser_webext_update1.xpi`);
   ok(addon, "Addon was installed");
   is(addon.version, "1.0", "Version 1 of the addon is installed");
 
   let win = await BrowserOpenAddonsMgr("addons://list/extension");
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media.js
@@ -526,17 +526,17 @@ var gTests = [
   },
 },
 
 {
   desc: "'Always Allow' disabled on http pages",
   run: async function checkNoAlwaysOnHttp() {
     // Load an http page instead of the https version.
     let browser = gBrowser.selectedBrowser;
-    browser.loadURI(browser.documentURI.spec.replace("https://", "http://"));
+    BrowserTestUtils.loadURI(browser, browser.documentURI.spec.replace("https://", "http://"));
     await BrowserTestUtils.browserLoaded(browser);
 
     // Initially set both permissions to 'allow'.
     let Perms = Services.perms;
     let uri = browser.documentURI;
     Perms.add(uri, "microphone", Perms.ALLOW_ACTION);
     Perms.add(uri, "camera", Perms.ALLOW_ACTION);
 
--- a/browser/components/customizableui/test/browser_exit_background_customize_mode.js
+++ b/browser/components/customizableui/test/browser_exit_background_customize_mode.js
@@ -16,17 +16,17 @@ add_task(async function test_exit_backgr
   is(gBrowser.tabs.length, 2, "Should have 2 tabs");
 
   let custTab = gBrowser.selectedTab;
 
   let finishedCustomizing = BrowserTestUtils.waitForEvent(gNavToolbox, "aftercustomization");
   await BrowserTestUtils.switchTab(gBrowser, nonCustomizingTab);
   await finishedCustomizing;
 
-  custTab.linkedBrowser.loadURI("http://example.com");
+  BrowserTestUtils.loadURI(custTab.linkedBrowser, "http://example.com");
   await BrowserTestUtils.browserLoaded(custTab.linkedBrowser);
 
   Assert.equal(gBrowser.tabContainer.querySelector("tab[customizemode=true]"),
                null,
                "Should not have a tab marked as being the customize tab now.");
 
   await startCustomizing();
   is(gBrowser.tabs.length, 3, "Should have 3 tabs now");
--- a/browser/components/extensions/parent/ext-browser.js
+++ b/browser/components/extensions/parent/ext-browser.js
@@ -119,16 +119,17 @@ global.waitForTabLoaded = (tab, url) => 
     });
   });
 };
 
 global.replaceUrlInTab = (gBrowser, tab, url) => {
   let loaded = waitForTabLoaded(tab, url);
   gBrowser.loadURI(url, {
     flags: Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY,
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), // This is safe from this functions usage however it would be preferred not to dot his.
   });
   return loaded;
 };
 
 /**
  * Manages tab-specific and window-specific context data, and dispatches
  * tab select events across all windows.
  */
--- a/browser/components/feeds/test/browser/browser_registerProtocolHandler_notification.js
+++ b/browser/components/feeds/test/browser/browser_registerProtocolHandler_notification.js
@@ -2,17 +2,17 @@
  * 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/. */
 
 const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
 add_task(async function() {
   let notificationValue = "Protocol Registration: web+testprotocol";
   let testURI = TEST_PATH + "browser_registerProtocolHandler_notification.html";
 
-  window.gBrowser.selectedBrowser.loadURI(testURI);
+  BrowserTestUtils.loadURI(window.gBrowser.selectedBrowser, testURI);
   await TestUtils.waitForCondition(function() {
     // Do not start until the notification is up
     let notificationBox = window.gBrowser.getNotificationBox();
     let notification = notificationBox.getNotificationWithValue(notificationValue);
     return notification;
   }, "Still can not get notification after retrying 100 times.", 100, 100);
 
   let notificationBox = window.gBrowser.getNotificationBox();
--- a/browser/components/newtab/lib/SnippetsFeed.jsm
+++ b/browser/components/newtab/lib/SnippetsFeed.jsm
@@ -185,17 +185,19 @@ this.SnippetsFeed = class SnippetsFeed {
     Services.prefs.removeObserver(FXA_USERNAME_PREF, this._refresh);
     Services.obs.removeObserver(this, SEARCH_ENGINE_OBSERVER_TOPIC);
     this.store.dispatch(ac.BroadcastToContent({type: at.SNIPPETS_RESET}));
   }
 
   async showFirefoxAccounts(browser) {
     const url = await FxAccounts.config.promiseSignUpURI("snippets");
     // We want to replace the current tab.
-    browser.loadURI(url);
+    browser.loadURI(url, {
+      triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+    });
   }
 
   async onAction(action) {
     switch (action.type) {
       case at.INIT:
         this.init();
         break;
       case at.UNINIT:
--- a/browser/components/originattributes/test/browser/browser_firstPartyIsolation_aboutPages.js
+++ b/browser/components/originattributes/test/browser/browser_firstPartyIsolation_aboutPages.js
@@ -101,17 +101,17 @@ add_task(async function test_remote_wind
  */
 add_task(async function test_remote_window_open_data_uri2() {
   let win = await BrowserTestUtils.openNewBrowserWindow({ remote: true });
   let browser = win.gBrowser.selectedBrowser;
 
   // The iframe test2.html will fetch test2.js, which will have cookies.
   const DATA_URI = `data:text/html,
                     <iframe id="iframe1" src="http://mochi.test:8888/browser/browser/components/originattributes/test/browser/test2.html"></iframe>`;
-  browser.loadURI(DATA_URI);
+  BrowserTestUtils.loadURI(browser, DATA_URI);
   await BrowserTestUtils.browserLoaded(browser, true);
 
   await ContentTask.spawn(browser, {}, async function() {
     info("origin " + content.document.nodePrincipal.origin);
 
     let iframe = content.document.getElementById("iframe1");
     info("iframe principal: " + iframe.contentDocument.nodePrincipal.origin);
 
--- a/browser/components/originattributes/test/browser/browser_firstPartyIsolation_blobURI.js
+++ b/browser/components/originattributes/test/browser/browser_firstPartyIsolation_blobURI.js
@@ -17,17 +17,17 @@ add_task(async function setup() {
 add_task(async function test_blob_uri_inherit_oa_from_content() {
   const BASE_URI = "http://mochi.test:8888/browser/browser/components/" +
                    "originattributes/test/browser/dummy.html";
   const BASE_DOMAIN = "mochi.test";
 
   // First we load a normal web page.
   let win = await BrowserTestUtils.openNewBrowserWindow({ remote: true });
   let browser = win.gBrowser.selectedBrowser;
-  browser.loadURI(BASE_URI);
+  BrowserTestUtils.loadURI(browser, BASE_URI);
   await BrowserTestUtils.browserLoaded(browser);
 
   // Then navigate to the blob: URI.
   await ContentTask.spawn(browser, { firstPartyDomain: BASE_DOMAIN }, async function(attrs) {
     info("origin " + content.document.nodePrincipal.origin);
     Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
                  attrs.firstPartyDomain, "The document should have firstPartyDomain");
 
--- a/browser/components/originattributes/test/browser/browser_firstPartyIsolation_js_uri.js
+++ b/browser/components/originattributes/test/browser/browser_firstPartyIsolation_js_uri.js
@@ -7,17 +7,17 @@ add_task(async function setup() {
 });
 
 add_task(async function test_remote_window_open_js_uri() {
   let win = await BrowserTestUtils.openNewBrowserWindow({ remote: true });
   let browser = win.gBrowser.selectedBrowser;
 
   Assert.ok(browser.isRemoteBrowser, "should be a remote browser");
 
-  browser.loadURI(`javascript:1;`);
+  BrowserTestUtils.loadURI(browser, `javascript:1;`);
   await ContentTask.spawn(browser, {}, async function() {
     info("origin " + content.document.nodePrincipal.origin);
 
     Assert.ok(content.document.nodePrincipal.isNullPrincipal,
               "The principal of remote javascript: should be a NullPrincipal.");
 
     let str = content.document.nodePrincipal.originNoSuffix;
     let expectDomain = str.substring("moz-nullprincipal:{".length, str.length - 1) + ".mozilla";
@@ -30,17 +30,17 @@ add_task(async function test_remote_wind
 });
 
 add_task(async function test_remote_window_open_js_uri2() {
   let win = await BrowserTestUtils.openNewBrowserWindow({ remote: true });
   let browser = win.gBrowser.selectedBrowser;
 
   Assert.ok(browser.isRemoteBrowser, "should be a remote browser");
 
-  browser.loadURI(`javascript:
+  BrowserTestUtils.loadURI(browser, `javascript:
     let iframe = document.createElement("iframe");
     iframe.src = "http://example.com";
     iframe.id = "iframe1";
     document.body.appendChild(iframe);
     alert("connect to http://example.com");
  `);
 
   await BrowserTestUtils.browserLoaded(browser, true, function(url) {
--- a/browser/components/preferences/in-content/subdialogs.js
+++ b/browser/components/preferences/in-content/subdialogs.js
@@ -154,17 +154,19 @@ SubDialog.prototype = {
           this._frame.removeEventListener("load", onBlankLoad);
           // We're now officially done closing, so update the state to reflect that.
           this._openedURL = null;
           this._isClosing = false;
           this._resolveClosePromise();
         }
       };
       this._frame.addEventListener("load", onBlankLoad);
-      this._frame.loadURI("about:blank");
+      this._frame.loadURI("about:blank", {
+        triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+      });
     }, 0);
   },
 
   handleEvent(aEvent) {
     switch (aEvent.type) {
       case "click":
         // Close the dialog if the user clicked the overlay background, just
         // like when the user presses the ESC key (case "command" below).
--- a/browser/components/preferences/in-content/sync.js
+++ b/browser/components/preferences/in-content/sync.js
@@ -353,17 +353,19 @@ var gSyncPane = {
     win.switchToTabHavingURI(url, true, options);
   },
 
   // Replace the current tab with the specified URL.
   replaceTabWithUrl(url) {
     // Get the <browser> element hosting us.
     let browser = window.docShell.chromeEventHandler;
     // And tell it to load our URL.
-    browser.loadURI(url);
+    browser.loadURI(url, {
+      triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+    });
   },
 
   async signIn() {
     const url = await FxAccounts.config.promiseSignInURI(this._getEntryPoint());
     this.replaceTabWithUrl(url);
   },
 
   async reSignIn() {
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_blobUrl.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_blobUrl.js
@@ -5,32 +5,32 @@
 
 const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
   + "privatebrowsing/test/browser/empty_file.html";
 
 add_task(async function test() {
   info("Creating a normal window...");
   let win = await BrowserTestUtils.openNewBrowserWindow();
   let tab = win.gBrowser.selectedBrowser;
-  tab.loadURI(BASE_URI);
+  BrowserTestUtils.loadURI(tab, BASE_URI);
   await BrowserTestUtils.browserLoaded(tab);
 
   let blobURL;
 
   info("Creating a blob URL...");
   await ContentTask.spawn(tab, null, function() {
     return Promise.resolve(content.window.URL.createObjectURL(new content.window.Blob([123])));
   }).then(newURL => { blobURL = newURL; });
 
   info("Blob URL: " + blobURL);
 
   info("Creating a private window...");
   let privateWin = await BrowserTestUtils.openNewBrowserWindow({ private: true });
   let privateTab = privateWin.gBrowser.selectedBrowser;
-  privateTab.loadURI(BASE_URI);
+  BrowserTestUtils.loadURI(privateTab, BASE_URI);
   await BrowserTestUtils.browserLoaded(privateTab);
 
   await ContentTask.spawn(privateTab, blobURL, function(url) {
     return new Promise(resolve => {
       var xhr = new content.window.XMLHttpRequest();
       xhr.onerror = function() { resolve("SendErrored"); };
       xhr.onload = function() { resolve("SendLoaded"); };
       xhr.open("GET", url);
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
@@ -22,74 +22,74 @@ add_task(async function test() {
 
   function getElts(browser) {
     return browser.contentTitle.split("|");
   }
 
   // Step 1
   let non_private_browser = gBrowser.selectedBrowser;
   let url = prefix + "?action=set&name=test&value=value&initial=true";
-  non_private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(non_private_browser, url);
   await BrowserTestUtils.browserLoaded(non_private_browser, false, url);
 
 
   // Step 2
   let private_window = await BrowserTestUtils.openNewBrowserWindow({ private: true });
   let private_browser = private_window.getBrowser().selectedBrowser;
   url = prefix + "?action=set&name=test2&value=value2";
-  private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(private_browser, url);
   await BrowserTestUtils.browserLoaded(private_browser, false, url);
 
 
   // Step 3
   url = prefix + "?action=get&name=test2";
-  non_private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(non_private_browser, url);
   await BrowserTestUtils.browserLoaded(non_private_browser, false, url);
   let elts = await getElts(non_private_browser);
   isnot(elts[0], "value2", "public window shouldn't see private storage");
   is(elts[1], "1", "public window should only see public items");
 
 
   // Step 4
   url = prefix + "?action=get&name=test";
-  private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(private_browser, url);
   await BrowserTestUtils.browserLoaded(private_browser, false, url);
   elts = await getElts(private_browser);
   isnot(elts[0], "value", "private window shouldn't see public storage");
   is(elts[1], "1", "private window should only see private items");
 
 
   // Reopen the private window again, without privateBrowsing, which should clear the
   // the private storage.
   private_window.close();
   private_window = await BrowserTestUtils.openNewBrowserWindow({ private: false });
   private_browser = null;
   await new Promise(resolve => Cu.schedulePreciseGC(resolve));
   private_browser = private_window.getBrowser().selectedBrowser;
 
   url = prefix + "?action=get&name=test2";
-  private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(private_browser, url);
   await BrowserTestUtils.browserLoaded(private_browser, false, url);
   elts = await getElts(private_browser);
   isnot(elts[0], "value2", "public window shouldn't see cleared private storage");
   is(elts[1], "1", "public window should only see public items");
 
 
   // Making it private again should clear the storage and it shouldn't
   // be able to see the old private storage as well.
   private_window.close();
   private_window = await BrowserTestUtils.openNewBrowserWindow({ private: true });
   private_browser = null;
   await new Promise(resolve => Cu.schedulePreciseGC(resolve));
   private_browser = private_window.getBrowser().selectedBrowser;
 
   url = prefix + "?action=set&name=test3&value=value3";
-  private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(private_browser, url);
   await BrowserTestUtils.browserLoaded(private_browser, false, url);
   elts = await getElts(private_browser);
   is(elts[1], "1", "private window should only see new private items");
 
   // Cleanup.
   url = prefix + "?final=true";
-  non_private_browser.loadURI(url);
+  BrowserTestUtils.loadURI(non_private_browser, url);
   await BrowserTestUtils.browserLoaded(non_private_browser, false, url);
   private_window.close();
 });
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js
@@ -15,26 +15,26 @@ add_task(async function test() {
     is(crhCommand.hasAttribute("disabled"), aPrivateMode,
       "Clear Recent History command should be disabled according to the private browsing mode");
   }
 
   let testURI = "http://mochi.test:8888/";
 
   let privateWin = await BrowserTestUtils.openNewBrowserWindow({private: true});
   let privateBrowser = privateWin.gBrowser.selectedBrowser;
-  privateBrowser.loadURI(testURI);
+  BrowserTestUtils.loadURI(privateBrowser, testURI);
   await BrowserTestUtils.browserLoaded(privateBrowser);
 
   info("Test on private window");
   checkDisableOption(true, privateWin);
 
 
   let win = await BrowserTestUtils.openNewBrowserWindow();
   let browser = win.gBrowser.selectedBrowser;
-  browser.loadURI(testURI);
+  BrowserTestUtils.loadURI(browser, testURI);
   await BrowserTestUtils.browserLoaded(browser);
 
   info("Test on public window");
   checkDisableOption(false, win);
 
 
   // Cleanup
   await BrowserTestUtils.closeWindow(privateWin);
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
@@ -31,24 +31,24 @@ add_task(async function test() {
       notification.remove();
 
       aWindow.gBrowser.removeCurrentTab();
     })();
   }
 
   let win = await BrowserTestUtils.openNewBrowserWindow();
   let browser = win.gBrowser.selectedBrowser;
-  browser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(browser, testPageURL);
   await BrowserTestUtils.browserLoaded(browser);
 
   await checkGeolocation(false, win);
 
   let privateWin = await BrowserTestUtils.openNewBrowserWindow({private: true});
   let privateBrowser = privateWin.gBrowser.selectedBrowser;
-  privateBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(privateBrowser, testPageURL);
   await BrowserTestUtils.browserLoaded(privateBrowser);
 
   await checkGeolocation(true, privateWin);
 
   // Cleanup
   await BrowserTestUtils.closeWindow(win);
   await BrowserTestUtils.closeWindow(privateWin);
 });
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
@@ -8,18 +8,17 @@
                 "browser_privatebrowsing_localStorage_page1.html";
 
   let win = await BrowserTestUtils.openNewBrowserWindow({private: true});
 
   win.gBrowser.selectedTab = BrowserTestUtils.addTab(win.gBrowser, page1);
   let browser = win.gBrowser.selectedBrowser;
   await BrowserTestUtils.browserLoaded(browser);
 
-  browser.loadURI(
-    "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/" +
+  BrowserTestUtils.loadURI(browser, "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/" +
     "browser_privatebrowsing_localStorage_page2.html");
   await BrowserTestUtils.browserLoaded(browser);
 
   is(browser.contentTitle, "2", "localStorage should contain 2 items");
 
   // Cleanup
   await BrowserTestUtils.closeWindow(win);
  });
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
@@ -41,17 +41,17 @@ add_task(async function test() {
         checkMenuItem(function() {
           aCallback();
         });
         notification.querySelector("button").doCommand();
       });
 
     }, {once: true});
 
-    aWindow.gBrowser.selectedBrowser.loadURI(testURI);
+    BrowserTestUtils.loadURI(aWindow.gBrowser.selectedBrowser, testURI);
   }
 
   let win1 = await BrowserTestUtils.openNewBrowserWindow();
   await new Promise(resolve => waitForFocus(resolve, win1));
   await new Promise(resolve => testPopupBlockerMenuItem(false, win1, resolve));
 
   let win2 = await BrowserTestUtils.openNewBrowserWindow({private: true});
   await new Promise(resolve => waitForFocus(resolve, win2));
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
@@ -27,17 +27,17 @@ function test() {
         "The Private Browsing menu item should read \"New Private Window\"");
       is(PrivateBrowsingUtils.isWindowPrivate(aWindow), aIsPrivateMode,
         "PrivateBrowsingUtils should report the correct per-window private browsing status (privateBrowsing should be " +
         aIsPrivateMode + ")");
 
       aCallback();
     });
 
-    aWindow.gBrowser.selectedBrowser.loadURI(testURI);
+    BrowserTestUtils.loadURI(aWindow.gBrowser.selectedBrowser, testURI);
   }
 
   function openPrivateBrowsingModeByUI(aWindow, aCallback) {
     Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
       aSubject.addEventListener("load", function() {
         Services.obs.removeObserver(observer, "domwindowopened");
           windowsToClose.push(aSubject);
           aCallback(aSubject);
--- a/browser/components/safebrowsing/content/test/browser_bug400731.js
+++ b/browser/components/safebrowsing/content/test/browser_bug400731.js
@@ -35,28 +35,28 @@ function test() {
 
 function testMalware(data) {
   ok(data.buttonPresent, "Ignore warning link should be present for malware");
 
   Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", false);
 
   // Now launch the unwanted software test
   onDOMContentLoaded(testUnwanted);
-  gBrowser.loadURI("http://www.itisatrap.org/firefox/unwanted.html");
+  BrowserTestUtils.loadURI(gBrowser, "http://www.itisatrap.org/firefox/unwanted.html");
 }
 
 function testUnwanted(data) {
   // Confirm that "Ignore this warning" is visible - bug 422410
   ok(!data.buttonPresent, "Ignore warning link should be missing for unwanted software");
 
   Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", true);
 
   // Now launch the phishing test
   onDOMContentLoaded(testPhishing);
-  gBrowser.loadURI("http://www.itisatrap.org/firefox/its-a-trap.html");
+  BrowserTestUtils.loadURI(gBrowser, "http://www.itisatrap.org/firefox/its-a-trap.html");
 }
 
 function testPhishing(data) {
   ok(data.buttonPresent, "Ignore warning link should be present for phishing");
 
   gBrowser.removeCurrentTab();
   finish();
 }
--- a/browser/components/safebrowsing/content/test/browser_bug415846.js
+++ b/browser/components/safebrowsing/content/test/browser_bug415846.js
@@ -27,17 +27,17 @@ function check_menu_at_page(url, testFn)
     gBrowser,
     url: "about:blank",
   }, async function(browser) {
     // We don't get load events when the DocShell redirects to error
     // pages, but we do get DOMContentLoaded, so we'll wait for that.
     let dclPromise = ContentTask.spawn(browser, null, async function() {
       await ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", false);
     });
-    browser.loadURI(url);
+    BrowserTestUtils.loadURI(browser, url);
     await dclPromise;
 
     let menu = document.getElementById("menu_HelpPopup");
     ok(menu, "Help menu should exist");
 
     let reportMenu =
       document.getElementById("menu_HelpPopup_reportPhishingtoolmenu");
     ok(reportMenu, "Report phishing menu item should exist");
--- a/browser/components/search/test/browser_426329.js
+++ b/browser/components/search/test/browser_426329.js
@@ -196,17 +196,19 @@ add_task(async function testShiftMiddleC
   let newTab = await newTabPromise;
 
   is(gBrowser.tabs.length, preTabNo + 1, "Shift+MiddleClick added new tab");
   is(newTab.linkedBrowser.currentURI.spec, url, "testShiftMiddleClick opened correct search page");
 });
 
 add_task(async function testRightClick() {
   preTabNo = gBrowser.tabs.length;
-  gBrowser.selectedBrowser.loadURI("about:blank");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank", {
+    triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+  });
   await new Promise(resolve => {
     setTimeout(function() {
       is(gBrowser.tabs.length, preTabNo, "RightClick did not open new tab");
       is(gBrowser.currentURI.spec, "about:blank", "RightClick did nothing");
       resolve();
     }, 5000);
     simulateClick({ button: 2 }, searchButton);
   });
@@ -250,17 +252,19 @@ add_task(async function testClearHistory
   ok(count == 0, "History cleared");
 });
 
 add_task(async function asyncCleanup() {
   searchBar.value = "";
   while (gBrowser.tabs.length != 1) {
     gBrowser.removeTab(gBrowser.tabs[0], {animate: false});
   }
-  gBrowser.selectedBrowser.loadURI("about:blank");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank", {
+    triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+  });
   await promiseRemoveEngine();
 });
 
 function promiseObserver(topic) {
   return new Promise(resolve => {
     let obs = (aSubject, aTopic, aData) => {
       Services.obs.removeObserver(obs, aTopic);
       resolve(aSubject);
--- a/browser/components/search/test/browser_abouthome_behavior.js
+++ b/browser/components/search/test/browser_abouthome_behavior.js
@@ -23,17 +23,17 @@ function test() {
     let engine = Services.search.getEngineByName(engine_name);
     ok(engine, engine_name + " is installed");
 
     Services.search.currentEngine = engine;
 
     // load about:home, but remove the listener first so it doesn't
     // get in the way
     gBrowser.removeProgressListener(listener);
-    gBrowser.loadURI("about:home");
+    BrowserTestUtils.loadURI(gBrowser, "about:home");
     info("Waiting for about:home load");
     tab.linkedBrowser.addEventListener("load", function load(event) {
       if (event.originalTarget != tab.linkedBrowser.contentDocumentAsCPOW ||
           event.target.location.href == "about:blank") {
         info("skipping spurious load event");
         return;
       }
       tab.linkedBrowser.removeEventListener("load", load, true);
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -2955,17 +2955,21 @@ var SessionStoreInternal = {
                       "Somehow a crashed browser is still remote.");
     }
 
     // We put the browser at about:blank in case the user is
     // restoring tabs on demand. This way, the user won't see
     // a flash of the about:tabcrashed page after selecting
     // the revived tab.
     aTab.removeAttribute("crashed");
-    browser.loadURI("about:blank");
+    browser.loadURI("about:blank", {
+      triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({
+        userContextId: aTab.userContextId,
+      }),
+    });
 
     let data = TabState.collect(aTab, TAB_CUSTOM_VALUES.get(aTab));
     this.restoreTab(aTab, data, {
       forceOnDemand: true,
     });
   },
 
   /**
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -175,17 +175,19 @@ function restoreSession() {
     var tabbrowser = top.gBrowser;
     var tabIndex = tabbrowser.getBrowserIndexForDocument(document);
     tabbrowser.removeTab(tabbrowser.tabs[tabIndex]);
   }, "browser-delayed-startup-finished");
 }
 
 function startNewSession() {
   if (Services.prefs.getIntPref("browser.startup.page") == 0)
-    getBrowserWindow().gBrowser.loadURI("about:blank");
+    getBrowserWindow().gBrowser.loadURI("about:blank", {
+      triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+    });
   else
     getBrowserWindow().BrowserHome();
 }
 
 function onListClick(aEvent) {
   // don't react to right-clicks
   if (aEvent.button == 2)
     return;
--- a/browser/components/sessionstore/test/browser_394759_perwindowpb.js
+++ b/browser/components/sessionstore/test/browser_394759_perwindowpb.js
@@ -11,17 +11,17 @@ const TESTS = [
   { url: "about:mozilla",
     key: "bug 394759 PB",
     value: "uniq" + r() },
 ];
 
 function promiseTestOpenCloseWindow(aIsPrivate, aTest) {
   return (async function() {
     let win = await BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
-    win.gBrowser.selectedBrowser.loadURI(aTest.url);
+    BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, aTest.url);
     await promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, aTest.url);
     // Mark the window with some unique data to be restored later on.
     ss.setWindowValue(win, aTest.key, aTest.value);
     await TabStateFlusher.flushWindow(win);
     // Close.
     await BrowserTestUtils.closeWindow(win);
   })();
 }
--- a/browser/components/sessionstore/test/browser_480893.js
+++ b/browser/components/sessionstore/test/browser_480893.js
@@ -28,17 +28,17 @@ add_task(async function() {
   let homepage = "http://mochi.test:8888/";
   await SpecialPowers.pushPrefEnv({
     "set": [
       ["browser.startup.homepage", homepage],
       ["browser.startup.page", 1],
     ],
   });
 
-  browser.loadURI("about:sessionrestore");
+  BrowserTestUtils.loadURI(browser, "about:sessionrestore");
   await BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
   doc = browser.contentDocument;
 
   // Click on the "Close" button after about:sessionrestore is loaded.
   doc.getElementById("errorCancel").click();
   await BrowserTestUtils.browserLoaded(browser);
 
   is(browser.currentURI.spec, homepage, "loaded page is the homepage");
--- a/browser/components/sessionstore/test/browser_491168.js
+++ b/browser/components/sessionstore/test/browser_491168.js
@@ -12,17 +12,20 @@ add_task(async function() {
 
   // Add a new tab.
   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
   await promiseBrowserLoaded(browser);
 
   // Load a new URI with a specific referrer.
   let referrerURI = Services.io.newURI(REFERRER1);
-  browser.loadURI("http://example.org", { referrerURI });
+  browser.loadURI("http://example.org", {
+    referrerURI,
+    triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+  });
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
   let tabState = JSON.parse(ss.getTabState(tab));
   is(tabState.entries[0].referrer, REFERRER1,
      "Referrer retrieved via getTabState matches referrer set via loadURI.");
 
   tabState.entries[0].referrer = REFERRER2;
--- a/browser/components/sessionstore/test/browser_async_window_flushing.js
+++ b/browser/components/sessionstore/test/browser_async_window_flushing.js
@@ -92,17 +92,17 @@ add_task(async function test_remove_unin
                    initialClosedWindows + 1]);
 
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
 
   // Now browse the initial tab of that window to an interesting
   // site.
   let tab = newWin.gBrowser.selectedTab;
   let browser = tab.linkedBrowser;
-  browser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(browser, PAGE);
 
   await BrowserTestUtils.browserLoaded(browser, false, PAGE);
   await TabStateFlusher.flush(browser);
 
   // Send a message that will cause the content to purge its
   // history entries and make itself seem uninteresting.
   await ContentTask.spawn(browser, null, async function() {
     // Epic hackery to make this browser seem suddenly boring.
@@ -152,17 +152,17 @@ add_task(async function test_synchronous
   let state = JSON.parse(ss.getBrowserState());
   ok(state, "Make sure we can get the state");
   let initialWindows = state.windows.length;
 
   // Open a new window and send the first tab somewhere
   // interesting.
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
   let browser = newWin.gBrowser.selectedBrowser;
-  browser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(browser, PAGE);
   await BrowserTestUtils.browserLoaded(browser, false, PAGE);
   await TabStateFlusher.flush(browser);
 
   state = JSON.parse(ss.getBrowserState());
   is(state.windows.length, initialWindows + 1,
      "The new window to be in the state");
 
   // Now close the window, and make sure that the window was removed
--- a/browser/components/sessionstore/test/browser_background_tab_crash.js
+++ b/browser/components/sessionstore/test/browser_background_tab_crash.js
@@ -27,17 +27,17 @@
 async function setupBackgroundTabs(testFn) {
   const REMOTE_PAGE = "http://www.example.com";
   const NON_REMOTE_PAGE = "about:robots";
 
   // Browse the initial tab to a non-remote page, which we'll have in the
   // foreground.
   let initialTab = gBrowser.selectedTab;
   let initialBrowser = initialTab.linkedBrowser;
-  initialBrowser.loadURI(NON_REMOTE_PAGE);
+  BrowserTestUtils.loadURI(initialBrowser, NON_REMOTE_PAGE);
   await BrowserTestUtils.browserLoaded(initialBrowser);
 
   // Open some tabs that should be running in the content process.
   let tab1 =
     await BrowserTestUtils.openNewForegroundTab(gBrowser, REMOTE_PAGE);
   let remoteBrowser1 = tab1.linkedBrowser;
   await TabStateFlusher.flush(remoteBrowser1);
 
--- a/browser/components/sessionstore/test/browser_backup_recovery.js
+++ b/browser/components/sessionstore/test/browser_backup_recovery.js
@@ -68,17 +68,17 @@ add_task(async function test_creation() 
   ok(!(await File.exists(Paths.recoveryBackup)), "After write, recoveryBackup sessionstore doesn't exist");
   ok((await promiseRead(Paths.recovery)).includes(URL), "Recovery sessionstore file contains the required tab");
   ok(!(await File.exists(Paths.clean)), "After first write, clean shutdown " +
     "sessionstore doesn't exist, since we haven't shutdown yet");
 
   // Open a second tab, save session, ensure that the correct files exist.
   info("Testing situation after a second write");
   let URL2 = URL_BASE + "?second_write";
-  tab.linkedBrowser.loadURI(URL2);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, URL2);
   await promiseBrowserLoaded(tab.linkedBrowser);
   await TabStateFlusher.flush(tab.linkedBrowser);
   await SessionSaver.run();
 
   ok((await File.exists(Paths.recovery)), "After second write, recovery sessionstore file still exists");
   ok((await promiseRead(Paths.recovery)).includes(URL2), "Recovery sessionstore file contains the latest url");
   ok((await File.exists(Paths.recoveryBackup)), "After write, recoveryBackup sessionstore now exists");
   let backup = await promiseRead(Paths.recoveryBackup);
--- a/browser/components/sessionstore/test/browser_broadcast.js
+++ b/browser/components/sessionstore/test/browser_broadcast.js
@@ -115,15 +115,15 @@ function promiseNewWindow() {
   });
 }
 
 async function createTabWithStorageData(urls, win = window) {
   let tab = BrowserTestUtils.addTab(win.gBrowser);
   let browser = tab.linkedBrowser;
 
   for (let url of urls) {
-    browser.loadURI(url);
+    BrowserTestUtils.loadURI(browser, url);
     await promiseBrowserLoaded(browser);
     await modifySessionStorage(browser, {test: INITIAL_VALUE});
   }
 
   return tab;
 }
--- a/browser/components/sessionstore/test/browser_closed_objects_changed_notifications_tabs.js
+++ b/browser/components/sessionstore/test/browser_closed_objects_changed_notifications_tabs.js
@@ -7,17 +7,17 @@
 const MAX_TABS_UNDO_PREF = "browser.sessionstore.max_tabs_undo";
 const TOPIC = "sessionstore-closed-objects-changed";
 
 let notificationsCount = 0;
 
 async function openWindow(url) {
   let win = await promiseNewWindowLoaded();
   let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
-  win.gBrowser.selectedBrowser.loadURI(url, { flags });
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url, { flags });
   await promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, url);
   return win;
 }
 
 async function closeWindow(win) {
   await awaitNotification(() => BrowserTestUtils.closeWindow(win));
 }
 
--- a/browser/components/sessionstore/test/browser_closed_objects_changed_notifications_windows.js
+++ b/browser/components/sessionstore/test/browser_closed_objects_changed_notifications_windows.js
@@ -9,17 +9,17 @@ requestLongerTimeout(2);
 const MAX_WINDOWS_UNDO_PREF = "browser.sessionstore.max_windows_undo";
 const TOPIC = "sessionstore-closed-objects-changed";
 
 let notificationsCount = 0;
 
 async function openWindow(url) {
   let win = await promiseNewWindowLoaded();
   let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
-  win.gBrowser.selectedBrowser.loadURI(url, { flags });
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url, { flags });
   await promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, url);
   return win;
 }
 
 async function closeWindow(win) {
   await awaitNotification(() => BrowserTestUtils.closeWindow(win));
 }
 
--- a/browser/components/sessionstore/test/browser_crashedTabs.js
+++ b/browser/components/sessionstore/test/browser_crashedTabs.js
@@ -129,17 +129,17 @@ function promiseTabCrashedReady(browser)
  */
 add_task(async function test_crash_page_not_in_history() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
 
   // Check the tab state and make sure the tab crashed page isn't
   // mentioned.
@@ -158,26 +158,26 @@ add_task(async function test_crash_page_
  */
 add_task(async function test_revived_history_from_remote() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
 
   // Browse to a new site that will cause the browser to
   // become remote again.
-  browser.loadURI(PAGE_2);
+  BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseTabRestored(newTab);
   ok(!newTab.hasAttribute("crashed"), "Tab shouldn't be marked as crashed anymore.");
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await TabStateFlusher.flush(browser);
 
   // Check the tab state and make sure the tab crashed page isn't
   // mentioned.
   let {entries} = JSON.parse(ss.getTabState(newTab));
@@ -197,26 +197,26 @@ add_task(async function test_revived_his
  */
 add_task(async function test_revived_history_from_non_remote() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
 
   // Browse to a new site that will not cause the browser to
   // become remote again.
-  browser.loadURI("about:mozilla");
+  BrowserTestUtils.loadURI(browser, "about:mozilla");
   await promiseBrowserLoaded(browser);
   ok(!newTab.hasAttribute("crashed"), "Tab shouldn't be marked as crashed anymore.");
   ok(!browser.isRemoteBrowser, "Should not be a remote browser");
   await TabStateFlusher.flush(browser);
 
   // Check the tab state and make sure the tab crashed page isn't
   // mentioned.
   let {entries} = JSON.parse(ss.getTabState(newTab));
@@ -235,28 +235,28 @@ add_task(async function test_revived_his
  */
 add_task(async function test_revive_tab_from_session_store() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   let newTab2 = BrowserTestUtils.addTab(gBrowser, "about:blank", { sameProcessAsFrameLoader: browser.frameLoader });
   let browser2 = newTab2.linkedBrowser;
   ok(browser2.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser2);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_2);
+  BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
   // Background tabs should not be crashed, but should be in the "to be restored"
   // state.
@@ -288,33 +288,33 @@ add_task(async function test_revive_tab_
  */
 add_task(async function test_revive_all_tabs_from_session_store() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   // In order to see a second about:tabcrashed page, we'll need
   // a second window, since only selected tabs will show
   // about:tabcrashed.
   let win2 = await BrowserTestUtils.openNewBrowserWindow();
   let newTab2 = BrowserTestUtils.addTab(win2.gBrowser, PAGE_1, { sameProcessAsFrameLoader: browser.frameLoader });
   win2.gBrowser.selectedTab = newTab2;
   let browser2 = newTab2.linkedBrowser;
   ok(browser2.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser2);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_2);
+  BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
   await TabStateFlusher.flush(browser2);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
   // Both tabs should now be crashed.
@@ -348,17 +348,17 @@ add_task(async function test_revive_all_
  */
 add_task(async function test_close_tab_after_crash() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
 
   let promise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
@@ -377,17 +377,17 @@ add_task(async function test_close_tab_a
  */
 add_task(async function test_hide_restore_all_button() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
   await BrowserTestUtils.crashBrowser(browser);
 
   let doc = browser.contentDocument;
@@ -396,17 +396,17 @@ add_task(async function test_hide_restor
 
   let restoreAllStyles = window.getComputedStyle(restoreAllButton);
   is(restoreAllStyles.display, "none", "Restore All button should be hidden");
   ok(restoreOneButton.classList.contains("primary"), "Restore Tab button should have the primary class");
 
   let newTab2 = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
 
-  browser.loadURI(PAGE_2);
+  BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseBrowserLoaded(browser);
 
   // Load up a second window so we can get another tab to show
   // about:tabcrashed
   let win2 = await BrowserTestUtils.openNewBrowserWindow();
   let newTab3 = BrowserTestUtils.addTab(win2.gBrowser, PAGE_2, { sameProcessAsFrameLoader: browser.frameLoader });
   win2.gBrowser.selectedTab = newTab3;
   let otherWinBrowser = newTab3.linkedBrowser;
@@ -435,17 +435,17 @@ add_task(async function test_hide_restor
 
 add_task(async function test_aboutcrashedtabzoom() {
   let newTab = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = newTab;
   let browser = newTab.linkedBrowser;
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   FullZoom.enlarge();
   let zoomLevel = ZoomManager.getZoomForBrowser(browser);
   ok(zoomLevel !== 1, "should have enlarged");
 
   await TabStateFlusher.flush(browser);
 
--- a/browser/components/sessionstore/test/browser_dying_cache.js
+++ b/browser/components/sessionstore/test/browser_dying_cache.js
@@ -7,17 +7,17 @@
  */
 
 add_task(async function test() {
   // Open a new window.
   let win = await promiseNewWindowLoaded();
 
   // Load some URL in the current tab.
   let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
-  win.gBrowser.selectedBrowser.loadURI("about:robots", { flags });
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, "about:robots", { flags });
   await promiseBrowserLoaded(win.gBrowser.selectedBrowser);
 
   // Open a second tab and close the first one.
   let tab = BrowserTestUtils.addTab(win.gBrowser, "about:mozilla");
   await promiseBrowserLoaded(tab.linkedBrowser);
   await TabStateFlusher.flush(tab.linkedBrowser);
   await promiseRemoveTabAndSessionState(win.gBrowser.tabs[0]);
 
--- a/browser/components/sessionstore/test/browser_forget_async_closings.js
+++ b/browser/components/sessionstore/test/browser_forget_async_closings.js
@@ -73,17 +73,17 @@ let forgetWinHelper = async function(for
 
   is(ss.getClosedWindowCount(), 0, "We should have 0 closed windows being stored.");
 
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
 
   // Create a tab worth remembering.
   let tab = newWin.gBrowser.selectedTab;
   let browser = tab.linkedBrowser;
-  browser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(browser, PAGE);
   await BrowserTestUtils.browserLoaded(browser, false, PAGE);
   await TabStateFlusher.flush(browser);
 
   // Now close the window and immediately choose to forget it.
   let windowClosed = BrowserTestUtils.windowClosed(newWin);
 
   let handled = false;
   whenDomWindowClosedHandled(() => {
--- a/browser/components/sessionstore/test/browser_frametree.js
+++ b/browser/components/sessionstore/test/browser_frametree.js
@@ -15,17 +15,17 @@ add_task(async function test_frametree()
   let tab = BrowserTestUtils.addTab(gBrowser, URL);
   let browser = tab.linkedBrowser;
   await promiseBrowserLoaded(browser);
 
   // The page is a single frame with no children.
   is(await countNonDynamicFrames(browser), 0, "no child frames");
 
   // Navigate to a frameset.
-  browser.loadURI(URL_FRAMESET);
+  BrowserTestUtils.loadURI(browser, URL_FRAMESET);
   await promiseBrowserLoaded(browser);
 
   // The frameset has two frames.
   is(await countNonDynamicFrames(browser), 2, "two non-dynamic child frames");
 
   // Go back in history.
   let pageShowPromise = ContentTask.spawn(browser, null, async () => {
     return ContentTaskUtils.waitForEvent(this, "pageshow", true);
--- a/browser/components/sessionstore/test/browser_history_persist.js
+++ b/browser/components/sessionstore/test/browser_history_persist.js
@@ -29,17 +29,17 @@ add_task(async function check_history_no
     let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsISHistory);
 
     is(sessionHistory.count, 1, "Should be a single history entry");
     is(sessionHistory.getEntryAtIndex(0).URI.spec, "about:blank", "Should be the right URL");
   });
 
   // Load a new URL into the tab, it should replace the about:blank history entry
-  browser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(browser, "about:robots");
   await promiseBrowserLoaded(browser);
   await ContentTask.spawn(browser, null, function() {
     let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsISHistory);
     is(sessionHistory.count, 1, "Should be a single history entry");
     is(sessionHistory.getEntryAtIndex(0).URI.spec, "about:robots", "Should be the right URL");
   });
 
@@ -72,17 +72,17 @@ add_task(async function check_history_de
     let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsISHistory);
 
     is(sessionHistory.count, 1, "Should be a single history entry");
     is(sessionHistory.getEntryAtIndex(0).URI.spec, "about:blank", "Should be the right URL");
   });
 
   // Load a new URL into the tab, it should replace the about:blank history entry
-  browser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(browser, "about:robots");
   await promiseBrowserLoaded(browser);
   await ContentTask.spawn(browser, null, function() {
     let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsISHistory);
     is(sessionHistory.count, 2, "Should be two history entries");
     is(sessionHistory.getEntryAtIndex(0).URI.spec, "about:blank", "Should be the right URL");
     is(sessionHistory.getEntryAtIndex(1).URI.spec, "about:robots", "Should be the right URL");
   });
--- a/browser/components/sessionstore/test/browser_multiple_navigateAndRestore.js
+++ b/browser/components/sessionstore/test/browser_multiple_navigateAndRestore.js
@@ -8,19 +8,19 @@ add_task(async function() {
   let tab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
     forceNotRemote: true,
   });
   gBrowser.selectedTab = tab;
   let browser = gBrowser.selectedBrowser;
   ok(!browser.isRemoteBrowser, "Ensure browser is not remote");
   // Load a remote page, and then another remote page immediately
   // after.
-  browser.loadURI(PAGE_1);
+  BrowserTestUtils.loadURI(browser, PAGE_1);
   browser.stop();
-  browser.loadURI(PAGE_2);
+  BrowserTestUtils.loadURI(browser, PAGE_2);
   await BrowserTestUtils.browserLoaded(browser);
 
   ok(browser.isRemoteBrowser, "Should have switched remoteness");
   await TabStateFlusher.flush(browser);
   let state = JSON.parse(ss.getTabState(tab));
   let entries = state.entries;
   is(entries.length, 1, "There should only be one entry");
   is(entries[0].url, PAGE_2, "Should have PAGE_2 as the sole history entry");
--- a/browser/components/sessionstore/test/browser_privatetabs.js
+++ b/browser/components/sessionstore/test/browser_privatetabs.js
@@ -17,17 +17,17 @@ add_task(async function() {
     info("Setting up public tab");
     tab1 = BrowserTestUtils.addTab(gBrowser, URL_PUBLIC);
     await promiseBrowserLoaded(tab1.linkedBrowser);
 
     info("Setting up private tab");
     tab2 = BrowserTestUtils.addTab(gBrowser);
     await promiseBrowserLoaded(tab2.linkedBrowser);
     await setUsePrivateBrowsing(tab2.linkedBrowser, true);
-    tab2.linkedBrowser.loadURI(URL_PRIVATE);
+    BrowserTestUtils.loadURI(tab2.linkedBrowser, URL_PRIVATE);
     await promiseBrowserLoaded(tab2.linkedBrowser);
 
     info("Flush to make sure chrome received all data.");
     await TabStateFlusher.flush(tab1.linkedBrowser);
     await TabStateFlusher.flush(tab2.linkedBrowser);
 
     info("Checking out state");
     let state = await promiseRecoveryFileContents();
--- a/browser/components/sessionstore/test/browser_replace_load.js
+++ b/browser/components/sessionstore/test/browser_replace_load.js
@@ -27,16 +27,18 @@ var testSwitchToTab = async function(url
   Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
 
   // Prepare the tab state.
   let promise = promiseTabRestoring(tab);
   ss.setTabState(tab, JSON.stringify(STATE));
   ok(tab.hasAttribute("pending"), "tab is pending");
   await promise;
 
+  options.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
+
   // Switch-to-tab with a similar URI.
   switchToTabHavingURI(url, false, options);
 
   // Tab should now restore
   await promiseTabRestored(tab);
   is(browser.currentURI.spec, url, "correct URL loaded");
 
   // Check that we didn't lose any history entries.
--- a/browser/components/sessionstore/test/browser_scrollPositions.js
+++ b/browser/components/sessionstore/test/browser_scrollPositions.js
@@ -120,17 +120,17 @@ add_task(async function test_scroll_back
   let browser = tab.linkedBrowser;
   await BrowserTestUtils.browserLoaded(browser);
 
   // Scroll down a little.
   await sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y});
   await checkScroll(tab, {scroll: SCROLL_STR}, "scroll on first page is fine");
 
   // Navigate to a different page and scroll there as well.
-  browser.loadURI(URL2);
+  BrowserTestUtils.loadURI(browser, URL2);
   await BrowserTestUtils.browserLoaded(browser);
 
   // Scroll down a little.
   await sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL2_X, y: SCROLL2_Y});
   await checkScroll(tab, {scroll: SCROLL2_STR}, "scroll on second page is fine");
 
   // Close the window
   await BrowserTestUtils.closeWindow(newWin);
--- a/browser/components/sessionstore/test/browser_sessionHistory.js
+++ b/browser/components/sessionstore/test/browser_sessionHistory.js
@@ -71,17 +71,17 @@ add_task(async function test_pageshow() 
   const URL2 = "data:text/html;charset=utf-8,<h1>second</h1>";
 
   // Create a new tab.
   let tab = BrowserTestUtils.addTab(gBrowser, URL);
   let browser = tab.linkedBrowser;
   await promiseBrowserLoaded(browser);
 
   // Create a second shistory entry.
-  browser.loadURI(URL2);
+  BrowserTestUtils.loadURI(browser, URL2);
   await promiseBrowserLoaded(browser);
 
   // Wait until shistory changes.
   let pageShowPromise = ContentTask.spawn(browser, null, async () => {
     return ContentTaskUtils.waitForEvent(this, "pageshow", true);
   });
 
   // Go back to the previous url which is loaded from the bfcache.
@@ -159,17 +159,17 @@ add_task(async function test_about_page_
   await TabStateFlusher.flush(browser);
   let {entries} = JSON.parse(ss.getTabState(tab));
   is(entries.length, 1, "there is one shistory entry");
   is(entries[0].url, "about:blank", "url is correct");
 
   // Verify that the title is also recorded.
   is(entries[0].title, "about:blank", "title is correct");
 
-  browser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(browser, "about:robots");
   await promiseBrowserLoaded(browser);
 
   // Check that we have changed the history entry.
   await TabStateFlusher.flush(browser);
   ({entries} = JSON.parse(ss.getTabState(tab)));
   is(entries.length, 1, "there is one shistory entry");
   is(entries[0].url, "about:robots", "url is correct");
 
--- a/browser/components/sessionstore/test/browser_sessionStorage.js
+++ b/browser/components/sessionstore/test/browser_sessionStorage.js
@@ -71,27 +71,27 @@ add_task(async function session_storage(
 
   ({storage} = JSON.parse(ss.getTabState(tab2)));
   is(storage["http://example.com"].test, "modified2",
     "sessionStorage data for example.com has been duplicated correctly");
   is(storage["http://mochi.test:8888"].test, "modified3",
     "sessionStorage data for mochi.test has been duplicated correctly");
 
   // Check that loading a new URL discards data.
-  browser2.loadURI("http://mochi.test:8888/");
+  BrowserTestUtils.loadURI(browser2, "http://mochi.test:8888/");
   await promiseBrowserLoaded(browser2);
   await TabStateFlusher.flush(browser2);
 
   ({storage} = JSON.parse(ss.getTabState(tab2)));
   is(storage["http://mochi.test:8888"].test, "modified3",
     "navigating retains correct storage data");
   ok(!storage["http://example.com"], "storage data was discarded");
 
   // Check that loading a new URL discards data.
-  browser2.loadURI("about:mozilla");
+  BrowserTestUtils.loadURI(browser2, "about:mozilla");
   await promiseBrowserLoaded(browser2);
   await TabStateFlusher.flush(browser2);
 
   let state = JSON.parse(ss.getTabState(tab2));
   ok(!state.hasOwnProperty("storage"), "storage data was discarded");
 
   // Test that clearing the data in the first tab works properly within
   // the subframe
--- a/browser/components/sessionstore/test/browser_switch_remoteness.js
+++ b/browser/components/sessionstore/test/browser_switch_remoteness.js
@@ -22,26 +22,26 @@ add_task(async function() {
   ok(browser.isRemoteBrowser, "browser is remote");
 
   // Get the maximum number of preceding entries to save.
   const MAX_BACK = Services.prefs.getIntPref("browser.sessionstore.max_serialize_back");
   ok(MAX_BACK > -1, "check that the default has a value that caps data");
 
   // Load more pages than we would save to disk on a clean shutdown.
   for (let i = 0; i < MAX_BACK + 2; i++) {
-    browser.loadURI(URL + i);
+    BrowserTestUtils.loadURI(browser, URL + i);
     await promiseBrowserLoaded(browser);
     ok(browser.isRemoteBrowser, "browser is still remote");
   }
 
   // Check we have the right number of shistory entries.
   await countHistoryEntries(browser, MAX_BACK + 2);
 
   // Load a non-remote page.
-  browser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(browser, "about:robots");
   await promiseTabRestored(tab);
   ok(!browser.isRemoteBrowser, "browser is not remote anymore");
 
   // Check that we didn't lose any shistory entries.
   await countHistoryEntries(browser, MAX_BACK + 3);
 
   // Cleanup.
   await BrowserTestUtils.closeWindow(win);
--- a/browser/components/sessionstore/test/browser_undoCloseById.js
+++ b/browser/components/sessionstore/test/browser_undoCloseById.js
@@ -12,17 +12,17 @@ async function openAndCloseTab(window, u
   await promiseBrowserLoaded(tab.linkedBrowser, true, url);
   await TabStateFlusher.flush(tab.linkedBrowser);
   await promiseRemoveTabAndSessionState(tab);
 }
 
 async function openWindow(url) {
   let win = await promiseNewWindowLoaded();
   let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
-  win.gBrowser.selectedBrowser.loadURI(url, { flags });
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url, { flags });
   await promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, url);
   return win;
 }
 
 async function closeWindow(win) {
   await BrowserTestUtils.closeWindow(win);
   // Wait 20 ms to allow SessionStorage a chance to register the closed window.
   await new Promise(resolve => setTimeout(resolve, 20));
--- a/browser/components/shell/HeadlessShell.jsm
+++ b/browser/components/shell/HeadlessShell.jsm
@@ -8,19 +8,19 @@ var EXPORTED_SYMBOLS = ["HeadlessShell"]
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/osfile.jsm");
 
 // Refrences to the progress listeners to keep them from being gc'ed
 // before they are called.
 const progressListeners = new Map();
 
-function loadContentWindow(webNavigation, uri) {
+function loadContentWindow(webNavigation, uri, principal) {
   return new Promise((resolve, reject) => {
-    webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
+    webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null, principal);
     let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
                                 .getInterface(Ci.nsIDocShell);
     let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsIWebProgress);
     let progressListener = {
       onLocationChange(progress, request, location, flags) {
         // Ignore inner-frame events
         if (progress != webProgress) {
@@ -45,17 +45,17 @@ function loadContentWindow(webNavigation
                                     Ci.nsIWebProgress.NOTIFY_LOCATION);
   });
 }
 
 async function takeScreenshot(fullWidth, fullHeight, contentWidth, contentHeight, path, url) {
   try {
     var windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
     // nsIWindowlessBrowser inherits from nsIWebNavigation.
-    let contentWindow = await loadContentWindow(windowlessBrowser, url);
+    let contentWindow = await loadContentWindow(windowlessBrowser, url, Services.scriptSecurityManager.getSystemPrincipal());
     contentWindow.resizeTo(contentWidth, contentHeight);
 
     let canvas = contentWindow.document.createElementNS("http://www.w3.org/1999/xhtml", "html:canvas");
     let context = canvas.getContext("2d");
     let width = fullWidth ? contentWindow.innerWidth + contentWindow.scrollMaxX - contentWindow.scrollMinX
                           : contentWindow.innerWidth;
     let height = fullHeight ? contentWindow.innerHeight + contentWindow.scrollMaxY - contentWindow.scrollMinY
                             : contentWindow.innerHeight;
--- a/browser/components/shell/test/browser_1119088.js
+++ b/browser/components/shell/test/browser_1119088.js
@@ -53,12 +53,12 @@ function onPageLoad() {
     gBrowser.removeCurrentTab();
     finish();
   }, 1000);
 }
 
 function test() {
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(onPageLoad, false, "about:logo");
-  gBrowser.loadURI("about:logo");
+  BrowserTestUtils.loadURI(gBrowser, "about:logo");
 
   waitForExplicitFinish();
 }
--- a/browser/components/translation/test/browser_translation_exceptions.js
+++ b/browser/components/translation/test/browser_translation_exceptions.js
@@ -28,17 +28,17 @@ function test() {
         await testCase.run();
       }
     })().then(finish, ex => {
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
    });
 
-  gBrowser.selectedBrowser.loadURI("http://example.com/");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "http://example.com/");
 }
 
 function getLanguageExceptions() {
   let langs = Services.prefs.getCharPref(kLanguagesPref);
   return langs ? langs.split(",") : [];
 }
 
 function getDomainExceptions() {
--- a/browser/components/translation/test/browser_translation_infobar.js
+++ b/browser/components/translation/test/browser_translation_infobar.js
@@ -83,17 +83,17 @@ function test() {
       gBrowser.removeTab(tab);
       Services.prefs.clearUserPref(kShowUIPref);
     });
     run_tests(() => {
       finish();
     });
   });
 
-  gBrowser.selectedBrowser.loadURI("data:text/plain,test page");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "data:text/plain,test page");
 }
 
 function checkURLBarIcon(aExpectTranslated = false) {
   is(!PopupNotifications.getNotification("translate"), aExpectTranslated,
      "translate icon " + (aExpectTranslated ? "not " : "") + "shown");
   is(!!PopupNotifications.getNotification("translated"), aExpectTranslated,
      "translated icon " + (aExpectTranslated ? "" : "not ") + "shown");
 }
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -463,32 +463,36 @@ var UITour = {
           const url = new URL(uri);
           // Call our helper to validate extraURLCampaignParams and populate URLSearchParams
           if (!this._populateCampaignParams(url, data.extraURLCampaignParams)) {
             log.warn("showFirefoxAccounts: invalid campaign args specified");
             return;
           }
 
           // We want to replace the current tab.
-          browser.loadURI(url.href);
+          browser.loadURI(url.href, {
+            triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+          });
         });
         break;
       }
 
       case "showConnectAnotherDevice": {
         FxAccounts.config.promiseConnectDeviceURI("uitour").then(uri => {
           const url = new URL(uri);
           // Call our helper to validate extraURLCampaignParams and populate URLSearchParams
           if (!this._populateCampaignParams(url, data.extraURLCampaignParams)) {
             log.warn("showConnectAnotherDevice: invalid campaign args specified");
             return;
           }
 
           // We want to replace the current tab.
-          browser.loadURI(url.href);
+          browser.loadURI(url.href, {
+            triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+          });
         });
         break;
       }
 
       case "resetFirefox": {
         // Open a reset profile dialog window.
         if (ResetProfile.resetSupported()) {
           ResetProfile.openConfirmationDialog(window);
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -242,16 +242,19 @@ var ContentSearch = {
     // where === "current"), openUILinkIn will not work because that tab is no
     // longer the current one. For this case we manually load the URI.
     if (where === "current") {
       // Since we're going to load the search in the same browser, blur the search
       // UI to prevent further interaction before we start loading.
       this._reply(msg, "Blur");
       browser.loadURI(submission.uri.spec, {
         postData: submission.postData,
+        triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({
+          userContextId: win.gBrowser.selectedBrowser.getAttribute("userContextId"),
+        }),
       });
     } else {
       let params = {
         postData: submission.postData,
         inBackground: Services.prefs.getBoolPref("browser.tabs.loadInBackground"),
       };
       win.openTrustedLinkIn(submission.uri.spec, where, params);
     }
--- a/browser/modules/test/browser/browser_SitePermissions_tab_urls.js
+++ b/browser/modules/test/browser/browser_SitePermissions_tab_urls.js
@@ -32,50 +32,50 @@ add_task(async function testTemporaryPer
                     newURI("http://example.com"),
                     newURI("http://example.org") ];
 
   let id = "microphone";
 
   await BrowserTestUtils.withNewTab("about:blank", async function(browser) {
     for (let uri of same) {
         let loaded = BrowserTestUtils.browserLoaded(browser, false, uri.spec);
-        browser.loadURI(uri.spec);
+        BrowserTestUtils.loadURI(browser, uri.spec);
         await loaded;
 
         SitePermissions.set(uri, id, SitePermissions.BLOCK, SitePermissions.SCOPE_TEMPORARY, browser);
 
         for (let uri2 of same) {
           let loaded2 = BrowserTestUtils.browserLoaded(browser, false, uri2.spec);
-          browser.loadURI(uri2.spec);
+          BrowserTestUtils.loadURI(browser, uri2.spec);
           await loaded2;
 
           Assert.deepEqual(SitePermissions.get(uri2, id, browser), {
             state: SitePermissions.BLOCK,
             scope: SitePermissions.SCOPE_TEMPORARY,
           }, `${uri.spec} should share tab permissions with ${uri2.spec}`);
         }
 
         SitePermissions.clearTemporaryPermissions(browser);
     }
 
     for (let uri of different) {
       let loaded = BrowserTestUtils.browserLoaded(browser, false, uri.spec);
-      browser.loadURI(uri.spec);
+      BrowserTestUtils.loadURI(browser, uri.spec);
       await loaded;
 
       SitePermissions.set(uri, id, SitePermissions.BLOCK, SitePermissions.SCOPE_TEMPORARY, browser);
 
       Assert.deepEqual(SitePermissions.get(uri, id, browser), {
         state: SitePermissions.BLOCK,
         scope: SitePermissions.SCOPE_TEMPORARY,
       });
 
       for (let uri2 of different) {
         loaded = BrowserTestUtils.browserLoaded(browser, false, uri2.spec);
-        browser.loadURI(uri2.spec);
+        BrowserTestUtils.loadURI(browser, uri2.spec);
         await loaded;
 
         if (uri2 != uri) {
           Assert.deepEqual(SitePermissions.get(uri2, id, browser), {
             state: SitePermissions.UNKNOWN,
             scope: SitePermissions.SCOPE_PERSISTENT,
           }, `${uri.spec} should not share tab permissions with ${uri2.spec}`);
         }
--- a/browser/modules/test/browser/browser_UsageTelemetry_content_aboutHome.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_content_aboutHome.js
@@ -47,17 +47,17 @@ add_task(async function test_abouthome_a
   let search_hist = getAndClearKeyedHistogram("SEARCH_COUNTS");
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
 
   info("Setup waiting for search input to initialise.");
   let promiseAboutHomeSearchLoaded = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "ContentSearchClient", true, null, true).then(() => false);
 
   info("Load about:home.");
-  tab.linkedBrowser.loadURI("about:home");
+  BrowserTestUtils.loadURI(tab.linkedBrowser, "about:home");
   info("Wait for ActivityStream search input.");
   await promiseAboutHomeSearchLoaded;
 
   info("Wait for ContentSearchUI search provider to initialize.");
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
     await ContentTaskUtils.waitForCondition(() => content.wrappedJSObject.gContentSearchController.defaultEngine);
   });
 
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/TestRunner.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/TestRunner.jsm
@@ -203,17 +203,17 @@ var TestRunner = {
 
   cleanup() {
     let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
     let gBrowser = browserWindow.gBrowser;
     while (gBrowser.tabs.length > 1) {
       gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
     }
     gBrowser.unpinTab(gBrowser.selectedTab);
-    gBrowser.selectedBrowser.loadURI("data:text/html;charset=utf-8,<h1>Done!");
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "data:text/html;charset=utf-8,<h1>Done!");
     browserWindow.restore();
     Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
   },
 
   // helpers
 
   /**
   * Calculate the bounding box based on CSS selector from config for cropping
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.jsm
@@ -186,17 +186,19 @@ function fiveTabsHelper() {
 }
 
 function closeAllButOneTab(url = "about:blank") {
   let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
   let gBrowser = browserWindow.gBrowser;
   // Close all tabs except the last so we don't quit the browser.
   while (gBrowser.tabs.length > 1)
     gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
-  gBrowser.selectedBrowser.loadURI(url);
+  gBrowser.selectedBrowser.loadURI(url, {
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+  });
   if (gBrowser.selectedTab.pinned)
     gBrowser.unpinTab(gBrowser.selectedTab);
   let newTabButton = browserWindow.document.getAnonymousElementByAttribute(browserWindow.gBrowser.tabContainer, "class", "tabs-newtab-button toolbarbutton-1");
   hoverTab(newTabButton, false);
 }
 
 function hoverTab(tab, hover = true) {
   if (hover) {
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1856,8 +1856,56 @@ add_gcc_flag(
 @depends(c_compiler.try_compile(flags=['-fsanitize=fuzzer-no-link'],
          check_msg='whether the C compiler supports -fsanitize=fuzzer-no-link'))
 def have_libfuzzer_flag_fuzzer_no_link(value):
     if value:
         return True
 
 
 set_config('HAVE_LIBFUZZER_FLAG_FUZZER_NO_LINK', have_libfuzzer_flag_fuzzer_no_link)
+
+# Shared library building
+# ==============================================================
+
+# XXX: The use of makefile constructs in these variables is awful.
+@depends(target, c_compiler)
+def make_shared_library(target, compiler):
+    if target.os == 'WINNT':
+        if compiler.type in ('gcc', 'clang'):
+            return namespace(
+                mkshlib=['$(CXX)', '$(DSO_LDOPTS)', '-o', '$@'],
+                mkcshlib=['$(CC)', '$(DSO_LDOPTS)', '-o', '$@'],
+            )
+        else:
+            linker = [
+                '$(LINKER)',
+                '-NOLOGO', '-DLL',
+                '-OUT:$@',
+                '-PDB:$(LINK_PDBFILE)',
+                '$(DSO_LDOPTS)'
+            ]
+            return namespace(
+                mkshlib=linker,
+                mkcshlib=linker,
+            )
+
+    cc = ['$(CC)', '$(COMPUTED_C_LDFLAGS)']
+    cxx = ['$(CXX)', '$(COMPUTED_CXX_LDFLAGS)']
+    flags = ['$(PGO_CFLAGS)', '$(DSO_PIC_CFLAGS)', '$(DSO_LDOPTS)']
+    output = ['-o', '$@']
+
+    if target.kernel == 'Darwin':
+        soname = []
+    elif target.os == 'NetBSD':
+        soname = ['-Wl,-soname,$(DSO_SONAME)']
+    else:
+        assert compiler.type in ('gcc', 'clang')
+
+        soname = ['-Wl,-h,$(DSO_SONAME)']
+
+    return namespace(
+        mkshlib=cxx + flags + soname + output,
+        mkcshlib=cc + flags + soname + output,
+    )
+
+
+set_config('MKSHLIB', make_shared_library.mkshlib)
+set_config('MKCSHLIB', make_shared_library.mkcshlib)
--- a/devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attach.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attach.js
@@ -28,17 +28,17 @@ function test() {
     // createWorker in the tab to be resolved.
     yield createWorkerInTab(tab, WORKER1_URL);
     let { workers } = yield listWorkers(tabClient);
     let [, workerClient1] = yield attachWorker(tabClient,
                                                findWorker(workers, WORKER1_URL));
     is(workerClient1.isClosed, false, "worker in tab 1 should not be closed");
 
     executeSoon(() => {
-      tab.linkedBrowser.loadURI(TAB2_URL);
+      BrowserTestUtils.loadURI(tab.linkedBrowser, TAB2_URL);
     });
     yield waitForWorkerClose(workerClient1);
     is(workerClient1.isClosed, true, "worker in tab 1 should be closed");
 
     yield createWorkerInTab(tab, WORKER2_URL);
     ({ workers } = yield listWorkers(tabClient));
     let [, workerClient2] = yield attachWorker(tabClient,
                                                findWorker(workers, WORKER2_URL));
--- a/devtools/client/debugger/test/mochitest/browser_dbg_navigation.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_navigation.js
@@ -45,17 +45,17 @@ function testNavigate([aGrip, aResponse]
       outstanding[0].resolve();
     } else {
       ok(true, "Tab finished navigating.");
       gClient.removeListener("tabNavigated", onTabNavigated);
       outstanding[1].resolve();
     }
   });
 
-  gBrowser.selectedBrowser.loadURI(TAB2_URL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TAB2_URL);
   return promise.all(outstanding.map(e => e.promise))
                 .then(() => aGrip.actor);
 }
 
 function testDetach(aActor) {
   let deferred = promise.defer();
 
   gClient.addOneTimeListener("tabDetached", (aType, aPacket) => {
--- a/devtools/client/framework/test/browser_source_map-reload.js
+++ b/devtools/client/framework/test/browser_source_map-reload.js
@@ -18,17 +18,17 @@ const ORIGINAL_LINE = 13;
 add_task(async function() {
   // Start with the empty page, then navigate, so that we can properly
   // listen for new sources arriving.
   const toolbox = await openNewTabAndToolbox(INITIAL_URL, "webconsole");
   const service = toolbox.sourceMapURLService;
   const tab = toolbox.target.tab;
 
   let sourceSeen = waitForSourceLoad(toolbox, JS_URL);
-  tab.linkedBrowser.loadURI(PAGE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE_URL);
   await sourceSeen;
 
   info(`checking original location for ${JS_URL}:${GENERATED_LINE}`);
   let newLoc = await service.originalPositionFor(JS_URL, GENERATED_LINE);
   is(newLoc.sourceUrl, ORIGINAL_URL_1, "check mapped URL");
   is(newLoc.line, ORIGINAL_LINE, "check mapped line number");
 
   // Reload the page.  The sjs ensures that a different source file
--- a/devtools/client/framework/test/browser_toolbox_remoteness_change.js
+++ b/devtools/client/framework/test/browser_toolbox_remoteness_change.js
@@ -13,17 +13,17 @@ add_task(async function() {
 
   let toolbox = await openToolboxForTab(tab);
 
   const onToolboxDestroyed = toolbox.once("destroyed");
   const onToolboxCreated = gDevTools.once("toolbox-created");
 
   info("Navigate to a URL supporting remote process");
   const onLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-  gBrowser.loadURI(URL_2);
+  BrowserTestUtils.loadURI(gBrowser, URL_2);
   await onLoaded;
 
   is(tab.linkedBrowser.getAttribute("remote"), "true", "Navigated to a data: URI and switching to remote");
 
   info("Waiting for the toolbox to be destroyed");
   await onToolboxDestroyed;
 
   info("Waiting for a new toolbox to be created");
--- a/devtools/client/framework/test/browser_toolbox_window_title_changes.js
+++ b/devtools/client/framework/test/browser_toolbox_window_title_changes.js
@@ -44,25 +44,25 @@ function test() {
         toolbox.selectTool(TOOL_ID_2);
         return onTitleChanged;
       })
       .then(checkTitle.bind(null, NAME_1, URL_1, "tool changed"))
 
     // navigate to different local url and check title
       .then(function() {
         const onTitleChanged = waitForTitleChange(toolbox);
-        gBrowser.loadURI(URL_2);
+        BrowserTestUtils.loadURI(gBrowser, URL_2);
         return onTitleChanged;
       })
       .then(checkTitle.bind(null, NAME_2, URL_2, "url changed"))
 
     // navigate to a real url and check title
       .then(() => {
         const onTitleChanged = waitForTitleChange(toolbox);
-        gBrowser.loadURI(URL_3);
+        BrowserTestUtils.loadURI(gBrowser, URL_3);
         return onTitleChanged;
       })
       .then(checkTitle.bind(null, NAME_3, URL_3, "url changed"))
 
     // destroy toolbox, create new one hosted in a window (with a
     // different tool id), and check title
       .then(function() {
         // Give the tools a chance to handle the navigation event before
--- a/devtools/client/inspector/markup/test/browser_markup_display_node_02.js
+++ b/devtools/client/inspector/markup/test/browser_markup_display_node_02.js
@@ -41,16 +41,33 @@ const TEST_DATA = [
         node.style.display = "block";
       `);
     },
     after: {
       visible: false
     }
   },
   {
+    desc: "Reusing the 'grid' node, updating the display to 'grid again",
+    selector: "#grid",
+    before: {
+      visible: false
+    },
+    changeStyle: async function(testActor) {
+      await testActor.eval(`
+        let node = document.getElementById("grid");
+        node.style.display = "grid";
+      `);
+    },
+    after: {
+      textContent: "grid",
+      visible: true
+    }
+  },
+  {
     desc: "Showing a 'grid' node by changing its style property",
     selector: "#block",
     before: {
       visible: false
     },
     changeStyle: async function(testActor) {
       await testActor.eval(`
         let node = document.getElementById("block");
--- a/devtools/client/inspector/markup/views/element-editor.js
+++ b/devtools/client/inspector/markup/views/element-editor.js
@@ -277,16 +277,17 @@ ElementEditor.prototype = {
     this.updateCustomBadge();
     this.updateTextEditor();
   },
 
   updateEventBadge: function() {
     const showEventBadge = this.node.hasEventListeners;
     if (this._eventBadge && !showEventBadge) {
       this._eventBadge.remove();
+      this._eventBadge = null;
     } else if (showEventBadge && !this._eventBadge) {
       this._createEventBadge();
     }
   },
 
   _createEventBadge: function() {
     this._eventBadge = this.doc.createElement("div");
     this._eventBadge.classList.add("markup-badge");
@@ -299,16 +300,17 @@ ElementEditor.prototype = {
 
   /**
    * Update the markup display badge.
    */
   updateDisplayBadge: function() {
     const showDisplayBadge = this.node.displayType in DISPLAY_TYPES;
     if (this._displayBadge && !showDisplayBadge) {
       this._displayBadge.remove();
+      this._displayBadge = null;
     } else if (showDisplayBadge) {
       if (!this._displayBadge) {
         this._createDisplayBadge();
       }
       this._updateDisplayBadgeContent();
     }
   },
 
@@ -334,16 +336,17 @@ ElementEditor.prototype = {
 
   /**
    * Update the markup custom element badge.
    */
   updateCustomBadge: function() {
     const showCustomBadge = !!this.node.customElementLocation;
     if (this._customBadge && !showCustomBadge) {
       this._customBadge.remove();
+      this._customBadge = null;
     } else if (!this._customBadge && showCustomBadge) {
       this._createCustomBadge();
     }
   },
 
   _createCustomBadge: function() {
     this._customBadge = this.doc.createElement("div");
     this._customBadge.classList.add("markup-badge");
--- a/devtools/client/netmonitor/test/browser_net_cause.js
+++ b/devtools/client/netmonitor/test/browser_net_cause.js
@@ -95,17 +95,17 @@ add_task(async function() {
   const {
     getDisplayedRequests,
     getSortedRequests,
   } = windowRequire("devtools/client/netmonitor/src/selectors/index");
 
   store.dispatch(Actions.batchEnable(false));
 
   const wait = waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
-  tab.linkedBrowser.loadURI(CAUSE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, CAUSE_URL);
   await wait;
 
   const requests = getSortedRequests(store.getState());
   await Promise.all(requests.map(requestItem =>
     connector.requestData(requestItem.id, "stackTrace")));
 
   is(store.getState().requests.requests.size, EXPECTED_REQUESTS.length,
     "All the page events should be recorded.");
--- a/devtools/client/netmonitor/test/browser_net_cause_source_map.js
+++ b/devtools/client/netmonitor/test/browser_net_cause_source_map.js
@@ -21,17 +21,17 @@ add_task(async function() {
   // page has actually made at least one request.
   const { tab, monitor } = await initNetMonitor(SIMPLE_URL);
 
   const { document, store, windowRequire } = monitor.panelWin;
   const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
 
   store.dispatch(Actions.batchEnable(false));
   let waitPromise = waitForNetworkEvents(monitor, N_EXPECTED_REQUESTS);
-  tab.linkedBrowser.loadURI(CAUSE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, CAUSE_URL);
   await waitPromise;
 
   info("Clicking item and waiting for details panel to open");
   waitPromise = waitForDOM(document, ".network-details-panel");
   const xhrRequestItem = document.querySelectorAll(".request-list-item")[3];
   EventUtils.sendMouseEvent({ type: "mousedown" }, xhrRequestItem);
   await waitPromise;
 
--- a/devtools/client/netmonitor/test/browser_net_charts-01.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-01.js
@@ -11,17 +11,17 @@ add_task(async function() {
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
 
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const pie = Chart.Pie(document, {
     width: 100,
     height: 100,
     data: [{
       size: 1,
       label: "foo"
--- a/devtools/client/netmonitor/test/browser_net_charts-02.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-02.js
@@ -13,17 +13,17 @@ add_task(async function() {
 
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const pie = Chart.Pie(document, {
     data: null,
     width: 100,
     height: 100
   });
 
--- a/devtools/client/netmonitor/test/browser_net_charts-03.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-03.js
@@ -12,17 +12,17 @@ add_task(async function() {
 
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const table = Chart.Table(document, {
     title: "Table title",
     data: [{
       label1: 1,
       label2: 11.1
     }, {
--- a/devtools/client/netmonitor/test/browser_net_charts-04.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-04.js
@@ -13,17 +13,17 @@ add_task(async function() {
 
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const table = Chart.Table(document, {
     title: "Table title",
     data: null,
     totals: {
       label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
       label2: value => "World " + L10N.numberWithDecimals(value, 2)
--- a/devtools/client/netmonitor/test/browser_net_charts-05.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-05.js
@@ -12,17 +12,17 @@ add_task(async function() {
 
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const chart = Chart.PieTable(document, {
     title: "Table title",
     data: [{
       size: 1,
       label: 11.1
     }, {
--- a/devtools/client/netmonitor/test/browser_net_charts-06.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-06.js
@@ -12,17 +12,17 @@ add_task(async function() {
 
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const pie = Chart.Pie(document, {
     data: [],
     width: 100,
     height: 100
   });
 
--- a/devtools/client/netmonitor/test/browser_net_charts-07.js
+++ b/devtools/client/netmonitor/test/browser_net_charts-07.js
@@ -12,17 +12,17 @@ add_task(async function() {
 
   const { monitor, tab } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   const { document, windowRequire } = monitor.panelWin;
   const { Chart } = windowRequire("devtools/client/shared/widgets/Chart");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const table = Chart.Table(document, {
     data: [],
     totals: {
       label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
       label2: value => "World " + L10N.numberWithDecimals(value, 2)
     },
--- a/devtools/client/netmonitor/test/browser_net_columns_showhide.js
+++ b/devtools/client/netmonitor/test/browser_net_columns_showhide.js
@@ -12,17 +12,17 @@ add_task(async function() {
 
   const { document, store, parent, connector, windowRequire } = monitor.panelWin;
   const { requestData } = connector;
   const {
     getSortedRequests,
   } = windowRequire("devtools/client/netmonitor/src/selectors/index");
 
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   const item = getSortedRequests(store.getState()).get(0);
   ok(item.responseHeadersAvailable, "headers are available for lazily fetching");
 
   if (item.responseHeadersAvailable && !item.responseHeaders) {
     await requestData(item.id, "responseHeaders");
   }
--- a/devtools/client/netmonitor/test/browser_net_edit_resend_caret.js
+++ b/devtools/client/netmonitor/test/browser_net_edit_resend_caret.js
@@ -16,17 +16,17 @@ add_task(async function() {
 
   const { document, store, windowRequire, parent } = monitor.panelWin;
   const parentDocument = parent.document;
   const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
   store.dispatch(Actions.batchEnable(false));
 
   // Reload to have one request in the list.
   const waitForEvents = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await waitForEvents;
 
   // Open context menu and execute "Edit & Resend".
   const firstRequest = document.querySelectorAll(".request-list-item")[0];
   const waitForHeaders = waitUntil(() => document.querySelector(".headers-overview"));
   EventUtils.sendMouseEvent({ type: "mousedown" }, firstRequest);
   await waitForHeaders;
   await waitForRequestData(store, ["requestHeaders"]);
--- a/devtools/client/netmonitor/test/browser_net_frame.js
+++ b/devtools/client/netmonitor/test/browser_net_frame.js
@@ -162,17 +162,17 @@ add_task(async function() {
   const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
   const {
     getDisplayedRequests,
     getSortedRequests,
   } = windowRequire("devtools/client/netmonitor/src/selectors/index");
 
   store.dispatch(Actions.batchEnable(false));
 
-  tab.linkedBrowser.loadURI(TOP_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, TOP_URL);
 
   await waitForNetworkEvents(monitor, REQUEST_COUNT);
 
   is(store.getState().requests.requests.size, REQUEST_COUNT,
     "All the page events should be recorded.");
 
   // Fetch stack-trace data from the backend and wait till
   // all packets are received.
--- a/devtools/client/netmonitor/test/browser_net_telemetry_edit_resend.js
+++ b/devtools/client/netmonitor/test/browser_net_telemetry_edit_resend.js
@@ -22,17 +22,17 @@ add_task(async function() {
   Services.telemetry.clearEvents();
 
   // Ensure no events have been logged
   const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
   ok(!snapshot.parent, "No events have been logged for the main process");
 
   // Reload to have one request in the list.
   const waitForEvents = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await waitForEvents;
 
   // Open context menu and execute "Edit & Resend".
   const firstRequest = document.querySelectorAll(".request-list-item")[0];
   const waitForHeaders = waitUntil(() => document.querySelector(".headers-overview"));
   EventUtils.sendMouseEvent({ type: "mousedown" }, firstRequest);
   await waitForHeaders;
   await waitForRequestData(store, ["requestHeaders", "responseHeaders"]);
--- a/devtools/client/netmonitor/test/browser_net_telemetry_filters_changed.js
+++ b/devtools/client/netmonitor/test/browser_net_telemetry_filters_changed.js
@@ -26,17 +26,17 @@ add_task(async function() {
   Services.telemetry.clearEvents();
 
   // Ensure no events have been logged
   const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
   ok(!snapshot.parent, "No events have been logged for the main process");
 
   // Reload to have one request in the list.
   const wait = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await wait;
 
   info("Click on the 'HTML' filter");
   EventUtils.sendMouseEvent({ type: "click" },
     document.querySelector(".requests-list-filter-html-button"));
 
   checkTelemetryEvent({
     trigger: "html",
--- a/devtools/client/netmonitor/test/browser_net_telemetry_sidepanel_changed.js
+++ b/devtools/client/netmonitor/test/browser_net_telemetry_sidepanel_changed.js
@@ -22,17 +22,17 @@ add_task(async function() {
   Services.telemetry.clearEvents();
 
   // Ensure no events have been logged
   const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
   ok(!snapshot.parent, "No events have been logged for the main process");
 
   // Reload to have one request in the list.
   const waitForEvents = waitForNetworkEvents(monitor, 1);
-  tab.linkedBrowser.loadURI(SIMPLE_URL);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SIMPLE_URL);
   await waitForEvents;
 
   // Click on a request and wait till the default "Headers" side panel is opened.
   info("Click on a request");
   const waitForHeaders = waitUntil(() => document.querySelector(".headers-overview"));
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.querySelectorAll(".request-list-item")[0]);
   await waitForHeaders;
--- a/devtools/client/responsive.html/browser/swap.js
+++ b/devtools/client/responsive.html/browser/swap.js
@@ -112,16 +112,17 @@ function swapToInnerBrowser({ tab, conta
       const { newFrameloader } = E10SUtils.shouldLoadURIInBrowser(
         tab.linkedBrowser,
         "about:blank"
       );
       if (newFrameloader) {
         debug(`Tab will force a new frameloader on navigation, load about:blank first`);
         await loadURIWithNewFrameLoader(tab.linkedBrowser, "about:blank", {
           flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
+          triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
         });
       }
 
       tab.isResponsiveDesignMode = true;
 
       // Hide the browser content temporarily while things move around to avoid displaying
       // strange intermediate states.
       tab.linkedBrowser.style.visibility = "hidden";
@@ -150,16 +151,17 @@ function swapToInnerBrowser({ tab, conta
       // to achieve in a nice way.
       containerBrowser.messageManager.sendAsyncMessage("SessionStore:flush", {
         epoch: -1,
       });
       // Prevent the `containerURL` from ending up in the tab's history.
       debug("Load container URL");
       containerBrowser.loadURI(containerURL, {
         flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
       });
 
       // Copy tab listener state flags to container tab.  Each tab gets its own tab
       // listener and state flags which cache document loading progress.  The state flags
       // are checked when switching tabs to update the browser UI.  The later step of
       // `swapBrowsersAndCloseOther` will fold the state back into the main tab.
       const stateFlags = gBrowser._tabListeners.get(tab).mStateFlags;
       gBrowser._tabListeners.get(containerTab).mStateFlags = stateFlags;
--- a/devtools/client/responsive.html/browser/web-navigation.js
+++ b/devtools/client/responsive.html/browser/web-navigation.js
@@ -59,33 +59,34 @@ BrowserElementWebNavigation.prototype = 
     // No equivalent in the current BrowserElement API
     this._sendMessage("WebNavigation:GotoIndex", { index });
   },
 
   loadURI(uri, flags, referrer, postData, headers) {
     // No equivalent in the current BrowserElement API
     this.loadURIWithOptions(uri, flags, referrer,
                             Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-                            postData, headers, null, null);
+                            postData, headers, null,
+                            Services.scriptSecurityManager.createNullPrincipal({}));
   },
 
   loadURIWithOptions(uri, flags, referrer, referrerPolicy, postData, headers,
                      baseURI, triggeringPrincipal) {
     // No equivalent in the current BrowserElement API
     this._sendMessage("WebNavigation:LoadURI", {
       uri,
       flags,
       referrer: referrer ? referrer.spec : null,
       referrerPolicy: referrerPolicy,
       postData: postData ? readInputStreamToString(postData) : null,
       headers: headers ? readInputStreamToString(headers) : null,
       baseURI: baseURI ? baseURI.spec : null,
       triggeringPrincipal: triggeringPrincipal
                            ? Utils.serializePrincipal(triggeringPrincipal)
-                           : null,
+                           : Services.scriptSecurityManager.createNullPrincipal({}),
       requestTime: telemetry.msSystemNow(),
     });
   },
 
   setOriginAttributesBeforeLoading(originAttributes) {
     // No equivalent in the current BrowserElement API
     this._sendMessage("WebNavigation:SetOriginAttributes", {
       originAttributes,
--- a/devtools/client/responsive.html/test/browser/head.js
+++ b/devtools/client/responsive.html/test/browser/head.js
@@ -336,17 +336,17 @@ async function waitForPageShow(browser) 
 }
 
 function waitForViewportLoad(ui) {
   return BrowserTestUtils.waitForContentEvent(ui.getViewportBrowser(), "load", true);
 }
 
 function load(browser, url) {
   const loaded = BrowserTestUtils.browserLoaded(browser, false, url);
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   return loaded;
 }
 
 function back(browser) {
   const shown = waitForPageShow(browser);
   browser.goBack();
   return shown;
 }
--- a/devtools/client/scratchpad/test/browser_scratchpad_browser_last_window_closing.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_browser_last_window_closing.js
@@ -11,17 +11,17 @@ function test() {
   // Observer must be attached *before* Scratchpad is opened.
   CloseObserver.init();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,<p>test browser last window closing</p>");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,<p>test browser last window closing</p>");
 }
 
 function runTests({ Scratchpad }) {
   const browser = Services.wm.getEnumerator("navigator:browser").getNext();
   const oldPrompt = Services.prompt;
   let button;
 
   Services.prompt = {
--- a/devtools/client/scratchpad/test/browser_scratchpad_chrome_context_pref.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_chrome_context_pref.js
@@ -10,17 +10,17 @@ function test() {
 
   Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,Scratchpad test for bug 646070 - chrome context preference");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,Scratchpad test for bug 646070 - chrome context preference");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   ok(sp, "Scratchpad object exists in new window");
 
   const environmentMenu = gScratchpadWindow.document
                           .getElementById("sp-environment-menu");
--- a/devtools/client/scratchpad/test/browser_scratchpad_contexts.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_contexts.js
@@ -6,17 +6,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,test context switch in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,test context switch in Scratchpad");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   const contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
   const chromeMenu = gScratchpadWindow.document.getElementById("sp-menu-browser");
   const notificationBox = sp.notificationBox;
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_display_non_error_exceptions.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_display_non_error_exceptions.js
@@ -6,17 +6,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests, {"state": {"text": ""}});
   });
 
-  gBrowser.loadURI("data:text/html, test that exceptions are output as " +
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html, test that exceptions are output as " +
                    "comments correctly in Scratchpad");
 }
 
 function runTests() {
   var scratchpad = gScratchpadWindow.Scratchpad;
 
   var message = "\"Hello World!\"";
   var openComment = "\n/*\n";
--- a/devtools/client/scratchpad/test/browser_scratchpad_display_outputs_errors.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_display_outputs_errors.js
@@ -6,17 +6,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests, {"state": {"text": ""}});
   });
 
-  gBrowser.loadURI("data:text/html,<p>test that exceptions are output as " +
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test that exceptions are output as " +
                    "comments for 'display' and not sent to the console in Scratchpad");
 }
 
 function runTests() {
   const scratchpad = gScratchpadWindow.Scratchpad;
 
   const message = "\"Hello World!\"";
   const openComment = "\n/*\n";
--- a/devtools/client/scratchpad/test/browser_scratchpad_edit_ui_updates.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_edit_ui_updates.js
@@ -11,17 +11,17 @@ var DEVTOOLS_CHROME_ENABLED = "devtools.
 function test() {
   waitForExplicitFinish();
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, false);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,test Edit menu updates Scratchpad - bug 699130");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,test Edit menu updates Scratchpad - bug 699130");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   const doc = gScratchpadWindow.document;
   const winUtils = gScratchpadWindow.windowUtils;
   const OS = Services.appinfo.OS;
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_eval_func.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_eval_func.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,test Scratchpad eval function.");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,test Scratchpad eval function.");
 }
 
 function reportErrorAndQuit(error) {
   DevToolsUtils.reportException("browser_scratchpad_eval_func.js", error);
   ok(false);
   finish();
 }
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_execute_print.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_execute_print.js
@@ -6,17 +6,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test run() and display() in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test run() and display() in Scratchpad");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   const tests = [{
     method: "run",
     prepare: async function() {
       await inContent(function() {
--- a/devtools/client/scratchpad/test/browser_scratchpad_falsy.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_falsy.js
@@ -6,17 +6,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(testFalsy);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test falsy display() values in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test falsy display() values in Scratchpad");
 }
 
 function testFalsy() {
   const scratchpad = gScratchpadWindow.Scratchpad;
   verifyFalsies(scratchpad).then(function() {
     scratchpad.setBrowserContext();
     verifyFalsies(scratchpad).then(finish);
   });
--- a/devtools/client/scratchpad/test/browser_scratchpad_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_files.js
@@ -14,17 +14,17 @@ var gFileContent = "hello.world('bug6367
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test file open and save in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test file open and save in Scratchpad");
 }
 
 function runTests() {
   gScratchpad = gScratchpadWindow.Scratchpad;
 
   createTempFile("fileForBug636725.tmp", gFileContent, function(aStatus, aFile) {
     ok(Components.isSuccessCode(aStatus),
       "The temporary file was saved successfully");
--- a/devtools/client/scratchpad/test/browser_scratchpad_goto_line_ui.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_goto_line_ui.js
@@ -6,17 +6,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test the 'Jump to line' feature in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test the 'Jump to line' feature in Scratchpad");
 }
 
 function runTests(aWindow, aScratchpad) {
   const editor = aScratchpad.editor;
   const text = "foobar bug650345\nBug650345 bazbaz\nfoobar omg\ntest";
   editor.setText(text);
   editor.setCursor({ line: 0, ch: 0 });
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_help_key.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_help_key.js
@@ -2,17 +2,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 650760 */
 
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-  gBrowser.loadURI("data:text/html,Test keybindings for opening Scratchpad MDN Documentation, bug 650760");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,Test keybindings for opening Scratchpad MDN Documentation, bug 650760");
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTest);
   });
 }
 
 function runTest() {
   const sp = gScratchpadWindow.Scratchpad;
   ok(sp, "Scratchpad object exists in new window");
--- a/devtools/client/scratchpad/test/browser_scratchpad_initialization.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_initialization.js
@@ -8,17 +8,17 @@ function test() {
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, false);
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,initialization test for Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,initialization test for Scratchpad");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   ok(sp, "Scratchpad object exists in new window");
   is(typeof sp.run, "function", "Scratchpad.run() exists");
   is(typeof sp.inspect, "function", "Scratchpad.inspect() exists");
   is(typeof sp.display, "function", "Scratchpad.display() exists");
--- a/devtools/client/scratchpad/test/browser_scratchpad_inspect.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_inspect.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,<p>test inspect() in Scratchpad</p>");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,<p>test inspect() in Scratchpad</p>");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
 
   sp.setText("({ a: 'foobarBug636725' })");
 
   sp.inspect().then(function() {
--- a/devtools/client/scratchpad/test/browser_scratchpad_long_string.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_long_string.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,<p>test long string in Scratchpad</p>");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,<p>test long string in Scratchpad</p>");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
 
   sp.setText("'0'.repeat(10000)");
 
   sp.display().then(() => {
--- a/devtools/client/scratchpad/test/browser_scratchpad_modeline.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_modeline.js
@@ -14,17 +14,17 @@ function test() {
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, false);
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test file open and save in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test file open and save in Scratchpad");
 }
 
 function runTests() {
   gScratchpad = gScratchpadWindow.Scratchpad;
   function size(obj) {
     return Object.keys(obj).length;
   }
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_open_error_console.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_open_error_console.js
@@ -7,17 +7,17 @@ const {HUDService} = require("devtools/c
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,test Scratchpad." +
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,test Scratchpad." +
                    "openErrorConsole()");
 }
 
 function runTests() {
   Services.obs.addObserver(function observer(aSubject) {
     Services.obs.removeObserver(observer, "web-console-created");
     aSubject.QueryInterface(Ci.nsISupportsString);
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_pprint-02.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_pprint-02.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,test Scratchpad pretty print.");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,test Scratchpad pretty print.");
 }
 
 var gTabsize;
 
 function runTests(sw) {
   gTabsize = Services.prefs.getIntPref("devtools.editor.tabsize");
   Services.prefs.setIntPref("devtools.editor.tabsize", 6);
   const space = " ".repeat(6);
--- a/devtools/client/scratchpad/test/browser_scratchpad_pprint.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_pprint.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,test Scratchpad pretty print.");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,test Scratchpad pretty print.");
 }
 
 function runTests(sw) {
   const sp = sw.Scratchpad;
   sp.setText("function main() { console.log(5); }");
   sp.prettyPrint().then(() => {
     const prettyText = sp.getText();
     ok(prettyText.includes("\n"));
--- a/devtools/client/scratchpad/test/browser_scratchpad_pprint_error_goto_line.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_pprint_error_goto_line.js
@@ -8,17 +8,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,"
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,"
                    + "test Scratchpad pretty print error goto line.");
 }
 
 function testJumpToPrettyPrintError(sp, error, remark) {
   info("will test jumpToLine after prettyPrint error" + remark);
 
   // CodeMirror lines and columns are 0-based, Scratchpad UI and error
   // stack are 1-based.
--- a/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
@@ -322,14 +322,14 @@ function test() {
   // files max for this test.
   PreferenceObserver.init();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(startTest);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test recent files in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test recent files in Scratchpad");
 }
 
 function finishTest() {
   finish();
 }
--- a/devtools/client/scratchpad/test/browser_scratchpad_remember_view_options.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_remember_view_options.js
@@ -11,17 +11,17 @@ function test() {
   // view menu options. After each change we compare the correspondent
   // preference value with the expected value.
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<title>Bug 1140839</title>" +
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<title>Bug 1140839</title>" +
                    "<p>test Scratchpad should remember View options");
 }
 
 function runTests() {
   const doc = gScratchpadWindow.document;
 
   const testData = [
     {itemMenuId: "sp-menu-line-numbers", prefId: "devtools.scratchpad.lineNumbers", expectedVal: false},
--- a/devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
@@ -23,17 +23,17 @@ var gFirstFileSaved = false;
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test that undo get's reset after file load in Scratchpad");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test that undo get's reset after file load in Scratchpad");
 }
 
 function runTests() {
   gScratchpad = gScratchpadWindow.Scratchpad;
 
   // Create a temporary file.
   gFileA = FileUtils.getFile("TmpD", ["fileAForBug684546.tmp"]);
   gFileA.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
--- a/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
@@ -117,11 +117,11 @@ function tempFileSaved(aStatus) {
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(startTest);
   });
 
-  gBrowser.loadURI("data:text/html,<p>test reverting to last saved state of" +
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test reverting to last saved state of" +
                    " a file </p>");
 }
--- a/devtools/client/scratchpad/test/browser_scratchpad_run_error_goto_line.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_run_error_goto_line.js
@@ -8,17 +8,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,test Scratchpad pretty print.");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,test Scratchpad pretty print.");
 }
 
 function runTests(sw) {
   const sp = sw.Scratchpad;
   sp.setText([
     "// line 1",
     "// line 2",
     "var re = /a bad /regexp/; // line 3 is an obvious syntax error!",
--- a/devtools/client/scratchpad/test/browser_scratchpad_tab.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_tab.js
@@ -10,17 +10,17 @@ function test() {
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     Services.prefs.setIntPref("devtools.editor.tabsize", 5);
 
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,Scratchpad test for the Tab key, bug 660560");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,Scratchpad test for the Tab key, bug 660560");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   ok(sp, "Scratchpad object exists in new window");
 
   ok(sp.editor.hasFocus(), "the editor has focus");
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_tab_switch.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_tab_switch.js
@@ -12,20 +12,20 @@ function test() {
   tab1 = BrowserTestUtils.addTab(gBrowser);
   gBrowser.selectedTab = tab1;
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     tab2 = BrowserTestUtils.addTab(gBrowser);
     gBrowser.selectedTab = tab2;
     BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
       openScratchpad(runTests);
     });
-    gBrowser.loadURI("data:text/html,test context switch in Scratchpad tab 2");
+    BrowserTestUtils.loadURI(gBrowser, "data:text/html,test context switch in Scratchpad tab 2");
   });
 
-  gBrowser.loadURI("data:text/html,test context switch in Scratchpad tab 1");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,test context switch in Scratchpad tab 1");
 }
 
 async function runTests() {
   sp = gScratchpadWindow.Scratchpad;
 
   const contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
   const browserMenu = gScratchpadWindow.document.getElementById("sp-menu-browser");
   const notificationBox = sp.notificationBox;
@@ -77,17 +77,17 @@ async function runTests2() {
   sp.setText("window.foosbug653108 = 'ahoyhoy';");
   await sp.run();
   await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
     is(content.wrappedJSObject.foosbug653108, "ahoyhoy",
       "content.foosbug653108 has been set 2");
   });
 
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(runTests3);
-  gBrowser.loadURI("data:text/html,test context switch in Scratchpad location 2");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,test context switch in Scratchpad location 2");
 }
 
 function runTests3() {
   // Check that the sandbox is not cached.
 
   sp.setText("typeof foosbug653108;");
   sp.run().then(function([, , result]) {
     is(result, "undefined", "global variable does not exist");
--- a/devtools/client/scratchpad/test/browser_scratchpad_throw_output.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_throw_output.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(testThrowOutput);
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,<p>Test throw outputs in Scratchpad</p>");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,<p>Test throw outputs in Scratchpad</p>");
 }
 
 function testThrowOutput() {
   const scratchpad = gScratchpadWindow.Scratchpad, tests = [];
 
   const falsyValues = ["false", "0", "-0", "null", "undefined", "Infinity",
                        "-Infinity", "NaN"];
   falsyValues.forEach(function(value) {
--- a/devtools/client/scratchpad/test/browser_scratchpad_ui.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_ui.js
@@ -5,17 +5,17 @@
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function() {
     openScratchpad(runTests);
   });
 
-  gBrowser.loadURI("data:text/html,<title>foobarBug636725</title>" +
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<title>foobarBug636725</title>" +
                    "<p>test inspect() in Scratchpad");
 }
 
 function runTests() {
   const sp = gScratchpadWindow.Scratchpad;
   const doc = gScratchpadWindow.document;
 
   const methodsAndItems = {
--- a/devtools/client/scratchpad/test/browser_scratchpad_unsaved.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_unsaved.js
@@ -16,17 +16,17 @@ function test() {
   waitForExplicitFinish();
 
   testListeners();
   testRestoreNotFromFile();
   testRestoreFromFileSaved();
   testRestoreFromFileUnsaved();
 
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-  gBrowser.loadURI("data:text/html,<p>test star* UI for unsaved file changes");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html,<p>test star* UI for unsaved file changes");
 }
 
 function testListeners() {
   openScratchpad(function(aWin, aScratchpad) {
     aScratchpad.setText("new text");
     ok(isStar(aWin), "show star if scratchpad text changes");
 
     aScratchpad.dirty = false;
--- a/devtools/client/scratchpad/test/browser_scratchpad_wrong_window_focus.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_wrong_window_focus.js
@@ -31,17 +31,17 @@ function test() {
           const hud = toolbox.getCurrentPanel().hud;
           hud.ui.clearOutput(true);
           testFocus(sw, hud);
         });
       });
     });
   });
 
-  gBrowser.loadURI("data:text/html;charset=utf8,<p>test window focus for Scratchpad.");
+  BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8,<p>test window focus for Scratchpad.");
 }
 
 function testFocus(sw, hud) {
   const sp = sw.Scratchpad;
 
   function onMessage(messages) {
     const msg = [...messages][0];
     const node = msg.node;
--- a/devtools/client/scratchpad/test/head.js
+++ b/devtools/client/scratchpad/test/head.js
@@ -82,17 +82,17 @@ function openTabAndScratchpad(aOptions =
   waitForExplicitFinish();
   // eslint-disable-next-line new-cap
   return new promise(resolve => {
     gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
     const {selectedBrowser} = gBrowser;
     BrowserTestUtils.browserLoaded(selectedBrowser).then(function() {
       openScratchpad((win, sp) => resolve([win, sp]), aOptions);
     });
-    gBrowser.loadURI("data:text/html;charset=utf8," + (aOptions.tabContent || ""));
+    BrowserTestUtils.loadURI(gBrowser, "data:text/html;charset=utf8," + (aOptions.tabContent || ""));
   });
 }
 
 /**
  * Create a temporary file, write to it and call a callback
  * when done.
  *
  * @param string aName
--- a/devtools/client/styleeditor/test/head.js
+++ b/devtools/client/styleeditor/test/head.js
@@ -41,17 +41,17 @@ var addTab = function(url, win) {
  * Navigate the currently selected tab to a new URL and wait for it to load.
  * @param {String} url The url to be loaded in the current tab.
  * @return a promise that resolves when the page has fully loaded.
  */
 var navigateTo = function(url) {
   info(`Navigating to ${url}`);
   const browser = gBrowser.selectedBrowser;
 
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   return BrowserTestUtils.browserLoaded(browser);
 };
 
 var navigateToAndWaitForStyleSheets = async function(url, ui) {
   const onReset = ui.once("stylesheets-reset");
   await navigateTo(url);
   await onReset;
 };
--- a/devtools/server/actors/targets/content-process.js
+++ b/devtools/server/actors/targets/content-process.js
@@ -44,16 +44,17 @@ function ContentProcessTargetActor(conne
   };
 
   // Scope into which the webconsole executes:
   // A sandbox with chrome privileges with a `tabs` getter.
   const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
     .createInstance(Ci.nsIPrincipal);
   const sandbox = Cu.Sandbox(systemPrincipal, {
     sandboxPrototype,
+    wantGlobalProperties: ["ChromeUtils"],
   });
   this._consoleScope = sandbox;
 
   this._workerList = null;
   this._workerTargetActorPool = null;
   this._onWorkerListChanged = this._onWorkerListChanged.bind(this);
 }
 exports.ContentProcessTargetActor = ContentProcessTargetActor;
--- a/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js
+++ b/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js
@@ -9,24 +9,24 @@ add_task(async function runTests() {
 
   registerCleanupFunction(function() {
     gBrowser.removeTab(tab);
   });
 
   let browser = tab.linkedBrowser;
 
   let loaded = BrowserTestUtils.browserLoaded(browser);
-  browser.loadURI("about:config");
+  BrowserTestUtils.loadURI(browser, "about:config");
   let href = await loaded;
   is(href, "about:config", "Check about:config loaded");
 
   // Using a dummy onunload listener to disable the bfcache as that can prevent
   // the test browser load detection mechanism from working.
   loaded = BrowserTestUtils.browserLoaded(browser);
-  browser.loadURI("data:text/html,<body%20onunload=''><iframe></iframe></body>");
+  BrowserTestUtils.loadURI(browser, "data:text/html,<body%20onunload=''><iframe></iframe></body>");
   href = await loaded;
   is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>",
     "Check data URL loaded");
 
   loaded = BrowserTestUtils.browserLoaded(browser);
   browser.goBack();
   href = await loaded;
   is(href, "about:config", "Check we've gone back to about:config");
--- a/docshell/test/browser/browser_bug1415918_beforeunload_options.js
+++ b/docshell/test/browser/browser_bug1415918_beforeunload_options.js
@@ -99,17 +99,17 @@ add_task(async function test() {
 
   /*
    * Check condition where no one requests a prompt.  In all cases,
    * permitUnload should be true, and all handlers fired.
    */
 
   buttonId = "button0";
   url = TEST_PATH + "file_bug1415918_beforeunload_2.html";
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   await BrowserTestUtils.browserLoaded(browser, false, url);
   buttonId = "";
 
   promptShown = false;
   ok(browser.permitUnload().permitUnload, "permit unload should be true");
   ok(!promptShown, "prompt should not have been displayed");
 
   // Check that all beforeunload handlers fired and reset attributes.
@@ -153,17 +153,17 @@ add_task(async function test() {
 
   /*
    * Check condition where the parent beforeunload handler does not request a prompt,
    * but a child beforeunload handler does.
    */
 
   buttonId = "button0";
   url = TEST_PATH + "file_bug1415918_beforeunload_3.html";
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   await BrowserTestUtils.browserLoaded(browser, false, url);
 
   // Prompt is shown, user clicks OK.
   promptShown = false;
   ok(browser.permitUnload().permitUnload, "permit unload should be true");
   ok(promptShown, "prompt should have been displayed");
 
   // Check that all beforeunload handlers fired and reset attributes.
--- a/docshell/test/browser/browser_bug420605.js
+++ b/docshell/test/browser/browser_bug420605.js
@@ -108,10 +108,10 @@ function test() {
     var info = getNavHistoryEntry(makeURI(pageurl));
     ok(!info, "The test page must not have been visited already.");
     info = getNavHistoryEntry(makeURI(fragmenturl));
     ok(!info, "The fragment test page must not have been visited already.");
 
     // Now open the test page in a new tab.
     gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
     BrowserTestUtils.waitForContentEvent(gBrowser.selectedBrowser, "DOMContentLoaded", true).then(onPageLoad);
-    gBrowser.selectedBrowser.loadURI(pageurl);
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, pageurl);
 }
--- a/docshell/test/browser/browser_bug422543.js
+++ b/docshell/test/browser/browser_bug422543.js
@@ -4,17 +4,17 @@
 add_task(async function runTests() {
   await setup();
   let browser = gBrowser.selectedBrowser;
   // Now that we're set up, initialize our frame script.
   await checkListeners("initial", "listeners initialized");
 
   // Check if all history listeners are always notified.
   info("# part 1");
-  await whenPageShown(browser, () => browser.loadURI("http://www.example.com/"));
+  await whenPageShown(browser, () => BrowserTestUtils.loadURI(browser, "http://www.example.com/"));
   await checkListeners("newentry", "shistory has a new entry");
   ok(browser.canGoBack, "we can go back");
 
   await whenPageShown(browser, () => browser.goBack());
   await checkListeners("gotoindex", "back to the first shentry");
   ok(browser.canGoForward, "we can go forward");
 
   await whenPageShown(browser, () => browser.goForward());
--- a/docshell/test/browser/browser_dataURI_unique_opaque_origin.js
+++ b/docshell/test/browser/browser_dataURI_unique_opaque_origin.js
@@ -9,17 +9,17 @@ add_task(async function setup() {
 add_task(async function test_dataURI_unique_opaque_origin() {
   let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com");
   let browser = tab.linkedBrowser;
   await BrowserTestUtils.browserLoaded(browser);
 
   let pagePrincipal = browser.contentPrincipal;
   info("pagePrincial " + pagePrincipal.origin);
 
-  browser.loadURI("data:text/html,hi");
+  BrowserTestUtils.loadURI(browser, "data:text/html,hi");
   await BrowserTestUtils.browserLoaded(browser);
 
   await ContentTask.spawn(browser, { principal: pagePrincipal }, async function(args) {
     info("data URI principal: " + content.document.nodePrincipal.origin);
     Assert.ok(content.document.nodePrincipal.isNullPrincipal,
               "data: URI should have NullPrincipal.");
     Assert.ok(!content.document.nodePrincipal.equals(args.principal),
               "data: URI should have unique opaque origin.");
--- a/docshell/test/browser/browser_loadDisallowInherit.js
+++ b/docshell/test/browser/browser_loadDisallowInherit.js
@@ -1,48 +1,57 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function test() {
   waitForExplicitFinish();
 
   // data: URI will only inherit principal only when the pref is false.
   Services.prefs.setBoolPref("security.data_uri.unique_opaque_origin", false);
+  // data: URIs will only open at the top level when the pref is false
+  //   or the use of system principal but we can't use that to test here.
+  Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", false);
   registerCleanupFunction(function () {
     Services.prefs.clearUserPref("security.data_uri.unique_opaque_origin");
+    Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
   });
 
   executeSoon(startTest);
 }
 
 function startTest() {
   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   let browser = gBrowser.getBrowserForTab(tab);
 
-  function loadURL(url, flags, func) {
+  function loadURL(url, flags, triggeringPrincipal, func) {
     BrowserTestUtils.browserLoaded(browser, false, url).then(() => {
       func();
     });
-    browser.loadURI(url, { flags });
+    browser.loadURI(url, { flags, triggeringPrincipal });
   }
 
   // Load a normal http URL
   function testURL(url, func) {
-    loadURL("http://example.com/", 0, function () {
+    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+                   getService(Ci.nsIScriptSecurityManager);
+    let ios = Cc["@mozilla.org/network/io-service;1"].
+                getService(Ci.nsIIOService);
+    let artificialPrincipal = secMan.createCodebasePrincipal(ios.newURI("http://example.com/"), {});
+    loadURL("http://example.com/", 0, artificialPrincipal, function () {
       let pagePrincipal = browser.contentPrincipal;
       ok(pagePrincipal, "got principal for http:// page");
 
       // Now load the URL normally
-      loadURL(url, 0, function () {
+      loadURL(url, 0, artificialPrincipal, function () {
         ok(browser.contentPrincipal.equals(pagePrincipal), url + " should inherit principal");
 
         // Now load the URL and disallow inheriting the principal
         let webNav = Ci.nsIWebNavigation;
-        loadURL(url, webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, function () {
+        loadURL(url, webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, artificialPrincipal, function () {
           let newPrincipal = browser.contentPrincipal;
           ok(newPrincipal, "got inner principal");
           ok(!newPrincipal.equals(pagePrincipal),
              url + " should not inherit principal when loaded with DISALLOW_INHERIT_OWNER");
 
           func();
         });
       });
--- a/docshell/test/browser/browser_loadURI.js
+++ b/docshell/test/browser/browser_loadURI.js
@@ -14,18 +14,21 @@ function test() {
   var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].
                    createInstance(Ci.nsIStringInputStream);
   dataStream.data = gPostData;
 
   var postStream = Cc["@mozilla.org/network/mime-input-stream;1"].
                    createInstance(Ci.nsIMIMEInputStream);
   postStream.addHeader("Content-Type", "application/x-www-form-urlencoded");
   postStream.setData(dataStream);
+  var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
+                          .getService(Ci.nsIPrincipal);
 
   tab.linkedBrowser.loadURI("http://mochi.test:8888/browser/docshell/test/browser/print_postdata.sjs", {
+    triggeringPrincipal: systemPrincipal,
     postData: postStream,
   });
   BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
     ContentTask.spawn(tab.linkedBrowser, gPostData, function(postData) {
       var bodyText = content.document.body.textContent;
       is(bodyText, postData, "post data was submitted correctly");
     }).then(() => { finish(); });
   });
--- a/docshell/test/chrome/bug112564_window.xul
+++ b/docshell/test/chrome/bug112564_window.xul
@@ -9,16 +9,17 @@
 <window id="112564Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         width="600"
         height="600"
         onload="onLoad();"
         title="112564 test">
 
   <script type="application/javascript"><![CDATA[
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     const LISTEN_EVENTS = ["load", "unload", "pageshow", "pagehide"];
 
     var gBrowser;
     var gTestsIterator;
     var gExpected = [];
 
     function ok(condition, message) {
       window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
@@ -83,26 +84,26 @@
       // Load a secure page with a no-cache header, followed by a simple page.
       // no-cache should not interfere with the bfcache in the way no-store
       // does.
       var test1DocURI = "https://example.com:443/tests/docshell/test/chrome/112564_nocache.html";
 
       gExpected = [{type: "pagehide", persisted: true},
                    {type: "load", title: "test1"},
                    {type: "pageshow", title: "test1", persisted: false}];
-      gBrowser.loadURI(test1DocURI);
+      BrowserTestUtils.loadURI(gBrowser, test1DocURI);
       yield undefined;
 
       var test2Doc = "data:text/html,<html><head><title>test2</title></head>" +
                      "<body>test2</body></html>";
 
       gExpected = [{type: "pagehide", title: "test1", persisted: true},
                    {type: "load", title: "test2"},
                    {type: "pageshow", title: "test2", persisted: false}];
-      gBrowser.loadURI(test2Doc);
+      BrowserTestUtils.loadURI(gBrowser, test2Doc);
       yield undefined;
 
       // Now go back in history. First page has been cached.
       // Check persisted property to confirm
       gExpected = [{type: "pagehide", title: "test2", persisted: true},
                    {type: "pageshow", title: "test1", persisted: true}];
       gBrowser.goBack();
       yield undefined;
--- a/docshell/test/chrome/bug215405_window.xul
+++ b/docshell/test/chrome/bug215405_window.xul
@@ -9,16 +9,17 @@
 <window id="215405Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         width="600"
         height="600"
         onload="onLoad();"
         title="215405 test">
 
   <script type="application/javascript"><![CDATA[
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     var imports = [ "SimpleTest", "is", "isnot", "ok"];
     for (var name of imports) {
       window[name] = window.opener.wrappedJSObject[name];
     }
 
     const text="MOZILLA";
     const nostoreURI = "http://mochi.test:8888/tests/docshell/test/chrome/" +
                        "215405_nostore.html";
@@ -56,17 +57,17 @@
       gTestsIterator.next();
     }
 
     function* testsIterator() {
       // No-store tests
       var testName = "[nostore]";
 
       // Load a page with a no-store header
-      gBrowser.loadURI(nostoreURI);
+      BrowserTestUtils.loadURI(gBrowser, nostoreURI);
       yield undefined;
 
 
       // Now that the page has loaded, amend the form contents
       var form = gBrowser.contentDocument.getElementById("inp");
       form.value = text;
 
       // Attempt to scroll the page
@@ -82,17 +83,17 @@
       isnot(scrollX, originalXPosition,
             testName + " failed to scroll window horizontally");
       isnot(scrollY, originalYPosition,
             testName + " failed to scroll window vertically");
 
       // Load a new document into the browser
       var simple = "data:text/html,<html><head><title>test2</title></head>" +
                      "<body>test2</body></html>";
-      gBrowser.loadURI(simple);
+      BrowserTestUtils.loadURI(gBrowser, simple);
       yield undefined;
 
 
       // Now go back in history. First page should not have been cached.
       gBrowser.goBack();
       yield undefined;
 
 
@@ -106,17 +107,17 @@
       isnot(formValue, text, testName + " form value incorrectly restored");
 
     
       // https no-cache
       testName = "[nocache]";
 
       // Load a page with a no-cache header. This should not be
       // restricted like no-store (bug 567365)
-      gBrowser.loadURI(nocacheURI);
+      BrowserTestUtils.loadURI(gBrowser, nocacheURI);
       yield undefined;
 
 
       // Now that the page has loaded, amend the form contents
       form = gBrowser.contentDocument.getElementById("inp");
       form.value = text;
 
       // Attempt to scroll the page
@@ -129,17 +130,17 @@
       // Save the scroll position for future comparison
       scrollX = gBrowser.contentWindow.scrollX;
       scrollY = gBrowser.contentWindow.scrollY;
       isnot(scrollX, originalXPosition,
             testName + " failed to scroll window horizontally");
       isnot(scrollY, originalYPosition,
             testName + " failed to scroll window vertically");
 
-      gBrowser.loadURI(simple);
+      BrowserTestUtils.loadURI(gBrowser, simple);
       yield undefined;
 
 
       // Now go back in history to the cached page.
       gBrowser.goBack();
       yield undefined;
 
 
--- a/docshell/test/chrome/bug364461_window.xul
+++ b/docshell/test/chrome/bug364461_window.xul
@@ -9,17 +9,17 @@
 <window id="364461Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         width="600"
         height="600"
         onload="onLoad();"
         title="364461 test">
 
   <script type="application/javascript"><![CDATA[
-
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     const LISTEN_EVENTS = ["load", "unload", "pageshow", "pagehide"];
 
     var gBrowser;
     var gTestsIterator;
     var gExpected = [];
 
     function ok(condition, message) {
       window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
@@ -71,37 +71,36 @@
       }
     }
 
     function nextTest() {
       gTestsIterator.next();
     }
 
     function* testsIterator() {
-
       // Tests 1 + 2:
       //  Back/forward between two simple documents. Bfcache will be used.
 
       var test1Doc = "data:text/html,<html><head><title>test1</title></head>" +
                      "<body>test1</body></html>";
 
       gExpected = [{type: "pagehide", persisted: true},
 
                    {type: "load", title: "test1"},
                    {type: "pageshow", title: "test1", persisted: false}];
-      gBrowser.loadURI(test1Doc);
+      BrowserTestUtils.loadURI(gBrowser, test1Doc);
       yield undefined;
 
       var test2Doc = "data:text/html,<html><head><title>test2</title></head>" +
                      "<body>test2</body></html>";
 
       gExpected = [{type: "pagehide", title: "test1", persisted: true},
                    {type: "load", title: "test2"},
                    {type: "pageshow", title: "test2", persisted: false}];
-      gBrowser.loadURI(test2Doc);
+      BrowserTestUtils.loadURI(gBrowser, test2Doc);
       yield undefined;
 
       gExpected = [{type: "pagehide", title: "test2", persisted: true},
                    {type: "pageshow", title: "test1", persisted: true}];
       gBrowser.goBack();
       yield undefined;
       
       gExpected = [{type: "pagehide", title: "test1", persisted: true},
@@ -129,28 +128,28 @@
 
       gExpected = [{type: "pagehide", title: "test2", persisted: true},
                    {type: "load", title: "test3-nested2"},
                    {type: "pageshow", title: "test3-nested2", persisted: false},
                    {type: "load", title: "test3-nested1"},
                    {type: "pageshow", title: "test3-nested1", persisted: false},
                    {type: "load", title: "test3"},
                    {type: "pageshow", title: "test3", persisted: false}];
-      gBrowser.loadURI(test3Doc);
+      BrowserTestUtils.loadURI(gBrowser, test3Doc);
       yield undefined;
 
       var test4Doc = "data:text/html,<html><head><title>test4</title></head>" +
                      "<body>test4</body></html>";
 
       gExpected = [{type: "pagehide", title: "test3", persisted: true},
                    {type: "pagehide", title: "test3-nested1", persisted: true},
                    {type: "pagehide", title: "test3-nested2", persisted: true},
                    {type: "load", title: "test4"},
                    {type: "pageshow", title: "test4", persisted: false}];
-      gBrowser.loadURI(test4Doc);
+      BrowserTestUtils.loadURI(gBrowser, test4Doc);
       yield undefined;
 
       gExpected = [{type: "pagehide", title: "test4", persisted: true},
                    {type: "pageshow", title: "test3-nested2", persisted: true},
                    {type: "pageshow", title: "test3-nested1", persisted: true},
                    {type: "pageshow", title: "test3", persisted: true}];
       gBrowser.goBack();
       yield undefined;
@@ -170,27 +169,27 @@
       
       var test5Doc = "data:text/html,<html><head><title>test5</title></head>" +
                      "<body onunload='while(false) { /* nop */ }'>" +
                      "test5</body></html>";
 
       gExpected = [{type: "pagehide", title: "test4", persisted: true},
                    {type: "load", title: "test5"},
                    {type: "pageshow", title: "test5", persisted: false}];
-      gBrowser.loadURI(test5Doc);
+      BrowserTestUtils.loadURI(gBrowser, test5Doc);
       yield undefined;
 
       var test6Doc = "data:text/html,<html><head><title>test6</title></head>" +
                      "<body>test6</body></html>";
 
       gExpected = [{type: "pagehide", title: "test5", persisted: false},
                    {type: "unload", title: "test5"},
                    {type: "load", title: "test6"},
                    {type: "pageshow", title: "test6", persisted: false}];
-      gBrowser.loadURI(test6Doc);
+      BrowserTestUtils.loadURI(gBrowser, test6Doc);
       yield undefined;
 
       gExpected = [{type: "pagehide", title: "test6", persisted: true},
                    {type: "load", title: "test5"},
                    {type: "pageshow", title: "test5", persisted: false}];
       gBrowser.goBack();
       yield undefined;
       
@@ -216,17 +215,17 @@
                       "</iframe>" +
                     "</body></html>";
       
       gExpected = [{type: "pagehide", title: "test6", persisted: true},
                    {type: "load", title: "test7-nested1"},
                    {type: "pageshow", title: "test7-nested1", persisted: false},
                    {type: "load", title: "test7"},
                    {type: "pageshow", title: "test7", persisted: false}];
-      gBrowser.loadURI(test7Doc);
+      BrowserTestUtils.loadURI(gBrowser, test7Doc);
       yield undefined;
 
       // Simulates a click on the link inside the iframe
       function clickIframeLink() {
         var iframe = gBrowser.contentDocument.getElementsByTagName("iframe")[0];
         var w = iframe.contentWindow;
         var d = iframe.contentDocument;
         
--- a/docshell/test/chrome/bug396519_window.xul
+++ b/docshell/test/chrome/bug396519_window.xul
@@ -9,17 +9,17 @@
 <window id="396519Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         width="600"
         height="600"
         onload="onLoad();"
         title="396519 test">
 
   <script type="application/javascript"><![CDATA[
-
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     const LISTEN_EVENTS = ["pageshow"];
 
     var gBrowser;
     var gTestCount = 0;
     var gTestsIterator;
     var gExpected = [];
 
     function ok(condition, message) {
@@ -88,52 +88,51 @@
       setTimeout(nextTest, 0);
     }
 
     function nextTest() {
       gTestsIterator.next();
     }
 
     function* testsIterator() {
-
       // Tests 1 + 2:
       //  Back/forward between two simple documents. Bfcache will be used.
 
       var test1Doc = "data:text/html,<html><head><title>test1</title></head>" +
                      "<body>test1</body></html>";
 
       gTestCount++;
       gExpected = [false];
-      gBrowser.loadURI(test1Doc);
+      BrowserTestUtils.loadURI(gBrowser, test1Doc);
       yield undefined;
 
       gTestCount++;
       gExpected = [true, false];
       var test2Doc = test1Doc.replace(/1/,"2");
-      gBrowser.loadURI(test2Doc);
+      BrowserTestUtils.loadURI(gBrowser, test2Doc);
       yield undefined;
 
       gTestCount++;
       gExpected = [true, true, false];
-      gBrowser.loadURI(test1Doc);
+      BrowserTestUtils.loadURI(gBrowser, test1Doc);
       yield undefined;
 
       gTestCount++;
       gExpected = [true, true, true, false];
-      gBrowser.loadURI(test2Doc);
+      BrowserTestUtils.loadURI(gBrowser, test2Doc);
       yield undefined;
 
       gTestCount++;
       gExpected = [false, true, true, true, false];
-      gBrowser.loadURI(test1Doc);
+      BrowserTestUtils.loadURI(gBrowser, test1Doc);
       yield undefined;
 
       gTestCount++;
       gExpected = [false, false, true, true, true, false];
-      gBrowser.loadURI(test2Doc);
+      BrowserTestUtils.loadURI(gBrowser, test2Doc);
       yield undefined;
 
       gTestCount++;
       gExpected = [false, false, true, true, false, true];
       gBrowser.goBack();
       yield undefined;
 
       gTestCount++;
--- a/docshell/test/chrome/bug582176_window.xul
+++ b/docshell/test/chrome/bug582176_window.xul
@@ -6,17 +6,18 @@
         width="600"
         height="600"
         onload="nextTestAsync();"
         title="bug 582176 test">
 
   <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
   <script type="application/javascript" src="docshell_helpers.js" />
   <script type="application/javascript"><![CDATA[
-  
+
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     // Define the generator-iterator for the tests.
     var tests = testIterator();
 
     ////
     // Execute the next test in the generator function.
     //
     function nextTestAsync() {
       SimpleTest.executeSoon(tests.next.bind(tests));
@@ -45,36 +46,36 @@
           notificationCount++;
         }
       };
 
       os = Cc["@mozilla.org/observer-service;1"].
         getService(Ci.nsIObserverService);
       os.addObserver(observer, "content-document-global-created");
 
-      browser.loadURI("http://mochi.test:8888/tests/docshell/test/chrome/582176_dummy.html");
+      BrowserTestUtils.loadURI(browser, "http://mochi.test:8888/tests/docshell/test/chrome/582176_dummy.html");
       yield undefined;
       is(browser.contentWindow.testVar, undefined,
          "variable unexpectedly there already");
       browser.contentWindow.wrappedJSObject.testVar = 1;
       is(notificationCount, 1, "Should notify on first navigation");
 
-      browser.loadURI("http://mochi.test:8888/tests/docshell/test/chrome/582176_dummy.html?2");
+      BrowserTestUtils.loadURI(browser, "http://mochi.test:8888/tests/docshell/test/chrome/582176_dummy.html?2");
       yield undefined;
       is(browser.contentWindow.wrappedJSObject.testVar, undefined,
          "variable should no longer be there");
       is(notificationCount, 2, "Should notify on second navigation");
 
       browser.goBack();
       yield undefined;
       is(browser.contentWindow.wrappedJSObject.testVar, 1,
          "variable should still be there");
       is(notificationCount, 2, "Should not notify on back navigation");
 
-      browser.loadURI("http://mochi.test:8888/tests/docshell/test/chrome/582176_xml.xml");
+      BrowserTestUtils.loadURI(browser, "http://mochi.test:8888/tests/docshell/test/chrome/582176_xml.xml");
       yield undefined;
       is(browser.contentDocument.body.textContent, "xslt result",
          "Transform performed successfully");
       is(notificationCount, 3, "Should notify only once on XSLT navigation");
 
       os.removeObserver(observer, "content-document-global-created")
 
       // Tell the framework the test is finished.
--- a/docshell/test/chrome/bug92598_window.xul
+++ b/docshell/test/chrome/bug92598_window.xul
@@ -9,16 +9,17 @@
 <window id="92598Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         width="600"
         height="600"
         onload="onLoad();"
         title="92598 test">
 
   <script type="application/javascript"><![CDATA[
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     const LISTEN_EVENTS = ["load", "unload", "pageshow", "pagehide"];
 
     var gBrowser;
     var gTestsIterator;
     var gExpected = [];
 
     function ok(condition, message) {
       window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
@@ -82,27 +83,27 @@
     function* testsIterator() {
       // Load a page with a no-cache header, followed by a simple page
       // On pagehide, first page should report it is not being persisted
       var test1DocURI = "http://mochi.test:8888/tests/docshell/test/chrome/92598_nostore.html";
 
       gExpected = [{type: "pagehide", persisted: true},
                    {type: "load", title: "test1"},
                    {type: "pageshow", title: "test1", persisted: false}];
-      gBrowser.loadURI(test1DocURI);
+      BrowserTestUtils.loadURI(gBrowser, test1DocURI);
       yield undefined;
 
       var test2Doc = "data:text/html,<html><head><title>test2</title></head>" +
                      "<body>test2</body></html>";
 
       gExpected = [{type: "pagehide", title: "test1", persisted: false},
                    {type: "unload", title: "test1"},
                    {type: "load", title: "test2"},
                    {type: "pageshow", title: "test2", persisted: false}];
-      gBrowser.loadURI(test2Doc);
+      BrowserTestUtils.loadURI(gBrowser, test2Doc);
       yield undefined;
 
       // Now go back in history. First page should not have been cached.
       // Check persisted property to confirm
       gExpected = [{type: "pagehide", title: "test2", persisted: true},
                    {type: "load", title: "test1"},
                    {type: "pageshow", title: "test1", persisted: false}];
       gBrowser.goBack();
--- a/docshell/test/chrome/docshell_helpers.js
+++ b/docshell/test/chrome/docshell_helpers.js
@@ -1,16 +1,17 @@
 /**  
  * Import common SimpleTest methods so that they're usable in this window.
  */
 var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror", "todo",
   "todo_is", "todo_isnot" ];
 for (var name of imports) {
   window[name] = window.opener.wrappedJSObject[name];
 }
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 
 /**
  * Define global constants and variables.
  */
 const NAV_NONE = 0;
 const NAV_BACK = 1;
 const NAV_FORWARD = 2;
 const NAV_URI = 3;
@@ -164,17 +165,17 @@ function doPageNavigation(params) {
     TestWindow.getBrowser().goBack();
   }
   else if (forward) {
     gNavType = NAV_FORWARD;
     TestWindow.getBrowser().goForward();
   }
   else if (uri) {
     gNavType = NAV_URI;
-    TestWindow.getBrowser().loadURI(uri);
+    BrowserTestUtils.loadURI(TestWindow.getBrowser(), uri);
   }
   else if (reload) {
     gNavType = NAV_RELOAD;
     TestWindow.getBrowser().reload();
   }
   else if (waitOnly) {
     gNavType = NAV_NONE;
   }
--- a/docshell/test/navigation/browser_bug343515.js
+++ b/docshell/test/navigation/browser_bug343515.js
@@ -96,17 +96,17 @@ function step3() {
     for (var i = 0; i < content.frames.length; i++) {
       info("step 3, frame " + i + " info: " + content.frames[i].location);
       let docshell = content.frames[i].docShell;
 
       Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
     }
   }).then(() => {
     // Navigate tab 2 to a different page
-    ctx.tab2Browser.loadURI(testPath + "bug343515_pg3.html");
+    BrowserTestUtils.loadURI(ctx.tab2Browser, testPath + "bug343515_pg3.html");
 
     // bug343515_pg3.html consists of a page with two iframes, one of which
     // contains another iframe, so there'll be a total of 4 load events
     nShotsListener(ctx.tab2Browser, "load", step4, 4);
   });
 }
 
 function step4() {
@@ -165,17 +165,17 @@ function step5() {
 
       Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`);
     }
   }).then(() => {
     // Switch to tab 1
     return BrowserTestUtils.switchTab(gBrowser, ctx.tab1);
   }).then(() => {
     // Navigate to page 3
-    ctx.tab1Browser.loadURI(testPath + "bug343515_pg3.html");
+    BrowserTestUtils.loadURI(ctx.tab1Browser, testPath + "bug343515_pg3.html");
 
     // bug343515_pg3.html consists of a page with two iframes, one of which
     // contains another iframe, so there'll be a total of 4 load events
     nShotsListener(ctx.tab1Browser, "load", step6, 4);
   });
 }
 
 function step6() {
--- a/dom/base/test/browser_aboutnewtab_process_selection.js
+++ b/dom/base/test/browser_aboutnewtab_process_selection.js
@@ -49,17 +49,17 @@ add_task(async function(){
   BrowserOpenTab();
   let tab2 = gBrowser.selectedTab;
   await ensurePreloaded(gBrowser);
 
   // Check that the process count did not change.
   is(ppmm.childCount, originalChildCount, "Preloaded browser should (still) not create a new content process.")
 
   // Navigate to a content page from the parent side.
-  tab2.linkedBrowser.loadURI(TEST_URL);
+  BrowserTestUtils.loadURI(tab2.linkedBrowser, TEST_URL);
   await BrowserTestUtils.browserLoaded(tab2.linkedBrowser, false, TEST_URL);
   is(ppmm.childCount, originalChildCount + 1,
      "Navigating away from the preloaded browser (parent side) should create a new content process.")
 
   // Navigate to a content page from the child side.
   await BrowserTestUtils.switchTab(gBrowser, tab1);
   await ContentTask.spawn(tab1.linkedBrowser, null, async function() {
     const TEST_URL = "http://www.example.com/browser/dom/base/test/dummy.html";
@@ -92,17 +92,17 @@ add_task(async function preloaded_state_
   // Now check that the tabs have the correct browser attributes set
   let consumedTabState = gBrowser.selectedBrowser.getAttribute("preloadedState");
   is(consumedTabState, CONSUMED_STATE, "The opened tab consumed the preloaded browser and updated the attribute");
 
   preloadedTabState = gBrowser._preloadedBrowser.getAttribute("preloadedState");
   is(preloadedTabState, PRELOADED_STATE, "The preloaded browser has the correct attribute");
 
   // Navigate away and check that the attribute has been removed altogether
-  gBrowser.selectedBrowser.loadURI(TEST_URL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URL);
   let navigatedTabHasState = gBrowser.selectedBrowser.hasAttribute("preloadedState");
   ok(!navigatedTabHasState, "Correctly removed the preloadState attribute when navigating away");
 
   // Remove tabs and preloaded browsers
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
   gBrowser.removePreloadedBrowser();
 });
 
--- a/dom/base/test/browser_bug902350.js
+++ b/dom/base/test/browser_bug902350.js
@@ -13,17 +13,17 @@ add_task(async function mixed_content_bl
                                                              waitForLoad: true });
   let testBrowser = newTab.linkedBrowser;
 
   var url = httpsTestRoot + "file_bug902350.html";
   var frameUrl = httpsTestRoot + "file_bug902350_frame.html";
   let loadPromise = BrowserTestUtils.browserLoaded(testBrowser, false, url);
   let frameLoadPromise = BrowserTestUtils.browserLoaded(testBrowser, true,
                                                         frameUrl);
-  testBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(testBrowser, url);
   await loadPromise;
   await frameLoadPromise;
 
   // Find the iframe and click the link in it.
   let insecureUrl = "http://example.com/";
   let insecureLoadPromise = BrowserTestUtils.browserLoaded(testBrowser, false,
                                                            insecureUrl);
   ContentTask.spawn(testBrowser, null, function() {
--- a/dom/base/test/browser_messagemanager_loadprocessscript.js
+++ b/dom/base/test/browser_messagemanager_loadprocessscript.js
@@ -117,17 +117,17 @@ add_task(async function() {
 add_task(async function() {
   // This test is only relevant in e10s
   if (!gMultiProcessBrowser)
     return;
 
   checkBaseProcessCount("Should still be at the base number of processes at this point");
 
   // Load something in the main process
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   let init = Services.ppmm.initialProcessData;
   init.test123 = "hello";
   init.test456 = new Map();
   init.test456.set("hi", "bye");
 
   // With no remote frames left we should be down to one process.
@@ -141,17 +141,17 @@ add_task(async function() {
     Services.ppmm.loadProcessScript(processScriptURL, true);
 
     // The main process should respond
     await check;
 
     check = checkProcess(Services.ppmm);
     // Reset the default browser to start a new child process
     gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, true);
-    gBrowser.selectedBrowser.loadURI("about:blank");
+    BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank");
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
     checkBaseProcessCount("Should be back to the base number of processes at this point");
 
     // The new process should have responded
     await check;
 
     Services.ppmm.removeDelayedProcessScript(processScriptURL);
--- a/dom/base/test/browser_state_notifications.js
+++ b/dom/base/test/browser_state_notifications.js
@@ -101,17 +101,17 @@ const test = Test(async function() {
     // This test is executed synchronously when the event is received.
     is(d.readyState, "interactive", "document is interactive");
     is(d.URL, uri2, "document.URL matches URL loaded");
   });
   documentLoaded = receive("content-document-loaded", isData);
   pageShown = receive("content-page-shown", isData);
   let pageHidden = receive("content-page-hidden", isData);
 
-  browser1.loadURI(uri2);
+  BrowserTestUtils.loadURI(browser1, uri2);
 
   let hiddenPage = await pageHidden;
   is(interactiveDocument1, hiddenPage, "loaded document is hidden");
 
   let interactiveDocument2 = await documentInteractive;
 
   let loadedDocument2 = await documentLoaded;
   is(loadedDocument2.readyState, "complete", "document is loaded");
@@ -135,17 +135,17 @@ const test = Test(async function() {
   hiddenPage = await pageHidden;
   is(interactiveDocument2, hiddenPage, "new document is hidden");
 
   shownPage = await pageShown;
   is(interactiveDocument1, shownPage, "previous document is shown");
 
   info("load uri#3");
 
-  browser1.loadURI(uri3);
+  BrowserTestUtils.loadURI(browser1, uri3);
 
   pageShown = receive("content-page-shown", isData);
 
   let interactiveDocument3 = await documentInteractive;
 
   let loadedDocument3 = await documentLoaded;
   is(loadedDocument3.readyState, "complete", "document is loaded");
   is(interactiveDocument3, loadedDocument3, "interactive document is loaded");
--- a/dom/base/test/browser_timeout_throttling_with_audio_playback.js
+++ b/dom/base/test/browser_timeout_throttling_with_audio_playback.js
@@ -28,17 +28,17 @@ Services.scriptloader.loadSubScript(kPlu
 
 async function runTest(url) {
   let currentTab = gBrowser.selectedTab;
   let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, kBaseURI);
   let newBrowser = gBrowser.getBrowserForTab(newTab);
 
   // Wait for the UI to indicate that audio is being played back.
   let promise = BrowserTestUtils.waitForAttribute("soundplaying", newTab, "true");
-  newBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(newBrowser, url);
   await promise;
 
   // Put the tab in the background.
   await BrowserTestUtils.switchTab(gBrowser, currentTab);
 
   let timeout = await ContentTask.spawn(newBrowser, kDelay, function(delay) {
     return new Promise(resolve => {
       let before = new Date();
--- a/dom/base/test/browser_use_counters.js
+++ b/dom/base/test/browser_use_counters.js
@@ -138,17 +138,17 @@ var check_use_counter_iframe = async fun
   newTab.linkedBrowser.stop();
 
   // Hold on to the current values of the telemetry histograms we're
   // interested in.
   let [histogram_page_before, histogram_document_before,
        histogram_docs_before, histogram_toplevel_docs_before] =
       await grabHistogramsFromContent(use_counter_middlefix);
 
-  gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gHttpTestRoot + "file_use_counter_outer.html");
   await waitForPageLoad(gBrowser.selectedBrowser);
 
   // Inject our desired file into the iframe of the newly-loaded page.
   await ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) {
     ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
     let deferred = PromiseUtils.defer();
 
     let wu = content.window.windowUtils;
@@ -202,17 +202,17 @@ var check_use_counter_img = async functi
   newTab.linkedBrowser.stop();
 
   // Hold on to the current values of the telemetry histograms we're
   // interested in.
   let [histogram_page_before, histogram_document_before,
        histogram_docs_before, histogram_toplevel_docs_before] =
       await grabHistogramsFromContent(use_counter_middlefix);
 
-  gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gHttpTestRoot + "file_use_counter_outer.html");
   await waitForPageLoad(gBrowser.selectedBrowser);
 
   // Inject our desired file into the img of the newly-loaded page.
   await ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, async function(opts) {
     ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
     let deferred = PromiseUtils.defer();
 
     let img = content.document.getElementById('display');
@@ -268,17 +268,17 @@ var check_use_counter_direct = async fun
   newTab.linkedBrowser.stop();
 
   // Hold on to the current values of the telemetry histograms we're
   // interested in.
   let [histogram_page_before, histogram_document_before,
        histogram_docs_before, histogram_toplevel_docs_before] =
       await grabHistogramsFromContent(use_counter_middlefix);
 
-  gBrowser.selectedBrowser.loadURI(gHttpTestRoot + file);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gHttpTestRoot + file);
   await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
     ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
     await new Promise(resolve => {
       let listener = () => {
         removeEventListener("load", listener, true);
 
         let wu = content.window.windowUtils;
         wu.forceUseCounterFlush(content.document);
--- a/dom/events/test/test_bug415498.xul
+++ b/dom/events/test/test_bug415498.xul
@@ -15,16 +15,17 @@ https://bugzilla.mozilla.org/show_bug.cg
           src="chrome://mochikit/content/chrome-harness.js"></script>
 <body  xmlns="http://www.w3.org/1999/xhtml">
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=415498">Mozilla Bug 415498</a>
 
   <p id="display"></p>
 
   <pre id="test">
   <script class="testbody" type="application/javascript"><![CDATA[
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 
     /** Test for Bug 415498 **/
     SimpleTest.waitForExplicitFinish();
 
     var gTestsIterator;
     var gConsole;
     var gConsoleListener;
     var gMessages = [];
@@ -59,26 +60,26 @@ https://bugzilla.mozilla.org/show_bug.cg
 
       var browser = $("browser");
       browser.addEventListener("load", function() {
         setTimeout(nextTest, 0)
       }, false);
 
       // 1) This document uses addEventListener to register a method throwing an exception
       var chromeDir = getRootDirectory(window.location.href);
-      browser.loadURI(chromeDir + "bug415498-doc1.html");
+      BrowserTestUtils.loadURI(browser, chromeDir + "bug415498-doc1.html");
       yield undefined;
 
       ok(verifyErrorReceived("HierarchyRequestError"),
          "Error message not reported in event listener callback!");
       gMessages = [];
 
       // 2) This document sets window.onload to register a method throwing an exception
       var chromeDir = getRootDirectory(window.location.href);
-      browser.loadURI(chromeDir + "bug415498-doc2.html");
+      BrowserTestUtils.loadURI(browser, chromeDir + "bug415498-doc2.html");
       yield undefined;
 
       ok(verifyErrorReceived("HierarchyRequestError"),
          "Error message not reported in window.onload!");
     }
     
     function verifyErrorReceived(errorString) {
       for (var i = 0; i < gMessages.length; i++) {
--- a/dom/events/test/test_bug617528.xul
+++ b/dom/events/test/test_bug617528.xul
@@ -12,16 +12,17 @@ https://bugzilla.mozilla.org/show_bug.cg
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=617528"
        target="_blank">Mozilla Bug 617528</a>
   </body>
 
   <script type="application/javascript"><![CDATA[
+    ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
     var _window;
     var browser;
 
     function start() {
       _window = window.open("window_bug617528.xul", "_new", "chrome");
       _window.addEventListener("load", onLoad, false);
     }
 
@@ -34,17 +35,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       var uri='data:text/html,\
 <html>\
   <body>\
     <div oncontextmenu="event.preventDefault()">\
       <input id="node" type="text" value="Click here"></input>\
     </div>\
   </body>\
 </html>';
-      browser.loadURI(uri);
+      BrowserTestUtils.loadURI(browser, uri);
     }
 
     function onPageShow() {
       browser.removeEventListener("pageshow", onPageShow, true);
       SimpleTest.executeSoon(doTest);
     }
 
     function onContextMenu1(event) {
--- a/dom/html/test/browser_DOMDocElementInserted.js
+++ b/dom/html/test/browser_DOMDocElementInserted.js
@@ -11,14 +11,14 @@ add_task(async function() {
       removeEventListener("DOMDocElementInserted", listener, true);
       deferred.resolve(event.target.documentURIObject.spec);
     };
     addEventListener("DOMDocElementInserted", listener, true);
 
     return deferred.promise;
   });
 
-  tab.linkedBrowser.loadURI(uri);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, uri);
   let loadedURI = await eventPromise;
   is(loadedURI, uri, "Should have seen the event for the right URI");
 
   gBrowser.removeTab(tab);
 });
--- a/dom/indexedDB/test/browser_forgetThisSite.js
+++ b/dom/indexedDB/test/browser_forgetThisSite.js
@@ -21,43 +21,43 @@ const testPageURL4 = "http://" + domains
 add_task(async function test1() {
   requestLongerTimeout(2);
   // Avoids the prompt
   setPermission(testPageURL1, "indexedDB");
   setPermission(testPageURL2, "indexedDB");
 
   // Set database version for domain 1
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-  gBrowser.selectedBrowser.loadURI(testPageURL1);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL1);
   await waitForMessage(11, gBrowser);
   gBrowser.removeCurrentTab();
 });
 
 add_task(async function test2() {
   // Set database version for domain 2
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-  gBrowser.selectedBrowser.loadURI(testPageURL2);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL2);
   await waitForMessage(11, gBrowser);
   gBrowser.removeCurrentTab();
 });
 
 add_task(async function test3() {
   // Remove database from domain 2
   ForgetAboutSite.removeDataFromDomain(domains[1]).then(() => {
     setPermission(testPageURL4, "indexedDB");
   });
 });
 
 add_task(async function test4() {
   // Get database version for domain 1
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-  gBrowser.selectedBrowser.loadURI(testPageURL3);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL3);
   await waitForMessage(11, gBrowser);
   gBrowser.removeCurrentTab();
 });
 
 add_task(async function test5() {
   // Get database version for domain 2
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-  gBrowser.selectedBrowser.loadURI(testPageURL4);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL4);
   await waitForMessage(1, gBrowser);
   gBrowser.removeCurrentTab();
 });
--- a/dom/indexedDB/test/browser_permissionsPromptAllow.js
+++ b/dom/indexedDB/test/browser_permissionsPromptAllow.js
@@ -21,17 +21,17 @@ add_task(async function test1() {
     ok(true, "prompt shown");
     triggerMainCommand(this);
   });
   registerPopupEventHandler("popuphidden", function() {
     ok(true, "prompt hidden");
   });
 
   info("loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
 
   await waitForMessage(true, gBrowser);
   is(getPermission(testPageURL, "indexedDB"),
      Ci.nsIPermissionManager.ALLOW_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
 });
 
@@ -45,17 +45,17 @@ add_task(async function test2() {
   registerPopupEventHandler("popupshown", function() {
     ok(false, "Shouldn't show a popup this time");
   });
   registerPopupEventHandler("popuphidden", function() {
     ok(false, "Shouldn't show a popup this time");
   });
 
   info("loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
 
   await waitForMessage(true, gBrowser);
   is(getPermission(testPageURL, "indexedDB"),
      Ci.nsIPermissionManager.ALLOW_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
   unregisterAllPopupEventHandlers();
   removePermission(testPageURL, "indexedDB");
--- a/dom/indexedDB/test/browser_permissionsPromptDeny.js
+++ b/dom/indexedDB/test/browser_permissionsPromptDeny.js
@@ -20,17 +20,17 @@ add_task(async function test1() {
   registerPopupEventHandler("popuphidden", function() {
     ok(true, "prompt hidden");
   });
 
   info("creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage("InvalidStateError", gBrowser);
 
   is(getPermission(testPageURL, "indexedDB"),
      Ci.nsIPermissionManager.DENY_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
 });
 
@@ -47,17 +47,17 @@ add_task(async function test2() {
   registerPopupEventHandler("popuphidden", function() {
     ok(false, "prompt hidden");
   }, win);
 
   info("creating private tab");
   win.gBrowser.selectedTab = BrowserTestUtils.addTab(win.gBrowser);
 
   info("loading test page: " + testPageURL);
-  win.gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, testPageURL);
   await waitForMessage("InvalidStateError", win.gBrowser);
 
   is(getPermission(testPageURL, "indexedDB"),
      Ci.nsIPermissionManager.DENY_ACTION,
      "Correct permission set");
   unregisterAllPopupEventHandlers();
   win.gBrowser.removeCurrentTab();
   await BrowserTestUtils.closeWindow(win);
@@ -73,17 +73,17 @@ add_task(async function test3() {
   registerPopupEventHandler("popuphidden", function() {
     ok(false, "Shouldn't show a popup this time");
   });
 
   info("creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage("InvalidStateError", gBrowser);
 
   is(getPermission(testPageURL, "indexedDB"),
      Ci.nsIPermissionManager.DENY_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
   unregisterAllPopupEventHandlers();
   removePermission(testPageURL, "indexedDB");
--- a/dom/indexedDB/test/browser_permissionsPromptWorker.js
+++ b/dom/indexedDB/test/browser_permissionsPromptWorker.js
@@ -21,17 +21,17 @@ add_task(async function test1() {
   });
   registerPopupEventHandler("popuphidden", function() {
     ok(true, "prompt hidden");
   });
 
   info("creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   info("loading test page: " + testWorkerURL);
-  gBrowser.selectedBrowser.loadURI(testWorkerURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testWorkerURL);
 
   await waitForMessage("ok", gBrowser);
   is(getPermission(testWorkerURL, "indexedDB"),
      Ci.nsIPermissionManager.ALLOW_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
 });
 
@@ -49,15 +49,15 @@ add_task(async function test2() {
     ok(false, "prompt hidden");
   });
 
   info("creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
 
   info("loading test page: " + testSharedWorkerURL);
-  gBrowser.selectedBrowser.loadURI(testSharedWorkerURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testSharedWorkerURL);
   await waitForMessage("InvalidStateError", gBrowser);
   is(getPermission(testSharedWorkerURL, "indexedDB"),
      Ci.nsIPermissionManager.UNKNOWN_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
 });
--- a/dom/indexedDB/test/browser_perwindow_privateBrowsing.js
+++ b/dom/indexedDB/test/browser_perwindow_privateBrowsing.js
@@ -10,26 +10,26 @@ const notificationID = "indexedDB-permis
 add_task(async function test1() {
   // Avoids the actual prompt
   setPermission(testPageURL, "indexedDB");
 
   info("creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
 
   await waitForMessage(true, gBrowser);
   gBrowser.removeCurrentTab();
 });
 
 add_task(async function test2() {
   info("creating private window");
   let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
 
   info("creating tab");
   win.gBrowser.selectedTab = BrowserTestUtils.addTab(win.gBrowser);
-  win.gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, testPageURL);
   await waitForMessage("InvalidStateError", win.gBrowser);
   win.gBrowser.removeCurrentTab();
   await BrowserTestUtils.closeWindow(win);
   win = null;
 });
--- a/dom/ipc/tests/browser_domainPolicy.js
+++ b/dom/ipc/tests/browser_domainPolicy.js
@@ -44,17 +44,17 @@ async function test_domainPolicy() {
           content.addEventListener('load', listener2);
         };
         addEventListener("DOMDocElementInserted", listener, true);
         return deferred.promise;
       }
 
       return loadBase();
     });
-    tab.linkedBrowser.loadURI("http://mochi.test:8888/browser/dom/ipc/tests/file_domainPolicy_base.html");
+    BrowserTestUtils.loadURI(tab.linkedBrowser, "http://mochi.test:8888/browser/dom/ipc/tests/file_domainPolicy_base.html");
     return initPromise;
   }
 
   // We use ContentTask for the tests, but we also want to pass some data and some helper functions too.
   // To do that, we serialize an input object via JSON |ipcArgs| and some shared helper functions |initUtils|
   // and eval them in the content process.
   var ipcArgs = {};
   function initUtils(obj) {
--- a/dom/plugins/test/mochitest/browser_bug1335475.js
+++ b/dom/plugins/test/mochitest/browser_bug1335475.js
@@ -12,17 +12,17 @@ add_task(async function() {
     await ContentTask.spawn(browser, null, async function() {
       is(content.window.navigator.plugins.length, 0,
          "plugins should not be available to null-principal about:blank");
       ok(!("application/x-test" in content.window.navigator.mimeTypes),
          "plugins should not be available to null-principal about:blank");
     });
 
     let promise = BrowserTestUtils.browserLoaded(browser);
-    browser.loadURI(gTestRoot + "plugin_test.html");
+    BrowserTestUtils.loadURI(browser, gTestRoot + "plugin_test.html");
     await promise;
 
     await ContentTask.spawn(browser, null, async function() {
       ok(content.window.navigator.plugins.length > 0,
          "plugins should be available to HTTP-loaded pages");
       ok("application/x-test" in content.window.navigator.mimeTypes,
          "plugins should be available to HTTP-loaded pages");
 
@@ -45,17 +45,17 @@ add_task(async function() {
       ok("application/x-test" in content.window.navigator.mimeTypes,
          "plugins should be available when a site triggers an about:blank load");
     });
 
     // navigate to the file: URI, which shouldn't allow plugins. This might
     // be wrapped in jar:, but that shouldn't matter for this test
     promise = BrowserTestUtils.browserLoaded(browser);
     let converteduri = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry).convertChromeURL(Services.io.newURI(rootDir + "plugin_test.html"));
-    browser.loadURI(converteduri.spec);
+    BrowserTestUtils.loadURI(browser, converteduri.spec);
     await promise;
 
     await ContentTask.spawn(browser, null, async function() {
       ok(!("application/x-test" in content.window.navigator.mimeTypes),
          "plugins should not be available to file: URI content");
     });
   });
 
--- a/dom/plugins/test/mochitest/test_privatemode_perwindowpb.xul
+++ b/dom/plugins/test/mochitest/test_privatemode_perwindowpb.xul
@@ -15,16 +15,17 @@
 <body xmlns="http://www.w3.org/1999/xhtml" onload="runTestsCallback()">
 <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
 <embed id="plugin2" type="application/x-test" width="200" height="200"></embed>
 </body>
 <script class="testbody" type="application/javascript">
 <![CDATA[
 SimpleTest.waitForExplicitFinish();
 
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function whenDelayedStartupFinished(aWindow, aCallback) {
   Services.obs.addObserver(function observer(aSubject, aTopic) {
     if (aWindow == aSubject) {
       Services.obs.removeObserver(observer, aTopic);
       SimpleTest.executeSoon(aCallback);
@@ -54,24 +55,24 @@ function runTestsCallback() {
   var mainWindow = window.docShell.rootTreeItem.domWindow;
   var contentPage = getRootDirectory(window.location.href) + "privatemode_perwindowpb.xul";
 
   function testOnWindow(aIsPrivate, aCallback) {
     var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
     whenDelayedStartupFinished(win, function () {
       win.addEventListener("DOMContentLoaded", function onInnerLoad() {
         if (win.content.location.href == "about:privatebrowsing") {
-          win.gBrowser.loadURI(contentPage);
+          BrowserTestUtils.loadURI(win.gBrowser, contentPage)
           return;
         }
         win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
         win.gBrowser.selectedBrowser.focus();
         SimpleTest.executeSoon(function() { aCallback(win); });
       }, true);
-      SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+      SimpleTest.executeSoon(function() { BrowserTestUtils.loadURI(win.gBrowser, contentPage); });
     });
   }
 
   testOnWindow(true, function(aWin) {
     pluginElement1 = aWin.gBrowser.contentDocument.getElementById("plugin1");
     pluginElement2 = aWin.gBrowser.contentDocument.getElementById("plugin2");
 
     var officialState1, officialState2;
--- a/dom/quota/test/browser_permissionsPromptAllow.js
+++ b/dom/quota/test/browser_permissionsPromptAllow.js
@@ -19,17 +19,17 @@ add_task(async function testPermissionAl
   registerPopupEventHandler("popuphidden", function () {
     ok(true, "prompt hidden");
   });
 
   info("Creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("Loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage(true, gBrowser);
 
   is(getPermission(testPageURL, "persistent-storage"),
      Ci.nsIPermissionManager.ALLOW_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
   unregisterAllPopupEventHandlers();
   // Keep persistent-storage permission for the next test.
@@ -45,17 +45,17 @@ add_task(async function testNoPermission
   registerPopupEventHandler("popuphidden", function () {
     ok(false, "Shouldn't show a popup this time");
   });
 
   info("Creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("Loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage(true, gBrowser);
 
   is(getPermission(testPageURL, "persistent-storage"),
      Ci.nsIPermissionManager.ALLOW_ACTION,
      "Correct permission set");
   gBrowser.removeCurrentTab();
   unregisterAllPopupEventHandlers();
   removePermission(testPageURL, "persistent-storage");
--- a/dom/quota/test/browser_permissionsPromptDeny.js
+++ b/dom/quota/test/browser_permissionsPromptDeny.js
@@ -19,17 +19,17 @@ add_task(async function testPermissionDe
   registerPopupEventHandler("popuphidden", function () {
     ok(true, "prompt hidden");
   });
 
   info("Creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("Loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage(false, gBrowser);
 
   is(getPermission(testPageURL, "persistent-storage"),
      Ci.nsIPermissionManager.DENY_ACTION,
      "Correct permission set");
   unregisterAllPopupEventHandlers();
   gBrowser.removeCurrentTab();
   // Keep persistent-storage permission for the next test.
@@ -45,17 +45,17 @@ add_task(async function testNoPermission
   registerPopupEventHandler("popuphidden", function () {
     ok(false, "Shouldn't show a popup this time");
   });
 
   info("Creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("Loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage(false, gBrowser);
 
   is(getPermission(testPageURL, "persistent-storage"),
      Ci.nsIPermissionManager.DENY_ACTION,
      "Correct permission set");
   unregisterAllPopupEventHandlers();
   gBrowser.removeCurrentTab();
   removePermission(testPageURL, "persistent-storage");
@@ -73,17 +73,17 @@ add_task(async function testPermissionDe
   registerPopupEventHandler("popuphidden", function () {
     ok(true, "prompt hidden");
   });
 
   info("Creating tab");
   gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   info("Loading test page: " + testPageURL);
-  gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testPageURL);
   await waitForMessage(false, gBrowser);
 
   // Pressing ESC results in a temporary block permission on the browser object.
   // So the global permission for the URL should still be unknown, but the browser
   // should have a block permission with a temporary scope.
   is(getPermission(testPageURL, "persistent-storage"),
      Ci.nsIPermissionManager.UNKNOWN_ACTION,
      "Correct permission set");
--- a/dom/quota/test/browser_permissionsPromptUnknown.js
+++ b/dom/quota/test/browser_permissionsPromptUnknown.js
@@ -20,17 +20,17 @@ add_task(async function testPermissionUn
   registerPopupEventHandler("popuphidden", function () {
     ok(false, "Shouldn't show a popup this time");
   }, win);
 
   info("Creating private tab");
   win.gBrowser.selectedTab = BrowserTestUtils.addTab(win.gBrowser);
 
   info("Loading test page: " + testPageURL);
-  win.gBrowser.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, testPageURL);
   await waitForMessage(false, win.gBrowser);
 
   is(getPermission(testPageURL, "persistent-storage"),
      Ci.nsIPermissionManager.UNKNOWN_ACTION,
      "Correct permission set");
   unregisterAllPopupEventHandlers(win);
   win.gBrowser.removeCurrentTab();
   await BrowserTestUtils.closeWindow(win);
--- a/dom/security/test/general/browser_test_data_download.js
+++ b/dom/security/test/general/browser_test_data_download.js
@@ -26,10 +26,10 @@ function test() {
     Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
   });
   addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) {
     is(win.document.getElementById("location").value, "data-foo.html",
        "file name of download should match");
      win.close();
      finish();
   });
-  gBrowser.loadURI(kTestURI);
+  BrowserTestUtils.loadURI(gBrowser, kTestURI);
 }
--- a/dom/security/test/general/browser_test_data_text_csv.js
+++ b/dom/security/test/general/browser_test_data_text_csv.js
@@ -26,10 +26,10 @@ function test() {
     Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
   });
   addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) {
     is(win.document.getElementById("location").value, "text/csv;foo,bar,foobar",
        "file name of download should match");
      win.close();
      finish();
   });
-  gBrowser.loadURI(kTestURI);
+  BrowserTestUtils.loadURI(gBrowser, kTestURI);
 }
--- a/dom/serviceworkers/test/browser_download.js
+++ b/dom/serviceworkers/test/browser_download.js
@@ -69,12 +69,12 @@ function test() {
 
       downloadListener = {
         onDownloadAdded: downloadVerifier,
         onDownloadChanged: downloadVerifier
       };
 
       return downloadList.addView(downloadListener);
     }).then(function() {
-      gBrowser.loadURI(url);
+      BrowserTestUtils.loadURI(gBrowser, url);
     });
   });
 }
--- a/dom/serviceworkers/test/browser_force_refresh.js
+++ b/dom/serviceworkers/test/browser_force_refresh.js
@@ -35,17 +35,17 @@ function test() {
                                      ['browser.cache.memory.enable', false]]},
                             function() {
     var url = gTestRoot + 'browser_base_force_refresh.html';
     var tab = BrowserTestUtils.addTab(gBrowser);
     var tabBrowser = gBrowser.getBrowserForTab(tab);
     gBrowser.selectedTab = tab;
 
     tab.linkedBrowser.messageManager.loadFrameScript("data:,(" + encodeURIComponent(frameScript) + ")()", true);
-    gBrowser.loadURI(url);
+    BrowserTestUtils.loadURI(gBrowser, url);
 
     async function done() {
       tab.linkedBrowser.messageManager.removeMessageListener("test:event", eventHandler);
 
       await ContentTask.spawn(tabBrowser, null, async function() {
         const swr = await content.navigator.serviceWorker.getRegistration();
         await swr.unregister();
       });
--- a/dom/serviceworkers/test/test_privateBrowsing.html
+++ b/dom/serviceworkers/test/test_privateBrowsing.html
@@ -2,38 +2,39 @@
 <head>
   <title>Test for ServiceWorker - Private Browsing</title>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 </head>
 <body>
 
 <script type="application/javascript">
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 
 var mainWindow;
 
 var contentPage = "http://mochi.test:8888/chrome/dom/workers/test/empty.html";
 var workerScope = "http://mochi.test:8888/chrome/dom/serviceworkers/test/";
 var workerURL = workerScope + "worker.js";
 
 function testOnWindow(aIsPrivate, aCallback) {
   var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
   win.addEventListener("load", function() {
     win.addEventListener("DOMContentLoaded", function onInnerLoad() {
       if (win.content.location.href != contentPage) {
-        win.gBrowser.loadURI(contentPage);
+        BrowserTestUtils.loadURI(win.gBrowser, contentPage);
         return;
       }
 
       win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
       SimpleTest.executeSoon(function() { aCallback(win); });
     }, true);
 
     if (!aIsPrivate) {
-      win.gBrowser.loadURI(contentPage);
+      BrowserTestUtils.loadURI(win.gBrowser, contentPage);
     }
   }, {capture: true, once: true});
 }
 
 function setupWindow() {
   mainWindow = window.docShell.rootTreeItem.domWindow;
   runTest();
 }
--- a/dom/storage/StorageUtils.cpp
+++ b/dom/storage/StorageUtils.cpp
@@ -86,18 +86,17 @@ PrincipalsEqual(nsIPrincipal* aObjectPri
 void
 ReverseString(const nsACString& aSource, nsACString& aResult)
 {
   nsACString::const_iterator sourceBegin, sourceEnd;
   aSource.BeginReading(sourceBegin);
   aSource.EndReading(sourceEnd);
 
   aResult.SetLength(aSource.Length());
-  nsACString::iterator destEnd;
-  aResult.EndWriting(destEnd);
+  auto destEnd = aResult.EndWriting();
 
   while (sourceBegin != sourceEnd) {
     *(--destEnd) = *sourceBegin;
     ++sourceBegin;
   }
 }
 
 nsresult
--- a/dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js
+++ b/dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js
@@ -47,17 +47,17 @@ function test() {
         consoleObserver, "console-api-log-event");
       aWindow.nativeConsole.log("foo bar baz (private: " + aIsPrivateMode + ")");
     });
 
     // We expect that console API messages are always stored.
     storageShouldOccur = true;
     innerID = getInnerWindowId(aWindow);
     beforeEvents = ConsoleAPIStorage.getEvents(innerID);
-    aWindow.gBrowser.selectedBrowser.loadURI(testURI);
+    BrowserTestUtils.loadURI(aWindow.gBrowser.selectedBrowser, testURI);
   }
 
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       windowsToClose.push(aWin);
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
--- a/dom/tests/browser/browser_autofocus_background.js
+++ b/dom/tests/browser/browser_autofocus_background.js
@@ -8,17 +8,17 @@ add_task(async function() {
       tagName: "INPUT"},
   ];
 
   // Set the focus to the first tab.
   tabs[0].linkedBrowser.focus();
 
   // Load the second tab in the background.
   let loadedPromise = BrowserTestUtils.browserLoaded(tabs[1].linkedBrowser);
-  tabs[1].linkedBrowser.loadURI(testingList[0].uri);
+  BrowserTestUtils.loadURI(tabs[1].linkedBrowser, testingList[0].uri);
   await loadedPromise;
 
   for (var i = 0; i < testingList.length; ++i) {
     // Get active element in the tab.
     let tagName = await ContentTask.spawn(tabs[i + 1].linkedBrowser, null, async function() {
       return content.document.activeElement.tagName;
     });
 
--- a/dom/tests/browser/browser_autofocus_preference.js
+++ b/dom/tests/browser/browser_autofocus_preference.js
@@ -1,15 +1,15 @@
 add_task(async function() {
   await SpecialPowers.pushPrefEnv({"set": [["browser.autofocus", false]]});
 
   const url = "data:text/html,<!DOCTYPE html><html><body><input autofocus><button autofocus></button><textarea autofocus></textarea><select autofocus></select></body></html>";
 
   let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.selectedBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
   await loadedPromise;
 
   await new Promise(resolve => executeSoon(resolve));
 
   await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
     is(content.document.activeElement, content.document.body, "body focused");
   });
 });
--- a/dom/tests/browser/browser_bug1236512.js
+++ b/dom/tests/browser/browser_bug1236512.js
@@ -51,17 +51,17 @@ add_task(async function() {
   });
   winTest.moveTo(200, 200);
   winTest.resizeTo(500, 500);
   await resizePromise;
 
   let browserTest = winTest.gBrowser;
 
   info(`loading test page: ${testPageURL}`);
-  browserTest.selectedBrowser.loadURI(testPageURL);
+  BrowserTestUtils.loadURI(browserTest.selectedBrowser, testPageURL);
   await BrowserTestUtils.browserLoaded(browserTest.selectedBrowser);
 
   info("test init visibility state");
   await testContentVisibilityState(false /* isHidden */, browserTest);
 
   info("test window should report 'hidden' if it is fully covered by another " +
        "window");
   await new Promise(resolve => waitForFocus(resolve, window));
--- a/dom/tests/browser/browser_hasbeforeunload.js
+++ b/dom/tests/browser/browser_hasbeforeunload.js
@@ -425,17 +425,17 @@ add_task(async function test_inner_windo
     // away with a beforeunload listener set, and ensure
     // that we clear the hasBeforeUnload value.
     await addBeforeUnloadListeners(browser, 5);
     await navigateSubframe(browser, "http://example.com");
     assertHasBeforeUnload(browser, false);
 
     // Now send the page back to the test page for
     // the next few tests.
-    browser.loadURI(PAGE_URL);
+    BrowserTestUtils.loadURI(browser, PAGE_URL);
     await BrowserTestUtils.browserLoaded(browser);
 
     // We want to test hasBeforeUnload works properly with
     // beforeunload event listeners in <iframe> elements too.
     // We prepare a structure like this with 3 content windows
     // to exercise:
     //
     // <top-level content window at PAGE_URL> (TOP)
@@ -629,17 +629,17 @@ add_task(async function test_outer_windo
     // iframe inside it, and ensure that we clear the hasBeforeUnload
     // value.
     await addOuterBeforeUnloadListeners(browser, 5);
     await navigateSubframe(browser, "http://example.com", TOP);
     assertHasBeforeUnload(browser, false);
 
     // Now send the page back to the test page for
     // the next few tests.
-    browser.loadURI(PAGE_URL);
+    BrowserTestUtils.loadURI(browser, PAGE_URL);
     await BrowserTestUtils.browserLoaded(browser);
 
     // We should initially start with hasBeforeUnload set to false.
     assertHasBeforeUnload(browser, false);
 
     await prepareSubframes(browser, [
       { sandboxAttributes: null, },
       { sandboxAttributes: null, },
--- a/dom/tests/browser/browser_localStorage_e10s.js
+++ b/dom/tests/browser/browser_localStorage_e10s.js
@@ -49,17 +49,17 @@ async function openTestTabInOwnProcess(n
   ok(!knownTabs.byName.has(name), "tab needs its own name: " + name);
   ok(!knownTabs.byPid.has(pid), "tab needs to be in its own process: " + pid);
 
   let knownTab = new KnownTab(name, tab);
   knownTabs.byPid.set(pid, knownTab);
   knownTabs.byName.set(name, knownTab);
 
   // Now trigger the actual load of our page.
-  tab.linkedBrowser.loadURI(realUrl);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, realUrl);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   is(tab.linkedBrowser.frameLoader.tabParent.osPid, pid, "still same pid");
   return knownTab;
 }
 
 /**
  * Close all the tabs we opened.
  */
--- a/dom/tests/mochitest/beacon/test_beaconCookies.html
+++ b/dom/tests/mochitest/beacon/test_beaconCookies.html
@@ -17,16 +17,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 // not enabled by default yet.
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({'set': [["beacon.enabled", true]]}, beginTest);
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 
 var baseURL = "http://mochi.test:8888/chrome/dom/tests/mochitest/beacon/";
 
 function whenDelayedStartupFinished(aWindow, aCallback) {
   Services.obs.addObserver(function observer(aSubject, aTopic) {
     if (aWindow == aSubject) {
       Services.obs.removeObserver(observer, aTopic);
       setTimeout(aCallback, 0);
@@ -49,28 +50,28 @@ var next;
 
 function beginTest() {
   testOnWindow({}, function(aNormalWindow) {
     Services.obs.addObserver(function waitCookie() {
       Services.obs.removeObserver(waitCookie, "cookie-changed");
       ok(true, "cookie set by beacon request in normal window");
       testOnPrivateWindow();
     }, "cookie-changed");
-    aNormalWindow.gBrowser.selectedBrowser.loadURI(baseURL + "file_beaconCookies.html");
+    BrowserTestUtils.loadURI(aNormalWindow.gBrowser.selectedBrowser, baseURL + "file_beaconCookies.html");
   });
 }
 
 function testOnPrivateWindow() {
   testOnWindow({private: true}, function(aPrivateWindow) {
     Services.obs.addObserver(function waitCookie() {
       Services.obs.removeObserver(waitCookie, "private-cookie-changed");
       ok(true, "private cookie set by beacon request in private window");
       cleanup();
     }, "private-cookie-changed");
-    aPrivateWindow.gBrowser.selectedBrowser.loadURI(baseURL + "file_beaconCookies.html");
+    BrowserTestUtils.loadURI(aPrivateWindow.gBrowser.selectedBrowser, baseURL + "file_beaconCookies.html");
   });
 }
 
 function cleanup() {
   for (var i = 0; i < windowsToClose.length; ++i) {
     windowsToClose[i].close();
   }
   SimpleTest.finish();
--- a/dom/url/tests/browser_download_after_revoke.js
+++ b/dom/url/tests/browser_download_after_revoke.js
@@ -41,10 +41,10 @@ function test () {
 
       content.URL.revokeObjectURL(url);
     });
   }
 
   BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(onLoad);
 
   info("Loading download page...");
-  gBrowser.loadURI("http://example.com/browser/dom/url/tests/empty.html");
+  BrowserTestUtils.loadURI(gBrowser, "http://example.com/browser/dom/url/tests/empty.html");
 }
--- a/dom/workers/test/test_sharedWorker_privateBrowsing.html
+++ b/dom/workers/test/test_sharedWorker_privateBrowsing.html
@@ -2,36 +2,36 @@
 <head>
   <title>Test for SharedWorker - Private Browsing</title>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 </head>
 <body>
 
 <script type="application/javascript">
-
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 var mainWindow;
 
 var contentPage = "http://mochi.test:8888/chrome/dom/workers/test/empty.html";
 
 function testOnWindow(aIsPrivate, aCallback) {
   var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
   win.addEventListener("load", function() {
     win.addEventListener("DOMContentLoaded", function onInnerLoad() {
       if (win.content.location.href != contentPage) {
-        win.gBrowser.loadURI(contentPage);
+        BrowserTestUtils.loadURI(win.gBrowser, contentPage);
         return;
       }
 
       win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
       SimpleTest.executeSoon(function() { aCallback(win); });
     }, true);
 
     if (!aIsPrivate) {
-      win.gBrowser.loadURI(contentPage);
+      BrowserTestUtils.loadURI(win.gBrowser, contentPage);
     }
   }, {capture: true, once: true});
 }
 
 function setupWindow() {
   mainWindow = window.docShell.rootTreeItem.domWindow;
   runTest();
 }
--- a/dom/xslt/base/txDouble.cpp
+++ b/dom/xslt/base/txDouble.cpp
@@ -174,18 +174,18 @@ void txDouble::toString(double aValue, n
         length = intDigits;
     }
     if (aValue < 0)
         ++length;
     // grow the string
     uint32_t oldlength = aDest.Length();
     if (!aDest.SetLength(oldlength + length, mozilla::fallible))
         return; // out of memory
-    nsAString::iterator dest;
-    aDest.BeginWriting(dest).advance(int32_t(oldlength));
+    auto dest = aDest.BeginWriting();
+    std::advance(dest, oldlength);
     if (aValue < 0) {
         *dest = '-'; ++dest;
     }
     int i;
     // leading zeros
     if (intDigits < 1) {
         *dest = '0'; ++dest;
         *dest = '.'; ++dest;
--- a/gfx/skia/skia/src/core/SkBitmapDevice.h
+++ b/gfx/skia/skia/src/core/SkBitmapDevice.h
@@ -114,16 +114,17 @@ protected:
 
     ///////////////////////////////////////////////////////////////////////////
 
     void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
                      SkImage*, const SkMatrix&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
     sk_sp<SkSpecialImage> snapSpecial() override;
+    void setImmutable() override { fBitmap.setImmutable(); }
 
     ///////////////////////////////////////////////////////////////////////////
 
     bool onReadPixels(const SkPixmap&, int x, int y) override;
     bool onWritePixels(const SkPixmap&, int, int) override;
     bool onPeekPixels(SkPixmap*) override;
     bool onAccessPixels(SkPixmap*) override;
 
--- a/gfx/skia/skia/src/core/SkCanvas.cpp
+++ b/gfx/skia/skia/src/core/SkCanvas.cpp
@@ -1190,16 +1190,17 @@ void SkCanvas::internalRestore() {
 
     /*  Time to draw the layer's offscreen. We can't call the public drawSprite,
         since if we're being recorded, we don't want to record this (the
         recorder will have already recorded the restore).
     */
     if (layer) {
         if (fMCRec) {
             const SkIPoint& origin = layer->fDevice->getOrigin();
+            layer->fDevice->setImmutable();
             this->internalDrawDevice(layer->fDevice.get(), origin.x(), origin.y(),
                                      layer->fPaint.get(),
                                      layer->fClipImage.get(), layer->fClipMatrix);
             // restore what we smashed in internalSaveLayer
             fMCRec->fMatrix = layer->fStashedMatrix;
             // reset this, since internalDrawDevice will have set it to true
             delete layer;
         } else {
--- a/gfx/skia/skia/src/core/SkDevice.h
+++ b/gfx/skia/skia/src/core/SkDevice.h
@@ -266,16 +266,17 @@ protected:
     virtual void drawTextRSXform(const void* text, size_t len, const SkRSXform[],
                                  const SkPaint&);
 
     virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
                              SkImage* clipImage, const SkMatrix& clipMatrix);
     virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
     virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
     virtual sk_sp<SkSpecialImage> snapSpecial();
+    virtual void setImmutable() {}
 
     bool readPixels(const SkPixmap&, int x, int y);
 
     ///////////////////////////////////////////////////////////////////////////
 
     virtual GrContext* context() const { return nullptr; }
 
     virtual sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&);
--- a/js/src/build/moz.build
+++ b/js/src/build/moz.build
@@ -4,16 +4,18 @@
 # 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/.
 
 CONFIGURE_SUBST_FILES += [
     'js-config',
     'js.pc',
 ]
 
+LIBRARY_DEFINES['EXPORT_JS_API'] = True
+
 if not CONFIG['JS_STANDALONE']:
     LIBRARY_DEFINES['MOZ_HAS_MOZGLUE'] = True
 
 # JavaScript must be built shared, even for static builds, as it is used by
 # other modules which are always built shared. Failure to do so results in
 # the js code getting copied into xpinstall and jsd as well as mozilla-bin,
 # and then the static data cells used for locking no longer work.
 #
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -3429,40 +3429,43 @@ BytecodeEmitter::wrapWithDestructuringIt
         return tryNoteList.append(JSTRY_DESTRUCTURING_ITERCLOSE, iterDepth, start, end);
     }
     return true;
 }
 
 bool
 BytecodeEmitter::emitDefault(ParseNode* defaultExpr, ParseNode* pattern)
 {
+    IfEmitter ifUndefined(this);
+    if (!ifUndefined.emitIf(Nothing())) {
+        return false;
+    }
+
     if (!emit1(JSOP_DUP)) {                               // VALUE VALUE
         return false;
     }
     if (!emit1(JSOP_UNDEFINED)) {                         // VALUE VALUE UNDEFINED
         return false;
     }
     if (!emit1(JSOP_STRICTEQ)) {                          // VALUE EQL?
         return false;
     }
-    // Emit source note to enable ion compilation.
-    if (!newSrcNote(SRC_IF)) {
-        return false;
-    }
-    JumpList jump;
-    if (!emitJump(JSOP_IFEQ, &jump)) {                    // VALUE
-        return false;
-    }
-    if (!emit1(JSOP_POP)) {                               // .
-        return false;
-    }
-    if (!emitInitializerInBranch(defaultExpr, pattern)) { // DEFAULTVALUE
-        return false;
-    }
-    if (!emitJumpTargetAndPatch(jump)) {
+
+    if (!ifUndefined.emitThen()) {                        // VALUE
+        return false;
+    }
+
+    if (!emit1(JSOP_POP)) {                               //
+        return false;
+    }
+    if (!emitInitializer(defaultExpr, pattern)) {         // DEFAULTVALUE
+        return false;
+    }
+
+    if (!ifUndefined.emitEnd()) {                         // VALUE/DEFAULTVALUE
         return false;
     }
     return true;
 }
 
 bool
 BytecodeEmitter::setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name)
 {
@@ -3517,23 +3520,16 @@ BytecodeEmitter::emitInitializer(ParseNo
             return false;
         }
     }
 
     return true;
 }
 
 bool
-BytecodeEmitter::emitInitializerInBranch(ParseNode* initializer, ParseNode* pattern)
-{
-    TDZCheckCache tdzCache(this);
-    return emitInitializer(initializer, pattern);
-}
-
-bool
 BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern, DestructuringFlavor flav)
 {
     MOZ_ASSERT(pattern->isKind(ParseNodeKind::Array));
     MOZ_ASSERT(this->stackDepth != 0);
 
     // Here's pseudo code for |let [a, b, , c=y, ...d] = x;|
     //
     // Lines that are annotated "covered by trynote" mean that upon throwing
@@ -8445,44 +8441,23 @@ BytecodeEmitter::emitFunctionFormalParam
 
         // First push the RHS if there is a default expression or if it is
         // rest.
 
         if (initializer) {
             // If we have an initializer, emit the initializer and assign it
             // to the argument slot. TDZ is taken care of afterwards.
             MOZ_ASSERT(hasParameterExprs);
-            if (!emitArgOp(JSOP_GETARG, argSlot)) {
-                return false;
-            }
-            if (!emit1(JSOP_DUP)) {
-                return false;
-            }
-            if (!emit1(JSOP_UNDEFINED)) {
-                return false;
-            }
-            if (!emit1(JSOP_STRICTEQ)) {
-                return false;
-            }
-            // Emit source note to enable Ion compilation.
-            if (!newSrcNote(SRC_IF)) {
-                return false;
-            }
-            JumpList jump;
-            if (!emitJump(JSOP_IFEQ, &jump)) {
-                return false;
-            }
-            if (!emit1(JSOP_POP)) {
-                return false;
-            }
-            if (!emitInitializerInBranch(initializer, bindingElement)) {
-                return false;
-            }
-            if (!emitJumpTargetAndPatch(jump)) {
-                return false;
+
+            if (!emitArgOp(JSOP_GETARG, argSlot)) {       // ARG
+                return false;
+            }
+
+            if (!emitDefault(initializer, bindingElement)) {
+                return false;                             // ARG/DEFAULT
             }
         } else if (isRest) {
             if (!emit1(JSOP_REST)) {
                 return false;
             }
             checkTypeSet(JSOP_REST);
         }
 
@@ -9433,26 +9408,16 @@ BytecodeEmitter::emitTree(ParseNode* pn,
     if (emitLevel == 1) {
         if (!updateSourceCoordNotes(pn->pn_pos.end)) {
             return false;
         }
     }
     return true;
 }
 
-bool
-BytecodeEmitter::emitTreeInBranch(ParseNode* pn,
-                                  ValueUsage valueUsage /* = ValueUsage::WantValue */)
-{
-    // Code that may be conditionally executed always need their own TDZ
-    // cache.
-    TDZCheckCache tdzCache(this);
-    return emitTree(pn, valueUsage);
-}
-
 static bool
 AllocSrcNote(JSContext* cx, SrcNotesVector& notes, unsigned* index)
 {
     if (!notes.growBy(1)) {
         ReportOutOfMemory(cx);
         return false;
     }
 
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -462,20 +462,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter
         EMIT_LINENOTE,
         SUPPRESS_LINENOTE
     };
 
     // Emit code for the tree rooted at pn.
     MOZ_MUST_USE bool emitTree(ParseNode* pn, ValueUsage valueUsage = ValueUsage::WantValue,
                                EmitLineNumberNote emitLineNote = EMIT_LINENOTE);
 
-    // Emit code for the tree rooted at pn with its own TDZ cache.
-    MOZ_MUST_USE bool emitTreeInBranch(ParseNode* pn,
-                                       ValueUsage valueUsage = ValueUsage::WantValue);
-
     // Emit global, eval, or module code for tree rooted at body. Always
     // encompasses the entire source.
     MOZ_MUST_USE bool emitScript(ParseNode* body);
 
     // Emit function code for the tree rooted at body.
     enum class TopLevelFunction {
         No,
         Yes
@@ -769,17 +765,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter
     // |pattern| is a lhs node of the default expression.  If it's an
     // identifier and |defaultExpr| is an anonymous function, |SetFunctionName|
     // is called at compile time.
     MOZ_MUST_USE bool emitDefault(ParseNode* defaultExpr, ParseNode* pattern);
 
     MOZ_MUST_USE bool setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name);
 
     MOZ_MUST_USE bool emitInitializer(ParseNode* initializer, ParseNode* pattern);
-    MOZ_MUST_USE bool emitInitializerInBranch(ParseNode* initializer, ParseNode* pattern);
 
     MOZ_MUST_USE bool emitCallSiteObject(CallSiteNode* callSiteObj);
     MOZ_MUST_USE bool emitTemplateString(ListNode* templateString);
     MOZ_MUST_USE bool emitAssignment(ParseNode* lhs, ParseNodeKind pnk, ParseNode* rhs);
 
     MOZ_MUST_USE bool emitReturn(UnaryNode* returnNode);
     MOZ_MUST_USE bool emitExpressionStatement(UnaryNode* exprStmt);
     MOZ_MUST_USE bool emitStatementList(ListNode* stmtList);
--- a/js/src/fuzz-tests/moz.build
+++ b/js/src/fuzz-tests/moz.build
@@ -1,16 +1,18 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 GeckoProgram('fuzz-tests', linkage=None)
 
+include('../js-cxxflags.mozbuild')
+
 UNIFIED_SOURCES += [
     'testExample.cpp',
     'tests.cpp',
     'testStructuredCloneReader.cpp',
 ]
 
 if CONFIG['JS_BUILD_BINAST']:
     UNIFIED_SOURCES += [
@@ -41,12 +43,9 @@ USE_LIBS += [
     'static:js',
 ]
 
 if CONFIG['MOZ_NEEDS_LIBATOMIC']:
     OS_LIBS += ['atomic']
 
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
-if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
-    CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing']
-
 DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR
--- a/js/src/gdb/moz.build
+++ b/js/src/gdb/moz.build
@@ -1,16 +1,18 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 GeckoProgram('gdb-tests', linkage=None)
 
+include('../js-cxxflags.mozbuild')
+
 SOURCES += [
     # This file must not be unified with any of the test files, or the use()
     # and breakpoint() functions might get optimized out.
     'gdb-tests.cpp'
 ]
 
 UNIFIED_SOURCES += [
     'tests/test-asmjs.cpp',
@@ -36,18 +38,11 @@ LOCAL_INCLUDES += [
 ]
 
 USE_LIBS += [
     'static:js',
 ]
 
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
-if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
-    CXXFLAGS += ['-Wno-shadow', '-fno-strict-aliasing']
-
-# This is intended as a temporary workaround to enable VS2015.
-if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
-    CXXFLAGS += ['-wd4312']
-
 DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR
 FINAL_TARGET_PP_FILES += ['gdb-tests-gdb.py.in']
 OBJDIR_FILES.js.src.gdb += ['!/dist/bin/gdb-tests-gdb.py']
new file mode 100644
--- /dev/null
+++ b/js/src/js-config.mozbuild
@@ -0,0 +1,37 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+# Nightly-only features
+if CONFIG['NIGHTLY_BUILD']:
+    DEFINES['ENABLE_BINARYDATA'] = True
+    DEFINES['ENABLE_WASM_BULKMEM_OPS'] = True
+    DEFINES['ENABLE_WASM_SATURATING_TRUNC_OPS'] = True
+    DEFINES['ENABLE_WASM_THREAD_OPS'] = True
+    DEFINES['ENABLE_WASM_GC'] = True
+    DEFINES['WASM_PRIVATE_REFTYPES'] = True
+
+# Some huge-mapping optimization instead of bounds checks on supported
+# platforms.
+if CONFIG['JS_CODEGEN_X64'] or CONFIG['JS_CODEGEN_ARM64']:
+    DEFINES['WASM_HUGE_MEMORY'] = True
+
+# Enables CACHEIR_LOGS to diagnose IC coverage.
+if CONFIG['MOZ_DEBUG'] or CONFIG['NIGHTLY_BUILD']:
+    DEFINES['JS_CACHEIR_SPEW'] = True
+
+# Build with SharedArrayBuffer code.
+# NOTE: This Realm creation options decide if this is exposed to script.
+DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True
+
+# CTypes
+if CONFIG['JS_HAS_CTYPES']:
+    DEFINES['JS_HAS_CTYPES'] = True
+    if not CONFIG['MOZ_SYSTEM_FFI']:
+        DEFINES['FFI_BUILDING'] = True
+
+# Forward MOZ_LINKER config
+if CONFIG['MOZ_LINKER']:
+    DEFINES['MOZ_LINKER'] = True
new file mode 100644
--- /dev/null
+++ b/js/src/js-cxxflags.mozbuild
@@ -0,0 +1,33 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+# ICU pkg-config flags
+CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+
+if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
+    # C4805 warns mixing bool with other integral types in computation.
+    # But given the conversion from bool is specified, and this is a
+    # pattern widely used in code in js/src, suppress this warning here.
+    CXXFLAGS += ['-wd4805']
+    # C4661 ("no suitable definition provided for explicit template
+    # instantiation request") is emitted for all Parser methods that
+    # have a Parser<FullParseHandler> definition but no
+    # Parser<SyntaxParseHandler> definition, see bug 1167030.
+    CXXFLAGS += ['-wd4661']
+    # FIXME: unary minus operator applied to unsigned type (bug 1229189)
+    CXXFLAGS += ['-wd4146']
+    # FIXME: 'operation' : conversion from 'type1' to 'type2' of
+    # greater size (bug 1259304)
+    CXXFLAGS += ['-wd4312']
+
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
+    # Also disable strict-aliasing for GCC compiler, that is enabled by default
+    # starting with version 7.1, see Bug 1363009
+    CXXFLAGS += ['-fno-strict-aliasing']
+    # Error on bad printf-like format strings
+    CXXFLAGS += ['-Werror=format']
+    # Ignore shadowed variable warnings as there are too many.
+    CXXFLAGS += ['-Wno-shadow']
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -1,16 +1,18 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 GeckoProgram('jsapi-tests', linkage=None)
 
+include('../js-cxxflags.mozbuild')
+
 UNIFIED_SOURCES += [
     'selfTest.cpp',
     'testAddPropertyPropcache.cpp',
     'testArgumentsObject.cpp',
     'testArrayBuffer.cpp',
     'testArrayBufferView.cpp',
     'testAtomicOperations.cpp',
     'testBoundFunction.cpp',
@@ -169,17 +171,10 @@ USE_LIBS += [
     'static:js',
 ]
 
 if CONFIG['MOZ_NEEDS_LIBATOMIC']:
     OS_LIBS += ['atomic']
 
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
-if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
-    CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing']
-
-# This is intended as a temporary workaround to enable VS2015.
-if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
-    CXXFLAGS += ['-wd4312']
-
 DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR
 OBJDIR_PP_FILES.js.src['jsapi-tests'] += ['jsapi-tests-gdb.py.in']
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -1,14 +1,17 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
+include('js-config.mozbuild')
+include('js-cxxflags.mozbuild')
+
 # Directory metadata
 component_engine = ('Core', 'JavaScript Engine')
 component_gc     = ('Core', 'JavaScript: GC')
 component_intl   = ('Core', 'JavaScript: Internationalization API')
 component_jit    = ('Core', 'JavaScript Engine: JIT')
 component_stl    = ('Core', 'JavaScript: Standard Library')
 component_wasm   = ('Core', 'Javascript: Web Assembly')
 
@@ -694,24 +697,16 @@ ReservedWordsGenerated.inputs += [
 ]
 
 DIRS += [
     'build',
 ]
 
 FINAL_LIBRARY = 'js'
 
-if CONFIG['NIGHTLY_BUILD']:
-    DEFINES['ENABLE_BINARYDATA'] = True
-    DEFINES['ENABLE_WASM_BULKMEM_OPS'] = True
-    DEFINES['ENABLE_WASM_SATURATING_TRUNC_OPS'] = True
-    DEFINES['ENABLE_WASM_THREAD_OPS'] = True
-    DEFINES['ENABLE_WASM_GC'] = True
-    DEFINES['WASM_PRIVATE_REFTYPES'] = True
-
 if CONFIG['JS_BUILD_BINAST']:
     # Using SOURCES, as UNIFIED_SOURCES causes mysterious bugs on 32-bit platforms.
     # These parts of BinAST are designed only to test evolutions of the
     # specification.
     SOURCES += ['frontend/BinTokenReaderTester.cpp']
     # These parts of BinAST should eventually move to release.
     SOURCES += [
         'frontend/BinSource-auto.cpp',
@@ -724,59 +719,16 @@ if CONFIG['JS_BUILD_BINAST']:
     # Instrument BinAST files for fuzzing as we have a fuzzing target for BinAST.
     if CONFIG['FUZZING_INTERFACES'] and CONFIG['LIBFUZZER']:
         SOURCES['frontend/BinSource-auto.cpp'].flags += libfuzzer_flags
         SOURCES['frontend/BinSource.cpp'].flags += libfuzzer_flags
         SOURCES['frontend/BinToken.cpp'].flags += libfuzzer_flags
         SOURCES['frontend/BinTokenReaderBase.cpp'].flags += libfuzzer_flags
         SOURCES['frontend/BinTokenReaderMultipart.cpp'].flags += libfuzzer_flags
 
-# Wasm code should use WASM_HUGE_MEMORY instead of JS_CODEGEN_X64
-# so that it is easy to use the huge-mapping optimization for other
-# 64-bit platforms in the future.
-
-if CONFIG['JS_CODEGEN_X64'] or CONFIG['JS_CODEGEN_ARM64']:
-    DEFINES['WASM_HUGE_MEMORY'] = True
-
-if CONFIG['MOZ_DEBUG'] or CONFIG['NIGHTLY_BUILD']:
-    DEFINES['JS_CACHEIR_SPEW'] = True
-
-# Also set in shell/moz.build
-DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True
-
-DEFINES['EXPORT_JS_API'] = True
-
-if CONFIG['JS_HAS_CTYPES']:
-    DEFINES['JS_HAS_CTYPES'] = True
-
-if CONFIG['MOZ_LINKER']:
-    DEFINES['MOZ_LINKER'] = True
-
-if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
-    # Prevent floating point errors caused by VC++ optimizations
-    # XXX We should add this to CXXFLAGS, too?
-    CFLAGS += ['-fp:precise']
-    # C4805 warns mixing bool with other integral types in computation.
-    # But given the conversion from bool is specified, and this is a
-    # pattern widely used in code in js/src, suppress this warning here.
-    CXXFLAGS += ['-wd4805']
-    # C4661 ("no suitable definition provided for explicit template
-    # instantiation request") is emitted for all Parser methods that
-    # have a Parser<FullParseHandler> definition but no
-    # Parser<SyntaxParseHandler> definition, see bug 1167030.
-    CXXFLAGS += ['-wd4661']
-    # FIXME: unary minus operator applied to unsigned type (bug 1229189)
-    CXXFLAGS += ['-wd4146']
-    # FIXME: 'operation' : conversion from 'type1' to 'type2' of
-    # greater size (bug 1259304)
-    CXXFLAGS += ['-wd4312']
-
-CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
-CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
-
 # Prepare self-hosted JS code for embedding
 GENERATED_FILES += [('selfhosted.out.h', 'selfhosted.js')]
 selfhosted = GENERATED_FILES[('selfhosted.out.h', 'selfhosted.js')]
 selfhosted.script = 'builtin/embedjs.py:generate_selfhosted'
 selfhosted.inputs = [
     'js.msg',
     'builtin/TypedObjectConstants.h',
     'builtin/SelfHostingDefines.h',
@@ -814,24 +766,16 @@ selfhosted.inputs = [
     'builtin/TypedObject.js',
     'builtin/WeakMap.js',
     'builtin/WeakSet.js'
 ]
 
 if CONFIG['JS_HAS_CTYPES']:
     if CONFIG['MOZ_SYSTEM_FFI']:
         CXXFLAGS += CONFIG['MOZ_FFI_CFLAGS']
-    else:
-        # Windows needs this to be linked with a static library.
-        DEFINES['FFI_BUILDING'] = True
-
-if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
-    # Also disable strict-aliasing for GCC compiler, that is enabled by default
-    # starting with version 7.1, see Bug 1363009
-    CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing']
 
 # Suppress warnings in third-party code.
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     SOURCES['util/DoubleToString.cpp'].flags += ['-Wno-implicit-fallthrough']
 
 # Generate GC statistics phase data.
 GENERATED_FILES += ['gc/StatsPhasesGenerated.h']
 StatsPhasesGeneratedHeader = GENERATED_FILES['gc/StatsPhasesGenerated.h']
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -433,18 +433,16 @@ if test -n "${CLANG_CXX}${CLANG_CL}"; th
 fi
 
 MOZ_CONFIG_SANITIZE
 
 dnl ========================================================
 dnl GNU specific defaults
 dnl ========================================================
 if test "$GNU_CC"; then
-    MKSHLIB='$(CXX) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(DSO_SONAME) -o $@'
-    MKCSHLIB='$(CC) $(COMPUTED_C_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(DSO_SONAME) -o $@'
     DSO_LDOPTS='-shared'
     if test "$GCC_USE_GNU_LD"; then
         # Some tools like ASan use a runtime library that is only
         # linked against executables, so we must allow undefined
         # symbols for shared objects in some cases.
         if test -z "$MOZ_ASAN$MOZ_MSAN$MOZ_UBSAN$MOZ_TSAN"; then
             # Don't allow undefined symbols in libraries
             DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
@@ -568,18 +566,16 @@ CPPFLAGS="$CPPFLAGS $MOZ_HARDENING_CFLAG
 CXXFLAGS="$CXXFLAGS $MOZ_HARDENING_CFLAGS_JS"
 
 dnl ========================================================
 dnl System overrides of the defaults for target
 dnl ========================================================
 
 case "$target" in
 *-darwin*)
-    MKSHLIB='$(CXX) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
-    MKCSHLIB='$(CC) $(COMPUTED_C_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
     MOZ_OPTIMIZE_FLAGS="-O3 -fno-stack-protector"
     CFLAGS="$CFLAGS -fno-common"
     CXXFLAGS="$CXXFLAGS -fno-common -stdlib=libc++"
     DSO_LDOPTS=''
     STRIP="$STRIP -x -S"
     LDFLAGS="$LDFLAGS -lobjc"
     # The ExceptionHandling framework is needed for Objective-C exception
     # logging code in nsObjCExceptions.h. Currently we only use that in debug
@@ -652,18 +648,16 @@ case "$target" in
     RC=rc.exe
     if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
         CC="$CC -mwindows"
         CXX="$CXX -mwindows"
         CPP="$CPP -mwindows"
         CFLAGS="$CFLAGS -mms-bitfields"
         CXXFLAGS="$CXXFLAGS -mms-bitfields"
         DSO_LDOPTS='-shared'
-        MKSHLIB='$(CXX) $(DSO_LDOPTS) -o $@'
-        MKCSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
         RC='$(WINDRES)'
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -lusp10 -lgdi32 -lwinmm -lwsock32"
         MOZ_FIX_LINK_PATHS=
 
         if test -z "$CLANG_CC"; then
@@ -694,18 +688,16 @@ case "$target" in
             AR='lib'
             AR_FLAGS='-NOLOGO -OUT:$@'
             ;;
         esac
         AR_EXTRACT=
         RANLIB='echo not_ranlib'
         STRIP='echo not_strip'
         PKG_SKIP_STRIP=1
-        MKSHLIB='$(LINKER) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
-        MKCSHLIB='$(LINKER) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         WIN32_SUBSYSTEM_VERSION=6.01
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         _USE_CPP_INCLUDE_FLAG=1
         _DEFINES_CFLAGS="-FI $jsconfdefs -DMOZILLA_CLIENT"
         _DEFINES_CXXFLAGS="-FI $jsconfdefs -DMOZILLA_CLIENT"
         CFLAGS="$CFLAGS -W3 -Gy -Zc:inline"
@@ -882,18 +874,16 @@ case "$target" in
     else
     	DSO_PIC_CFLAGS='-fPIC -DPIC'
     	DSO_LDOPTS='-shared'
     fi
     # This will fail on a.out systems prior to 1.5.1_ALPHA.
     if test "$LIBRUNPATH"; then
 	DSO_LDOPTS="-Wl,-R$LIBRUNPATH $DSO_LDOPTS"
     fi
-    MKSHLIB='$(CXX) $(COMPUTED_CXX_LDFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(DSO_SONAME) -o $@'
-    MKCSHLIB='$(CC) $(COMPUTED_C_LDFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(DSO_SONAME) -o $@'
     ;;
 
 *-openbsd*)
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     DSO_LDOPTS='-shared -fPIC'
     if test "$LIBRUNPATH"; then
 	DSO_LDOPTS="-R$LIBRUNPATH $DSO_LDOPTS"
@@ -1792,18 +1782,16 @@ AC_SUBST(HOST_AR)
 AC_SUBST(HOST_AR_FLAGS)
 AC_SUBST(HOST_RANLIB)
 AC_SUBST(HOST_BIN_SUFFIX)
 
 AC_SUBST(TARGET_XPCOM_ABI)
 
 AC_SUBST(GCC_USE_GNU_LD)
 
-AC_SUBST(MKSHLIB)
-AC_SUBST(MKCSHLIB)
 AC_SUBST_LIST(DSO_CFLAGS)
 AC_SUBST_LIST(DSO_PIC_CFLAGS)
 AC_SUBST(DSO_LDOPTS)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(MOZ_LINKER)
 AC_SUBST(WIN32_CONSOLE_EXE_LDFLAGS)
--- a/js/src/shell/moz.build
+++ b/js/src/shell/moz.build
@@ -5,32 +5,28 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 if CONFIG['JS_SHELL_NAME']:
     GeckoProgram(CONFIG['JS_SHELL_NAME'], linkage=None)
     if CONFIG['JS_BUNDLED_EDITLINE']:
         USE_LIBS += ['editline']
     USE_LIBS += ['static:js']
 
+include('../js-config.mozbuild')
+include('../js-cxxflags.mozbuild')
+
 UNIFIED_SOURCES += [
     'js.cpp',
     'jsoptparse.cpp',
     'jsshell.cpp',
     'OSObject.cpp'
 ]
 
 DEFINES['EXPORT_JS_API'] = True
 
-if CONFIG['NIGHTLY_BUILD']:
-    DEFINES['ENABLE_WASM_GC'] = True
-    DEFINES['WASM_PRIVATE_REFTYPES'] = True
-
-# Also set in ../moz.build
-DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True
-
 if CONFIG['CC_TYPE'] == 'msvc':
     # PGO is unnecessary for the js shell, but clang/gcc cannot turn off PGO
     # because we need to resolve symbols from PGO runtime library when our
     # object files have been compiled for PGO.
     NO_PGO = True
 
 LOCAL_INCLUDES += [
     '!..',
@@ -44,23 +40,16 @@ OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 GENERATED_FILES += [('shellmoduleloader.out.h', 'shellmoduleloader.js')]
 shellmoduleloader = GENERATED_FILES[('shellmoduleloader.out.h', 'shellmoduleloader.js')]
 shellmoduleloader.script = '../builtin/embedjs.py:generate_shellmoduleloader'
 shellmoduleloader.inputs = [
     '../js.msg',
     'ModuleLoader.js',
 ]
 
-if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
-    CXXFLAGS += ['-Wno-shadow', '-Werror=format']
-
-# This is intended as a temporary workaround to enable VS2015.
-if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
-    CXXFLAGS += ['-wd4312']
-
 # Place a GDB Python auto-load file next to the shell executable, both in
 # the build directory and in the dist/bin directory.
 DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR
 FINAL_TARGET_PP_FILES += ['js-gdb.py.in']
 OBJDIR_FILES.js.src.shell += ['!/dist/bin/js-gdb.py']
 
 # People expect the js shell to wind up in the top-level JS dir.
 OBJDIR_FILES.js.src += ['!/dist/bin/js%s' % CONFIG['BIN_SUFFIX']]
--- a/layout/forms/test/test_bug536567_perwindowpb.html
+++ b/layout/forms/test/test_bug536567_perwindowpb.html
@@ -141,26 +141,32 @@ function whenDelayedStartupFinished(aWin
   }, "browser-delayed-startup-finished");
 }
 
 function testOnWindow(aIsPrivate, aCallback) {
   var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
   whenDelayedStartupFinished(win, function() {
     win.addEventListener("DOMContentLoaded", function onInnerLoad() {
       if (win.content.location.href != contentPage) {
-        win.gBrowser.loadURI(contentPage);
+        win.gBrowser.loadURI(contentPage, {
+          triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+        });
         return;
       }
       win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
       win.gBrowser.selectedBrowser.focus();
       SimpleTest.info("DOMContentLoaded's window: " + win.location + " vs. " + window.location);
       win.setTimeout(function() { aCallback(win); }, 0);
     }, true);
     SimpleTest.info("load's window: " + win.location + " vs. " + window.location);
-    win.setTimeout(function() { win.gBrowser.loadURI(contentPage); }, 0);
+    win.setTimeout(function() {
+      win.gBrowser.loadURI(contentPage, {
+        triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+      });
+    }, 0);
   });
 }
 
 MockFilePicker.showCallback = function(filepicker) {
   var test = tests[testIndex];
   var returned = -1;
   for (var i = 0; i < dirs.length; i++) {
      var dir = MockFilePicker.displayDirectory
--- a/layout/tools/layout-debug/ui/content/layoutdebug.js
+++ b/layout/tools/layout-debug/ui/content/layoutdebug.js
@@ -105,20 +105,25 @@ function OnLDBLoad()
   gBrowser = document.getElementById("browser");
 
   gProgressListener = new nsLDBBrowserContentListener();
   gBrowser.addProgressListener(gProgressListener);
 
   gDebugger = Cc[NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID].
                   createInstance(nsILayoutDebuggingTools);
 
-  if (window.arguments && window.arguments[0])
-    gBrowser.loadURI(window.arguments[0]);
-  else
-    gBrowser.loadURI("about:blank");
+  if (window.arguments && window.arguments[0]) {
+    gBrowser.loadURI(window.arguments[0], {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
+  } else {
+    gBrowser.loadURI("about:blank", {
+      triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+    });
+  }
 
   gDebugger.init(gBrowser.contentWindow);
 
   checkPersistentMenus();
 }
 
 function checkPersistentMenu(item)
 {
@@ -156,12 +161,14 @@ function openFile()
   var nsIFilePicker = Ci.nsIFilePicker;
   var fp = Cc["@mozilla.org/filepicker;1"]
         .createInstance(nsIFilePicker);
   fp.init(window, "Select a File", nsIFilePicker.modeOpen);
   fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
   fp.open(rv => {
     if (rv == nsIFilePicker.returnOK && fp.fileURL.spec &&
         fp.fileURL.spec.length > 0) {
-      gBrowser.loadURI(fp.fileURL.spec);
+      gBrowser.loadURI(fp.fileURL.spec, {
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+      });
     }
   });
 }
--- a/layout/tools/layout-debug/ui/content/layoutdebug.xul
+++ b/layout/tools/layout-debug/ui/content/layoutdebug.xul
@@ -105,17 +105,19 @@
                        label="&ldb.ReloadButton.label;"
                        oncommand="gBrowser.reload();" />
         <toolbarbutton id="stop-button" class="toolbarbutton-1"
                        label="&ldb.StopButton.label;"
                        oncommand="gBrowser.stop();" />
 
         <textbox id="urlbar" flex="1"
                  onkeypress="if (event.keyCode == 13)
-                               gBrowser.loadURI(this.value);" />
+                               gBrowser.loadURI(this.value, {
+                                 triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+                               });" />
       </toolbar>
     </toolbox>
 
     <browser flex="1" id="browser" type="content" primary="true"/>
 
     <hbox>
       <description id="status-text" value="" />
     </hbox>
--- a/layout/tools/recording/recording.js
+++ b/layout/tools/recording/recording.js
@@ -35,10 +35,12 @@ this.OnRecordingLoad = function OnRecord
         gContainingWindow.close();
         return;
     }
 
     gBrowser.addEventListener("load", OnDocumentLoad, true);
 
     var args = window.arguments[0].wrappedJSObject;
 
-    gBrowser.loadURI(args.uri);
+    gBrowser.loadURI(args.uri, {
+      triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+    });
 };
--- a/mfbt/ChaosMode.h
+++ b/mfbt/ChaosMode.h
@@ -24,16 +24,20 @@ enum ChaosFeature {
   // Altering timer scheduling.
   TimerScheduling = 0x4,
   // Read and write less-than-requested amounts.
   IOAmounts = 0x8,
   // Iterate over hash tables in random order.
   HashTableIteration = 0x10,
   // Randomly refuse to use cached version of image (when allowed by spec).
   ImageCache = 0x20,
+  // Delay dispatching threads to encourage dispatched tasks to run.
+  TaskDispatching = 0x40,
+  // Delay task running to encourage sending threads to run.
+  TaskRunning = 0x80,
   Any = 0xffffffff,
 };
 
 namespace detail {
 extern MFBT_DATA Atomic<uint32_t,
                         SequentiallyConsistent,
                         recordreplay::Behavior::DontPreserve> gChaosModeCounter;
 extern MFBT_DATA ChaosFeature gChaosFeatures;
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -776,18 +776,17 @@ nsStandardURL::BuildNormalizedSpec(const
     }
 
     //
     // generate the normalized URL string
     //
     // approxLen should be correct or 1 high
     if (!mSpec.SetLength(approxLen+1, fallible)) // buf needs a trailing '\0' below
         return NS_ERROR_OUT_OF_MEMORY;
-    char *buf;
-    mSpec.BeginWriting(buf);
+    char *buf = mSpec.BeginWriting();
     uint32_t i = 0;
     int32_t diff = 0;
 
     if (mScheme.mLen > 0) {
         i = AppendSegmentToBuf(buf, i, spec, mScheme, mScheme);
         net_ToLowerCase(buf + mScheme.mPos, mScheme.mLen);
         i = AppendToBuf(buf, i, "://", 3);
     }
@@ -1506,20 +1505,18 @@ nsStandardURL::SetSpecWithEncoding(const
     // Make a backup of the curent URL
     nsStandardURL prevURL(false,false);
     prevURL.CopyMembers(this, eHonorRef, EmptyCString());
     Clear();
 
     if (IsSpecialProtocol(filteredURI)) {
         // Bug 652186: Replace all backslashes with slashes when parsing paths
         // Stop when we reach the query or the hash.
-        nsAutoCString::iterator start;
-        nsAutoCString::iterator end;
-        filteredURI.BeginWriting(start);
-        filteredURI.EndWriting(end);
+        auto start = filteredURI.BeginWriting();
+        auto end = filteredURI.EndWriting();
         while (start != end) {
             if (*start == '?' || *start == '#') {
                 break;
             }
             if (*start == '\\') {
                 *start = '/';
             }
             start++;
@@ -2388,20 +2385,18 @@ nsStandardURL::Resolve(const nsACString 
     nsAutoCString baseProtocol(Scheme());
 
     // We need to do backslash replacement for the following cases:
     // 1. The input is an absolute path with a http/https/ftp scheme
     // 2. The input is a relative path, and the base URL has a http/https/ftp scheme
     if ((protocol.IsEmpty() && IsSpecialProtocol(baseProtocol)) ||
          IsSpecialProtocol(protocol)) {
 
-        nsAutoCString::iterator start;
-        nsAutoCString::iterator end;
-        buf.BeginWriting(start);
-        buf.EndWriting(end);
+        auto start = buf.BeginWriting();
+        auto end = buf.EndWriting();
         while (start != end) {
             if (*start == '?' || *start == '#') {
                 break;
             }
             if (*start == '\\') {
                 *start = '/';
             }
             start++;
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -2992,17 +2992,16 @@ nsCookieService::ImportCookies(nsIFile *
   nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(fileInputStream, &rv);
   if (NS_FAILED(rv)) return rv;
 
   static const char kTrue[] = "TRUE";
 
   nsAutoCString buffer, baseDomain;
   bool isMore = true;
   int32_t hostIndex, isDomainIndex, pathIndex, secureIndex, expiresIndex, nameIndex, cookieIndex;
-  nsACString::char_iterator iter;
   int32_t numInts;
   int64_t expires;
   bool isDomain, isHttpOnly = false;
   uint32_t originalCookieCount = mDefaultDBState->cookieCount;
 
   int64_t currentTimeInUsec = PR_Now();
   int64_t currentTime = currentTimeInUsec / PR_USEC_PER_SEC;
   // we use lastAccessedCounter to keep cookies in recently-used order,
@@ -3060,18 +3059,18 @@ nsCookieService::ImportCookies(nsIFile *
         (expiresIndex  = buffer.FindChar('\t', secureIndex)   + 1) == 0 ||
         (nameIndex     = buffer.FindChar('\t', expiresIndex)  + 1) == 0 ||
         (cookieIndex   = buffer.FindChar('\t', nameIndex)     + 1) == 0) {
       continue;
     }
 
     // check the expirytime first - if it's expired, ignore
     // nullstomp the trailing tab, to avoid copying the string
-    buffer.BeginWriting(iter);
-    *(iter += nameIndex - 1) = char(0);
+    auto iter = buffer.BeginWriting() + nameIndex - 1;
+    *iter = char(0);
     numInts = PR_sscanf(buffer.get() + expiresIndex, "%lld", &expires);
     if (numInts != 1 || expires < currentTime) {
       continue;
     }
 
     isDomain = Substring(buffer, isDomainIndex, pathIndex - isDomainIndex - 1).EqualsLiteral(kTrue);
     const nsACString& host = Substring(buffer, hostIndex, isDomainIndex - hostIndex - 1);
     // check for bad legacy cookies (domain not starting with a dot, or containing a port),
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -413,27 +413,16 @@ nsHttpChannel::Init(nsIURI *uri,
                     nsIURI *proxyURI,
                     uint64_t channelId)
 {
     nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo,
                                         proxyResolveFlags, proxyURI, channelId);
     if (NS_FAILED(rv))
         return rv;
 
-#ifdef MOZ_GECKO_PROFILER
-    mLastStatusReported = TimeStamp::Now(); // in case we enable the profiler after Init()
-    if (profiler_is_active()) {
-        int32_t priority = PRIORITY_NORMAL;
-        GetPriority(&priority);
-        profiler_add_network_marker(uri, priority, channelId, NetworkLoadType::LOAD_START,
-                                    mChannelCreationTimestamp, mLastStatusReported,
-                                    0);
-    }
-#endif
-
     LOG(("nsHttpChannel::Init [this=%p]\n", this));
 
     return rv;
 }
 
 nsresult
 nsHttpChannel::AddSecurityMessage(const nsAString& aMessageTag,
                                   const nsAString& aMessageCategory)
@@ -6283,24 +6272,31 @@ nsHttpChannel::AsyncOpen(nsIStreamListen
 
     LOG(("nsHttpChannel::AsyncOpen [this=%p]\n", this));
 
 #ifdef MOZ_TASK_TRACER
     if (tasktracer::IsStartLogging()) {
         uint64_t sourceEventId, parentTaskId;
         tasktracer::SourceEventType sourceEventType;
         GetCurTraceInfo(&sourceEventId, &parentTaskId, &sourceEventType);
-        nsCOMPtr<nsIURI> uri;
-        GetURI(getter_AddRefs(uri));
         nsAutoCString urispec;
-        uri->GetSpec(urispec);
+        mURI->GetSpec(urispec);
         tasktracer::AddLabel("nsHttpChannel::AsyncOpen %s", urispec.get());
     }
 #endif
 
+#ifdef MOZ_GECKO_PROFILER
+    mLastStatusReported = TimeStamp::Now(); // in case we enable the profiler after AsyncOpen()
+    if (profiler_is_active()) {
+        profiler_add_network_marker(mURI, mPriority, mChannelId, NetworkLoadType::LOAD_START,
+                                    mChannelCreationTimestamp, mLastStatusReported,
+                                    0);
+    }
+#endif
+
     NS_CompareLoadInfoAndLoadContext(this);
 
 #ifdef DEBUG
     AssertPrivateBrowsingId();
 #endif
 
     NS_ENSURE_ARG_POINTER(listener);
     NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
--- a/old-configure.in
+++ b/old-configure.in
@@ -503,18 +503,16 @@ dnl GNU specific defaults
 dnl ========================================================
 if test "$GNU_CC"; then
     MMX_FLAGS="-mmmx"
     SSE_FLAGS="-msse"
     SSE2_FLAGS="-msse2"
     SSSE3_FLAGS="-mssse3"
     # FIXME: Let us build with strict aliasing. bug 414641.
     CFLAGS="$CFLAGS -fno-strict-aliasing"
-    MKSHLIB='$(CXX) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(DSO_SONAME) -o $@'
-    MKCSHLIB='$(CC) $(COMPUTED_C_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(DSO_SONAME) -o $@'
     WARNINGS_AS_ERRORS='-Werror'
     DSO_CFLAGS=''
 
     if test "$OS_ARCH" != "WINNT" -o -z "$CLANG_CC"; then
         DSO_PIC_CFLAGS='-fPIC'
         ASFLAGS="$ASFLAGS -fPIC"
     fi
 
@@ -732,18 +730,16 @@ fi
 MOZ_DOING_LTO(lto_is_enabled)
 
 dnl ========================================================
 dnl System overrides of the defaults for target
 dnl ========================================================
 
 case "$target" in
 *-darwin*)
-    MKSHLIB='$(CXX) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
-    MKCSHLIB='$(CC) $(COMPUTED_C_LDFLAGS) $(PGO_CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
     MOZ_OPTIMIZE_FLAGS="-O3"
     CXXFLAGS="$CXXFLAGS -stdlib=libc++"
     DSO_LDOPTS=''
     STRIP_FLAGS="$STRIP_FLAGS -x -S"
     # Ensure that if we're targeting iOS an SDK was provided.
     AC_CACHE_CHECK(for iOS target,
                    ac_cv_ios_target,
                    [AC_TRY_COMPILE([#include <TargetConditionals.h>
@@ -835,18 +831,16 @@ case "$target" in
     # #include <string> vs -I./dist/include/string issue so don't use it
     if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
         CC="$CC -mwindows"
         CXX="$CXX -mwindows"
         CPP="$CPP -mwindows"
         CFLAGS="$CFLAGS -mms-bitfields"
         CXXFLAGS="$CXXFLAGS -mms-bitfields"
         DSO_LDOPTS='-shared'
-        MKSHLIB='$(CXX) $(DSO_LDOPTS) -o $@'
-        MKCSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
         RC='$(WINDRES)'
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -luuid -lusp10 -lgdi32 -lwinmm -lwsock32 -luserenv -lsecur32"
         MOZ_FIX_LINK_PATHS=
 
         MOZ_OPTIMIZE_FLAGS="-O1"
@@ -885,18 +879,16 @@ case "$target" in
             AR='lib'
             AR_FLAGS='-NOLOGO -OUT:$@'
             ;;
         esac
         AR_EXTRACT=
         RANLIB='echo not_ranlib'
         STRIP='echo not_strip'
         PKG_SKIP_STRIP=1
-        MKSHLIB='$(LINKER) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
-        MKCSHLIB='$(LINKER) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         WIN32_SUBSYSTEM_VERSION=6.01
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         _USE_CPP_INCLUDE_FLAG=1
         _DEFINES_CFLAGS="-FI $_objdir/mozilla-config.h -DMOZILLA_CLIENT"
         _DEFINES_CXXFLAGS="-FI $_objdir/mozilla-config.h -DMOZILLA_CLIENT"
         CFLAGS="$CFLAGS -W3 -Gy -Zc:inline"
@@ -1108,18 +1100,16 @@ case "$target" in
     else
         DSO_PIC_CFLAGS='-fPIC -DPIC'
         DSO_LDOPTS='-shared'
     fi
     # This will fail on a.out systems prior to 1.5.1_ALPHA.
     if test "$LIBRUNPATH"; then
         DSO_LDOPTS="-Wl,-R$LIBRUNPATH $DSO_LDOPTS"
     fi
-    MKSHLIB='$(CXX) $(COMPUTED_CXX_LDFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(DSO_SONAME) -o $@'
-    MKCSHLIB='$(CC) $(COMPUTED_C_LDFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(DSO_SONAME) -o $@'
     ;;
 
 *-openbsd*)
     if test -z "$X11BASE"; then
         X11BASE=/usr/X11R6
     fi
     MOZ_FIX_LINK_PATHS="$MOZ_FIX_LINK_PATHS -Wl,-rpath-link,${X11BASE}/lib"
     DSO_CFLAGS=''
@@ -4399,18 +4389,16 @@ AC_SUBST(HOST_BIN_SUFFIX)
 
 AC_SUBST(TARGET_XPCOM_ABI)
 AC_SUBST(HAVE_TOOLCHAIN_SUPPORT_MSSSE3)
 AC_SUBST(HAVE_TOOLCHAIN_SUPPORT_MSSE4_1)
 AC_SUBST(HAVE_X86_AVX2)
 AC_SUBST(HAVE_ALTIVEC)
 AC_SUBST(GCC_USE_GNU_LD)
 
-AC_SUBST(MKSHLIB)
-AC_SUBST(MKCSHLIB)
 AC_SUBST_LIST(DSO_CFLAGS)
 AC_SUBST_LIST(DSO_PIC_CFLAGS)
 AC_SUBST(DSO_LDOPTS)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(NS_ENABLE_TSF)
 AC_SUBST(WIN32_CONSOLE_EXE_LDFLAGS)
--- a/parser/htmlparser/nsScannerString.cpp
+++ b/parser/htmlparser/nsScannerString.cpp
@@ -454,30 +454,28 @@ copy_multifragment_string( nsScannerIter
     return result;
   }
 
 bool
 CopyUnicodeTo( const nsScannerIterator& aSrcStart,
                const nsScannerIterator& aSrcEnd,
                nsAString& aDest )
   {
-    nsAString::iterator writer;
-
     mozilla::CheckedInt<nsAString::size_type> distance(Distance(aSrcStart, aSrcEnd));
     if (!distance.isValid()) {
       return false; // overflow detected
     }
 
     if (!aDest.SetLength(distance.value(), mozilla::fallible)) {
       aDest.Truncate();
       return false; // out of memory
     }
-    aDest.BeginWriting(writer);
+    auto writer = aDest.BeginWriting();
     nsScannerIterator fromBegin(aSrcStart);
-    
+
     copy_multifragment_string(fromBegin, aSrcEnd, writer);
     return true;
   }
 
 bool
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsScannerSharedSubstring& aDest )
@@ -493,29 +491,29 @@ AppendUnicodeTo( const nsScannerIterator
     return AppendUnicodeTo(aSrcStart, aSrcEnd, aDest.writable());
   }
 
 bool
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsAString& aDest )
   {
-    nsAString::iterator writer;
     const nsAString::size_type oldLength = aDest.Length();
     CheckedInt<nsAString::size_type> newLen(Distance(aSrcStart, aSrcEnd));
     newLen += oldLength;
     if (!newLen.isValid()) {
       return false; // overflow detected
     }
 
     if (!aDest.SetLength(newLen.value(), mozilla::fallible))
       return false; // out of memory
-    aDest.BeginWriting(writer).advance(oldLength);
+    auto writer = aDest.BeginWriting();
+    std::advance(writer, oldLength);
     nsScannerIterator fromBegin(aSrcStart);
-    
+
     copy_multifragment_string(fromBegin, aSrcEnd, writer);
     return true;
   }
 
 bool
 FindCharInReadable( char16_t aChar,
                     nsScannerIterator& aSearchStart,
                     const nsScannerIterator& aSearchEnd )
--- a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
@@ -51,17 +51,17 @@ function test() {
                                Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
       ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                                 privacyFlags(aIsPrivateMode)),
                                 "checking sts host");
 
       aCallback();
     });
 
-    aWindow.gBrowser.selectedBrowser.loadURI(testURI);
+    BrowserTestUtils.loadURI(aWindow.gBrowser.selectedBrowser, testURI);
   }
 
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       windowsToClose.push(aWin);
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
--- a/services/fxaccounts/tests/browser/browser_device_connected.js
+++ b/services/fxaccounts/tests/browser/browser_device_connected.js
@@ -21,17 +21,17 @@ add_task(async function setup() {
   registerCleanupFunction(function() {
     FxAccounts.config.promiseManageDevicesURI = origManageDevicesURI;
     delete window.FxAccounts;
   });
 });
 
 async function testDeviceConnected(deviceName) {
   info("testDeviceConnected with deviceName=" + deviceName);
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await waitForDocLoadComplete();
 
   let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
 
   Services.obs.notifyObservers(null, "fxaccounts:device_connected", deviceName);
 
   let tab = await waitForTabPromise;
   Assert.ok("Tab successfully opened");
--- a/services/fxaccounts/tests/browser/browser_verify_login.js
+++ b/services/fxaccounts/tests/browser/browser_verify_login.js
@@ -9,17 +9,17 @@ add_task(async function() {
       deviceName: "Laptop",
       url: "http://localhost/newLogin",
       title: "Sign-in Request",
       body: "New sign-in request from vershwal's Nighty on Intel Mac OS X 10.12",
     },
   };
   info("testVerifyNewSignin");
   setupMockAlertsService();
-  gBrowser.selectedBrowser.loadURI("about:robots");
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
   await waitForDocLoadComplete();
 
   let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
 
   Services.obs.notifyObservers(null, "fxaccounts:verify_login", JSON.stringify(payload.data));
 
   let tab = await waitForTabPromise;
   Assert.ok("Tab successfully opened");
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -628,17 +628,19 @@ var BrowserTestUtils = {
    * @param {string} uri
    *        The URI to load.
    *
    * @return {Promise}
    * @resolves When we started loading the given URI.
    */
   async loadURI(browser, uri) {
     // Load the new URI.
-    browser.loadURI(uri);
+    browser.loadURI(uri, {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
 
     // Nothing to do in non-e10s mode.
     if (!browser.ownerGlobal.gMultiProcessBrowser) {
       return;
     }
 
     // Retrieve the given browser's current process type.
     let process = browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
--- a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
@@ -207,16 +207,23 @@ def verify_android_device(build_obj, ins
                 _log_info("Fetching AVD. This may take a while...")
                 emulator.update_avd()
             _log_info("Starting emulator running %s..." %
                       emulator.get_avd_description())
             emulator.start()
             emulator.wait_for_start()
             device_verified = True
 
+    if device_verified and "DEVICE_SERIAL" not in os.environ:
+        devices = adbhost.devices(timeout=10)
+        for d in devices:
+            if d['state'] == 'device':
+                os.environ["DEVICE_SERIAL"] = d['device_serial']
+                break
+
     if device_verified and install:
         # Determine if Firefox is installed on the device; if not,
         # prompt to install. This feature allows a test command to
         # launch an emulator, install Firefox, and proceed with testing
         # in one operation. It is also a basic safeguard against other
         # cases where testing is requested but Firefox installation has
         # been forgotten.
         # If Firefox is installed, there is no way to determine whether
--- a/testing/mozharness/mozharness/mozilla/testing/android.py
+++ b/testing/mozharness/mozharness/mozilla/testing/android.py
@@ -9,30 +9,51 @@ import datetime
 import glob
 import os
 import subprocess
 import tempfile
 import time
 from mozharness.mozilla.automation import TBPL_RETRY, EXIT_STATUS_DICT
 
 
-class AndroidMixin:
+class AndroidMixin(object):
     """
        Mixin class used by Android test scripts.
     """
 
-    def init(self):
+    def __init__(self, **kwargs):
         self.logcat_proc = None
         self.logcat_file = None
 
-        self.adb_path = self.query_exe('adb')
+        self._adb_path = None
         self.sdk_level = None
-        self.device_name = os.environ['DEVICE_NAME']
-        self.device_serial = os.environ['DEVICE_SERIAL']
-        self.device_ip = os.environ['DEVICE_IP']
+        self.device_name = os.environ.get('DEVICE_NAME', None)
+        self.device_serial = os.environ.get('DEVICE_SERIAL', None)
+        self.device_ip = os.environ.get('DEVICE_IP', None)
+        super(AndroidMixin, self).__init__(**kwargs)
+
+    @property
+    def adb_path(self):
+        '''Get the path to the adb executable.
+
+        Defer the use of query_exe() since it is defined by the
+        BaseScript Mixin which hasn't finished initialing by the
+        time the AndroidMixin is first initialized.
+        '''
+        if not self._adb_path:
+            try:
+                self._adb_path = self.query_exe('adb')
+            except AttributeError:
+                # Ignore attribute errors since BaseScript will
+                # attempt to access properties before the other Mixins
+                # have completed initialization. We recover afterwards
+                # when additional attemps occur after initialization
+                # is completed.
+                pass
+        return self._adb_path
 
     def _retry(self, max_attempts, interval, func, description, max_time=0):
         '''
         Execute func until it returns True, up to max_attempts times, waiting for
         interval seconds between each attempt. description is logged on each attempt.
         If max_time is specified, no further attempts will be made once max_time
         seconds have elapsed; this provides some protection for the case where
         the run-time for func is long or highly variable.
@@ -175,17 +196,16 @@ class AndroidMixin:
             self.info("Killing logcat pid %d." % self.logcat_proc.pid)
             self.logcat_proc.kill()
             self.logcat_file.close()
 
     def install_apk(self, apk):
         """
            Install the specified apk.
         """
-        self.init()
         cmd = [self.adb_path, '-s', self.device_serial, 'shell',
                'getprop', 'ro.build.version.sdk']
         self.sdk_level, _ = self._run_with_timeout(30, cmd)
 
         install_ok = self._retry(3, 30, self._install_apk, "Install app APK")
         if not install_ok:
             self.fatal('INFRA-ERROR: Failed to install %s on %s' %
                        (self.installer_path, self.device_name),
--- a/testing/mozharness/mozharness/mozilla/testing/codecoverage.py
+++ b/testing/mozharness/mozharness/mozilla/testing/codecoverage.py
@@ -59,18 +59,18 @@ class CodeCoverageMixin(SingleTestMixin)
     Mixin for setting GCOV_PREFIX during test execution, packaging up
     the resulting .gcda files and uploading them to blobber.
     """
     gcov_dir = None
     jsvm_dir = None
     prefix = None
     per_test_reports = {}
 
-    def __init__(self):
-        super(CodeCoverageMixin, self).__init__()
+    def __init__(self, **kwargs):
+        super(CodeCoverageMixin, self).__init__(**kwargs)
 
     @property
     def code_coverage_enabled(self):
         try:
             return bool(self.config.get('code_coverage'))
         except (AttributeError, KeyError, TypeError):
             return False
 
--- a/testing/mozharness/mozharness/mozilla/testing/per_test_base.py
+++ b/testing/mozharness/mozharness/mozilla/testing/per_test_base.py
@@ -14,17 +14,19 @@ import mozinfo
 from manifestparser import TestManifest
 
 from mozharness.mozilla.fetches import FetchesMixin
 
 
 class SingleTestMixin(FetchesMixin):
     """Utility functions for per-test testing like test verification and per-test coverage."""
 
-    def __init__(self):
+    def __init__(self, **kwargs):
+        super(SingleTestMixin, self).__init__(**kwargs)
+
         self.suites = {}
         self.tests_downloaded = False
         self.reftest_test_dir = None
         self.jsreftest_test_dir = None
         # Map from full test path on the test machine to a relative path in the source checkout.
         # Use self._map_test_path_to_source(test_machine_path, source_path) to add a mapping.
         self.test_src_path = {}
 
--- a/testing/talos/talos/pageloader/chrome/pageloader.js
+++ b/testing/talos/talos/pageloader/chrome/pageloader.js
@@ -321,20 +321,23 @@ function startAndLoadURI(pageName) {
     // If the test is doing its own timing, it'll also need to do its own
     // profiler pausing / resuming.
     TalosParentProfiler.resume("Starting to load URI " + pageName);
   }
 
   start_time = Date.now();
   if (loadNoCache) {
     content.loadURI(pageName, {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
       flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE
     });
   } else {
-    content.loadURI(pageName);
+    content.loadURI(pageName, {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
   }
 }
 
 function getTestName() { // returns tp5n
   var pageName = pages[pageIndex].url.spec;
   let parts = pageName.split("/");
   if (parts.length > 4) {
     return parts[4];
--- a/testing/talos/talos/tests/tabswitch/api.js
+++ b/testing/talos/talos/tests/tabswitch/api.js
@@ -215,17 +215,19 @@ async function test(window) {
   gBrowser.tabContainer.style.opacity = "0";
 
   let initialTab = gBrowser.selectedTab;
   await loadTabs(gBrowser, testURLs);
 
   // We'll switch back to about:blank after each tab switch
   // in an attempt to put the graphics layer into a "steady"
   // state before switching to the next tab.
-  initialTab.linkedBrowser.loadURI("about:blank", null, null);
+  initialTab.linkedBrowser.loadURI("about:blank", {
+    triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+  });
 
   let tabs = gBrowser.getTabsToTheEndFrom(initialTab);
   let times = [];
 
   for (let tab of tabs) {
     // Let's do an initial run to warm up any paint related caches
     // (like glyph caches for text). In the next loop we will start with
     // a GC before each switch so we don't need here.
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -431154,22 +431154,16 @@
     ]
    ],
    "webdriver/tests/accept_alert/accept.py": [
     [
      "/webdriver/tests/accept_alert/accept.py",
      {}
     ]
    ],
-   "webdriver/tests/actions/bounds.py": [
-    [
-     "/webdriver/tests/actions/bounds.py",
-     {}
-    ]
-   ],
    "webdriver/tests/actions/control_click.py": [
     [
      "/webdriver/tests/actions/control_click.py",
      {}
     ]
    ],
    "webdriver/tests/actions/key.py": [
     [
@@ -431202,16 +431196,22 @@
     ]
    ],
    "webdriver/tests/actions/mouse_pause_dblclick.py": [
     [
      "/webdriver/tests/actions/mouse_pause_dblclick.py",
      {}
     ]
    ],
+   "webdriver/tests/actions/none.py": [
+    [
+     "/webdriver/tests/actions/none.py",
+     {}
+    ]
+   ],
    "webdriver/tests/actions/pointer_origin.py": [
     [
      "/webdriver/tests/actions/pointer_origin.py",
      {}
     ]
    ],
    "webdriver/tests/actions/sequence.py": [
     [
@@ -431224,16 +431224,22 @@
    "webdriver/tests/actions/special_keys.py": [
     [
      "/webdriver/tests/actions/special_keys.py",
      {
       "timeout": "long"
      }
     ]
    ],
+   "webdriver/tests/actions/validity.py": [
+    [
+     "/webdriver/tests/actions/validity.py",
+     {}
+    ]
+   ],
    "webdriver/tests/add_cookie/add.py": [
     [
      "/webdriver/tests/add_cookie/add.py",
      {}
     ]
    ],
    "webdriver/tests/back/back.py": [
     [
@@ -598466,17 +598472,17 @@
    "c880aaab5cfbdfd11ebf885244cb7a5229c03ec5",
    "support"
   ],
   "fullscreen/META.yml": [
    "fbdb76390c7ad4390dac7d83004e5721fc62a37d",
    "support"
   ],
   "fullscreen/api/document-exit-fullscreen-active-document.html": [
-   "18b0bb6493bd8275a750091b862c7ee5ee770abf",
+   "8279fae533774fcf6daced99ffc84413a0a9172d",
    "testharness"
   ],
   "fullscreen/api/document-exit-fullscreen-manual.html": [
    "ebe7ea2f1cabace4fde968ba3d80d4dc09dc9660",
    "manual"
   ],
   "fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html": [
    "11e6a6ac328367273edd5a9d91f9854ea0160431",
@@ -656290,17 +656296,17 @@
    "c2545de46f0b5def00c273ecfb5a57f0d4029531",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/fennec.py": [
    "5e8ed28e2ee0e10acaa3e4ddf1e79164e795a2b2",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/firefox.py": [
-   "04f2ce84a41619a23e29d5436430b11fa2b6d7c5",
+   "9f7ebfa2ca544616e2feaeb53c8af73220d7271a",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/ie.py": [
    "a0730f8ba29ea8b65b56709a4f96ac5894078d94",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/opera.py": [
    "5c0109832be2da6fdbf224b64a9f8fc3b98045da",
@@ -661025,22 +661031,18 @@
   "webdriver/tests/accept_alert/accept.py": [
    "a111f103bf142b4041f2a8d1c6017de79b54560e",
    "wdspec"
   ],
   "webdriver/tests/actions/__init__.py": [
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
    "support"
   ],
-  "webdriver/tests/actions/bounds.py": [
-   "e218c851e75220cea0c296461dad1d8427619afb",
-   "wdspec"
-  ],
   "webdriver/tests/actions/conftest.py": [
-   "47aad72ba05d4e0c7afe989030c91c7824cb0b07",
+   "55cecd117828e525ac5712176f6f31787b301226",
    "support"
   ],
   "webdriver/tests/actions/control_click.py": [
    "2ec819b772fcfa4d0a37395aa64fb89ad7686bda",
    "wdspec"
   ],
   "webdriver/tests/actions/key.py": [
    "50c4ed9132b10cf63ad515bbfcbd30970b2c1974",
@@ -661061,16 +661063,20 @@
   "webdriver/tests/actions/mouse_dblclick.py": [
    "fc53a51ab7691e817139e0a5a8477c9a96dda842",
    "wdspec"
   ],
   "webdriver/tests/actions/mouse_pause_dblclick.py": [
    "ad179673176b9d8ae90837c7cf09d33c75780a75",
    "wdspec"
   ],
+  "webdriver/tests/actions/none.py": [
+   "07944a68ffeedfdbd5adac44244f6435b5c5c6cb",
+   "wdspec"
+  ],
   "webdriver/tests/actions/pointer_origin.py": [
    "cad59f0a13b1f584ea45226f061be0038b9de220",
    "wdspec"
   ],
   "webdriver/tests/actions/sequence.py": [
    "b62d00c3e9b82d6200b3f6a0cd99d8a208281601",
    "wdspec"
   ],
@@ -661093,16 +661099,20 @@
   "webdriver/tests/actions/support/refine.py": [
    "3a6d63e04ce941d26ab3898cb2fc2a730d46c1ce",
    "support"
   ],
   "webdriver/tests/actions/support/test_actions_wdspec.html": [
    "6f844cd255a075d31caf1c19957af3d6ac833778",
    "support"
   ],
+  "webdriver/tests/actions/validity.py": [
+   "ce8a0d60f7df192e21c6abbad1871bb0ac8f5f78",
+   "wdspec"
+  ],
   "webdriver/tests/add_cookie/__init__.py": [
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
    "support"
   ],
   "webdriver/tests/add_cookie/add.py": [
    "24ac645029e0dc57327b62ad3d24fbab1640ad2c",
    "wdspec"
   ],
@@ -661610,17 +661620,17 @@
    "857d289fcaf054492e17ba730c6f530d55fe2640",
    "wdspec"
   ],
   "webdriver/tests/new_session/page_load_strategy.py": [
    "69288ef43335605e4c9d21cfa56bd2806f6e92b0",
    "wdspec"
   ],
   "webdriver/tests/new_session/platform_name.py": [
-   "0504f04259d8e289e1581669ba9066a14bb4d529",
+   "54fe4743bed44e75d6771ede5d4b7bf2f267bb95",
    "wdspec"
   ],
   "webdriver/tests/new_session/response.py": [
    "3e8520718237e6d74fe368d68c4a7bf2ead08c9e",
    "wdspec"
   ],
   "webdriver/tests/new_session/support/__init__.py": [
    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
@@ -668622,17 +668632,17 @@
    "626f2043f328bb4f3fd883a87f018fad55bf5f7e",
    "testharness"
   ],
   "x-frame-options/invalid.sub.html": [
    "4604033d01fc2fa345e8f1f1cfdbb9397b89a996",
    "testharness"
   ],
   "x-frame-options/multiple.sub.html": [
-   "f7a28e40ee22be3493c3926e15c40d2e814ad2e4",
+   "717e9fd25c51ee80f3adf029740d475790b3875e",
    "testharness"
   ],
   "x-frame-options/redirect.sub.html": [
    "0bc708b358cb309718ba5c4350f8150b87c4c8f0",
    "testharness"
   ],
   "x-frame-options/sameorigin.sub.html": [
    "9efbc320946e34baa416e39205d8f39c71325637",
--- a/testing/web-platform/tests/webdriver/tests/actions/conftest.py
+++ b/testing/web-platform/tests/webdriver/tests/actions/conftest.py
@@ -9,16 +9,21 @@ def key_chain(session):
 @pytest.fixture
 def mouse_chain(session):
     return session.actions.sequence(
         "pointer",
         "pointer_id",
         {"pointerType": "mouse"})
 
 
+@pytest.fixture
+def none_chain(session):
+    return session.actions.sequence("none", "none_id")
+
+
 @pytest.fixture(autouse=True)
 def release_actions(session, request):
     # release all actions after each test
     # equivalent to a teardown_function, but with access to session fixture
     request.addfinalizer(session.actions.release)
 
 
 @pytest.fixture
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/tests/actions/none.py
@@ -0,0 +1,19 @@
+from tests.support.asserts import assert_error, assert_success
+
+
+def perform_actions(session, actions):
+    return session.transport.send(
+        "POST",
+        "/session/{session_id}/actions".format(**vars(session)),
+        {"actions": actions},
+    )
+
+
+def test_null_response_value(session, none_chain):
+    response = perform_actions(session, [none_chain.pause(0).dict])
+    assert_success(response, None)
+
+
+def test_no_browsing_context(session, closed_window, none_chain):
+    response = perform_actions(session, [none_chain.pause(0).dict])
+    assert_error(response, "no such window")
rename from testing/web-platform/tests/webdriver/tests/actions/bounds.py
rename to testing/web-platform/tests/webdriver/tests/actions/validity.py
--- a/testing/web-platform/tests/webdriver/tests/actions/bounds.py
+++ b/testing/web-platform/tests/webdriver/tests/actions/validity.py
@@ -44,8 +44,21 @@ def test_pause_invalid_types(session, ac
             "id": "foobar",
             "actions": [{
                 "type": "pause",
                 "duration": invalid_type
             }]
         }]
         response = perform_actions(session, actions)
         assert_error(response, "invalid argument")
+
+
+@pytest.mark.parametrize("action_type", ["none", "key", "pointer"])
+def test_pause_without_duration(session, action_type):
+    actions = [{
+        "type": action_type,
+        "id": "foobar",
+        "actions": [{
+            "type": "pause",
+        }]
+    }]
+    response = perform_actions(session, actions)
+    assert_success(response)
--- a/testing/web-platform/tests/webdriver/tests/new_session/platform_name.py
+++ b/testing/web-platform/tests/webdriver/tests/new_session/platform_name.py
@@ -1,11 +1,11 @@
 import pytest
 
 from tests.support import platform_name
 from tests.support.asserts import assert_success
 
 
-@pytest.mark.skip_if(platform_name is None, reason="Unsupported platform {}".format(platform_name))
+@pytest.mark.skipif(platform_name is None, reason="Unsupported platform {}".format(platform_name))
 def test_corresponds_to_local_system(new_session, add_browser_capabilities):
     response, _ = new_session({"capabilities": {"alwaysMatch": add_browser_capabilities({})}})
     value = assert_success(response)
     assert value["capabilities"]["platformName"] == platform_name
--- a/testing/webdriver/src/actions.rs
+++ b/testing/webdriver/src/actions.rs
@@ -38,17 +38,22 @@ pub enum NullActionItem {
 #[serde(tag = "type")]
 pub enum GeneralAction {
     #[serde(rename = "pause")]
     Pause(PauseAction),
 }
 
 #[derive(Debug, PartialEq, Serialize, Deserialize)]
 pub struct PauseAction {
-    pub duration: u64,
+    #[serde(
+        default,
+        skip_serializing_if = "Option::is_none",
+        deserialize_with = "deserialize_to_option_u64"
+    )]
+    pub duration: Option<u64>,
 }
 
 #[derive(Debug, PartialEq, Serialize, Deserialize)]
 #[serde(untagged)]
 pub enum KeyActionItem {
     General(GeneralAction),
     Key(KeyAction),
 }
@@ -246,17 +251,17 @@ mod test {
             "actions":[{
                 "type":"pause","duration":1
             }]
         }"#;
         let data = ActionSequence {
             id: Some("none".into()),
             actions: ActionsType::Null {
                 actions: vec![NullActionItem::General(GeneralAction::Pause(PauseAction {
-                    duration: 1,
+                    duration: Some(1),
                 }))],
             },
         };
 
         check_serialize_deserialize(&json, &data);
     }
 
     #[test]
@@ -353,17 +358,17 @@ mod test {
             "type":"none",
             "actions":[{
                 "type":"pause",
                 "duration":1
             }]
         }"#;
         let data = ActionsType::Null {
             actions: vec![NullActionItem::General(GeneralAction::Pause(PauseAction {
-                duration: 1,
+                duration: Some(1),
             }))],
         };
 
         check_serialize_deserialize(&json, &data);
     }
 
     #[test]
     fn test_json_actions_type_key() {
@@ -438,40 +443,41 @@ mod test {
     fn test_json_actions_type_invalid() {
         let json = r#"{"actions":[{"foo":"bar"}]}"#;
         assert!(serde_json::from_str::<ActionsType>(&json).is_err());
     }
 
     #[test]
     fn test_json_null_action_item_general() {
         let json = r#"{"type":"pause","duration":1}"#;
-        let data = NullActionItem::General(GeneralAction::Pause(PauseAction { duration: 1 }));
+        let data = NullActionItem::General(GeneralAction::Pause(PauseAction { duration: Some(1) }));
 
         check_serialize_deserialize(&json, &data);
     }
 
     #[test]
     fn test_json_null_action_item_invalid_type() {
         let json = r#"{"type":"invalid"}"#;
         assert!(serde_json::from_str::<NullActionItem>(&json).is_err());
     }
 
     #[test]
     fn test_json_general_action_pause() {
         let json = r#"{"type":"pause","duration":1}"#;
-        let data = GeneralAction::Pause(PauseAction { duration: 1 });
+        let data = GeneralAction::Pause(PauseAction { duration: Some(1) });
 
         check_serialize_deserialize(&json, &data);
     }
 
     #[test]
     fn test_json_general_action_pause_with_duration_missing() {
         let json = r#"{"type":"pause"}"#;
+        let data = GeneralAction::Pause(PauseAction { duration: None });
 
-        assert!(serde_json::from_str::<GeneralAction>(&json).is_err());
+        check_serialize_deserialize(&json, &data);
     }
 
     #[test]
     fn test_json_general_action_pause_with_duration_null() {
         let json = r#"{"type":"pause","duration":null}"#;
 
         assert!(serde_json::from_str::<GeneralAction>(&json).is_err());
     }
@@ -488,17 +494,17 @@ mod test {
         let json = r#"{"type":"pause","duration":-30}"#;
 
         assert!(serde_json::from_str::<GeneralAction>(&json).is_err());
     }
 
     #[test]
     fn test_json_key_action_item_general() {
         let json = r#"{"type":"pause","duration":1}"#;
-        let data = KeyActionItem::General(GeneralAction::Pause(PauseAction { duration: 1 }));
+        let data = KeyActionItem::General(GeneralAction::Pause(PauseAction { duration: Some(1) }));
 
         check_serialize_deserialize(&json, &data);
     }
 
     #[test]
     fn test_json_key_action_item_key() {
         let json = r#"{"type":"keyDown","value":"f"}"#;
         let data = KeyActionItem::Key(KeyAction::Down(KeyDownAction {
@@ -642,17 +648,17 @@ mod test {
         let json = r#"{"type":"keyUp","value":"fo"}"#;
 
         assert!(serde_json::from_str::<KeyAction>(&json).is_err());
     }
 
     #[test]
     fn test_json_pointer_action_item_general() {
         let json = r#"{"type":"pause","duration":1}"#;
-        let data = PointerActionItem::General(GeneralAction::Pause(PauseAction { duration: 1 }));
+        let data = PointerActionItem::General(GeneralAction::Pause(PauseAction { duration: Some(1) }));
 
         check_serialize_deserialize(&json, &data);
     }
 
     #[test]
     fn test_json_pointer_action_item_pointer() {
         let json = r#"{"type":"pointerCancel"}"#;
         let data = PointerActionItem::Pointer(PointerAction::Cancel);
--- a/toolkit/actors/WebNavigationChild.jsm
+++ b/toolkit/actors/WebNavigationChild.jsm
@@ -102,16 +102,19 @@ class WebNavigationChild extends ActorCh
     if (postData)
       postData = Utils.makeInputStream(postData);
     if (headers)
       headers = Utils.makeInputStream(headers);
     if (baseURI)
       baseURI = Services.io.newURI(baseURI);
     if (triggeringPrincipal)
       triggeringPrincipal = Utils.deserializePrincipal(triggeringPrincipal);
+    if (!triggeringPrincipal) {
+      triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal({});
+    }
     this._wrapURIChangeCall(() => {
       return this.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
                                                    postData, headers, baseURI, triggeringPrincipal);
     });
   }
 
   setOriginAttributes(originAttributes) {
     if (originAttributes) {
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -1107,17 +1107,17 @@ class HiddenXULWindow {
       let attrs = this.chromeShell.getOriginAttributes();
       attrs.privateBrowsingId = 1;
       this.chromeShell.setOriginAttributes(attrs);
     }
 
     let system = Services.scriptSecurityManager.getSystemPrincipal();
     this.chromeShell.createAboutBlankContentViewer(system);
     this.chromeShell.useGlobalHistory = false;
-    this.chromeShell.loadURI("chrome://extensions/content/dummy.xul", 0, null, null, null);
+    this.chromeShell.loadURI("chrome://extensions/content/dummy.xul", 0, null, null, null, system);
 
     await promiseObserved("chrome-document-global-created",
                           win => win.document == this.chromeShell.document);
     return promiseDocumentLoaded(windowlessBrowser.document);
   }
 
   /**
    * Creates the browser XUL element that will contain the WebExtension Page.
--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
+++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
@@ -126,17 +126,17 @@ class ContentPage {
 
     let system = Services.scriptSecurityManager.getSystemPrincipal();
 
     let chromeShell = this.windowlessBrowser.docShell
                           .QueryInterface(Ci.nsIWebNavigation);
 
     chromeShell.createAboutBlankContentViewer(system);
     chromeShell.useGlobalHistory = false;
-    chromeShell.loadURI("chrome://extensions/content/dummy.xul", 0, null, null, null);
+    chromeShell.loadURI("chrome://extensions/content/dummy.xul", 0, null, null, null, system);
 
     await promiseObserved("chrome-document-global-created",
                           win => win.document == chromeShell.document);
 
     let chromeDoc = await promiseDocumentLoaded(chromeShell.document);
 
     let browser = chromeDoc.createElement("browser");
     browser.setAttribute("type", "content");
@@ -177,17 +177,19 @@ class ContentPage {
   addFrameScriptHelper(func) {
     let frameScript = `data:text/javascript,${encodeURI(func)}`;
     this.browser.messageManager.loadFrameScript(frameScript, false, true);
   }
 
   async loadURL(url, redirectUrl = undefined) {
     await this.browserReady;
 
-    this.browser.loadURI(url);
+    this.browser.loadURI(url, {
+      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    });
     return promiseBrowserLoaded(this.browser, url, redirectUrl);
   }
 
   async fetch(url, options) {
     return this.sendMessage("Test:Fetch", {url, options});
   }
 
   spawn(params, task) {
--- a/toolkit/components/mozprotocol/tests/browser_mozprotocol.js
+++ b/toolkit/components/mozprotocol/tests/browser_mozprotocol.js
@@ -1,14 +1,14 @@
 // Check that entering moz://a into the address bar directs us to a new url
 add_task(async function() {
   let path = getRootDirectory(gTestPath).substring("chrome://mochitests/content/".length);
   await SpecialPowers.pushPrefEnv({
     set: [["toolkit.mozprotocol.url", `https://example.com/${path}mozprotocol.html`]],
   });
 
   await BrowserTestUtils.withNewTab("about:blank", async function() {
-    gBrowser.loadURI("moz://a");
+    BrowserTestUtils.loadURI(gBrowser, "moz://a");
     await BrowserTestUtils.waitForLocationChange(gBrowser,
       `https://example.com/${path}mozprotocol.html`);
     ok(true, "Made it to the expected page");
   });
 });
--- a/toolkit/components/passwordmgr/test/browser/browser_DOMFormHasPassword.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_DOMFormHasPassword.js
@@ -76,17 +76,17 @@ function task(contentIds) {
 
   return promise;
 }
 
 add_task(async function() {
   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
 
   let promise = ContentTask.spawn(tab.linkedBrowser, ids, task);
-  tab.linkedBrowser.loadURI("data:text/html;charset=utf-8," +
+  BrowserTestUtils.loadURI(tab.linkedBrowser, "data:text/html;charset=utf-8," +
                             "<html><body>" +
                             "<form id='" + ids.FORM1_ID + "'>" +
                             "<input id='" + ids.CHANGE_INPUT_ID + "'></form>" +
                             "<form id='" + ids.FORM2_ID + "'></form>" +
                             "</body></html>");
   await promise;
 
   ok(true, "Test completed");
--- a/toolkit/components/passwordmgr/test/browser/browser_DOMInputPasswordAdded.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_DOMInputPasswordAdded.js
@@ -82,17 +82,17 @@ function task(contentConsts) {
   }
 
   return promise;
 }
 
 add_task(async function() {
   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   let promise = ContentTask.spawn(tab.linkedBrowser, consts, task);
-  tab.linkedBrowser.loadURI("data:text/html;charset=utf-8," +
+  BrowserTestUtils.loadURI(tab.linkedBrowser, "data:text/html;charset=utf-8," +
                             "<html><body>" +
                             "<form id='" + consts.FORM1_ID + "'>" +
                             "<input id='" + consts.CHANGE_INPUT_ID + "'></form>" +
                             "<form id='" + consts.FORM2_ID + "'></form>" +
                             "</body></html>");
   await promise;
   gBrowser.removeCurrentTab();
 });
--- a/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js
@@ -52,17 +52,17 @@ add_task(async function test_urlbar_frag
     EventUtils.sendString("#fragment");
     EventUtils.synthesizeKey("KEY_Enter");
   });
 });
 
 add_task(async function test_backButton_forwardButton() {
   await withTestPage(async function(aBrowser) {
     // Load a new page in the tab so we can test going back
-    aBrowser.loadURI("https://example.com" + DIRECTORY_PATH + "formless_basic.html?second");
+    BrowserTestUtils.loadURI(aBrowser, "https://example.com" + DIRECTORY_PATH + "formless_basic.html?second");
     await BrowserTestUtils.browserLoaded(aBrowser, false,
                                          "https://example.com" + DIRECTORY_PATH +
                                          "formless_basic.html?second");
     await fillTestPage(aBrowser);
 
     let forwardButton = document.getElementById("forward-button");
 
     let forwardTransitionPromise;
@@ -116,17 +116,17 @@ add_task(async function test_reloadButto
 
 add_task(async function test_back_keyboard_shortcut() {
   if (Services.prefs.getIntPref("browser.backspace_action") != 0) {
     ok(true, "Skipped testing backspace to go back since it's disabled");
     return;
   }
   await withTestPage(async function(aBrowser) {
     // Load a new page in the tab so we can test going back
-    aBrowser.loadURI("https://example.com" + DIRECTORY_PATH + "formless_basic.html?second");
+    BrowserTestUtils.loadURI(aBrowser, "https://example.com" + DIRECTORY_PATH + "formless_basic.html?second");
     await BrowserTestUtils.browserLoaded(aBrowser, false,
                                          "https://example.com" + DIRECTORY_PATH +
                                          "formless_basic.html?second");
     await fillTestPage(aBrowser);
 
     let backPromise = BrowserTestUtils.browserStopped(aBrowser);
     EventUtils.synthesizeKey("KEY_Backspace");
     await backPromise;
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_switchtab.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_switchtab.js
@@ -29,12 +29,12 @@ add_task(async function test() {
 
   Services.wm.addListener(listener);
   registerCleanupFunction(() => {
     Services.wm.removeListener(listener);
     gBrowser.removeTab(tab);
   });
 
   BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => finish());
-  tab.linkedBrowser.loadURI("http://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs");
+  BrowserTestUtils.loadURI(tab.linkedBrowser, "http://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs");
 
   });
 });
--- a/toolkit/components/passwordmgr/test/chrome/test_privbrowsing_perwindowpb.html
+++ b/toolkit/components/passwordmgr/test/chrome/test_privbrowsing_perwindowpb.html
@@ -208,28 +208,28 @@ function whenDelayedStartupFinished(aWin
 }
 
 function testOnWindow(aIsPrivate, aCallback) {
   var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
   win.addEventListener("load", function() {
     whenDelayedStartupFinished(win, function() {
       win.addEventListener("DOMContentLoaded", function onInnerLoad() {
         if (win.content.location.href != contentPage) {
-          win.gBrowser.loadURI(contentPage);
+          BrowserTestUtils.loadURI(win.gBrowser, contentPage);
           return;
         }
         win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
         win.content.addEventListener("load", function innerLoad2() {
           win.content.removeEventListener("load", innerLoad2);
           testWindows.push(win);
           SimpleTest.executeSoon(function() { aCallback(win); });
         }, false, true);
       }, true);
-      SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+      SimpleTest.executeSoon(function() { BrowserTestUtils.loadURI(win.gBrowser, contentPage); });
     });
   }, {capture: true, once: true});
 }
 
 var ignoreLoad = false;
 function handleLoad(aEvent) {
   // ignore every other load event ... We get one for loading the subtest (which
   // we want to ignore), and another when the subtest's form submits itself
--- a/toolkit/components/perfmonitoring/tests/browser/browser_compartments.js
+++ b/toolkit/components/perfmonitoring/tests/browser/browser_compartments.js
@@ -209,17 +209,17 @@ add_task(async function test() {
 
   let newTab = BrowserTestUtils.addTab(gBrowser);
   let browser = newTab.linkedBrowser;
   // Setup monitoring in the tab
   info("Setting up monitoring in the tab");
   await ContentTask.spawn(newTab.linkedBrowser, null, frameScript);
 
   info("Opening URL");
-  newTab.linkedBrowser.loadURI(URL);
+  BrowserTestUtils.loadURI(newTab.linkedBrowser, URL);
 
   if (Services.sysinfo.getPropertyAsAString("name") == "Windows_NT") {
     info("Deactivating sanity checks under Windows (bug 1151240)");
   } else {
     info("Setting up sanity checks");
     monotinicity_tester(() => monitor.promiseSnapshot().then(snapshot => ({snapshot, pid: PARENT_PID})), "parent process");
     monotinicity_tester(() => promiseContentResponseOrNull(browser, "compartments-test:getStatistics", null), "content process" );
   }
--- a/toolkit/components/places/tests/browser/browser_bug399606.js
+++ b/toolkit/components/places/tests/browser/browser_bug399606.js
@@ -26,17 +26,17 @@ add_task(async function() {
     }
   }
 
   async function promiseLoadedThreeTimes(uri) {
     count = 0;
     expectedURI = uri;
     let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
     PlacesObservers.addListener(["page-visited"], onVisitsListener);
-    gBrowser.loadURI(uri);
+    BrowserTestUtils.loadURI(gBrowser, uri);
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, uri);
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, uri);
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, uri);
     PlacesObservers.removeListener(["page-visited"], onVisitsListener);
     BrowserTestUtils.removeTab(tab);
   }
 
   for (let uri of URIS) {
--- a/toolkit/components/places/tests/browser/browser_favicon_privatebrowsing_perwindowpb.js
+++ b/toolkit/components/places/tests/browser/browser_favicon_privatebrowsing_perwindowpb.js
@@ -19,17 +19,17 @@ function test() {
     whenNewWindowLoaded({private: aIsPrivate}, function(aWin) {
       windowsToClose.push(aWin);
       executeSoon(() => aCallback(aWin));
     });
   }
 
   function waitForTabLoad(aWin, aCallback) {
     BrowserTestUtils.browserLoaded(aWin.gBrowser.selectedBrowser).then(aCallback);
-    aWin.gBrowser.selectedBrowser.loadURI(pageURI);
+    BrowserTestUtils.loadURI(aWin.gBrowser.selectedBrowser, pageURI);
   }
 
   testOnWindow(true, function(win) {
     waitForTabLoad(win, function() {
       PlacesUtils.favicons.getFaviconURLForPage(NetUtil.newURI(pageURI),
         function(uri, dataLen, data, mimeType) {
           is(uri, null, "No result should be found");
           finish();
--- a/toolkit/components/places/tests/browser/browser_visited_notfound.js
+++ b/toolkit/components/places/tests/browser/browser_visited_notfound.js
@@ -24,15 +24,15 @@ add_task(async function test() {
       PlacesObservers.removeListener(["page-visited"], onVisits);
       is(events.length, 1, "Right number of visits");
       is(events[0].type, "page-visited");
       is(events[0].url, TEST_URL, "Check visited url");
       resolve();
     }
     PlacesObservers.addListener(["page-visited"], onVisits);
   });
-  gBrowser.selectedBrowser.loadURI(TEST_URL);
+  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URL);
   await promiseVisit;
 
   is(await PlacesTestUtils.fieldInDB(TEST_URL, "frecency"), frecency, "Frecency should be unchanged");
   is(await PlacesTestUtils.fieldInDB(TEST_URL, "hidden"), 0, "Page should not be hidden");
   is(await PlacesTestUtils.fieldInDB(TEST_URL, "typed"), 0, "page should not be marked as typed");
 });
--- a/toolkit/components/places/tests/browser/browser_visituri_nohistory.js
+++ b/toolkit/components/places/tests/browser/browser_visituri_nohistory.js
@@ -23,17 +23,17 @@ add_task(async function() {
 
   let visitUriPromise = promiseObserve("uri-visit-saved");
 
   await BrowserTestUtils.openNewForegroundTab(gBrowser, INITIAL_URL);
 
   await SpecialPowers.popPrefEnv();
 
   let browserLoadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.loadURI(FINAL_URL);
+  BrowserTestUtils.loadURI(gBrowser, FINAL_URL);
   await browserLoadedPromise;
 
   let subject = await visitUriPromise;
   let uri = subject.QueryInterface(Ci.nsIURI);
   is(uri.spec, FINAL_URL, "received expected visit");
 
   await PlacesUtils.history.clear();
   gBrowser.removeCurrentTab();
--- a/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
+++ b/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
@@ -1,11 +1,12 @@
 [DEFAULT]
 head = head_autocomplete.js
 skip-if = toolkit == 'android'
+skip-if = appname == "thunderbird"
 firefox-appdir = browser
 support-files =
   data/engine-rel-searchform.xml
   data/engine-suggestions.xml
   !/toolkit/components/places/tests/favicons/favicon-normal16.png
   autofill_tasks.js
 
 [test_416211.js]
--- a/toolkit/components/places/tests/unit/xpcshell.ini
+++ b/toolkit/components/places/tests/unit/xpcshell.ini
@@ -11,25 +11,28 @@ support-files =
   mobile_bookmarks_folder_import.json
   mobile_bookmarks_folder_merge.json
   mobile_bookmarks_multiple_folders.json
   mobile_bookmarks_root_import.json
   mobile_bookmarks_root_merge.json
   places.sparse.sqlite
 
 [test_000_frecency.js]
+skip-if = appname == "thunderbird"
 [test_331487.js]
 [test_384370.js]
 [test_385397.js]
 [test_399266.js]
 skip-if = os == "linux" # Bug 821781
 [test_402799.js]
 [test_408221.js]
+skip-if = appname == "thunderbird"
 [test_412132.js]
 [test_413784.js]
+skip-if = appname == "thunderbird"
 [test_415460.js]
 [test_415757.js]
 [test_419792_node_tags_property.js]
 [test_425563.js]
 [test_429505_remove_shortcuts.js]
 [test_433317_query_title_update.js]
 [test_433525_hasChildren_crash.js]
 [test_454977.js]
@@ -50,16 +53,17 @@ skip-if = os == "linux" # Bug 821781
 [test_bookmarks_html_escape_entities.js]
 [test_bookmarks_html_import_tags.js]
 [test_bookmarks_html_singleframe.js]
 [test_bookmarks_restore_notification.js]
 [test_broken_folderShortcut_result.js]
 [test_browserhistory.js]
 [test_childlessTags.js]
 [test_frecency.js]
+skip-if = appname == "thunderbird"
 [test_frecency_decay.js]
 [test_frecency_zero_updated.js]
 [test_getChildIndex.js]
 [test_hash.js]
 [test_history.js]
 [test_history_clear.js]
 [test_history_notifications.js]
 [test_history_observer.js]
--- a/toolkit/components/reader/test/browser_readerMode.js
+++ b/toolkit/components/reader/test/browser_readerMode.js
@@ -167,43 +167,43 @@ add_task(async function test_reader_view
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
   is(menuitem.hidden, true, "menuitem element should have the hidden attribute");
 
   info("Navigate a reader-able page");
   let waitForPageshow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
   await observeAttribute(menuitem, "hidden",
     () => {
       let url = TEST_PATH + "readerModeArticle.html";
-      tab.linkedBrowser.loadURI(url);
+      BrowserTestUtils.loadURI(tab.linkedBrowser, url);
     },
     () => {
       is(menuitem.hidden, false, "menuitem's hidden attribute should be false on a reader-able page");
     }
   );
   await waitForPageshow;
 
   info("Navigate a non-reader-able page");
   waitForPageshow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
   await observeAttribute(menuitem, "hidden",
     () => {
       let url = TEST_PATH + "readerModeArticleHiddenNodes.html";
-      tab.linkedBrowser.loadURI(url);
+      BrowserTestUtils.loadURI(tab.linkedBrowser, url);
     },
     () => {
       is(menuitem.hidden, true, "menuitem's hidden attribute should be true on a non-reader-able page");
     }
   );
   await waitForPageshow;
 
   info("Navigate a reader-able page");
   waitForPageshow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
   await observeAttribute(menuitem, "hidden",
     () => {
       let url = TEST_PATH + "readerModeArticle.html";
-      tab.linkedBrowser.loadURI(url);
+      BrowserTestUtils.loadURI(tab.linkedBrowser, url);
     },
     () => {
       is(menuitem.hidden, false, "menuitem's hidden attribute should be false on a reader-able page");
     }
   );
   await waitForPageshow;
 
   info("Enter Reader Mode");
@@ -230,16 +230,16 @@ add_task(async function test_reader_view
   );
   await waitForPageshow;
 
   info("Navigate a non-reader-able page");
   waitForPageshow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
   await observeAttribute(menuitem, "hidden",
     () => {
       let url = TEST_PATH + "readerModeArticleHiddenNodes.html";
-      tab.linkedBrowser.loadURI(url);
+      BrowserTestUtils.loadURI(tab.linkedBrowser, url);
     },
     () => {
       is(menuitem.hidden, true, "menuitem's hidden attribute should be true on a non-reader-able page");
     }
   );
   await waitForPageshow;
 });
--- a/toolkit/components/reader/test/browser_readerMode_hidden_nodes.js
+++ b/toolkit/components/reader/test/browser_readerMode_hidden_nodes.js
@@ -40,13 +40,13 @@ add_task(async function test_reader_butt
         removeEventListener("DOMContentLoaded", onDCL);
         addEventListener("MozAfterPaint", function onPaint() {
           removeEventListener("MozAfterPaint", onPaint);
           resolve();
         });
       });
     });
   });
-  tab.linkedBrowser.loadURI(url);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, url);
   await paintPromise;
 
   is_element_hidden(readerButton, "Reader mode button is still not present on tab with unreadable content.");
 });
--- a/toolkit/components/remotebrowserutils/RemoteWebNavigation.js
+++ b/toolkit/components/remotebrowserutils/RemoteWebNavigation.js
@@ -91,27 +91,28 @@ RemoteWebNavigation.prototype = {
           principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, attrs);
         }
         Services.io.speculativeConnect2(uri, principal, null);
       } catch (ex) {
         // Can't setup speculative connection for this uri string for some
         // reason (such as failing to parse the URI), just ignore it.
       }
     }
+
     this._sendMessage("WebNavigation:LoadURI", {
       uri: aURI,
       flags: aLoadFlags,
       referrer: aReferrer ? aReferrer.spec : null,
       referrerPolicy: aReferrerPolicy,
       postData: aPostData ? Utils.serializeInputStream(aPostData) : null,
       headers: aHeaders ? Utils.serializeInputStream(aHeaders) : null,
       baseURI: aBaseURI ? aBaseURI.spec : null,
       triggeringPrincipal: aTriggeringPrincipal
                            ? Utils.serializePrincipal(aTriggeringPrincipal)
-                           : null,
+                           : Services.scriptSecurityManager.createNullPrincipal({}),
       requestTime: Services.telemetry.msSystemNow(),
     });
   },
   setOriginAttributesBeforeLoading(aOriginAttributes) {
     this._sendMessage("WebNavigation:SetOriginAttributes", {
       originAttributes: aOriginAttributes,
     });
   },
--- a/toolkit/components/remotepagemanager/tests/browser/browser_RemotePageManager.js
+++ b/toolkit/components/remotepagemanager/tests/browser/browser_RemotePageManager.js
@@ -77,17 +77,17 @@ add_task(async function sharedData_aka_i
 // Test that opening a page creates a port, sends the load event and then
 // navigating to a new page sends the unload event. Going back should create a
 // new port
 add_task(async function init_navigate() {
   let port = await waitForPort(TEST_URL);
   is(port.browser, gBrowser.selectedBrowser, "Port is for the correct browser");
 
   let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.loadURI("about:blank");
+  BrowserTestUtils.loadURI(gBrowser, "about:blank");
 
   await waitForMessage(port, "RemotePage:Unload");
 
   // Port should be destroyed now
   try {
     port.addMessageListener("Foo", failOnMessage);
     ok(false, "Should have seen exception");
   } catch (e) {
--- a/toolkit/components/thumbnails/test/head.js
+++ b/toolkit/components/thumbnails/test/head.js
@@ -102,17 +102,17 @@ function addTab(aURI, aCallback) {
 
 /**
  * Loads a new URI into the currently selected tab.
  * @param aURI The URI to load.
  */
 function navigateTo(aURI) {
   let browser = gBrowser.selectedBrowser;
   BrowserTestUtils.browserLoaded(browser).then(next);
-  browser.loadURI(aURI);
+  BrowserTestUtils.loadURI(browser, aURI);
 }
 
 /**
  * Continues the current test execution when a load event for the given element
  * has been received.
  * @param aElement The DOM element to listen on.
  * @param aCallback The function to call when the load event was dispatched.
  */
--- a/toolkit/components/url-classifier/tests/mochitest/test_donottrack.html
+++ b/toolkit/components/url-classifier/tests/mochitest/test_donottrack.html
@@ -78,17 +78,19 @@ function executeTest(test) {
   var win = mainWindow.OpenBrowserWindow({private: test.setting.pbMode});
 
   return new Promise(function(resolve, reject) {
     win.addEventListener("load", function() {
       TestUtils.topicObserved("browser-delayed-startup-finished",
                               subject => subject == win).then(() => {
         win.addEventListener("DOMContentLoaded", function onInnerLoad() {
           if (win.content.location.href != contentPage) {
-            win.gBrowser.loadURI(contentPage);
+            win.gBrowser.loadURI(contentPage, {
+              triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+            });
             return;
           }
 
           win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
           win.content.addEventListener("message", function(event) {
             let [key, value] = event.data.split("=");
             if (key == "finish") {
@@ -99,17 +101,21 @@ function executeTest(test) {
             } else if (key == "DNT") {
               let msg = test.expected.dnt == "1" ? "" : "not ";
               is(value, test.expected.dnt, "DNT header should " + msg + "be sent");
             } else {
               ok(false, "unexpected message");
             }
           });
         }, true);
-        SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+        SimpleTest.executeSoon(function() {
+          win.gBrowser.loadURI(contentPage, {
+            triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+          });
+        });
       });
     }, {capture: true, once: true});
   });
 }
 
 let loop = function loop(index) {
   if (index >= tests.length) {
     SimpleTest.finish();
--- a/toolkit/components/url-classifier/tests/mochitest/test_fastblock_bug1477046.html
+++ b/toolkit/components/url-classifier/tests/mochitest/test_fastblock_bug1477046.html
@@ -101,17 +101,17 @@ function awaitBrowserLoaded(browser) {
   });
 }
 
 function testOnWindow(resolve, reject) {
   const mainWindow = window.docShell.rootTreeItem.domWindow;
   let win = mainWindow.OpenBrowserWindow({remote: true});
 
   whenDelayedStartupFinished(win, function() {
-    SimpleTest.executeSoon(function() { win.gBrowser.loadURI(gContentPage); });
+    SimpleTest.executeSoon(function() { BrowserTestUtils.loadURI(win.gBrowser, gContentPage); });
     awaitBrowserLoaded(win.gBrowser.selectedBrowser).then(() => {
       resolve(win);
     }).catch((reason) => {
       ok(false, reason);
       reject(reason);
     });
   });
 }
--- a/toolkit/components/url-classifier/tests/mochitest/test_privatebrowsing_trackingprotection.html
+++ b/toolkit/components/url-classifier/tests/mochitest/test_privatebrowsing_trackingprotection.html
@@ -26,30 +26,34 @@ ChromeUtils.import("resource://testing-c
 function testOnWindow(aPrivate) {
   return new Promise((resolve, reject) => {
     let win = mainWindow.OpenBrowserWindow({private: aPrivate});
     win.addEventListener("load", function() {
       TestUtils.topicObserved("browser-delayed-startup-finished",
                               subject => subject == win).then(() => {
         win.addEventListener("DOMContentLoaded", function onInnerLoad() {
           if (win.content.location.href != contentPage) {
-            win.gBrowser.loadURI(contentPage);
+            win.gBrowser.loadURI(contentPage, {
+              triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+            });
             return;
           }
           win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
           win.content.addEventListener("load", function innerLoad2() {
             win.content.removeEventListener("load", innerLoad2);
             SimpleTest.executeSoon(function() {
               resolve(win);
             });
           }, false, true);
         }, true);
         SimpleTest.executeSoon(function() {
-          win.gBrowser.loadURI(contentPage);
+          win.gBrowser.loadURI(contentPage, {
+            triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+          });
         });
       });
     }, {capture: true, once: true});
   });
 }
 
 var badids = [
   "badscript",
--- a/toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1157081.html
+++ b/toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1157081.html
@@ -16,36 +16,39 @@
 
 <script class="testbody" type="text/javascript">
 
 var mainWindow = window.docShell.rootTreeItem.domWindow;
 var contentPage = "chrome://mochitests/content/chrome/toolkit/components/url-classifier/tests/mochitest/classifiedAnnotatedPBFrame.html";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 ChromeUtils.import("resource://testing-common/TestUtils.jsm");
 
 function testOnWindow(aCallback) {
   var win = mainWindow.OpenBrowserWindow();
   win.addEventListener("load", function() {
     TestUtils.topicObserved("browser-delayed-startup-finished",
                             subject => subject == win).then(() => {
       win.addEventListener("DOMContentLoaded", function onInnerLoad() {
         if (win.content.location.href != contentPage) {
-          win.gBrowser.loadURI(contentPage);
+          BrowserTestUtils.loadURI(win.gBrowser, contentPage);
           return;
         }
         win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
         win.content.addEventListener("load", function innerLoad2() {
           win.content.removeEventListener("load", innerLoad2);
           SimpleTest.executeSoon(function() { aCallback(win); });
         }, false, true);
       }, true);
-      SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+      SimpleTest.executeSoon(function() {
+        BrowserTestUtils.loadURI(win.gBrowser, contentPage);
+      });
     });
   }, {capture: true, once: true});
 }
 
 var badids = [
   "badscript",
 ];
 
--- a/toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1312515.html
+++ b/toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1312515.html
@@ -19,36 +19,37 @@
 
 <script class="testbody" type="text/javascript">
 
 var mainWindow = window.docShell.rootTreeItem.domWindow;
 var contentPage = "http://www.itisatrap.org/chrome/toolkit/components/url-classifier/tests/mochitest/trackingRequest.html";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 ChromeUtils.import("resource://testing-common/TestUtils.jsm");
 
 function testOnWindow(aPrivate, aCallback) {
   var win = mainWindow.OpenBrowserWindow({private: aPrivate});
   win.addEventListener("load", function() {
     TestUtils.topicObserved("browser-delayed-startup-finished",
                             subject => subject == win).then(() => {
       win.addEventListener("DOMContentLoaded", function onInnerLoad() {
         if (win.content.location.href != contentPage) {
-          win.gBrowser.loadURI(contentPage);
+          BrowserTestUtils.loadURI(win.gBrowser, contentPage);
           return;
         }
         win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
         win.content.addEventListener("load", function innerLoad2() {
           win.content.removeEventListener("load", innerLoad2);
           SimpleTest.executeSoon(function() { aCallback(win); });
         }, false, true);
       }, true);
-      SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+      SimpleTest.executeSoon(function() { BrowserTestUtils.loadURI(win.gBrowser, contentPage); });
     });
   }, {capture: true, once: true});
 }
 
 const topic = "http-on-before-connect";
 var testUrl;
 var testWindow;
 var resolve;
--- a/toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_whitelist.html
+++ b/toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_whitelist.html
@@ -17,40 +17,41 @@
 <script class="testbody" type="text/javascript">
 
 var mainWindow = window.docShell.rootTreeItem.domWindow;
 var contentPage1 = "http://www.itisatrap.org/tests/toolkit/components/url-classifier/tests/mochitest/whitelistFrame.html";
 var contentPage2 = "http://example.com/tests/toolkit/components/url-classifier/tests/mochitest/whitelistFrame.html";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
+ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
 ChromeUtils.import("resource://testing-common/TestUtils.jsm");
 
 function testOnWindow(contentPage) {
   return new Promise((resolve, reject) => {
     var win = mainWindow.OpenBrowserWindow();
     win.addEventListener("load", function() {
       TestUtils.topicObserved("browser-delayed-startup-finished",
                               subject => subject == win).then(() => {
         win.addEventListener("DOMContentLoaded", function onInnerLoad() {
           if (win.content.location.href != contentPage) {
-            win.gBrowser.loadURI(contentPage);
+            BrowserTestUtils.loadURI(win.gBrowser, contentPage);
             return;
           }
           win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
           win.content.addEventListener("load", function innerLoad2() {
             win.content.removeEventListener("load", innerLoad2);
             SimpleTest.executeSoon(function() {
               resolve(win);
             });
           }, false, true);
         }, true);
         SimpleTest.executeSoon(function() {
-          win.gBrowser.loadURI(contentPage);
+          BrowserTestUtils.loadURI(win.gBrowser, contentPage);
         });
       });
     }, {capture: true, once: true});
   });
 }
 
 var alwaysbadids = [
   "badscript",
--- a/toolkit/components/viewsource/content/viewSource-content.js
+++ b/toolkit/components/viewsource/content/viewSource-content.js
@@ -276,17 +276,17 @@ var ViewSourceContent = {
    * Load some URL in the browser.
    *
    * @param URL
    *        The URL string to load.
    */
   loadSourceFromURL(URL) {
     let loadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
     let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
-    webNav.loadURI(URL, loadFlags, null, null, null);
+    webNav.loadURI(URL, loadFlags, null, null, null, Services.scriptSecurityManager.getSystemPrincipal());
   },
 
   /**
    * This handler is for click events from:
    *   * error page content, which can show up if the user attempts to view the
    *     source of an attack page.
    *   * in-page context menu actions
    */
@@ -599,17 +599,18 @@ var ViewSourceContent = {
 
     // all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl)
     let loadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
     let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET;
     let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
     webNav.loadURIWithOptions(uri, loadFlags,
                               null, referrerPolicy, // referrer
                               null, null, // postData, headers
-                              Services.io.newURI(baseURI));
+                              Services.io.newURI(baseURI),
+                              Services.scriptSecurityManager.getSystemPrincipal());
   },
 
   /**
    * Using special markers left in the serialized source, this helper makes the
    * underlying markup of the selected fragment to automatically appear as
    * selected on the inflated view-source DOM.
    */
   drawSelection() {
--- a/toolkit/content/tests/browser/browser_audioCompeting.js
+++ b/toolkit/content/tests/browser/browser_audioCompeting.js
@@ -53,23 +53,23 @@ add_task(async function setup_test_prefe
       ["dom.ipc.processCount", 1],
     ]});
 });
 
 add_task(async function cross_tabs_audio_competing() {
   info("- open tab 1 in foreground -");
   let tab1 = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                          "about:blank");
-  tab1.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab1.linkedBrowser, PAGE);
   await waitForTabPlayingEvent(tab1, true);
 
   info("- open tab 2 in foreground -");
   let tab2 = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab2.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab2.linkedBrowser, PAGE);
   await waitForTabPlayingEvent(tab1, false);
 
   info("- open tab 3 in foreground -");
   let tab3 = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                          "about:blank");
   await ContentTask.spawn(tab2.linkedBrowser, null,
                           audio_should_keep_playing_even_go_to_background);
 
@@ -82,17 +82,17 @@ add_task(async function cross_tabs_audio
   BrowserTestUtils.removeTab(tab2);
   BrowserTestUtils.removeTab(tab3);
 });
 
 add_task(async function within_one_tab_audio_competing() {
   info("- open tab and play audio1 -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await waitForTabPlayingEvent(tab, true);
 
   info("- play audio2 in the same tab -");
   await ContentTask.spawn(tab.linkedBrowser, null,
                           play_non_autoplay_audio);
 
   info("- remove tab -");
   BrowserTestUtils.removeTab(tab);
--- a/toolkit/content/tests/browser/browser_audioCompeting_onlyForActiveAgent.js
+++ b/toolkit/content/tests/browser/browser_audioCompeting_onlyForActiveAgent.js
@@ -110,17 +110,17 @@ function stop_audio1_from_page() {
       audio1.onpause = null;
       ok(true, "Audio1 stopped playing.");
       resolve();
     };
   });
 }
 
 async function audio_competing_for_active_agent(url, browser) {
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the default suspended state of all audio should be non-suspened -");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_all_audio_suspended);
 
--- a/toolkit/content/tests/browser/browser_autoplay_audibleMediaOccurred.js
+++ b/toolkit/content/tests/browser/browser_autoplay_audibleMediaOccurred.js
@@ -9,17 +9,19 @@ const PAGE = "https://example.com/browse
 add_task(async function testAudibleAutoplayMedia() {
   info("- open new tab  -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
   let browser = tab.linkedBrowser;
 
   // start observing the topic before loading the page to ensure we can get it.
   let audibleAutoplayOccurred = TestUtils.topicObserved("AudibleAutoplayMediaOccurred");
-  browser.loadURI(PAGE);
+  browser.loadURI(PAGE, {
+    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+  });
 
   await BrowserTestUtils.browserLoaded(browser);
   await audibleAutoplayOccurred;
   ok(true, "Got the topic 'AudibleAutoplayMediaOccurred'.");
 
   info("- remove tab -");
   BrowserTestUtils.removeTab(tab);
 });
--- a/toolkit/content/tests/browser/browser_autoplay_policy_iframe_hierarchy.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_iframe_hierarchy.js
@@ -40,17 +40,17 @@ var frameTestArray = [
 ];
 
 async function test_permission_propagation(testName, testSrc, layersNum) {
   info(`- start test for ${testName} -`);
   for (let layerIdx = 1; layerIdx <= layersNum; layerIdx++) {
     info("- open new tab -");
     let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                           "about:blank");
-    tab.linkedBrowser.loadURI(testSrc);
+    BrowserTestUtils.loadURI(tab.linkedBrowser, testSrc);
     await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
     // If the frame isn't activated, the video play will fail.
     async function playing_video_should_fail(layersNum) {
       for (let layerIdx = 1; layerIdx <= layersNum; layerIdx++) {
         let doc;
         if (layerIdx == 1) {
           doc = content.document;
--- a/toolkit/content/tests/browser/browser_autoplay_policy_play_twice.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_play_twice.js
@@ -8,17 +8,17 @@ function setup_test_preference(enableUse
     ["media.autoplay.enabled.user-gestures-needed", enableUserGesture],
   ]});
 }
 
 async function allow_play_for_played_video() {
   info("- open new tab  -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab.linkedBrowser.loadURI(VIDEO_PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, VIDEO_PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- simulate user-click to start video -");
   await BrowserTestUtils.synthesizeMouseAtCenter("#v", {button: 0},
                                                  tab.linkedBrowser);
 
   async function play_video_again() {
     let video = content.document.getElementById("v");
--- a/toolkit/content/tests/browser/browser_autoplay_policy_user_gestures.js
+++ b/toolkit/content/tests/browser/browser_autoplay_policy_user_gestures.js
@@ -39,17 +39,17 @@ function simulateUserGesture(gesture, ta
       return false;
   }
 }
 
 async function test_play_without_user_gesture() {
   info("- open new tab -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab.linkedBrowser.loadURI(VIDEO_PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, VIDEO_PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   async function check_autoplay_keyword() {
     info("- create an new autoplay video -");
     let video = content.document.createElement("video");
     video.src = "gizmo.mp4";
     video.autoplay = true;
     let canplayPromise = new Promise(function(resolve) {
@@ -77,17 +77,17 @@ async function test_play_without_user_ge
   info("- remove tab -");
   BrowserTestUtils.removeTab(tab);
 }
 
 async function test_play_with_user_gesture(gesture) {
   info("- open new tab -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab.linkedBrowser.loadURI(VIDEO_PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, VIDEO_PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- simulate user gesture -");
   await simulateUserGesture(gesture, tab.linkedBrowser);
 
   info("- call play() -");
   async function play_video(gesture) {
     let video = content.document.getElementById("v");
--- a/toolkit/content/tests/browser/browser_autoscroll_disabled.js
+++ b/toolkit/content/tests/browser/browser_autoscroll_disabled.js
@@ -2,17 +2,17 @@ add_task(async function() {
   const kPrefName_AutoScroll = "general.autoScroll";
   Services.prefs.setBoolPref(kPrefName_AutoScroll, false);
 
   let dataUri = 'data:text/html,<html><body id="i" style="overflow-y: scroll"><div style="height: 2000px"></div>\
       <iframe id="iframe" style="display: none;"></iframe>\
 </body></html>';
 
   let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.loadURI(dataUri);
+  BrowserTestUtils.loadURI(gBrowser, dataUri);
   await loadedPromise;
 
   await BrowserTestUtils.synthesizeMouse("#i", 50, 50, { button: 1 },
                                          gBrowser.selectedBrowser);
 
   await ContentTask.spawn(gBrowser.selectedBrowser, { }, async function() {
     var iframe = content.document.getElementById("iframe");
 
--- a/toolkit/content/tests/browser/browser_block_autoplay_media.js
+++ b/toolkit/content/tests/browser/browser_block_autoplay_media.js
@@ -34,25 +34,25 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_autoplay_media() {
   info("- open new background tab1 -");
   let tab1 = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab1.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab1.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
 
   info("- should block autoplay media for non-visited tab1 -");
   await check_audio_suspended(tab1.linkedBrowser, SuspendedType.SUSPENDED_BLOCK);
 
   info("- open new background tab2 -");
   let tab2 = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab2.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab2.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
 
   info("- should block autoplay for non-visited tab2 -");
   await check_audio_suspended(tab2.linkedBrowser, SuspendedType.SUSPENDED_BLOCK);
 
   info("- select tab1 as foreground tab -");
   await BrowserTestUtils.switchTab(window.gBrowser, tab1);
 
@@ -86,28 +86,28 @@ add_task(async function block_autoplay_m
   await SpecialPowers.pushPrefEnv({"set": [
     ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.PROMPT],
     ["media.autoplay.enabled.user-gestures-needed", true],
     ["media.autoplay.ask-permission", true],
   ]});
 
   info("- open new background tab4 -");
   let tab4 = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab4.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab4.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab4.linkedBrowser);
   info("- should block autoplay for non-visited tab4 -");
   await check_audio_suspended(tab4.linkedBrowser, SuspendedType.SUSPENDED_BLOCK);
   await check_audio_paused(tab4.linkedBrowser, true);
   tab4.linkedBrowser.resumeMedia();
   info("- should not block media from tab4 -");
   await waitForTabPlayingEvent(tab4, true);
   await check_audio_paused(tab4.linkedBrowser, false);
 
   info("- check that loading a new URI in page clears gesture activation status -");
-  tab4.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab4.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab4.linkedBrowser);
   info("- should block autoplay again as gesture activation status cleared -");
   await check_audio_paused(tab4.linkedBrowser, true);
 
   info("- remove tabs -");
   BrowserTestUtils.removeTab(tab1);
   BrowserTestUtils.removeTab(tab2);
   BrowserTestUtils.removeTab(tab3);
--- a/toolkit/content/tests/browser/browser_block_autoplay_media_pausedAfterPlay.js
+++ b/toolkit/content/tests/browser/browser_block_autoplay_media_pausedAfterPlay.js
@@ -33,27 +33,27 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_autoplay_media() {
   info("- open new background tab1, and check tab1's media suspend type -");
   let tab1 = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab1.linkedBrowser.loadURI(PAGE_SHOULD_NOT_PLAY);
+  BrowserTestUtils.loadURI(tab1.linkedBrowser, PAGE_SHOULD_NOT_PLAY);
   await BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
   await ContentTask.spawn(tab1.linkedBrowser, SuspendedType.NONE_SUSPENDED,
                           check_audio_suspended);
 
   info("- the tab1 should not be blocked -");
   await waitForTabBlockEvent(tab1, false);
 
   info("- open new background tab2, and check tab2's media suspend type -");
   let tab2 = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab2.linkedBrowser.loadURI(PAGE_SHOULD_PLAY);
+  BrowserTestUtils.loadURI(tab2.linkedBrowser, PAGE_SHOULD_PLAY);
   await BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
   await ContentTask.spawn(tab2.linkedBrowser, SuspendedType.SUSPENDED_BLOCK,
                           check_audio_suspended);
 
   info("- the tab2 should be blocked -");
   await waitForTabBlockEvent(tab2, true);
 
   info("- select tab1 as foreground tab, and tab1's media should be paused -");
--- a/toolkit/content/tests/browser/browser_block_autoplay_playAfterTabVisible.js
+++ b/toolkit/content/tests/browser/browser_block_autoplay_playAfterTabVisible.js
@@ -54,17 +54,17 @@ add_task(async function setup_test_prefe
 /**
  * This test is used for testing the visible tab which was not resumed yet.
  * If the tab doesn't have any media component, it won't be resumed even it
  * has already gone to foreground until we start audio.
  */
 add_task(async function media_should_be_able_to_play_in_visible_tab() {
   info("- open new background tab, and check tab's media pause state -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   await ContentTask.spawn(tab.linkedBrowser, true,
                           check_audio_pause_state);
 
   info("- select tab as foreground tab, and tab's media should still be paused -");
   await BrowserTestUtils.switchTab(window.gBrowser, tab);
   await ContentTask.spawn(tab.linkedBrowser, true,
                           check_audio_pause_state);
--- a/toolkit/content/tests/browser/browser_block_multipleMedia.js
+++ b/toolkit/content/tests/browser/browser_block_multipleMedia.js
@@ -81,17 +81,17 @@ add_task(async function setup_test_prefe
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_multiple_media() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
-  browser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(browser, PAGE);
   await BrowserTestUtils.browserLoaded(browser);
 
   info("- tab should be blocked -");
   await waitForTabBlockEvent(tab, true);
 
   info("- autoplay media should be blocked -");
   await ContentTask.spawn(browser, SuspendedType.SUSPENDED_BLOCK,
                                    check_autoplay_audio_suspended);
--- a/toolkit/content/tests/browser/browser_block_notInTreeAudio.js
+++ b/toolkit/content/tests/browser/browser_block_notInTreeAudio.js
@@ -48,17 +48,17 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_not_in_tree_media() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- tab should not be blocked -");
   await waitForTabBlockEvent(tab, false);
 
   info("- check audio's suspend state -");
   await ContentTask.spawn(tab.linkedBrowser, SuspendedType.NONE_SUSPENDED,
                           check_audio_suspended);
--- a/toolkit/content/tests/browser/browser_block_playMediaInMuteTab.js
+++ b/toolkit/content/tests/browser/browser_block_playMediaInMuteTab.js
@@ -59,17 +59,17 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function unblock_icon_should_disapear_after_resume_tab() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- audio doesn't be started in beginning -");
   await ContentTask.spawn(tab.linkedBrowser, true,
                           check_audio_pause_state);
 
   info("- audio shouldn't be muted or blocked -");
   await ContentTask.spawn(tab.linkedBrowser, SuspendedType.NONE_SUSPENDED,
--- a/toolkit/content/tests/browser/browser_block_plugIn.js
+++ b/toolkit/content/tests/browser/browser_block_plugIn.js
@@ -6,17 +6,17 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_plug_in() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- tab should be blocked -");
   await waitForTabBlockEvent(tab, true);
 
   info("- switch tab -");
   await BrowserTestUtils.switchTab(window.gBrowser, tab);
 
--- a/toolkit/content/tests/browser/browser_block_silentAudioTrack_media.js
+++ b/toolkit/content/tests/browser/browser_block_silentAudioTrack_media.js
@@ -30,17 +30,17 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function unblock_icon_should_disapear_after_resume_tab() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- the suspend state of tab should be suspend-block -");
   await ContentTask.spawn(tab.linkedBrowser, SuspendedType.SUSPENDED_BLOCK,
                           check_audio_suspended);
 
   info("- tab should display unblocking icon -");
   await waitForTabBlockEvent(tab, true);
@@ -60,17 +60,17 @@ add_task(async function unblock_icon_sho
 
   info("- remove tab -");
   BrowserTestUtils.removeTab(tab);
 });
 
 add_task(async function should_not_show_sound_indicator_after_resume_tab() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- the suspend state of tab should be suspend-block -");
   await ContentTask.spawn(tab.linkedBrowser, SuspendedType.SUSPENDED_BLOCK,
                           check_audio_suspended);
 
   info("- tab should display unblocking icon -");
   await waitForTabBlockEvent(tab, true);
--- a/toolkit/content/tests/browser/browser_block_webAudio.js
+++ b/toolkit/content/tests/browser/browser_block_webAudio.js
@@ -12,17 +12,17 @@ add_task(async function setup_test_prefe
     ["media.useAudioChannelService.testing", true],
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_web_audio() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- tab should be blocked -");
   await waitForTabBlockEvent(tab, true);
 
   info("- switch tab -");
   await BrowserTestUtils.switchTab(window.gBrowser, tab);
 
--- a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
+++ b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
@@ -87,17 +87,17 @@ body > div > div {width: 1000px;height: 
 </body></html>'},
     {elem: "r", expected: expectScrollNone, testwindow: true, middlemousepastepref: true},
     {elem: "s", expected: expectScrollNone, testwindow: true, middlemousepastepref: true},
   ];
 
   for (let test of allTests) {
     if (test.dataUri) {
       let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-      gBrowser.loadURI(test.dataUri);
+      BrowserTestUtils.loadURI(gBrowser, test.dataUri);
       await loadedPromise;
       continue;
      }
 
     let prefsChanged = "middlemousepastepref" in test;
     if (prefsChanged) {
       await pushPrefs([["middlemouse.paste", test.middlemousepastepref]]);
     }
--- a/toolkit/content/tests/browser/browser_content_url_annotation.js
+++ b/toolkit/content/tests/browser/browser_content_url_annotation.js
@@ -55,17 +55,17 @@ add_task(async function test_content_url
       await new Promise((resolve) => {
         addEventListener("RedirectDone", function listener() {
           dump("Got RedirectDone\n");
           removeEventListener("RedirectDone", listener);
           resolve();
         }, true, true);
       });
     });
-    browser.loadURI(url);
+    BrowserTestUtils.loadURI(browser, url);
     await promise;
 
     // Crash the tab
     let annotations = await BrowserTestUtils.crashBrowser(browser);
 
     ok("URL" in annotations, "annotated a URL");
     is(annotations.URL, redirect_url,
        "Should have annotated the URL after redirect");
--- a/toolkit/content/tests/browser/browser_isSynthetic.js
+++ b/toolkit/content/tests/browser/browser_isSynthetic.js
@@ -39,23 +39,23 @@ add_task(async function() {
   let tab = BrowserTestUtils.addTab(gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
   await BrowserTestUtils.browserLoaded(browser);
   let listener = new LocationChangeListener(browser);
 
   is(browser.isSyntheticDocument, false, "Should not be synthetic");
 
   let loadPromise = waitForPageShow(browser);
-  browser.loadURI("data:text/html;charset=utf-8,<html/>");
+  BrowserTestUtils.loadURI(browser, "data:text/html;charset=utf-8,<html/>");
   await loadPromise;
   is(listener.wasSynthetic, false, "Should not be synthetic");
   is(browser.isSyntheticDocument, false, "Should not be synthetic");
 
   loadPromise = waitForPageShow(browser);
-  browser.loadURI(FILES + "empty.png");
+  BrowserTestUtils.loadURI(browser, FILES + "empty.png");
   await loadPromise;
   is(listener.wasSynthetic, true, "Should be synthetic");
   is(browser.isSyntheticDocument, true, "Should be synthetic");
 
   loadPromise = waitForPageShow(browser);
   browser.goBack();
   await loadPromise;
   is(listener.wasSynthetic, false, "Should not be synthetic");
--- a/toolkit/content/tests/browser/browser_keyevents_during_autoscrolling.js
+++ b/toolkit/content/tests/browser/browser_keyevents_during_autoscrolling.js
@@ -57,17 +57,17 @@ add_task(async function() {
     }
     dispatchedKeyEvents |= keyFlag;
     is(keyFlag, expectedKeyEvents & keyFlag, aEvent.type + " fired: " + key);
   }
 
   var dataUri = 'data:text/html,<body style="height:10000px;"></body>';
 
   let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-  gBrowser.loadURI(dataUri);
+  BrowserTestUtils.loadURI(gBrowser, dataUri);
   await loadedPromise;
 
   await SimpleTest.promiseFocus(gBrowser.selectedBrowser);
 
   window.addEventListener("keydown", onKey);
   window.addEventListener("keypress", onKey);
   window.addEventListener("keyup", onKey);
 
--- a/toolkit/content/tests/browser/browser_mediaPlayback.js
+++ b/toolkit/content/tests/browser/browser_mediaPlayback.js
@@ -5,17 +5,17 @@ function wait_for_event(browser, event) 
   return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
     is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
     ok(!event.cancelable, "The event should not be cancelable");
     return true;
   });
 }
 
 async function test_on_browser(url, browser) {
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
   await wait_for_event(browser, "DOMAudioPlaybackStopped");
 }
 
 add_task(async function test_page() {
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: "about:blank",
--- a/toolkit/content/tests/browser/browser_mediaPlayback_mute.js
+++ b/toolkit/content/tests/browser/browser_mediaPlayback_mute.js
@@ -27,17 +27,17 @@ function test_audio_in_browser() {
   var audio = get_audio_element();
   return {
     computedVolume: audio.computedVolume,
     computedMuted: audio.computedMuted,
   };
 }
 
 async function test_on_browser(url, browser) {
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   var result = await ContentTask.spawn(browser, null, test_audio_in_browser);
   is(result.computedVolume, 1, "Audio volume is 1");
   is(result.computedMuted, false, "Audio is not muted");
 
   ok(!browser.audioMuted, "Audio should not be muted by default");
   browser.mute();
@@ -46,17 +46,17 @@ async function test_on_browser(url, brow
   await wait_for_event(browser, "DOMAudioPlaybackStopped");
 
   result = await ContentTask.spawn(browser, null, test_audio_in_browser);
   is(result.computedVolume, 0, "Audio volume is 0 when muted");
   is(result.computedMuted, true, "Audio is muted");
 }
 
 async function test_visibility(url, browser) {
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   var result = await ContentTask.spawn(browser, null, test_audio_in_browser);
   is(result.computedVolume, 1, "Audio volume is 1");
   is(result.computedMuted, false, "Audio is not muted");
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
--- a/toolkit/content/tests/browser/browser_mediaPlayback_suspended.js
+++ b/toolkit/content/tests/browser/browser_mediaPlayback_suspended.js
@@ -36,17 +36,17 @@ function check_audio_pause_state(expecte
     is(audio.paused, true, "Audio is paused correctly.");
   } else {
     is(audio.paused, false, "Audio is resumed correctly.");
   }
 }
 
 async function suspended_pause(url, browser) {
   info("### Start test for suspended-pause ###");
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the suspended state of audio should be non-suspened -");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_audio_suspended);
 
@@ -62,17 +62,17 @@ async function suspended_pause(url, brow
   await ContentTask.spawn(browser, false /* expect for playing */,
                                    check_audio_pause_state);
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_audio_suspended);
 }
 
 async function suspended_pause_disposable(url, browser) {
   info("### Start test for suspended-pause-disposable ###");
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the suspended state of audio should be non-suspened -");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_audio_suspended);
 
@@ -88,17 +88,17 @@ async function suspended_pause_disposabl
   await ContentTask.spawn(browser, false /* expect for playing */,
                                    check_audio_pause_state);
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_audio_suspended);
 }
 
 async function suspended_stop_disposable(url, browser) {
   info("### Start test for suspended-stop-disposable ###");
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the suspended state of audio should be non-suspened -");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_audio_suspended);
 
--- a/toolkit/content/tests/browser/browser_mediaPlayback_suspended_multipleAudio.js
+++ b/toolkit/content/tests/browser/browser_mediaPlayback_suspended_multipleAudio.js
@@ -133,17 +133,17 @@ function no_audio_resumed() {
     ok(false, "Can't get the audio element!");
   }
 
   is(autoPlay.paused && nonAutoPlay.paused, true, "No audio was resumed.");
 }
 
 async function suspended_pause(url, browser) {
   info("### Start test for suspended-pause ###");
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the default suspended state of all audio should be non-suspened-");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_all_audio_suspended);
 
@@ -171,17 +171,17 @@ async function suspended_pause(url, brow
 
   info("- both audio should be paused at the same time -");
   browser.pauseMedia(false /* non-disposable */);
   await ContentTask.spawn(browser, null, all_audio_onpause);
 }
 
 async function suspended_pause_disposable(url, browser) {
   info("### Start test for suspended-pause-disposable ###");
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the default suspended state of all audio should be non-suspened -");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_all_audio_suspended);
 
@@ -203,17 +203,17 @@ async function suspended_pause_disposabl
   await ContentTask.spawn(browser, false /* expect for playing */,
                                    check_autoplay_audio_pause_state);
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_all_audio_suspended);
 }
 
 async function suspended_stop_disposable(url, browser) {
   info("### Start test for suspended-stop-disposable ###");
-  browser.loadURI(url);
+  BrowserTestUtils.loadURI(browser, url);
 
   info("- page should have playing audio -");
   await wait_for_event(browser, "DOMAudioPlaybackStarted");
 
   info("- the default suspended state of all audio should be non-suspened -");
   await ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
                                    check_all_audio_suspended);
 
--- a/toolkit/content/tests/browser/browser_mute_plugIn.js
+++ b/toolkit/content/tests/browser/browser_mute_plugIn.js
@@ -33,17 +33,17 @@ add_task(async function setup_test_prefe
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function block_plug_in() {
   info("- open new tab -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- tab should be audible -");
   await waitForTabPlayingEvent(tab, true);
 
   info("- mute browser -");
   ok(!tab.linkedBrowser.audioMuted, "Audio should not be muted by default");
   await click_icon(tab);
--- a/toolkit/content/tests/browser/browser_mute_webAudio.js
+++ b/toolkit/content/tests/browser/browser_mute_webAudio.js
@@ -40,17 +40,17 @@ add_task(async function setup_test_prefe
     ["media.block-autoplay-until-in-foreground", true],
   ]});
 });
 
 add_task(async function mute_web_audio() {
   info("- open new tab -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
-  tab.linkedBrowser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("- tab should be audible -");
   await waitForTabPlayingEvent(tab, true);
 
   info("- mute browser -");
   ok(!tab.linkedBrowser.audioMuted, "Audio should not be muted by default");
   await click_icon(tab);
--- a/toolkit/content/tests/browser/browser_resume_bkg_video_on_tab_hover.js
+++ b/toolkit/content/tests/browser/browser_resume_bkg_video_on_tab_hover.js
@@ -102,17 +102,17 @@ add_task(async function setup_test_prefe
  */
 add_task(async function resume_and_suspend_background_video_decoding() {
   info("- open new background tab -");
   let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
   let browser = tab.linkedBrowser;
 
   info("- before loading media, we shoudn't send the tab hover msg for tab -");
   await check_should_not_send_unselected_tab_hover_msg(browser);
-  browser.loadURI(PAGE);
+  BrowserTestUtils.loadURI(browser, PAGE);
   await BrowserTestUtils.browserLoaded(browser);
 
   info("- should suspend background video decoding -");
   await get_video_decoding_suspend_promise(browser, true);
   await check_should_send_unselected_tab_hover_msg(browser);
 
   info("- when cursor is hovering over the tab, resuming the video decoding -");
   let promise = get_video_decoding_resume_promise(browser);
--- a/toolkit/content/tests/browser/browser_save_resend_postdata.js
+++ b/toolkit/content/tests/browser/browser_save_resend_postdata.js
@@ -12,17 +12,17 @@ MockFilePicker.init(window);
  *
  * Test for bug 485196 <https://bugzilla.mozilla.org/show_bug.cgi?id=485196>:
  * Web page generated by POST is retried as GET when Save Frame As used, and the
  * page is no longer in the cache.
  */
 function test() {
   waitForExplicitFinish();
 
-  gBrowser.loadURI("http://mochi.test:8888/browser/toolkit/content/tests/browser/data/post_form_outer.sjs");
+  BrowserTestUtils.loadURI(gBrowser, "http://mochi.test:8888/browser/toolkit/content/tests/browser/data/post_form_outer.sjs");
 
   gBrowser.addEventListener("pageshow", function pageShown(event) {
     if (event.target.location == "about:blank")
       return;
     gBrowser.removeEventListener("pageshow", pageShown);
 
     // Submit the form in the outer page, then wait for both the outer
     // document and the inner frame to be loaded again.
--- a/toolkit/content/tests/browser/browser_sound_indicator_silent_video.js
+++ b/toolkit/content/tests/browser/browser_sound_indicator_silent_video.js
@@ -28,17 +28,17 @@ add_task(async function should_not_show_
   info("- open new foreground tab -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
 
   info("- tab should not have sound indicator before playing silent video -");
   await waitForTabPlayingEvent(tab, false);
 
   info("- loading autoplay silent video -");
-  tab.linkedBrowser.loadURI(SILENT_PAGE);
+  BrowserTestUtils.loadURI(tab.linkedBrowser, SILENT_PAGE);
   await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   await ContentTask.spawn(tab.linkedBrowser, true /* playing */,
                           check_audio_playing_state);
 
   info("- tab should not have sound indicator after playing silent video -");
   await waitForTabPlayingEvent(tab, false);
 
   info("- remove tab -");
@@ -49,17 +49,17 @@ add_task(async function should_not_show_
   info("- open new foreground tab -");
   let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser,
                                                         "about:blank");
 
   info("- tab should not have sound indica