forked from mirrors/gecko-dev
		
	 6676c35ee3
			
		
	
	
		6676c35ee3
		
	
	
	
	
		
			
			Differential Revision: https://phabricator.services.mozilla.com/D6542 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			275 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| SimpleTest.requestCompleteLog();
 | |
| ChromeUtils.import("resource://testing-common/HandlerServiceTestUtils.jsm", this);
 | |
| 
 | |
| let gHandlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
 | |
| 
 | |
| let gOldMailHandlers = [];
 | |
| let gDummyHandlers = [];
 | |
| let gOriginalPreferredMailHandler;
 | |
| let gOriginalPreferredPDFHandler;
 | |
| 
 | |
| registerCleanupFunction(function() {
 | |
|   function removeDummyHandlers(handlers) {
 | |
|     // Remove any of the dummy handlers we created.
 | |
|     for (let i = handlers.Count() - 1; i >= 0; i--) {
 | |
|       try {
 | |
|         if (gDummyHandlers.some(h => h.uriTemplate == handlers.queryElementAt(i, Ci.nsIWebHandlerApp).uriTemplate)) {
 | |
|           handlers.removeElementAt(i);
 | |
|         }
 | |
|       } catch (ex) { /* ignore non-web-app handlers */ }
 | |
|     }
 | |
|   }
 | |
|   // Re-add the original protocol handlers:
 | |
|   let mailHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("mailto");
 | |
|   let mailHandlers = mailHandlerInfo.possibleApplicationHandlers;
 | |
|   for (let h of gOldMailHandlers) {
 | |
|     mailHandlers.appendElement(h);
 | |
|   }
 | |
|   removeDummyHandlers(mailHandlers);
 | |
|   mailHandlerInfo.preferredApplicationHandler = gOriginalPreferredMailHandler;
 | |
|   gHandlerService.store(mailHandlerInfo);
 | |
| 
 | |
|   let pdfHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("application/pdf");
 | |
|   removeDummyHandlers(pdfHandlerInfo.possibleApplicationHandlers);
 | |
|   pdfHandlerInfo.preferredApplicationHandler = gOriginalPreferredPDFHandler;
 | |
|   gHandlerService.store(pdfHandlerInfo);
 | |
| 
 | |
|   gBrowser.removeCurrentTab();
 | |
| });
 | |
| 
 | |
| function scrubMailtoHandlers(handlerInfo) {
 | |
|   // Remove extant web handlers because they have icons that
 | |
|   // we fetch from the web, which isn't allowed in tests.
 | |
|   let handlers = handlerInfo.possibleApplicationHandlers;
 | |
|   for (let i = handlers.Count() - 1; i >= 0; i--) {
 | |
|     try {
 | |
|       let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
 | |
|       gOldMailHandlers.push(handler);
 | |
|       // If we get here, this is a web handler app. Remove it:
 | |
|       handlers.removeElementAt(i);
 | |
|     } catch (ex) {}
 | |
|   }
 | |
| }
 | |
| 
 | |
