forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			283 lines
		
	
	
	
		
			8.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			283 lines
		
	
	
	
		
			8.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* Any copyright is dedicated to the Public Domain.
 | |
|  * http://creativecommons.org/publicdomain/zero/1.0/ */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const TEST_QUOTA_USAGE_HOST = "example.com";
 | |
| const TEST_QUOTA_USAGE_ORIGIN = "https://" + TEST_QUOTA_USAGE_HOST;
 | |
| const TEST_QUOTA_USAGE_URL =
 | |
|   getRootDirectory(gTestPath).replace(
 | |
|     "chrome://mochitests/content",
 | |
|     TEST_QUOTA_USAGE_ORIGIN
 | |
|   ) + "/site_data_test.html";
 | |
| const TEST_OFFLINE_HOST = "example.org";
 | |
| const TEST_OFFLINE_ORIGIN = "https://" + TEST_OFFLINE_HOST;
 | |
| const TEST_OFFLINE_URL =
 | |
|   getRootDirectory(gTestPath).replace(
 | |
|     "chrome://mochitests/content",
 | |
|     TEST_OFFLINE_ORIGIN
 | |
|   ) + "/offline/offline.html";
 | |
| const TEST_SERVICE_WORKER_URL =
 | |
|   getRootDirectory(gTestPath).replace(
 | |
|     "chrome://mochitests/content",
 | |
|     TEST_OFFLINE_ORIGIN
 | |
|   ) + "/service_worker_test.html";
 | |
| 
 | |
| const REMOVE_DIALOG_URL =
 | |
|   "chrome://browser/content/preferences/dialogs/siteDataRemoveSelected.xhtml";
 | |
| 
 | |
| ChromeUtils.defineModuleGetter(
 | |
|   this,
 | |
|   "SiteDataTestUtils",
 | |
|   "resource://testing-common/SiteDataTestUtils.jsm"
 | |
| );
 | |
| 
 | |
| XPCOMUtils.defineLazyServiceGetter(
 | |
|   this,
 | |
|   "serviceWorkerManager",
 | |
|   "@mozilla.org/serviceworkers/manager;1",
 | |
|   "nsIServiceWorkerManager"
 | |
| );
 | |
| 
 | |
| function promiseSiteDataManagerSitesUpdated() {
 | |
|   return TestUtils.topicObserved("sitedatamanager:sites-updated", () => true);
 | |
| }
 | |
| 
 | |
| function is_element_visible(aElement, aMsg) {
 | |
|   isnot(aElement, null, "Element should not be null, when checking visibility");
 | |
|   ok(!BrowserTestUtils.is_hidden(aElement), aMsg);
 | |
| }
 | |
| 
 | |
| function is_element_hidden(aElement, aMsg) {
 | |
|   isnot(aElement, null, "Element should not be null, when checking visibility");
 | |
|   ok(BrowserTestUtils.is_hidden(aElement), aMsg);
 | |
| }
 | |
| 
 | |
| function promiseLoadSubDialog(aURL) {
 | |
|   return new Promise((resolve, reject) => {
 | |
|     content.gSubDialog._dialogStack.addEventListener(
 | |
|       "dialogopen",
 | |
|       function dialogopen(aEvent) {
 | |
|         if (
 | |
|           aEvent.detail.dialog._frame.contentWindow.location == "about:blank"
 | |
|         ) {
 | |
|           return;
 | |
|         }
 | |
|         content.gSubDialog._dialogStack.removeEventListener(
 | |
|           "dialogopen",
 | |
|           dialogopen
 | |
|         );
 | |
| 
 | |
|         is(
 | |
|           aEvent.detail.dialog._frame.contentWindow.location.toString(),
 | |
|           aURL,
 | |
|           "Check the proper URL is loaded"
 | |
|         );
 | |
| 
 | |
|         // Check visibility
 | |
|         is_element_visible(aEvent.detail.dialog._overlay, "Overlay is visible");
 | |
| 
 | |
|         // Check that stylesheets were injected
 | |
|         let expectedStyleSheetURLs = aEvent.detail.dialog._injectedStyleSheets.slice(
 | |
|           0
 | |
|         );
 | |
|         for (let styleSheet of aEvent.detail.dialog._frame.contentDocument
 | |
|           .styleSheets) {
 | |
|           let i = expectedStyleSheetURLs.indexOf(styleSheet.href);
 | |
|           if (i >= 0) {
 | |
|             info("found " + styleSheet.href);
 | |
|             expectedStyleSheetURLs.splice(i, 1);
 | |
|           }
 | |
|         }
 | |
|         is(
 | |
|           expectedStyleSheetURLs.length,
 | |
|           0,
 | |
|           "All expectedStyleSheetURLs should have been found"
 | |
|         );
 | |
| 
 | |
|         // Wait for the next event tick to make sure the remaining part of the
 | |
|         // testcase runs after the dialog gets ready for input.
 | |
|         executeSoon(() => resolve(aEvent.detail.dialog._frame.contentWindow));
 | |
|       }
 | |
|     );
 | |
|   });
 | |
| }
 | |
