Backed out changeset 1d5e6c22fd3a (bug 1250048) for CSP failures/assertions in various tests/chunks CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Mon, 21 Mar 2016 12:42:36 -0700
changeset 289758 b8360b8b360f937dcf8147f943c485508e1fb4ee
parent 289757 f17a9b5483168647a9c50cd2ab0ef1534d9d0715
child 289759 272ec90eff7159e1c04a7aa588e4fc74e34873b0
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1250048
milestone48.0a1
backs out1d5e6c22fd3a5254e06fbbfe1f808481b931b85f
Backed out changeset 1d5e6c22fd3a (bug 1250048) for CSP failures/assertions in various tests/chunks CLOSED TREE MozReview-Commit-ID: I21ELiYYqdD
dom/fetch/InternalRequest.cpp
dom/manifest/ManifestObtainer.jsm
dom/security/nsContentSecurityManager.cpp
dom/security/test/csp/browser.ini
dom/security/test/csp/browser_manifest-src-override-default-src.js
dom/security/test/csp/browser_test_web_manifest.js
dom/security/test/csp/browser_test_web_manifest_mixed_content.js
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -34,17 +34,17 @@ InternalRequest::GetRequestConstructorCo
   // The "client" is not stored in our implementation. Fetch API users should
   // use the appropriate window/document/principal and other Gecko security
   // mechanisms as appropriate.
   copy->mSameOriginDataURL = true;
   copy->mPreserveContentCodings = true;
   // The default referrer is already about:client.
   copy->mReferrerPolicy = mReferrerPolicy;
 
-  copy->mContentPolicyType = mContentPolicyType;
+  copy->mContentPolicyType = nsIContentPolicy::TYPE_FETCH;
   copy->mMode = mMode;
   copy->mCredentialsMode = mCredentialsMode;
   copy->mCacheMode = mCacheMode;
   copy->mRedirectMode = mRedirectMode;
   copy->mCreatedByFetchEvent = mCreatedByFetchEvent;
   return copy.forget();
 }
 
--- a/dom/manifest/ManifestObtainer.jsm
+++ b/dom/manifest/ManifestObtainer.jsm
@@ -61,22 +61,17 @@ this.ManifestObtainer = { // jshint igno
    * Public interface for obtaining a web manifest from a XUL browser.
    * @param  {Window} The content Window from which to extract the manifest.
    * @return {Promise<Object>} The processed manifest.
    */
   contentObtainManifest: Task.async(function* (aContent) {
     if (!aContent || isXULBrowser(aContent)) {
       throw new TypeError("Invalid input. Expected a DOM Window.");
     }
-    let manifest;
-    try {
-      manifest = yield fetchManifest(aContent);
-    } catch (err) {
-      throw err;
-    }
+    const manifest = yield fetchManifest(aContent);
     return manifest;
   }
 )};
 
 function toError(aErrorClone) {
   let error;
   switch (aErrorClone.name) {
   case "TypeError":
@@ -134,27 +129,47 @@ const fetchManifest = Task.async(functio
   }
   const elem = aWindow.document.querySelector("link[rel~='manifest']");
   if (!elem || !elem.getAttribute("href")) {
     let msg = `No manifest to fetch at ${aWindow.location}`;
     throw new Error(msg);
   }
   // Throws on malformed URLs
   const manifestURL = new aWindow.URL(elem.href, elem.baseURI);
+  if (!canLoadManifest(elem)) {
+    let msg = `Content Security Policy: The page's settings blocked the `;
+    msg += `loading of a resource at ${elem.href}`;
+    throw new Error(msg);
+  }
   const reqInit = {
     mode: "cors"
   };
   if (elem.crossOrigin === "use-credentials") {
     reqInit.credentials = "include";
   }
-  const request = new aWindow.Request(manifestURL, reqInit);
-  let response;
-  request.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
-  try {
-    response = yield aWindow.fetch(request);
-  } catch (err) {
-    throw err;
-  }
+  const req = new aWindow.Request(manifestURL, reqInit);
+  req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
+  const response = yield aWindow.fetch(req);
   const manifest = yield processResponse(response, aWindow);
   return manifest;
 });
 
