|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /////////////////////////////////////////////////////////////////////////// |
|
6 // |
|
7 // Utilities for navigation tests |
|
8 // |
|
9 /////////////////////////////////////////////////////////////////////////// |
|
10 |
|
11 var body = "This frame was navigated."; |
|
12 var target_url = "data:text/html,<html><body>" + body + "</body></html>"; |
|
13 |
|
14 var popup_body = "This is a popup"; |
|
15 var target_popup_url = "data:text/html,<html><body>" + popup_body + "</body></html>"; |
|
16 |
|
17 /////////////////////////////////////////////////////////////////////////// |
|
18 // Functions that navigate frames |
|
19 /////////////////////////////////////////////////////////////////////////// |
|
20 |
|
21 function navigateByLocation(wnd) { |
|
22 try { |
|
23 wnd.location = target_url; |
|
24 } catch(ex) { |
|
25 // We need to keep our finished frames count consistent. |
|
26 // Oddly, this ends up simulating the behavior of IE7. |
|
27 window.open(target_url, "_blank", "width=10,height=10"); |
|
28 } |
|
29 } |
|
30 |
|
31 function navigateByOpen(name) { |
|
32 window.open(target_url, name, "width=10,height=10"); |
|
33 } |
|
34 |
|
35 function navigateByForm(name) { |
|
36 var form = document.createElement("form"); |
|
37 form.action = target_url; |
|
38 form.method = "POST"; |
|
39 form.target = name; document.body.appendChild(form); |
|
40 form.submit(); |
|
41 } |
|
42 |
|
43 var hyperlink_count = 0; |
|
44 |
|
45 function navigateByHyperlink(name) { |
|
46 var link = document.createElement("a"); |
|
47 link.href = target_url; |
|
48 link.target = name; |
|
49 link.id = "navigation_hyperlink_" + hyperlink_count++; |
|
50 document.body.appendChild(link); |
|
51 sendMouseEvent({type:"click"}, link.id); |
|
52 } |
|
53 |
|
54 /////////////////////////////////////////////////////////////////////////// |
|
55 // Functions that call into Mochitest framework |
|
56 /////////////////////////////////////////////////////////////////////////// |
|
57 |
|
58 function isNavigated(wnd, message) { |
|
59 var result = null; |
|
60 try { |
|
61 result = SpecialPowers.wrap(wnd).document.body.innerHTML; |
|
62 } catch(ex) { |
|
63 result = ex; |
|
64 } |
|
65 is(result, body, message); |
|
66 } |
|
67 |
|
68 function isBlank(wnd, message) { |
|
69 var result = null; |
|
70 try { |
|
71 result = wnd.document.body.innerHTML; |
|
72 } catch(ex) { |
|
73 result = ex; |
|
74 } |
|
75 is(result, "This is a blank document.", message); |
|
76 } |
|
77 |
|
78 function isAccessible(wnd, message) { |
|
79 try { |
|
80 wnd.document.body.innerHTML; |
|
81 ok(true, message); |
|
82 } catch(ex) { |
|
83 ok(false, message); |
|
84 } |
|
85 } |
|
86 |
|
87 function isInaccessible(wnd, message) { |
|
88 try { |
|
89 wnd.document.body.innerHTML; |
|
90 ok(false, message); |
|
91 } catch(ex) { |
|
92 ok(true, message); |
|
93 } |
|
94 } |
|
95 |
|
96 /////////////////////////////////////////////////////////////////////////// |
|
97 // Functions that require UniversalXPConnect privilege |
|
98 /////////////////////////////////////////////////////////////////////////// |
|
99 |
|
100 function xpcEnumerateContentWindows(callback) { |
|
101 |
|
102 var Ci = SpecialPowers.Ci; |
|
103 var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"] |
|
104 .getService(Ci.nsIWindowWatcher); |
|
105 var enumerator = ww.getWindowEnumerator(); |
|
106 |
|
107 var contentWindows = []; |
|
108 |
|
109 while (enumerator.hasMoreElements()) { |
|
110 var win = enumerator.getNext(); |
|
111 if (/ChromeWindow/.exec(win)) { |
|
112 var docshellTreeNode = win.QueryInterface(Ci.nsIInterfaceRequestor) |
|
113 .getInterface(Ci.nsIWebNavigation) |
|
114 .QueryInterface(Ci.nsIDocShellTreeItem); |
|
115 var childCount = docshellTreeNode.childCount; |
|
116 for (var i = 0; i < childCount; ++i) { |
|
117 var childTreeNode = docshellTreeNode.getChildAt(i); |
|
118 |
|
119 // we're only interested in content docshells |
|
120 if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent) |
|
121 continue; |
|
122 |
|
123 var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation); |
|
124 contentWindows.push(webNav.document.defaultView); |
|
125 } |
|
126 } else { |
|
127 contentWindows.push(win); |
|
128 } |
|
129 } |
|
130 |
|
131 while (contentWindows.length > 0) |
|
132 callback(contentWindows.pop()); |
|
133 } |
|
134 |
|
135 // Note: This only searches for top-level frames with this name. |
|
136 function xpcGetFramesByName(name) { |
|
137 var results = []; |
|
138 |
|
139 xpcEnumerateContentWindows(function(win) { |
|
140 if (win.name == name) |
|
141 results.push(win); |
|
142 }); |
|
143 |
|
144 return results; |
|
145 } |
|
146 |
|
147 function xpcCleanupWindows() { |
|
148 xpcEnumerateContentWindows(function(win) { |
|
149 if (win.location && win.location.protocol == "data:") |
|
150 win.close(); |
|
151 }); |
|
152 } |
|
153 |
|
154 function xpcWaitForFinishedFrames(callback, numFrames) { |
|
155 var finishedFrameCount = 0; |
|
156 function frameFinished() { |
|
157 finishedFrameCount++; |
|
158 |
|
159 if (finishedFrameCount == numFrames) { |
|
160 clearInterval(frameWaitInterval); |
|
161 setTimeout(callback, 0); |
|
162 return; |
|
163 } |
|
164 |
|
165 if (finishedFrameCount > numFrames) |
|
166 throw "Too many frames loaded."; |
|
167 } |
|
168 |
|
169 var finishedWindows = []; |
|
170 |
|
171 function contains(obj, arr) { |
|
172 for (var i = 0; i < arr.length; i++) { |
|
173 if (obj === arr[i]) |
|
174 return true; |
|
175 } |
|
176 return false; |
|
177 } |
|
178 |
|
179 function searchForFinishedFrames(win) { |
|
180 if ((escape(unescape(win.location)) == escape(target_url) || |
|
181 escape(unescape(win.location)) == escape(target_popup_url)) && |
|
182 win.document && |
|
183 win.document.body && |
|
184 (win.document.body.textContent == body || |
|
185 win.document.body.textContent == popup_body) && |
|
186 win.document.readyState == "complete") { |
|
187 |
|
188 var util = win.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) |
|
189 .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); |
|
190 var windowId = util.outerWindowID; |
|
191 if (!contains(windowId, finishedWindows)) { |
|
192 finishedWindows.push(windowId); |
|
193 frameFinished(); |
|
194 } |
|
195 } |
|
196 for (var i = 0; i < win.frames.length; i++) |
|
197 searchForFinishedFrames(win.frames[i]); |
|
198 } |
|
199 |
|
200 function poll() { |
|
201 try { |
|
202 // This only gives us UniversalXPConnect for the current stack frame |
|
203 // We're using setInterval, so the main page's privileges are still normal |
|
204 xpcEnumerateContentWindows(searchForFinishedFrames); |
|
205 } catch(ex) { |
|
206 // We might be accessing windows before they are fully constructed, |
|
207 // which can throw. We'll find those frames on our next poll(). |
|
208 } |
|
209 } |
|
210 |
|
211 var frameWaitInterval = setInterval(poll, 500); |
|
212 } |
|
213 |