| add_task(async function setup() {
 | |
|   // Create our dummy handlers
 | |
|   let handler1 = Cc["@mozilla.org/uriloader/web-handler-app;1"]
 | |
|                    .createInstance(Ci.nsIWebHandlerApp);
 | |
|   handler1.name = "Handler 1";
 | |
|   handler1.uriTemplate = "https://example.com/first/%s";
 | |
| 
 | |
|   let handler2 = Cc["@mozilla.org/uriloader/web-handler-app;1"]
 | |
|                      .createInstance(Ci.nsIWebHandlerApp);
 | |
|   handler2.name = "Handler 2";
 | |
|   handler2.uriTemplate = "http://example.org/second/%s";
 | |
|   gDummyHandlers.push(handler1, handler2);
 | |
| 
 | |
|   function substituteWebHandlers(handlerInfo) {
 | |
|     // Append the dummy handlers to replace them:
 | |
|     let handlers = handlerInfo.possibleApplicationHandlers;
 | |
|     handlers.appendElement(handler1);
 | |
|     handlers.appendElement(handler2);
 | |
|     gHandlerService.store(handlerInfo);
 | |
|   }
 | |
|   // Set up our mailto handler test infrastructure.
 | |
|   let mailtoHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("mailto");
 | |
|   scrubMailtoHandlers(mailtoHandlerInfo);
 | |
|   gOriginalPreferredMailHandler = mailtoHandlerInfo.preferredApplicationHandler;
 | |
|   substituteWebHandlers(mailtoHandlerInfo);
 | |
| 
 | |
|   // Now do the same for pdf handler:
 | |
|   let pdfHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("application/pdf");
 | |
|   // PDF doesn't have built-in web handlers, so no need to scrub.
 | |
|   gOriginalPreferredPDFHandler = pdfHandlerInfo.preferredApplicationHandler;
 | |
|   substituteWebHandlers(pdfHandlerInfo);
 | |
| 
 | |
|   await openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true });
 | |
|   info("Preferences page opened on the general pane.");
 | |
| 
 | |
|   await gBrowser.selectedBrowser.contentWindow.promiseLoadHandlersList;
 | |
|   info("Apps list loaded.");
 | |
| });
 | |
| 
 | |
