no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / docshell / test / browser / browser_browsingContext-02.js
blob8439b869b06924af46527f0eb114280cc73bc1df
1 /* Any copyright is dedicated to the Public Domain.
2    http://creativecommons.org/publicdomain/zero/1.0/ */
4 "use strict";
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";
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           };
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;
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           }
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;
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           }
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.
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           }
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           }
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           }
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");
155           let origin1 = [first, second, fifth, sixth];
156           let origin2 = [third, fourth];
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           ]);
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           }
180           let topBrowserId = topBC.browserId;
181           ok(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           }
196           ok(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           );
203           return [topBrowserId, sixth.browserId];
204         }
205       );
207       [sixth, seventh] = await Promise.all([sixth, seventh]);
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       );
230       for (let tab of [sixth, seventh]) {
231         BrowserTestUtils.removeTab(tab);
232       }
233     }
234   );