browser_file_share.js (5488B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { sinon } = ChromeUtils.importESModule( 7 "resource://testing-common/Sinon.sys.mjs" 8 ); 9 const BASE = getRootDirectory(gTestPath).replace( 10 "chrome://mochitests/content", 11 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 12 "http://example.com" 13 ); 14 const TEST_URL = BASE + "file_shareurl.html"; 15 16 let mockShareData = [ 17 { 18 name: "Test", 19 menuItemTitle: "Sharing Service Test", 20 image: 21 "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKE" + 22 "lEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==", 23 }, 24 ]; 25 26 // Setup spies for observing function calls from MacSharingService 27 let shareUrlSpy = sinon.spy(); 28 let openSharingPreferencesSpy = sinon.spy(); 29 let getSharingProvidersSpy = sinon.spy(); 30 31 let { MockRegistrar } = ChromeUtils.importESModule( 32 "resource://testing-common/MockRegistrar.sys.mjs" 33 ); 34 let mockMacSharingService = MockRegistrar.register( 35 "@mozilla.org/widget/macsharingservice;1", 36 { 37 getSharingProviders(url) { 38 getSharingProvidersSpy(url); 39 return mockShareData; 40 }, 41 shareUrl(name, url, title) { 42 shareUrlSpy(name, url, title); 43 }, 44 openSharingPreferences() { 45 openSharingPreferencesSpy(); 46 }, 47 QueryInterface: ChromeUtils.generateQI([Ci.nsIMacSharingService]), 48 } 49 ); 50 51 registerCleanupFunction(function () { 52 MockRegistrar.unregister(mockMacSharingService); 53 }); 54 55 /** 56 * Test the "Share" item menus in the tab contextmenu on MacOSX. 57 */ 58 add_task(async function test_file_menu_share() { 59 await BrowserTestUtils.withNewTab(TEST_URL, async () => { 60 // We can't toggle menubar items on OSX, so mocking instead. 61 let menu = document.getElementById("menu_FilePopup"); 62 await simulateMenuOpen(menu); 63 64 await BrowserTestUtils.waitForMutationCondition( 65 menu, 66 { childList: true }, 67 () => menu.querySelector(".share-tab-url-item") 68 ); 69 ok(true, "Got Share item"); 70 71 let popup = menu.querySelector(".share-tab-url-item").menupopup; 72 await simulateMenuOpen(popup); 73 ok(getSharingProvidersSpy.calledOnce, "getSharingProviders called"); 74 75 info( 76 "Check we have copy link, a service and one extra menu item for the More... button" 77 ); 78 let items = Array.from(popup.querySelectorAll("menuitem")); 79 is(items.length, 3, "There should be 2 sharing services."); 80 81 info("Click on the sharing service"); 82 let shareButton = items.find( 83 t => t.label == mockShareData[0].menuItemTitle 84 ); 85 is( 86 shareButton.label, 87 mockShareData[0].menuItemTitle, 88 "Share button's label should match the service's menu item title. " 89 ); 90 is( 91 shareButton.getAttribute("share-name"), 92 mockShareData[0].name, 93 "Share button's share-name value should match the service's name. " 94 ); 95 96 shareButton.doCommand(); 97 98 ok(shareUrlSpy.calledOnce, "shareUrl called"); 99 100 info("Check the correct data was shared."); 101 let [name, url, title] = shareUrlSpy.getCall(0).args; 102 is(name, mockShareData[0].name, "Shared correct service name"); 103 is(url, TEST_URL, "Shared correct URL"); 104 is(title, "Sharing URL", "Shared the correct title."); 105 await simulateMenuClosed(popup); 106 await simulateMenuClosed(menu); 107 108 info("Test the copy link button"); 109 await simulateMenuOpen(menu); 110 popup = menu.querySelector(".share-tab-url-item").menupopup; 111 await simulateMenuOpen(popup); 112 // Since the menu was collapsed previously, the popup needs to get the 113 // providers again. 114 ok(getSharingProvidersSpy.calledTwice, "getSharingProviders called again"); 115 items = Array.from(popup.querySelectorAll("menuitem")); 116 is(items.length, 3, "There should be 3 sharing services."); 117 info("Click on the Copy Link item"); 118 let copyLinkItem = items.find( 119 item => item.dataset.l10nId == "menu-share-copy-link" 120 ); 121 await SimpleTest.promiseClipboardChange(TEST_URL, () => 122 copyLinkItem.doCommand() 123 ); 124 await simulateMenuClosed(popup); 125 await simulateMenuClosed(menu); 126 127 info("Test the More... button"); 128 129 await simulateMenuOpen(menu); 130 popup = menu.querySelector(".share-tab-url-item").menupopup; 131 await simulateMenuOpen(popup); 132 // Since the menu was collapsed previously, the popup needs to get the 133 // providers again. 134 is(getSharingProvidersSpy.callCount, 3, "getSharingProviders called again"); 135 items = popup.querySelectorAll("menuitem"); 136 is(items.length, 3, "There should be 3 sharing services."); 137 138 info("Click on the More Button"); 139 let moreButton = items[2]; 140 moreButton.doCommand(); 141 ok(openSharingPreferencesSpy.calledOnce, "openSharingPreferences called"); 142 // Tidy up: 143 await simulateMenuClosed(popup); 144 await simulateMenuClosed(menu); 145 }); 146 }); 147 148 async function simulateMenuOpen(menu) { 149 return new Promise(resolve => { 150 menu.addEventListener("popupshown", resolve, { once: true }); 151 menu.dispatchEvent(new MouseEvent("popupshowing", { bubbles: true })); 152 menu.dispatchEvent(new MouseEvent("popupshown", { bubbles: true })); 153 }); 154 } 155 156 async function simulateMenuClosed(menu) { 157 return new Promise(resolve => { 158 menu.addEventListener("popuphidden", resolve, { once: true }); 159 menu.dispatchEvent(new MouseEvent("popuphiding", { bubbles: true })); 160 menu.dispatchEvent(new MouseEvent("popuphidden", { bubbles: true })); 161 }); 162 }