browser_handle_simple_command.js (7394B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { RootMessageHandler } = ChromeUtils.importESModule( 7 "chrome://remote/content/shared/messagehandler/RootMessageHandler.sys.mjs" 8 ); 9 10 // Test calling methods only implemented in the root version of a module. 11 add_task(async function test_rootModule_command() { 12 const rootMessageHandler = createRootMessageHandler("session-id-rootModule"); 13 const rootValue = await rootMessageHandler.handleCommand({ 14 moduleName: "command", 15 commandName: "testRootModule", 16 destination: { 17 type: RootMessageHandler.type, 18 }, 19 }); 20 21 is( 22 rootValue, 23 "root-value", 24 "Retrieved the expected value from testRootModule" 25 ); 26 27 rootMessageHandler.destroy(); 28 }); 29 30 // Test calling methods only implemented in the windowglobal-in-root version of 31 // a module. 32 add_task(async function test_windowglobalInRootModule_command() { 33 const browsingContextId = gBrowser.selectedBrowser.browsingContext.id; 34 35 const rootMessageHandler = createRootMessageHandler( 36 "session-id-windowglobalInRootModule" 37 ); 38 const interceptedValue = await rootMessageHandler.handleCommand({ 39 moduleName: "command", 40 commandName: "testInterceptModule", 41 destination: { 42 type: WindowGlobalMessageHandler.type, 43 id: browsingContextId, 44 }, 45 }); 46 47 is( 48 interceptedValue, 49 "intercepted-value", 50 "Retrieved the expected value from testInterceptModule" 51 ); 52 53 rootMessageHandler.destroy(); 54 }); 55 56 // Test calling methods only implemented in the windowglobal version of a 57 // module. 58 add_task(async function test_windowglobalModule_command() { 59 const browsingContextId = gBrowser.selectedBrowser.browsingContext.id; 60 61 const rootMessageHandler = createRootMessageHandler( 62 "session-id-windowglobalModule" 63 ); 64 const windowGlobalValue = await rootMessageHandler.handleCommand({ 65 moduleName: "command", 66 commandName: "testWindowGlobalModule", 67 destination: { 68 type: WindowGlobalMessageHandler.type, 69 id: browsingContextId, 70 }, 71 }); 72 73 is( 74 windowGlobalValue, 75 "windowglobal-value", 76 "Retrieved the expected value from testWindowGlobalModule" 77 ); 78 79 rootMessageHandler.destroy(); 80 }); 81 82 // Test calling a windowglobal module as soon as possible. 83 add_task(async function test_windowglobalModule_early_command() { 84 const rootMessageHandler = createRootMessageHandler( 85 "session-id-windowglobalModule-early" 86 ); 87 88 info("Setup an observer to send a command as soon as the context is created"); 89 const onContext = new Promise((resolve, reject) => { 90 const onContextAttached = async browsingContext => { 91 try { 92 const result = await rootMessageHandler.handleCommand({ 93 moduleName: "command", 94 commandName: "testWindowGlobalModule", 95 destination: { 96 type: WindowGlobalMessageHandler.type, 97 id: browsingContext.id, 98 }, 99 }); 100 info("Early command succeeded, resolve the retrieved value"); 101 resolve(result); 102 } catch (e) { 103 info("Early command failed, reject"); 104 reject(e); 105 } finally { 106 Services.obs.removeObserver( 107 onContextAttached, 108 "browsing-context-attached" 109 ); 110 } 111 }; 112 Services.obs.addObserver(onContextAttached, "browsing-context-attached"); 113 }); 114 115 const tab = await addTab("https://example.com/document-builder.sjs?html=tab"); 116 117 const windowGlobalValue = await onContext; 118 is( 119 windowGlobalValue, 120 "windowglobal-value", 121 "Retrieved the expected value from testWindowGlobalModule" 122 ); 123 124 rootMessageHandler.destroy(); 125 126 gBrowser.removeTab(tab); 127 }); 128 129 // Test calling a method on a module which is only available in the "windowglobal" 130 // folder. This will check that the MessageHandler/ModuleCache correctly moves 131 // on to the next layer when no implementation can be found in the root layer. 132 add_task(async function test_windowglobalOnlyModule_command() { 133 const browsingContextId = gBrowser.selectedBrowser.browsingContext.id; 134 135 const rootMessageHandler = createRootMessageHandler( 136 "session-id-windowglobalOnlyModule" 137 ); 138 const windowGlobalOnlyValue = await rootMessageHandler.handleCommand({ 139 moduleName: "commandwindowglobalonly", 140 commandName: "testOnlyInWindowGlobal", 141 destination: { 142 type: WindowGlobalMessageHandler.type, 143 id: browsingContextId, 144 }, 145 }); 146 147 is( 148 windowGlobalOnlyValue, 149 "only-in-windowglobal", 150 "Retrieved the expected value from testOnlyInWindowGlobal" 151 ); 152 153 rootMessageHandler.destroy(); 154 }); 155 156 // Try to create 2 sessions which will both set values in individual modules 157 // via a command `testSetValue`, and then retrieve the values via another 158 // command `testGetValue`. 159 // This will ensure that different sessions use different module instances. 160 add_task(async function test_multisession() { 161 const browsingContextId = gBrowser.selectedBrowser.browsingContext.id; 162 163 const rootMessageHandler1 = createRootMessageHandler( 164 "session-id-multisession-1" 165 ); 166 const rootMessageHandler2 = createRootMessageHandler( 167 "session-id-multisession-2" 168 ); 169 170 info("Set value for session 1"); 171 await rootMessageHandler1.handleCommand({ 172 moduleName: "command", 173 commandName: "testSetValue", 174 params: { value: "session1-value" }, 175 destination: { 176 type: WindowGlobalMessageHandler.type, 177 id: browsingContextId, 178 }, 179 }); 180 181 info("Set value for session 2"); 182 await rootMessageHandler2.handleCommand({ 183 moduleName: "command", 184 commandName: "testSetValue", 185 params: { value: "session2-value" }, 186 destination: { 187 type: WindowGlobalMessageHandler.type, 188 id: browsingContextId, 189 }, 190 }); 191 192 const session1Value = await rootMessageHandler1.handleCommand({ 193 moduleName: "command", 194 commandName: "testGetValue", 195 destination: { 196 type: WindowGlobalMessageHandler.type, 197 id: browsingContextId, 198 }, 199 }); 200 201 is( 202 session1Value, 203 "session1-value", 204 "Retrieved the expected value for session 1" 205 ); 206 207 const session2Value = await rootMessageHandler2.handleCommand({ 208 moduleName: "command", 209 commandName: "testGetValue", 210 destination: { 211 type: WindowGlobalMessageHandler.type, 212 id: browsingContextId, 213 }, 214 }); 215 216 is( 217 session2Value, 218 "session2-value", 219 "Retrieved the expected value for session 2" 220 ); 221 222 rootMessageHandler1.destroy(); 223 rootMessageHandler2.destroy(); 224 }); 225 226 // Test calling a method from the windowglobal-in-root module which will 227 // internally forward to the windowglobal module and will return a composite 228 // result built both in parent and content process. 229 add_task(async function test_forwarding_command() { 230 const browsingContextId = gBrowser.selectedBrowser.browsingContext.id; 231 232 const rootMessageHandler = createRootMessageHandler("session-id-forwarding"); 233 const interceptAndForwardValue = await rootMessageHandler.handleCommand({ 234 moduleName: "command", 235 commandName: "testInterceptAndForwardModule", 236 params: { id: "value" }, 237 destination: { 238 type: WindowGlobalMessageHandler.type, 239 id: browsingContextId, 240 }, 241 }); 242 243 is( 244 interceptAndForwardValue, 245 "intercepted-and-forward+forward-to-windowglobal-value", 246 "Retrieved the expected value from testInterceptAndForwardModule" 247 ); 248 249 rootMessageHandler.destroy(); 250 });