browser_resources_console_messages_navigation.js (5458B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test the resource command API around CONSOLE_MESSAGE when navigating 7 // tab and inner iframes to distinct origin/processes. 8 9 const TEST_URL = URL_ROOT_COM_SSL + "doc_console.html"; 10 const TEST_IFRAME_URL = URL_ROOT_ORG_SSL + "doc_console_iframe.html"; 11 const TEST_DOMAIN = "https://example.org"; 12 add_task(async function () { 13 const START_URL = "data:text/html;charset=utf-8,foo"; 14 const tab = await addTab(START_URL); 15 16 const { client, resourceCommand, targetCommand } = 17 await initResourceCommand(tab); 18 19 await testCrossProcessTabNavigation(tab.linkedBrowser, resourceCommand); 20 await testCrossProcessIframeNavigation(tab.linkedBrowser, resourceCommand); 21 22 targetCommand.destroy(); 23 await client.close(); 24 BrowserTestUtils.removeTab(tab); 25 }); 26 27 async function testCrossProcessTabNavigation(browser, resourceCommand) { 28 info( 29 "Navigate the top level document from data: URI to a https document including remote iframes" 30 ); 31 32 let doneResolve; 33 const messages = []; 34 const onConsoleLogsComplete = new Promise(resolve => (doneResolve = resolve)); 35 36 const onAvailable = resources => { 37 messages.push(...resources); 38 if (messages.length == 2) { 39 doneResolve(); 40 } 41 }; 42 43 await resourceCommand.watchResources( 44 [resourceCommand.TYPES.CONSOLE_MESSAGE], 45 { onAvailable } 46 ); 47 48 const onLoaded = BrowserTestUtils.browserLoaded(browser); 49 BrowserTestUtils.startLoadingURIString(browser, TEST_URL); 50 await onLoaded; 51 52 info("Wait for log message"); 53 await onConsoleLogsComplete; 54 55 // messages are coming from different targets so the order isn't guaranteed 56 const topLevelMessageResource = messages.find(resource => 57 resource.filename.startsWith(URL_ROOT_COM_SSL) 58 ); 59 const iframeMessage = messages.find(resource => 60 resource.filename.startsWith("data:") 61 ); 62 63 assertConsoleMessage(resourceCommand, topLevelMessageResource, { 64 targetFront: resourceCommand.targetCommand.targetFront, 65 messageText: "top-level document log", 66 }); 67 assertConsoleMessage(resourceCommand, iframeMessage, { 68 targetFront: resourceCommand.targetCommand 69 .getAllTargets([resourceCommand.targetCommand.TYPES.FRAME]) 70 .find(t => t.url.startsWith("data:")), 71 messageText: "data url data log", 72 }); 73 74 resourceCommand.unwatchResources([resourceCommand.TYPES.CONSOLE_MESSAGE], { 75 onAvailable, 76 }); 77 } 78 79 async function testCrossProcessIframeNavigation(browser, resourceCommand) { 80 info("Navigate an inner iframe from data: URI to a https remote URL"); 81 82 let doneResolve; 83 const messages = []; 84 const onConsoleLogsComplete = new Promise(resolve => (doneResolve = resolve)); 85 86 const onAvailable = resources => { 87 messages.push( 88 ...resources.filter(r => !r.arguments[0].startsWith("[WORKER] started")) 89 ); 90 if (messages.length == 3) { 91 doneResolve(); 92 } 93 }; 94 95 await resourceCommand.watchResources( 96 [resourceCommand.TYPES.CONSOLE_MESSAGE], 97 { 98 onAvailable, 99 } 100 ); 101 102 // messages are coming from different targets so the order isn't guaranteed 103 const topLevelMessageResource = messages.find(resource => 104 resource.arguments[0].startsWith("top-level") 105 ); 106 const dataUrlMessageResource = messages.find(resource => 107 resource.arguments[0].startsWith("data url") 108 ); 109 110 // Assert cached messages from the previous top document 111 assertConsoleMessage(resourceCommand, topLevelMessageResource, { 112 messageText: "top-level document log", 113 }); 114 assertConsoleMessage(resourceCommand, dataUrlMessageResource, { 115 messageText: "data url data log", 116 }); 117 118 // Navigate the iframe to another origin/process 119 await SpecialPowers.spawn(browser, [TEST_IFRAME_URL], function (iframeUrl) { 120 const iframe = content.document.querySelector("iframe"); 121 iframe.src = iframeUrl; 122 }); 123 124 info("Wait for log message"); 125 await onConsoleLogsComplete; 126 127 // iframeTarget will be different if Fission is on or off 128 const iframeTarget = await getIframeTargetFront( 129 resourceCommand.targetCommand 130 ); 131 132 const iframeMessageResource = messages.find(resource => 133 resource.arguments[0].endsWith("iframe log") 134 ); 135 assertConsoleMessage(resourceCommand, iframeMessageResource, { 136 messageText: `${TEST_DOMAIN} iframe log`, 137 targetFront: iframeTarget, 138 }); 139 140 resourceCommand.unwatchResources([resourceCommand.TYPES.CONSOLE_MESSAGE], { 141 onAvailable, 142 }); 143 } 144 145 function assertConsoleMessage(resourceCommand, messageResource, expected) { 146 is( 147 messageResource.resourceType, 148 resourceCommand.TYPES.CONSOLE_MESSAGE, 149 "Resource is a console message" 150 ); 151 if (expected.targetFront) { 152 is( 153 messageResource.targetFront, 154 expected.targetFront, 155 "Message has the correct target front" 156 ); 157 } 158 is( 159 messageResource.arguments[0], 160 expected.messageText, 161 "The correct type of message" 162 ); 163 } 164 165 async function getIframeTargetFront(targetCommand) { 166 const frameTargets = targetCommand.getAllTargets([targetCommand.TYPES.FRAME]); 167 const browsingContextID = await SpecialPowers.spawn( 168 gBrowser.selectedBrowser, 169 [], 170 () => { 171 return content.document.querySelector("iframe").browsingContext.id; 172 } 173 ); 174 const iframeTarget = frameTargets.find(target => { 175 return target.browsingContextID == browsingContextID; 176 }); 177 ok(iframeTarget, "Found the iframe target front"); 178 return iframeTarget; 179 }