+/**
+ * Checks against security manager if we can load the web manifest.
+ * @param  {HTMLLinkElement} aElem The HTML element to security check.
+ * @return {Boolean} True if it can, false if it can't.
+ */
+function canLoadManifest(aElem) {
+  const contentPolicy = Cc["@mozilla.org/layout/content-policy;1"]
+    .getService(Ci.nsIContentPolicy);
+  const mimeType = aElem.type || "application/manifest+json";
+  const elemURI = BrowserUtils.makeURI(
+    aElem.href, aElem.ownerDocument.characterSet
+  );
+  const shouldLoad = contentPolicy.shouldLoad(
+    Ci.nsIContentPolicy.TYPE_WEB_MANIFEST, elemURI,
+    aElem.ownerDocument.documentURIObject,
+    aElem, mimeType, null
+  );
+  return shouldLoad === Ci.nsIContentPolicy.ACCEPT;
+}
+
 this.EXPORTED_SYMBOLS = ["ManifestObtainer"]; // jshint ignore:line
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -283,22 +283,16 @@ DoContentSecurityChecks(nsIURI* aURI, ns
       break;
     }
 
     case nsIContentPolicy::TYPE_IMAGESET: {
       MOZ_ASSERT(false, "contentPolicyType not supported yet");
       break;
     }
 
