browser_aboutdebugging_addons_remote_runtime.js (4781B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const NETWORK_RUNTIME_HOST = "localhost:6080"; 7 const NETWORK_RUNTIME_APP_NAME = "TestNetworkApp"; 8 const USB_RUNTIME_ID = "test-runtime-id"; 9 const USB_RUNTIME_DEVICE_NAME = "test device name"; 10 const USB_RUNTIME_APP_NAME = "TestUsbApp"; 11 12 // Test that addons are displayed and updated for USB runtimes when expected. 13 add_task(async function () { 14 const mocks = new Mocks(); 15 16 const { document, tab, window } = await openAboutDebugging(); 17 await selectThisFirefoxPage(document, window.AboutDebugging.store); 18 19 info("Prepare USB client mock"); 20 const usbClient = mocks.createUSBRuntime(USB_RUNTIME_ID, { 21 deviceName: USB_RUNTIME_DEVICE_NAME, 22 name: USB_RUNTIME_APP_NAME, 23 }); 24 mocks.emitUSBUpdate(); 25 26 info("Test addons in runtime page for USB client"); 27 await connectToRuntime(USB_RUNTIME_DEVICE_NAME, document); 28 await waitForRuntimePage(USB_RUNTIME_APP_NAME, document); 29 await testAddonsOnMockedRemoteClient( 30 usbClient, 31 mocks.thisFirefoxClient, 32 document 33 ); 34 35 info("Prepare Network client mock"); 36 const networkClient = mocks.createNetworkRuntime(NETWORK_RUNTIME_HOST, { 37 name: NETWORK_RUNTIME_APP_NAME, 38 }); 39 40 info("Test addons in runtime page for Network client"); 41 await connectToRuntime(NETWORK_RUNTIME_HOST, document); 42 await waitForRuntimePage(NETWORK_RUNTIME_APP_NAME, document); 43 await testAddonsOnMockedRemoteClient( 44 networkClient, 45 mocks.thisFirefoxClient, 46 document 47 ); 48 49 await removeTab(tab); 50 }); 51 52 /** 53 * Check that addons are visible in the runtime page for a remote client (USB or network). 54 */ 55 async function testAddonsOnMockedRemoteClient( 56 remoteClient, 57 firefoxClient, 58 document 59 ) { 60 const extensionPane = getDebugTargetPane("Extensions", document); 61 info("Check an empty target pane message is displayed"); 62 ok( 63 extensionPane.querySelector(".qa-debug-target-list-empty"), 64 "Extensions list is empty" 65 ); 66 67 info("Add an extension to the remote client"); 68 const addon = { name: "Test extension name", debuggable: true }; 69 const temporaryAddon = { 70 name: "Test temporary extension", 71 debuggable: true, 72 temporarilyInstalled: true, 73 }; 74 remoteClient.listAddons = () => [addon, temporaryAddon]; 75 remoteClient._eventEmitter.emit("addonListChanged"); 76 77 info("Wait until the extension appears"); 78 await waitUntil( 79 () => !extensionPane.querySelector(".qa-debug-target-list-empty") 80 ); 81 82 const extensionTarget = findDebugTargetByText( 83 "Test extension name", 84 document 85 ); 86 ok(extensionTarget, "Extension target appeared for the remote runtime"); 87 88 const temporaryExtensionTarget = findDebugTargetByText( 89 "Test temporary extension", 90 document 91 ); 92 ok( 93 temporaryExtensionTarget, 94 "Temporary Extension target appeared for the remote runtime" 95 ); 96 97 const removeButton = temporaryExtensionTarget.querySelector( 98 ".qa-temporary-extension-remove-button" 99 ); 100 ok(removeButton, "Remove button expected for the temporary extension"); 101 102 const reloadButton = temporaryExtensionTarget.querySelector( 103 ".qa-temporary-extension-reload-button" 104 ); 105 ok(reloadButton, "Reload button expected for the temporary extension"); 106 107 // The goal here is to check that runtimes addons are only updated when the remote 108 // runtime is sending addonListChanged events. The reason for this test is because the 109 // previous implementation was updating the remote runtime extensions list when the 110 // _local_ AddonManager was updated. 111 info("Remove the extension from the remote client WITHOUT sending an event"); 112 remoteClient.listAddons = () => []; 113 114 info("Simulate an addon update on the ThisFirefox client"); 115 firefoxClient._eventEmitter.emit("addonListChanged"); 116 117 // To avoid wait for a set period of time we trigger another async update, adding a new 118 // tab. We assume that if the addon update mechanism had started, it would also be done 119 // when the new tab was processed. 120 info("Wait until the tab target for 'http://some.random/url.com' appears"); 121 const testTab = { 122 retrieveFavicon: () => {}, 123 outerWindowID: 0, 124 traits: {}, 125 url: "http://some.random/url.com", 126 }; 127 remoteClient.listTabs = () => [testTab]; 128 remoteClient._eventEmitter.emit("tabListChanged"); 129 await waitUntil(() => 130 findDebugTargetByText("http://some.random/url.com", document) 131 ); 132 133 ok( 134 findDebugTargetByText("Test extension name", document), 135 "The test extension is still visible" 136 ); 137 138 info( 139 "Emit `addonListChanged` on remoteClient and wait for the target list to update" 140 ); 141 remoteClient._eventEmitter.emit("addonListChanged"); 142 await waitUntil( 143 () => !findDebugTargetByText("Test extension name", document) 144 ); 145 }