| 
 | |
| function openPreferencesViaOpenPreferencesAPI(aPane, aOptions) {
 | |
|   return new Promise(resolve => {
 | |
|     let finalPrefPaneLoaded = TestUtils.topicObserved(
 | |
|       "sync-pane-loaded",
 | |
|       () => true
 | |
|     );
 | |
|     gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
 | |
|     openPreferences(aPane);
 | |
|     let newTabBrowser = gBrowser.selectedBrowser;
 | |
| 
 | |
|     newTabBrowser.addEventListener(
 | |
|       "Initialized",
 | |
|       function() {
 | |
|         newTabBrowser.contentWindow.addEventListener(
 | |
|           "load",
 | |
|           async function() {
 | |
|             let win = gBrowser.contentWindow;
 | |
|             let selectedPane = win.history.state;
 | |
|             await finalPrefPaneLoaded;
 | |
|             if (!aOptions || !aOptions.leaveOpen) {
 | |
|               gBrowser.removeCurrentTab();
 | |
|             }
 | |
|             resolve({ selectedPane });
 | |
|           },
 | |
|           { once: true }
 | |
|         );
 | |
|       },
 | |
|       { capture: true, once: true }
 | |
|     );
 | |
|   });
 | |
| }
 | |
| 
 | |
| function openSiteDataSettingsDialog() {
 | |
|   let doc = gBrowser.selectedBrowser.contentDocument;
 | |
|   let settingsBtn = doc.getElementById("siteDataSettings");
 | |
|   let dialogOverlay = content.gSubDialog._preloadDialog._overlay;
 | |
|   let dialogLoadPromise = promiseLoadSubDialog(
 | |
|     "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml"
 | |
|   );
 | |
|   let dialogInitPromise = TestUtils.topicObserved(
 | |
|     "sitedata-settings-init",
 | |
|     () => true
 | |
|   );
 | |
|   let fullyLoadPromise = Promise.all([
 | |
|     dialogLoadPromise,
 | |
|     dialogInitPromise,
 | |
|   ]).then(() => {
 | |
|     is_element_visible(dialogOverlay, "The Settings dialog should be visible");
 | |
|   });
 | |
|   settingsBtn.doCommand();
 | |
|   return fullyLoadPromise;
 | |
| }
 | |
| 
 | |
| function promiseSettingsDialogClose() {
 | |
|   return new Promise(resolve => {
 | |
|     let win = gBrowser.selectedBrowser.contentWindow;
 | |
|     let dialogOverlay = win.gSubDialog._topDialog._overlay;
 | |
|     let dialogWin = win.gSubDialog._topDialog._frame.contentWindow;
 | |
|     dialogWin.addEventListener(
 | |
|       "unload",
 | |
|       function unload() {
 | |
|         if (
 | |
|           dialogWin.document.documentURI ===
 | |
|           "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml"
 | |
|         ) {
 | |
|           is_element_hidden(
 | |
|             dialogOverlay,
 | |
|             "The Settings dialog should be hidden"
 | |
|           );
 | |
|           resolve();
 | |
|         }
 | |
|       },
 | |
|       { once: true }
 | |
|     );
 | |
|   });
 | |
| }
 | |
