Bug 1376973 - Part 2: Add test cases for making sure that favicons of allTabs popup menu is using correct originAttributes. r?baku,arthuredelstein draft
authorTim Huang <tihuang@mozilla.com>
Fri, 20 Oct 2017 09:19:58 +0800
changeset 683674 9ed411afa651b88684e6c5fd2e47981547e78562
parent 683673 0a64e07837da8f3a921bc81c2eaf12ef5d472c87
child 736697 71da816b3ee2eb65fbc9c8da92d11f5007c59e5c
push id85430
push userbmo:tihuang@mozilla.com
push dateFri, 20 Oct 2017 01:49:06 +0000
reviewersbaku, arthuredelstein
bugs1376973
milestone58.0a1
Bug 1376973 - Part 2: Add test cases for making sure that favicons of allTabs popup menu is using correct originAttributes. r?baku,arthuredelstein This patch adds test cases for testing favicons of allTabs menu in terms of originAttributes. It adds tests in existing tests, browser_favicon_userContextId.js and browser_favicon_firstParty.js. The test will open tabs with different originAttributes and trigger the popup of allTabs menu. Then it will verify that whether the network requests of favicon have correct originAttributes. MozReview-Commit-ID: 4Aa7RDFdosA
browser/components/originattributes/test/browser/browser_favicon_firstParty.js
browser/components/originattributes/test/browser/browser_favicon_userContextId.js
--- a/browser/components/originattributes/test/browser/browser_favicon_firstParty.js
+++ b/browser/components/originattributes/test/browser/browser_favicon_firstParty.js
@@ -1,16 +1,20 @@
 /**
  * Bug 1277803 - A test case for testing favicon loading across different first party domains.
  */
 
 const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 
+let EventUtils = {};
+Services.scriptloader.loadSubScript(
+  "chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
+
 const FIRST_PARTY_ONE = "example.com";
 const FIRST_PARTY_TWO = "example.org";
 const THIRD_PARTY = "mochi.test:8888";
 
 const TEST_SITE_ONE = "http://" + FIRST_PARTY_ONE;
 const TEST_SITE_TWO = "http://" + FIRST_PARTY_TWO;
 const THIRD_PARTY_SITE = "http://" + THIRD_PARTY;
 const TEST_DIRECTORY = "/browser/browser/components/originattributes/test/browser/";
@@ -47,19 +51,20 @@ function clearAllPlacesFavicons() {
       }
     };
 
     Services.obs.addObserver(observer, "places-favicons-expired");
     faviconService.expireAllFavicons();
   });
 }
 