| async function selectStandardOptions(itemToUse) {
 | |
|   async function selectItemInPopup(item) {
 | |
|     let popupShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
 | |
|     // Synthesizing the mouse on the .actionsMenu menulist somehow just selects
 | |
|     // the top row. Probably something to do with the multiple layers of anon
 | |
|     // content - workaround by using the `.open` setter instead.
 | |
|     list.open = true;
 | |
|     await popupShown;
 | |
|     let popupHidden = BrowserTestUtils.waitForEvent(popup, "popuphidden");
 | |
|     if (typeof item == "function") {
 | |
|       item = item();
 | |
|     }
 | |
|     item.click();
 | |
|     popup.hidePopup();
 | |
|     await popupHidden;
 | |
|     return item;
 | |
|   }
 | |
| 
 | |
|   let itemType = itemToUse.getAttribute("type");
 | |
|   // Center the item. Center rather than top so it doesn't get blocked by
 | |
|   // the search header.
 | |
|   itemToUse.scrollIntoView({block: "center"});
 | |
|   itemToUse.closest("richlistbox").selectItem(itemToUse);
 | |
|   Assert.ok(itemToUse.selected, "Should be able to select our item.");
 | |
|   // Force reflow to make sure it's visible and the container dropdown isn't
 | |
|   // hidden.
 | |
|   itemToUse.getBoundingClientRect().top;
 | |
|   let list = itemToUse.querySelector(".actionsMenu");
 | |
|   let popup = list.menupopup;
 | |
| 
 | |
|   // select one of our test cases:
 | |
|   let handlerItem = list.querySelector("menuitem[label*='Handler 1']");
 | |
|   await selectItemInPopup(handlerItem);
 | |
|   let {preferredAction, alwaysAskBeforeHandling} = HandlerServiceTestUtils.getHandlerInfo(itemType);
 | |
|   Assert.notEqual(preferredAction, Ci.nsIHandlerInfo.alwaysAsk,
 | |
|       "Should have selected something other than 'always ask' (" + itemType + ")");
 | |
|   Assert.ok(!alwaysAskBeforeHandling, "Should have turned off asking before handling (" + itemType + ")");
 | |
| 
 | |
|   // Test the alwaysAsk option
 | |
|   let alwaysAskItem = list.getElementsByAttribute("action", Ci.nsIHandlerInfo.alwaysAsk)[0];
 | |
|   await selectItemInPopup(alwaysAskItem);
 | |
|   Assert.equal(list.selectedItem, alwaysAskItem, "Should have selected always ask item (" + itemType + ")");
 | |
|   alwaysAskBeforeHandling = HandlerServiceTestUtils.getHandlerInfo(itemType).alwaysAskBeforeHandling;
 | |
|   Assert.ok(alwaysAskBeforeHandling, "Should have turned on asking before handling (" + itemType + ")");
 | |
| 
 | |
|   let useDefaultItem = list.getElementsByAttribute("action", Ci.nsIHandlerInfo.useSystemDefault);
 | |
|   useDefaultItem = useDefaultItem && useDefaultItem[0];
 | |
|   if (useDefaultItem) {
 | |
|     await selectItemInPopup(useDefaultItem);
 | |
|     Assert.equal(list.selectedItem, useDefaultItem, "Should have selected always ask item (" + itemType + ")");
 | |
|     preferredAction = HandlerServiceTestUtils.getHandlerInfo(itemType).preferredAction;
 | |
|     Assert.equal(preferredAction, Ci.nsIHandlerInfo.useSystemDefault, "Should have selected 'use default' (" + itemType + ")");
 | |
|   } else {
 | |
|     // Whether there's a "use default" item depends on the OS, so it's not
 | |
|     // possible to rely on it being the case or not.
 | |
|     info("No 'Use default' item, so not testing (" + itemType + ")");
 | |
|   }
 | |
| 
 | |
|   // Select a web app item.
 | |
|   let webAppItems = Array.from(popup.getElementsByAttribute("action", Ci.nsIHandlerInfo.useHelperApp));
 | |
|   webAppItems = webAppItems.filter(item => (item.handlerApp instanceof Ci.nsIWebHandlerApp));
 | |
|   Assert.equal(webAppItems.length, 2, "Should have 2 web application handler. (" + itemType + ")");
 | |
|   Assert.notEqual(webAppItems[0].label, webAppItems[1].label, "Should have 2 different web app handlers");
 | |
|   let selectedItem = await selectItemInPopup(webAppItems[0]);
 | |
| 
 | |
|   Assert.equal(selectedItem.label, itemToUse.querySelector(".actionContainer label").value,
 | |
|                "Should have selected correct item (" + itemType + ")");
 | |
|   let {preferredApplicationHandler} = HandlerServiceTestUtils.getHandlerInfo(itemType);
 | |
|   preferredApplicationHandler.QueryInterface(Ci.nsIWebHandlerApp);
 | |
|   Assert.equal(selectedItem.handlerApp.uriTemplate, preferredApplicationHandler.uriTemplate,
 | |
|                "App should actually be selected in the backend. (" + itemType + ")");
 | |
| 
 | |
|   // select the other web app item
 | |
|   selectedItem = await selectItemInPopup(webAppItems[1]);
 | |
| 
 | |
|   Assert.equal(selectedItem.label, itemToUse.querySelector(".actionContainer label").value,
 | |
|                "Should have selected correct item (" + itemType + ")");
 | |
|   preferredApplicationHandler = HandlerServiceTestUtils.getHandlerInfo(itemType).preferredApplicationHandler;
 | |
|   preferredApplicationHandler.QueryInterface(Ci.nsIWebHandlerApp);
 | |
|   Assert.equal(selectedItem.handlerApp.uriTemplate, preferredApplicationHandler.uriTemplate,
 | |
|                "App should actually be selected in the backend. (" + itemType + ")");
 | |
| }
 | |
| 
 | |
| add_task(async function checkDropdownBehavior() {
 | |
|   let win = gBrowser.selectedBrowser.contentWindow;
 | |
| 
 | |
|   let container = win.document.getElementById("handlersView");
 | |
| 
 | |
|   // First check a protocol handler item.
 | |
|   let mailItem = container.querySelector("richlistitem[type='mailto']");
 | |
|   Assert.ok(mailItem, "mailItem is present in handlersView.");
 | |
|   await selectStandardOptions(mailItem);
 | |
| 
 | |
|   // Then check a content menu item.
 | |
|   let pdfItem = container.querySelector("richlistitem[type='application/pdf']");
 | |
|   Assert.ok(pdfItem, "pdfItem is present in handlersView.");
 | |
|   await selectStandardOptions(pdfItem);
 | |
| });
 | |