| 
 | |
| function assertSitesListed(doc, hosts) {
 | |
|   let frameDoc = content.gSubDialog._topDialog._frame.contentDocument;
 | |
|   let removeAllBtn = frameDoc.getElementById("removeAll");
 | |
|   let sitesList = frameDoc.getElementById("sitesList");
 | |
|   let totalSitesNumber = sitesList.getElementsByTagName("richlistitem").length;
 | |
|   is(totalSitesNumber, hosts.length, "Should list the right sites number");
 | |
|   hosts.forEach(host => {
 | |
|     let site = sitesList.querySelector(`richlistitem[host="${host}"]`);
 | |
|     ok(site, `Should list the site of ${host}`);
 | |
|   });
 | |
|   is(removeAllBtn.disabled, false, "Should enable the removeAllBtn button");
 | |
| }
 | |
| 
 | |
| // Counter used by addTestData to generate unique cookie names across function
 | |
| // calls.
 | |
| let cookieID = 0;
 | |
| 
 | |
| async function addTestData(data) {
 | |
|   let hosts = new Set();
 | |
| 
 | |
|   for (let site of data) {
 | |
|     is(
 | |
|       typeof site.origin,
 | |
|       "string",
 | |
|       "Passed an origin string into addTestData."
 | |
|     );
 | |
|     if (site.persisted) {
 | |
|       await SiteDataTestUtils.persist(site.origin);
 | |
|     }
 | |
| 
 | |
|     if (site.usage) {
 | |
|       await SiteDataTestUtils.addToIndexedDB(site.origin, site.usage);
 | |
|     }
 | |
| 
 | |
|     for (let i = 0; i < (site.cookies || 0); i++) {
 | |
|       SiteDataTestUtils.addToCookies({
 | |
|         origin: site.origin,
 | |
|         name: `cookie${cookieID++}`,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
 | |
|       site.origin
 | |
|     );
 | |
| 
 | |
|     hosts.add(principal.baseDomain || principal.host);
 | |
|   }
 | |
| 
 | |
|   return Array.from(hosts);
 | |
| }
 | |
| 
 | |
| function promiseCookiesCleared() {
 | |
|   return TestUtils.topicObserved("cookie-changed", (subj, data) => {
 | |
|     return data === "cleared";
 | |
|   });
 | |
| }
 | |
| 
 | |
| async function loadServiceWorkerTestPage(url) {
 | |
|   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
 | |
|   await TestUtils.waitForCondition(() => {
 | |
|     return SpecialPowers.spawn(
 | |
|       tab.linkedBrowser,
 | |
|       [],
 | |
|       () =>
 | |
|         content.document.body.getAttribute(
 | |
|           "data-test-service-worker-registered"
 | |
|         ) === "true"
 | |
|     );
 | |
|   }, `Fail to load service worker test ${url}`);
 | |
|   BrowserTestUtils.removeTab(tab);
 | |
| }
 | |
| 
 | |
| function promiseServiceWorkersCleared() {
 | |
|   return TestUtils.waitForCondition(() => {
 | |
|     let serviceWorkers = serviceWorkerManager.getAllRegistrations();
 | |
|     if (!serviceWorkers.length) {
 | |
|       ok(true, "Cleared all service workers");
 | |
|       return true;
 | |
|     }
 | |
|     return false;
 | |
|   }, "Should clear all service workers");
 | |
| }
 | |
| 
 | |
| function promiseServiceWorkerRegisteredFor(url) {
 | |
|   return TestUtils.waitForCondition(() => {
 | |
|     try {
 | |
|       let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
 | |
|         url
 | |
|       );
 | |
|       let sw = serviceWorkerManager.getRegistrationByPrincipal(
 | |
|         principal,
 | |
|         principal.spec
 | |
|       );
 | |
|       if (sw) {
 | |
|         ok(true, `Found the service worker registered for ${url}`);
 | |
|         return true;
 | |
|       }
 | |
|     } catch (e) {}
 | |
|     return false;
 | |
|   }, `Should register service worker for ${url}`);
 | |
| }
 | 