-function observeFavicon(aFirstPartyDomain, aExpectedCookie, aPageURI) {
+function observeFavicon(aFirstPartyDomain, aExpectedCookie, aPageURI, aOnlyXUL) {
   let faviconReqXUL = false;
-  let faviconReqPlaces = false;
+  // If aOnlyXUL is true, we only care about the favicon request from XUL.
+  let faviconReqPlaces = aOnlyXUL === true;
   let expectedPrincipal = Services.scriptSecurityManager
                                   .createCodebasePrincipal(aPageURI, { firstPartyDomain: aFirstPartyDomain });
 
   return new Promise(resolve => {
     let observer = {
       observe(aSubject, aTopic, aData) {
         // Make sure that the topic is 'http-on-modify-request'.
         if (aTopic === "http-on-modify-request") {
@@ -239,16 +244,95 @@ async function doTest(aTestPage, aExpect
   tabInfo = await openTab(TEST_SITE_TWO + aTestPage);
 
   // Waiting until favicon requests are all made.
   await promiseObserveFavicon;
 
   await BrowserTestUtils.removeTab(tabInfo.tab);
 }
 
+async function doTestForAllTabsFavicon(aTestPage, aExpectedCookies, aIsThirdParty) {
+  let firstPageURI = makeURI(TEST_SITE_ONE + aTestPage);
+  let secondPageURI = makeURI(TEST_SITE_TWO + aTestPage);
+  let faviconURI = aIsThirdParty ? THIRD_PARTY_SITE + FAVICON_URI :
+                                   TEST_SITE_ONE + FAVICON_URI;
+
+  // Set the 'overflow' attribute to make allTabs button available.
+  let tabBrowser = document.getElementById("tabbrowser-tabs");
+  let allTabsBtn = document.getElementById("alltabs-button");
+  tabBrowser.setAttribute("overflow", true);
+
+  // Start to observe the event of that the favicon has been fully loaded.
+  let promiseFaviconLoaded = waitOnFaviconLoaded(faviconURI);
+
+  // Open the tab for the first site.
+  let tabInfo = await openTab(TEST_SITE_ONE + aTestPage);
+
+  // Waiting until the favicon loaded.
+  await promiseFaviconLoaded;
+
+  // We need to clear the image cache here for making sure the network request will
+  // be made for the favicon of allTabs menuitem.
+  clearAllImageCaches();
+
+  // Start to observe the allTabs favicon requests earlier in case we miss it.
+  let promiseObserveFavicon = observeFavicon(FIRST_PARTY_ONE, aExpectedCookies[0],
+                                             firstPageURI, true);
+
+  // Make the popup of allTabs showing up and trigger the loading of the favicon.
+  let allTabsPopupShownPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await promiseObserveFavicon;
+  await allTabsPopupShownPromise;
+
+  // Close the popup of allTabs and wait until it's done.
+  let allTabsPopupHiddenPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popuphidden");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await allTabsPopupHiddenPromise;
+
+  // Close the tab.
+  await BrowserTestUtils.removeTab(tabInfo.tab);
+
+  faviconURI = aIsThirdParty ? THIRD_PARTY_SITE + FAVICON_URI :
+                               TEST_SITE_TWO + FAVICON_URI;
+
+  // Start to observe the event of that favicon has been fully loaded.
+  promiseFaviconLoaded = waitOnFaviconLoaded(faviconURI);
+
+  // Open the tab for the second site.
+  tabInfo = await openTab(TEST_SITE_TWO + aTestPage);
+
+  // Wait until the favicon is fully loaded.
+  await promiseFaviconLoaded;
+
+  // Clear the image cache for the favicon of the second site.
+  clearAllImageCaches();
+
+  // Start to observe the allTabs favicon requests earlier in case we miss it.
+  promiseObserveFavicon = observeFavicon(FIRST_PARTY_TWO, aExpectedCookies[1],
+                                         secondPageURI, true);
+
+  // Make the popup of allTabs showing up again.
+  allTabsPopupShownPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await promiseObserveFavicon;
+  await allTabsPopupShownPromise;
+
+  // Close the popup of allTabs and wait until it's done.
+  allTabsPopupHiddenPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popuphidden");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await allTabsPopupHiddenPromise;
+
+  // Close the tab.
+  await BrowserTestUtils.removeTab(tabInfo.tab);
+
+  // Reset the 'overflow' attribute to make the allTabs button hidden again.
+  tabBrowser.removeAttribute("overflow");
+}
+
 add_task(async function setup() {
   // Make sure first party isolation is enabled.
   await SpecialPowers.pushPrefEnv({"set": [
       ["privacy.firstparty.isolate", true]
   ]});
 });
 
 // A clean up function to prevent affecting other tests.
@@ -277,16 +361,36 @@ add_task(async function test_favicon_fir
     if (testThirdParty) {
       await doTest(TEST_THIRD_PARTY_PAGE, cookies, THIRD_PARTY_SITE + FAVICON_URI);
     } else {
       await doTest(TEST_PAGE, cookies, TEST_SITE_ONE + FAVICON_URI);
     }
   }
 });
 
+add_task(async function test_allTabs_favicon_firstParty() {
+  for (let testThirdParty of [false, true]) {
+    // Clear all image caches and network caches before running the test.
+    clearAllImageCaches();
+
+    Services.cache2.clear();
+
+    // Clear Places favicon caches.
+    await clearAllPlacesFavicons();
+
+    let cookies = await generateCookies(testThirdParty);
+
+    if (testThirdParty) {
+      await doTestForAllTabsFavicon(TEST_THIRD_PARTY_PAGE, cookies, testThirdParty);
+    } else {
+      await doTestForAllTabsFavicon(TEST_PAGE, cookies, testThirdParty);
+    }
+  }
+});
+
 add_task(async function test_favicon_cache_firstParty() {
   // Clear all image caches and network caches before running the test.
   clearAllImageCaches();
 
   Services.cache2.clear();
 
   // Start to observer the event of that favicon has been fully loaded and cached.
   let promiseForFaviconLoaded = waitOnFaviconLoaded(THIRD_PARTY_SITE + TEST_FAVICON_CACHE_URI);
--- a/browser/components/originattributes/test/browser/browser_favicon_userContextId.js
+++ b/browser/components/originattributes/test/browser/browser_favicon_userContextId.js
@@ -2,16 +2,20 @@
  * Bug 1277803 - A test caes for testing favicon loading across different userContextId.
  */
 
 const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
 
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
   "resource://gre/modules/Promise.jsm");
 
+let EventUtils = {};
+Services.scriptloader.loadSubScript(
+  "chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
+
 const TEST_SITE = "http://example.net";
 const TEST_THIRD_PARTY_SITE = "http://mochi.test:8888";
 
 const TEST_PAGE = TEST_SITE + "/browser/browser/components/originattributes/" +
                   "test/browser/file_favicon.html";
 const FAVICON_URI = TEST_SITE + "/browser/browser/components/originattributes/" +
                     "test/browser/file_favicon.png";
 const TEST_THIRD_PARTY_PAGE = "http://example.com/browser/browser/components/" +
@@ -47,18 +51,18 @@ function clearAllPlacesFavicons() {
       }
     };
 
     Services.obs.addObserver(observer, "places-favicons-expired");
     faviconService.expireAllFavicons();
   });
 }
 
-function FaviconObserver(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL) {
-  this.reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL);
+function FaviconObserver(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL, aOnlyXUL) {
+  this.reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL, aOnlyXUL);
 }
 
 FaviconObserver.prototype = {
   observe(aSubject, aTopic, aData) {
     // Make sure that the topic is 'http-on-modify-request'.
     if (aTopic === "http-on-modify-request") {
       // We check the userContextId for the originAttributes of the loading
       // channel. All requests for the favicon should contain the correct
@@ -103,23 +107,24 @@ FaviconObserver.prototype = {
       ok(false, "Received unexpected topic: ", aTopic);
     }
 
     if (this._faviconReqXUL && this._faviconReqPlaces) {
       this._faviconLoaded.resolve();
     }
   },
 
-  reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL) {
+  reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL, aOnlyXUL) {
     this._curUserContextId = aUserContextId;
     this._expectedCookie = aExpectedCookie;
     this._expectedPrincipal = Services.scriptSecurityManager
                                       .createCodebasePrincipal(aPageURI, { userContextId: aUserContextId });
     this._faviconReqXUL = false;
-    this._faviconReqPlaces = false;
+    // If aOnlyXUL is true, we only care about the favicon request from XUL.
+    this._faviconReqPlaces = aOnlyXUL === true;
     this._faviconURL = aFaviconURL;
     this._faviconLoaded = new Promise.defer();
   },
 
   get promise() {
     return this._faviconLoaded.promise;
   }
 };
@@ -196,16 +201,97 @@ async function doTest(aTestPage, aFavico
   // Waiting for favicon requests are all made.
   await observer.promise;
 
   Services.obs.removeObserver(observer, "http-on-modify-request");
 
   await BrowserTestUtils.removeTab(tabInfo.tab);
 }
 
+async function doTestForAllTabsFavicon(aTestPage, aFaviconHost, aFaviconURL) {
+  let cookies = await generateCookies(aFaviconHost);
+  let pageURI = makeURI(aTestPage);
+
+  // Set the 'overflow' attribute to make allTabs button available.
+  let tabBrowser = document.getElementById("tabbrowser-tabs");
+  let allTabsBtn = document.getElementById("alltabs-button");
+  tabBrowser.setAttribute("overflow", true);
+
+  // Create the observer object for observing request channels of the personal
+  // container.
+  let observer = new FaviconObserver(USER_CONTEXT_ID_PERSONAL, cookies[0], pageURI, aFaviconURL, true);
+
+  // Add the observer earlier in case we miss it.
+  let promiseWaitOnFaviconLoaded = waitOnFaviconLoaded(aFaviconURL);
+
+  // Open the tab with the personal container.
+  let tabInfo = await openTabInUserContext(aTestPage, USER_CONTEXT_ID_PERSONAL);
+
+  // Waiting for favicon loaded.
+  await promiseWaitOnFaviconLoaded;
+
+  // We need to clear the image cache here for making sure the network request will
+  // be made for the favicon of allTabs menuitem.
+  clearAllImageCaches();
+
+  // Add the observer for listening favicon requests.
+  Services.obs.addObserver(observer, "http-on-modify-request");
+
+  // Make the popup of allTabs showing up and trigger the loading of the favicon.
+  let allTabsPopupShownPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await observer.promise;
+  await allTabsPopupShownPromise;
+
+  // Close the popup of allTabs and wait until it's done.
+  let allTabsPopupHiddenPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popuphidden");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await allTabsPopupHiddenPromise;
+
+  // Remove the observer for not receiving the favicon requests for opening a tab
+  // since we want to focus on the favicon of allTabs menu here.
+  Services.obs.removeObserver(observer, "http-on-modify-request");
+
+  // Close the tab.
+  await BrowserTestUtils.removeTab(tabInfo.tab);
+
+  // Open the tab under the work container and wait until the favicon is loaded.
+  promiseWaitOnFaviconLoaded = waitOnFaviconLoaded(aFaviconURL);
+  tabInfo = await openTabInUserContext(aTestPage, USER_CONTEXT_ID_WORK);
+  await promiseWaitOnFaviconLoaded;
+
+  // Clear the image cache again.
+  clearAllImageCaches();
+
+  // Reset the observer for observing requests for the work container.
+  observer.reset(USER_CONTEXT_ID_WORK, cookies[1], pageURI, aFaviconURL, true);
+
+  // Add the observer back for listening the favicon requests for allTabs menuitem.
+  Services.obs.addObserver(observer, "http-on-modify-request");
+
+  // Make the popup of allTabs showing up again.
+  allTabsPopupShownPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await observer.promise;
+  await allTabsPopupShownPromise;
+
+  // Close the popup of allTabs and wait until it's done.
+  allTabsPopupHiddenPromise = BrowserTestUtils.waitForEvent(allTabsBtn, "popuphidden");
+  EventUtils.synthesizeMouseAtCenter(allTabsBtn, {});
+  await allTabsPopupHiddenPromise;
+
+  Services.obs.removeObserver(observer, "http-on-modify-request");
+
+  // Close the tab.
+  await BrowserTestUtils.removeTab(tabInfo.tab);
+
+  // Reset the 'overflow' attribute to make the allTabs button hidden again.
+  tabBrowser.removeAttribute("overflow");
+}
+
 add_task(async function setup() {
   // Make sure userContext is enabled.
   await SpecialPowers.pushPrefEnv({"set": [
       ["privacy.userContext.enabled", true]
   ]});
 });
 
 // A clean up function to prevent affecting other tests.
@@ -242,8 +328,34 @@ add_task(async function test_thirdPartyF
   // Clear all network caches.
   Services.cache2.clear();
 
   // Clear Places favicon caches.
   await clearAllPlacesFavicons();
 
   await doTest(TEST_THIRD_PARTY_PAGE, TEST_THIRD_PARTY_SITE, THIRD_PARTY_FAVICON_URI);
 });
+
+add_task(async function test_allTabs_favicon_userContextId() {
+  // Clear all image caches before running the test.
+  clearAllImageCaches();
+
+  // Clear all network caches.
+  Services.cache2.clear();
+
+  // Clear Places favicon caches.
+  await clearAllPlacesFavicons();
+
+  await doTestForAllTabsFavicon(TEST_PAGE, TEST_SITE, FAVICON_URI);
+});
+
+add_task(async function test_allTabs_thirdPartyFavicon_userContextId() {
+  // Clear all image caches before running the test.
+  clearAllImageCaches();
+
+  // Clear all network caches.
+  Services.cache2.clear();
+
+  // Clear Places favicon caches.
+  await clearAllPlacesFavicons();
+
+  await doTestForAllTabsFavicon(TEST_THIRD_PARTY_PAGE, TEST_THIRD_PARTY_SITE, THIRD_PARTY_FAVICON_URI);
+});