| 
 | |
| add_task(async function sortingCheck() {
 | |
|   let win = gBrowser.selectedBrowser.contentWindow;
 | |
|   const handlerView = win.document.getElementById("handlersView");
 | |
|   const typeColumn = win.document.getElementById("typeColumn");
 | |
|   Assert.ok(typeColumn, "typeColumn is present in handlersView.");
 | |
| 
 | |
|   // Test default sorting
 | |
|   assertSortByType("ascending");
 | |
| 
 | |
|   const oldDir = typeColumn.getAttribute("sortDirection");
 | |
| 
 | |
| 
 | |
|   // Test sorting on the type column
 | |
|   typeColumn.click();
 | |
|   assertSortByType("descending");
 | |
|   Assert.notEqual(oldDir,
 | |
|                typeColumn.getAttribute("sortDirection"),
 | |
|                "Sort direction should change");
 | |
| 
 | |
|   typeColumn.click();
 | |
|   assertSortByType("ascending");
 | |
| 
 | |
|   const actionColumn = win.document.getElementById("actionColumn");
 | |
|   Assert.ok(actionColumn, "actionColumn is present in handlersView.");
 | |
| 
 | |
|   // Test sorting on the action column
 | |
|   const oldActionDir = actionColumn.getAttribute("sortDirection");
 | |
|   actionColumn.click();
 | |
|   assertSortByAction("ascending");
 | |
|   Assert.notEqual(oldActionDir,
 | |
|                actionColumn.getAttribute("sortDirection"),
 | |
|                "Sort direction should change");
 | |
| 
 | |
|   actionColumn.click();
 | |
|   assertSortByAction("descending");
 | |
| 
 | |
|   // Restore the default sort order
 | |
|   typeColumn.click();
 | |
|   assertSortByType("ascending");
 | |
| 
 | |
|   function assertSortByAction(order) {
 | |
|   Assert.equal(actionColumn.getAttribute("sortDirection"),
 | |
|                order,
 | |
|                `Sort direction should be ${order}`);
 | |
|     let siteItems = handlerView.getElementsByTagName("richlistitem");
 | |
|     for (let i = 0; i < siteItems.length - 1; ++i) {
 | |
|       let aType = siteItems[i].getAttribute("actionDescription").toLowerCase();
 | |
|       let bType = siteItems[i + 1].getAttribute("actionDescription").toLowerCase();
 | |
|       let result = 0;
 | |
|       if (aType > bType) {
 | |
|         result = 1;
 | |
|       } else if (bType > aType) {
 | |
|         result = -1;
 | |
|       }
 | |
|       if (order == "ascending") {
 | |
|         Assert.lessOrEqual(result, 0, "Should sort applications in the ascending order by action");
 | |
|       } else {
 | |
|         Assert.greaterOrEqual(result, 0, "Should sort applications in the descending order by action");
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   function assertSortByType(order) {
 | |
|   Assert.equal(typeColumn.getAttribute("sortDirection"),
 | |
|                order,
 | |
|                `Sort direction should be ${order}`);
 | |
|     let siteItems = handlerView.getElementsByTagName("richlistitem");
 | |
|     for (let i = 0; i < siteItems.length - 1; ++i) {
 | |
|       let aType = siteItems[i].getAttribute("typeDescription").toLowerCase();
 | |
|       let bType = siteItems[i + 1].getAttribute("typeDescription").toLowerCase();
 | |
|       let result = 0;
 | |
|       if (aType > bType) {
 | |
|         result = 1;
 | |
|       } else if (bType > aType) {
 | |
|         result = -1;
 | |
|       }
 | |
|       if (order == "ascending") {
 | |
|         Assert.lessOrEqual(result, 0, "Should sort applications in the ascending order by type");
 | |
|       } else {
 | |
|         Assert.greaterOrEqual(result, 0, "Should sort applications in the descending order by type");
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| });
 |