-    case nsIContentPolicy::TYPE_WEB_MANIFEST: {
-      mimeTypeGuess = EmptyCString();
-      requestingContext = aLoadInfo->LoadingNode();
-      break;
-    }
-
     default:
       // nsIContentPolicy::TYPE_INVALID
       MOZ_ASSERT(false, "can not perform security check without a valid contentType");
   }
 
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
   nsresult rv = NS_CheckContentLoadPolicy(internalContentPolicyType,
                                           aURI,
--- a/dom/security/test/csp/browser.ini
+++ b/dom/security/test/csp/browser.ini
@@ -1,4 +1,3 @@
 [DEFAULT]
 [browser_test_web_manifest.js]
 [browser_test_web_manifest_mixed_content.js]
-[browser_manifest-src-override-default-src.js]
deleted file mode 100644
--- a/dom/security/test/csp/browser_manifest-src-override-default-src.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Description of the tests:
- * Tests check that default-src can be overridden by manifest-src.
- */
-/*globals Cu, is, ok*/
-"use strict";
-const {
-  ManifestObtainer
-} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
-const path = "/tests/dom/security/test/csp/";
-const testFile = `${path}file_web_manifest.html`;
-const mixedContentFile = `${path}file_web_manifest_mixed_content.html`;
-const server = `${path}file_testserver.sjs`;
-const defaultURL = new URL(`http://example.org${server}`);
-const mixedURL = new URL(`http://mochi.test:8888${server}`);
-const tests = [
-  // Check interaction with default-src and another origin,
-  // CSP allows fetching from example.org, so manifest should load.
-  {
-    expected: `CSP manifest-src overrides default-src of elsewhere.com`,
-    get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("cors", "*");
-      url.searchParams.append("csp", "default-src http://elsewhere.com; manifest-src http://example.org");
-      return url.href;
-    },
-    run(manifest) {
-      is(manifest.name, "loaded", this.expected);
-    }
-  },
-  // Check interaction with default-src none,
-  // CSP allows fetching manifest from example.org, so manifest should load.
-  {
-    expected: `CSP manifest-src overrides default-src`,
-    get tabURL() {
-      const url = new URL(mixedURL);
-      url.searchParams.append("file", mixedContentFile);
-      url.searchParams.append("cors", "http://test:80");
-      url.searchParams.append("csp", "default-src 'self'; manifest-src http://test:80");
-      return url.href;
-    },
-    run(manifest) {
-      is(manifest.name, "loaded", this.expected);
-    }
-  },
-];
-
-//jscs:disable
-add_task(function* () {
-  //jscs:enable
-  const testPromises = tests.map((test) => {
-    const tabOptions = {
-      gBrowser,
-      url: test.tabURL,
-      skipAnimation: true,
-    };
-    return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
-  });
-  yield Promise.all(testPromises);
-});
-
-function* testObtainingManifest(aBrowser, aTest) {
-  const expectsBlocked = aTest.expected.includes("block");
-  const observer = (expectsBlocked) ? createNetObserver(aTest) : null;
-  // Expect an exception (from promise rejection) if there a content policy
-  // that is violated.
-  try {
-    const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
-    aTest.run(manifest);
-  } catch (e) {
-    const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
-    ok(wasBlocked,`Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
-    if (observer) {
-      yield observer.untilFinished;
-    }
-  }
-}
-
-// Helper object used to observe policy violations. It waits 1 seconds
-// for a response, and then times out causing its associated test to fail.
-function createNetObserver(test) {
-  let finishedTest;
-  let success = false;
-  const finished = new Promise((resolver) => {
-    finishedTest = resolver;
-  });
-  const timeoutId = setTimeout(() => {
-    if (!success) {
-      test.run("This test timed out.");
-      finishedTest();
-    }
-  }, 1000);
-  var observer = {
-    get untilFinished(){
-      return finished;
-    },
-    observe(subject, topic) {
-      SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
-      test.run(topic);
-      finishedTest();
-      clearTimeout(timeoutId);
-      success = true;
-    },
-  };
-  SpecialPowers.addObserver(observer, "csp-on-violate-policy", false);
-  return observer;
-}
--- a/dom/security/test/csp/browser_test_web_manifest.js
+++ b/dom/security/test/csp/browser_test_web_manifest.js
@@ -1,237 +1,249 @@
 /*
  * Description of the tests:
  *   These tests check for conformance to the CSP spec as they relate to Web Manifests.
  *
  *   In particular, the tests check that default-src and manifest-src directives are
  *   are respected by the ManifestObtainer.
  */
 /*globals Cu, is, ok*/
-"use strict";
+'use strict';
+requestLongerTimeout(10); // e10s tests take time.
 const {
   ManifestObtainer
-} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
-const path = "/tests/dom/security/test/csp/";
-const testFile = `${path}file_web_manifest.html`;
-const remoteFile = `${path}file_web_manifest_remote.html`;
-const httpsManifest = `${path}file_web_manifest_https.html`;
-const server = `${path}file_testserver.sjs`;
-const defaultURL = new URL(`http://example.org${server}`);
-const secureURL = new URL(`https://example.com:443${server}`);
+} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
+const path = '/tests/dom/security/test/csp/';
+const testFile = `file=${path}file_web_manifest.html`;
+const remoteFile = `file=${path}file_web_manifest_remote.html`;
+const httpsManifest = `file=${path}file_web_manifest_https.html`;
+const server = 'file_testserver.sjs';
+const defaultURL = `http://example.org${path}${server}`;
+const secureURL = `https://example.com:443${path}${server}`;
 const tests = [
   // CSP block everything, so trying to load a manifest
   // will result in a policy violation.
   {
-    expected: "default-src 'none' blocks fetching manifest.",
+    expected: `default-src 'none' blocks fetching manifest.`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("csp", "default-src 'none'");
-      return url.href;
+      let queryParts = [
+        `csp=default-src 'none'`,
+        testFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(topic) {
-      is(topic, "csp-on-violate-policy", this.expected);
+      is(topic, 'csp-on-violate-policy', this.expected);
     }
   },
   // CSP allows fetching only from mochi.test:8888,
   // so trying to load a manifest from same origin
   // triggers a CSP violation.
   {
-    expected: "default-src mochi.test:8888 blocks manifest fetching.",
+    expected: `default-src mochi.test:8888 blocks manifest fetching.`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("csp", "default-src mochi.test:8888");
-      return url.href;
+      let queryParts = [
+        `csp=default-src mochi.test:8888`,
+        testFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(topic) {
-      is(topic, "csp-on-violate-policy", this.expected);
+      is(topic, 'csp-on-violate-policy', this.expected);
     }
   },
   // CSP restricts fetching to 'self', so allowing the manifest
   // to load. The name of the manifest is then checked.
   {
-    expected: "CSP default-src 'self' allows fetch of manifest.",
+    expected: `CSP default-src 'self' allows fetch of manifest.`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("csp", "default-src 'self'");
-      return url.href;
+      let queryParts = [
+        `csp=default-src 'self'`,
+        testFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
-      is(manifest.name, "loaded", this.expected);
+      is(manifest.name, 'loaded', this.expected);
     }
   },
   // CSP only allows fetching from mochi.test:8888 and remoteFile
   // requests a manifest from that origin, so manifest should load.
   {
-    expected: "CSP default-src mochi.test:8888 allows fetching manifest.",
+    expected: 'CSP default-src mochi.test:8888 allows fetching manifest.',
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", remoteFile);
-      url.searchParams.append("csp", "default-src http://mochi.test:8888");
-      return url.href;
+      let queryParts = [
+        `csp=default-src http://mochi.test:8888`,
+        remoteFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
-      is(manifest.name, "loaded", this.expected);
+      is(manifest.name, 'loaded', this.expected);
     }
   },
   // default-src blocks everything, so any attempt to
   // fetch a manifest from another origin will trigger a
   // policy violation.
   {
-    expected: "default-src 'none' blocks mochi.test:8888",
+    expected: `default-src 'none' blocks mochi.test:8888`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", remoteFile);
-      url.searchParams.append("csp", "default-src 'none'");
-      return url.href;
+      let queryParts = [
+        `csp=default-src 'none'`,
+        remoteFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(topic) {
-      is(topic, "csp-on-violate-policy", this.expected);
+      is(topic, 'csp-on-violate-policy', this.expected);
     }
   },
   // CSP allows fetching from self, so manifest should load.
   {
-    expected: "CSP manifest-src allows self",
+    expected: `CSP manifest-src allows self`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("csp", "manifest-src 'self'");
-      return url.href;
+      let queryParts = [
+        `csp=manifest-src 'self'`,
+        testFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
-      is(manifest.name, "loaded", this.expected);
+      is(manifest.name, 'loaded', this.expected);
     }
   },
   // CSP allows fetching from example.org, so manifest should load.
   {
-    expected: "CSP manifest-src allows http://example.org",
+    expected: `CSP manifest-src allows http://example.org`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("csp", "manifest-src http://example.org");
-      return url.href;
+      let queryParts = [
+        `csp=manifest-src http://example.org`,
+        testFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
-      is(manifest.name, "loaded", this.expected);
+      is(manifest.name, 'loaded', this.expected);
     }
-  }, {
-    expected: "CSP manifest-src allows mochi.test:8888",
+  },
+  {
+    expected: `CSP manifest-src allows mochi.test:8888`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", remoteFile);
-      url.searchParams.append("cors", "*");
-      url.searchParams.append("csp", "default-src *; manifest-src http://mochi.test:8888");
-      return url.href;
+      let queryParts = [
+        `cors=*`,
+        `csp=default-src *; manifest-src http://mochi.test:8888`,
+        remoteFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
-      is(manifest.name, "loaded", this.expected);
+      is(manifest.name, 'loaded', this.expected);
     }
   },
   // CSP restricts fetching to mochi.test:8888, but the test
   // file is at example.org. Hence, a policy violation is
   // triggered.
   {
-    expected: "CSP blocks manifest fetching from example.org.",
+    expected: `CSP blocks manifest fetching from example.org.`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", testFile);
-      url.searchParams.append("csp", "manifest-src mochi.test:8888");
-      return url.href;
+      let queryParts = [
+        `csp=manifest-src mochi.test:8888`,
+        testFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(topic) {
-      is(topic, "csp-on-violate-policy", this.expected);
+      is(topic, 'csp-on-violate-policy', this.expected);
     }
   },
   // CSP is set to only allow manifest to be loaded from same origin,
   // but the remote file attempts to load from a different origin. Thus
   // this causes a CSP violation.
   {
-    expected: "CSP manifest-src 'self' blocks cross-origin fetch.",
+    expected: `CSP manifest-src 'self' blocks cross-origin fetch.`,
     get tabURL() {
-      const url = new URL(defaultURL);
-      url.searchParams.append("file", remoteFile);
-      url.searchParams.append("csp", "manifest-src 'self'");
-      return url.href;
+      let queryParts = [
+        `csp=manifest-src 'self'`,
+        remoteFile
+      ];
+      return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(topic) {
-      is(topic, "csp-on-violate-policy", this.expected);
+      is(topic, 'csp-on-violate-policy', this.expected);
     }
   },
   // CSP allows fetching over TLS from example.org, so manifest should load.
   {
-    expected: "CSP manifest-src allows example.com over TLS",
+    expected: `CSP manifest-src allows example.com over TLS`,
     get tabURL() {
+      let queryParts = [
+        'cors=*',
+        'csp=manifest-src https://example.com:443',
+        httpsManifest
+      ];
       // secureURL loads https://example.com:443
       // and gets manifest from https://example.org:443
-      const url = new URL(secureURL);
-      url.searchParams.append("file", httpsManifest);
-      url.searchParams.append("cors", "*");
-      url.searchParams.append("csp", "manifest-src https://example.com:443");
-      return url.href;
+      return `${secureURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
-      is(manifest.name, "loaded", this.expected);
+      is(manifest.name, 'loaded', this.expected);
     }
   },
 ];
 //jscs:disable
 add_task(function* () {
   //jscs:enable
-  const testPromises = tests.map((test) => {
-    const tabOptions = {
-      gBrowser,
-      url: test.tabURL,
-      skipAnimation: true,
-    };
-    return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
-  });
+  var testPromises = tests.map(
+      (test) => ([test, {gBrowser, url: test.tabURL, skipAnimation: true}])
+    ).map(
+      ([test, tabOptions]) => BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test))
+    );
   yield Promise.all(testPromises);
 });
 
 function* testObtainingManifest(aBrowser, aTest) {
-  const expectsBlocked = aTest.expected.includes("block");
+  const expectsBlocked = aTest.expected.includes('block');
   const observer = (expectsBlocked) ? createNetObserver(aTest) : null;
   // Expect an exception (from promise rejection) if there a content policy
   // that is violated.
   try {
     const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
     aTest.run(manifest);
   } catch (e) {
-    const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
-    ok(wasBlocked, `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
+    const wasBlocked = e.message.includes('blocked the loading of a resource');
+    ok(wasBlocked,`Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
     if (observer) {
       yield observer.untilFinished;
+      return;
     }
+    throw e;
   }
 }
 
 // Helper object used to observe policy violations. It waits 1 seconds
 // for a response, and then times out causing its associated test to fail.
 function createNetObserver(test) {
   let finishedTest;
   let success = false;
   const finished = new Promise((resolver) => {
     finishedTest = resolver;
   });
   const timeoutId = setTimeout(() => {
     if (!success) {
-      test.run("This test timed out.");
+      test.run('This test timed out.');
       finishedTest();
     }
   }, 1000);
   var observer = {
-    get untilFinished() {
+    get untilFinished(){
       return finished;
     },
     observe(subject, topic) {
-      SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
+      SpecialPowers.removeObserver(observer, 'csp-on-violate-policy');
       test.run(topic);
       finishedTest();
       clearTimeout(timeoutId);
       success = true;
     },
   };
-  SpecialPowers.addObserver(observer, "csp-on-violate-policy", false);
+  SpecialPowers.addObserver(observer, 'csp-on-violate-policy', false);
   return observer;
-}
\ No newline at end of file
+}
--- a/dom/security/test/csp/browser_test_web_manifest_mixed_content.js
+++ b/dom/security/test/csp/browser_test_web_manifest_mixed_content.js
@@ -1,53 +1,54 @@
 /*
  * Description of the test:
  *   Check that mixed content blocker works prevents fetches of
  *   mixed content manifests.
  */
-/*globals Cu, ok*/
-"use strict";
+'use strict';
 const {
   ManifestObtainer
-} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
-const path = "/tests/dom/security/test/csp/";
-const mixedContent = `${path}file_web_manifest_mixed_content.html`;
-const server = `${path}file_testserver.sjs`;
-const secureURL = new URL(`https://example.com${server}`);
+} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
+const path = '/tests/dom/security/test/csp/';
+const mixedContent = `file=${path}file_web_manifest_mixed_content.html`;
+const server = 'file_testserver.sjs';
+const secureURL = `https://example.com${path}${server}`;
 const tests = [
   // Trying to load mixed content in file_web_manifest_mixed_content.html
   // needs to result in an error.
   {
-    expected: "Mixed Content Blocker prevents fetching manifest.",
+    expected: `Mixed Content Blocker prevents fetching manifest.`,
     get tabURL() {
-      const url = new URL(secureURL);
-      url.searchParams.append("file", mixedContent);
-      return url.href;
+      let queryParts = [
+        mixedContent
+      ];
+      return `${secureURL}?${queryParts.join('&')}`;
     },
     run(error) {
       // Check reason for error.
-      const check = /NetworkError when attempting to fetch resource/.test(error.message);
+      const check = /blocked the loading of a resource/.test(error.message);
       ok(check, this.expected);
     }
   }
 ];
 
 //jscs:disable
-add_task(function* () {
+add_task(function*() {
   //jscs:enable
-  const testPromises = tests.map((test) => {
-    const tabOptions = {
-      gBrowser,
+  for (let test of tests) {
+    let tabOptions = {
+      gBrowser: gBrowser,
       url: test.tabURL,
-      skipAnimation: true,
     };
-    return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
-  });
-  yield Promise.all(testPromises);
-});
+    yield BrowserTestUtils.withNewTab(
+      tabOptions,
+      browser => testObtainingManifest(browser, test)
+    );
+  }
 
-function* testObtainingManifest(aBrowser, aTest) {
-  try {
-    yield ManifestObtainer.browserObtainManifest(aBrowser);
-  } catch (e) {
-    aTest.run(e);
+  function* testObtainingManifest(aBrowser, aTest) {
+    try {
+      yield ManifestObtainer.browserObtainManifest(aBrowser);
+    } catch (e) {
+      aTest.run(e)
+    }
   }
-}
+});