browser_browsingContext-02.js (7863B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 add_task(async function () { 7 await BrowserTestUtils.withNewTab( 8 { gBrowser, url: "about:blank" }, 9 async function (browser) { 10 const BASE1 = getRootDirectory(gTestPath).replace( 11 "chrome://mochitests/content", 12 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 13 "http://example.com" 14 ); 15 const BASE2 = getRootDirectory(gTestPath).replace( 16 "chrome://mochitests/content", 17 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 18 "http://test1.example.com" 19 ); 20 const URL = BASE1 + "onload_message.html"; 21 let sixth = BrowserTestUtils.waitForNewTab( 22 gBrowser, 23 URL + "#sixth", 24 true, 25 true 26 ); 27 let seventh = BrowserTestUtils.waitForNewTab( 28 gBrowser, 29 URL + "#seventh", 30 true, 31 true 32 ); 33 let browserIds = await SpecialPowers.spawn( 34 browser, 35 [{ base1: BASE1, base2: BASE2 }], 36 async function ({ base1, base2 }) { 37 let top = content; 38 top.name = "top"; 39 top.location.href += "#top"; 40 41 let contexts = { 42 top: top.location.href, 43 first: base1 + "dummy_page.html#first", 44 third: base2 + "dummy_page.html#third", 45 second: base1 + "dummy_page.html#second", 46 fourth: base2 + "dummy_page.html#fourth", 47 fifth: base1 + "dummy_page.html#fifth", 48 sixth: base1 + "onload_message.html#sixth", 49 seventh: base1 + "onload_message.html#seventh", 50 }; 51 52 function addFrame(target, name) { 53 return content.SpecialPowers.spawn( 54 target, 55 [name, contexts[name]], 56 async (name, context) => { 57 let doc = this.content.document; 58 59 let frame = doc.createElement("iframe"); 60 doc.body.appendChild(frame); 61 frame.name = name; 62 frame.src = context; 63 await new Promise(resolve => { 64 frame.addEventListener("load", resolve, { once: true }); 65 }); 66 return frame.browsingContext; 67 } 68 ); 69 } 70 71 function addWindow(target, name, { options, resolve }) { 72 return content.SpecialPowers.spawn( 73 target, 74 [name, contexts[name], options, resolve], 75 (name, context, options, resolve) => { 76 let win = this.content.open(context, name, options); 77 let bc = win && win.docShell.browsingContext; 78 79 if (resolve) { 80 return new Promise(resolve => 81 this.content.addEventListener("message", () => resolve(bc)) 82 ); 83 } 84 return Promise.resolve({ name }); 85 } 86 ); 87 } 88 89 // We're going to create a tree that looks like the 90 // following. 91 // 92 // top sixth seventh 93 // / \ 94 // / \ / 95 // first second 96 // / \ / 97 // / \ 98 // third fourth - - - 99 // / 100 // / 101 // fifth 102 // 103 // The idea is to have one top level non-auxiliary browsing 104 // context, five nested, one top level auxiliary with an 105 // opener, and one top level without an opener. Given that 106 // set of related and one unrelated browsing contexts we 107 // wish to confirm that targeting is able to find 108 // appropriate browsing contexts. 109 110 // WindowGlobalChild.findBrowsingContextWithName requires access 111 // checks, which can only be performed in the process of the accessor 112 // WindowGlobalChild. 113 function findWithName(bc, name) { 114 return content.SpecialPowers.spawn(bc, [name], name => { 115 return content.windowGlobalChild.findBrowsingContextWithName( 116 name 117 ); 118 }); 119 } 120 121 async function reachable(start, target) { 122 info(start.name, target.name); 123 is( 124 await findWithName(start, target.name), 125 target, 126 [start.name, "can reach", target.name].join(" ") 127 ); 128 } 129 130 async function unreachable(start, target) { 131 is( 132 await findWithName(start, target.name), 133 null, 134 [start.name, "can't reach", target.name].join(" ") 135 ); 136 } 137 138 let first = await addFrame(top, "first"); 139 info("first"); 140 let second = await addFrame(top, "second"); 141 info("second"); 142 let third = await addFrame(first, "third"); 143 info("third"); 144 let fourth = await addFrame(first, "fourth"); 145 info("fourth"); 146 let fifth = await addFrame(fourth, "fifth"); 147 info("fifth"); 148 let sixth = await addWindow(fourth, "sixth", { resolve: true }); 149 info("sixth"); 150 let seventh = await addWindow(fourth, "seventh", { 151 options: ["noopener"], 152 }); 153 info("seventh"); 154 155 let origin1 = [first, second, fifth, sixth]; 156 let origin2 = [third, fourth]; 157 158 let topBC = BrowsingContext.getFromWindow(top); 159 let frames = new Map([ 160 [topBC, [topBC, first, second, third, fourth, fifth, sixth]], 161 [first, [topBC, ...origin1, third, fourth]], 162 [second, [topBC, ...origin1, third, fourth]], 163 [third, [topBC, ...origin2, fifth, sixth]], 164 [fourth, [topBC, ...origin2, fifth, sixth]], 165 [fifth, [topBC, ...origin1, third, fourth]], 166 [sixth, [...origin1, third, fourth]], 167 ]); 168 169 for (let [start, accessible] of frames) { 170 for (let frame of frames.keys()) { 171 if (accessible.includes(frame)) { 172 await reachable(start, frame); 173 } else { 174 await unreachable(start, frame); 175 } 176 } 177 await unreachable(start, seventh); 178 } 179 180 let topBrowserId = topBC.browserId; 181 Assert.greater(topBrowserId, 0, "Should have a browser ID."); 182 for (let [name, bc] of Object.entries({ 183 first, 184 second, 185 third, 186 fourth, 187 fifth, 188 })) { 189 is( 190 bc.browserId, 191 topBrowserId, 192 `${name} frame should have the same browserId as top.` 193 ); 194 } 195 196 Assert.greater(sixth.browserId, 0, "sixth should have a browserId."); 197 isnot( 198 sixth.browserId, 199 topBrowserId, 200 "sixth frame should have a different browserId to top." 201 ); 202 203 return [topBrowserId, sixth.browserId]; 204 } 205 ); 206 207 [sixth, seventh] = await Promise.all([sixth, seventh]); 208 209 is( 210 browser.browserId, 211 browserIds[0], 212 "browser should have the right browserId." 213 ); 214 is( 215 browser.browsingContext.browserId, 216 browserIds[0], 217 "browser's BrowsingContext should have the right browserId." 218 ); 219 is( 220 sixth.linkedBrowser.browserId, 221 browserIds[1], 222 "sixth should have the right browserId." 223 ); 224 is( 225 sixth.linkedBrowser.browsingContext.browserId, 226 browserIds[1], 227 "sixth's BrowsingContext should have the right browserId." 228 ); 229 230 for (let tab of [sixth, seventh]) { 231 BrowserTestUtils.removeTab(tab); 232 } 233 } 234 ); 235 });