browser_handle_command_retry_fallback.js (3578B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { isInitialDocument } = ChromeUtils.importESModule( 7 "chrome://remote/content/shared/messagehandler/transports/BrowsingContextUtils.sys.mjs" 8 ); 9 10 // We are forcing the actors to shutdown while queries are unresolved. 11 const { PromiseTestUtils } = ChromeUtils.importESModule( 12 "resource://testing-common/PromiseTestUtils.sys.mjs" 13 ); 14 PromiseTestUtils.allowMatchingRejectionsGlobally( 15 /Actor 'MessageHandlerFrame' destroyed before query 'MessageHandlerFrameParent:sendCommand' was resolved/ 16 ); 17 18 // The tests in this file assert the fallback retry behavior for MessageHandler commands. 19 // We call "blocked" commands from resources/modules/windowglobal/retry.sys.mjs 20 // and then trigger reload and navigations to simulate AbortErrors and force the 21 // MessageHandler to retry the commands, when requested. 22 23 // If no retryOnAbort argument is provided, and the preference "remote.retry-on-abort" 24 // is set to false the framework should retry only if context is on the initial document. 25 add_task(async function test_default_fallback_retry_initial_document_only() { 26 let tab = BrowserTestUtils.addTab( 27 gBrowser, 28 "https://example.com/document-builder.sjs?html=tab" 29 ); 30 31 let rootMessageHandler = createRootMessageHandler( 32 "session-id-retry-initial-document" 33 ); 34 35 try { 36 const initialBrowsingContext = tab.linkedBrowser.browsingContext; 37 ok( 38 isInitialDocument(initialBrowsingContext), 39 "Module method needs to run in the initial document" 40 ); 41 42 info("Call a module method which will throw"); 43 const onBlockedOneTime = rootMessageHandler.handleCommand({ 44 moduleName: "retry", 45 commandName: "blockedOneTime", 46 destination: { 47 type: WindowGlobalMessageHandler.type, 48 id: initialBrowsingContext.id, 49 }, 50 }); 51 52 await onBlockedOneTime; 53 54 ok( 55 !isInitialDocument(tab.linkedBrowser.browsingContext), 56 "module method to be successful" 57 ); 58 } finally { 59 await cleanup(rootMessageHandler, tab, false); 60 } 61 62 // Now try again with a normal navigation which should not retry. 63 64 tab = BrowserTestUtils.addTab( 65 gBrowser, 66 "https://example.com/document-builder.sjs?html=tab" 67 ); 68 await BrowserTestUtils.browserLoaded(tab.linkedBrowser); 69 70 try { 71 rootMessageHandler = createRootMessageHandler("session-id-no-retry"); 72 const browsingContext = tab.linkedBrowser.browsingContext; 73 74 info("Call a module method which will throw"); 75 const onBlockedOneTime = rootMessageHandler.handleCommand({ 76 moduleName: "retry", 77 commandName: "blockedOneTime", 78 destination: { 79 type: WindowGlobalMessageHandler.type, 80 id: browsingContext.id, 81 }, 82 }); 83 84 // Reloading the tab will reject the pending query with an AbortError. 85 await BrowserTestUtils.reloadTab(tab); 86 87 await Assert.rejects( 88 onBlockedOneTime, 89 e => e.name == "DiscardedBrowsingContextError", 90 "Caught the expected abort error when reloading" 91 ); 92 } finally { 93 await cleanup(rootMessageHandler, tab); 94 } 95 }); 96 97 async function cleanup(rootMessageHandler, tab) { 98 const browsingContext = tab.linkedBrowser.browsingContext; 99 // Cleanup global JSM state in the test module. 100 await rootMessageHandler.handleCommand({ 101 moduleName: "retry", 102 commandName: "cleanup", 103 destination: { 104 type: WindowGlobalMessageHandler.type, 105 id: browsingContext.id, 106 }, 107 }); 108 109 rootMessageHandler.destroy(); 110 gBrowser.removeTab(tab); 111 }