|
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 function test() { |
|
6 requestLongerTimeout(2); // only debug builds seem to need more time... |
|
7 waitForExplicitFinish(); |
|
8 |
|
9 let manifest = { // normal provider |
|
10 name: "provider 1", |
|
11 origin: "https://example.com", |
|
12 sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", |
|
13 workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", |
|
14 iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" |
|
15 }; |
|
16 |
|
17 let postSubTest = function(cb) { |
|
18 let chats = document.getElementById("pinnedchats"); |
|
19 ok(chats.children.length == 0, "no chatty children left behind"); |
|
20 cb(); |
|
21 }; |
|
22 runSocialTestWithProvider(manifest, function (finishcb) { |
|
23 SocialSidebar.show(); |
|
24 ok(SocialSidebar.provider, "sidebar provider exists"); |
|
25 runSocialTests(tests, undefined, postSubTest, function() { |
|
26 finishcb(); |
|
27 }); |
|
28 }); |
|
29 } |
|
30 |
|
31 var tests = { |
|
32 testTearoffChat: function(next) { |
|
33 let chats = document.getElementById("pinnedchats"); |
|
34 let chatTitle; |
|
35 let port = SocialSidebar.provider.getWorkerPort(); |
|
36 ok(port, "provider has a port"); |
|
37 port.onmessage = function (e) { |
|
38 let topic = e.data.topic; |
|
39 switch (topic) { |
|
40 case "got-sidebar-message": |
|
41 port.postMessage({topic: "test-chatbox-open"}); |
|
42 break; |
|
43 case "got-chatbox-visibility": |
|
44 // chatbox is open, lets detach. The new chat window will be caught in |
|
45 // the window watcher below |
|
46 let doc = chats.selectedChat.contentDocument; |
|
47 // This message is (sometimes!) received a second time |
|
48 // before we start our tests from the onCloseWindow |
|
49 // callback. |
|
50 if (doc.location == "about:blank") |
|
51 return; |
|
52 chatTitle = doc.title; |
|
53 ok(chats.selectedChat.getAttribute("label") == chatTitle, |
|
54 "the new chatbox should show the title of the chat window"); |
|
55 let div = doc.createElement("div"); |
|
56 div.setAttribute("id", "testdiv"); |
|
57 div.setAttribute("test", "1"); |
|
58 doc.body.appendChild(div); |
|
59 let swap = document.getAnonymousElementByAttribute(chats.selectedChat, "anonid", "swap"); |
|
60 swap.click(); |
|
61 port.close(); |
|
62 break; |
|
63 case "got-chatbox-message": |
|
64 ok(true, "got chatbox message"); |
|
65 ok(e.data.result == "ok", "got chatbox windowRef result: "+e.data.result); |
|
66 chats.selectedChat.toggle(); |
|
67 break; |
|
68 } |
|
69 } |
|
70 |
|
71 Services.wm.addListener({ |
|
72 onWindowTitleChange: function() {}, |
|
73 onCloseWindow: function(xulwindow) {}, |
|
74 onOpenWindow: function(xulwindow) { |
|
75 var domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|
76 .getInterface(Components.interfaces.nsIDOMWindow); |
|
77 Services.wm.removeListener(this); |
|
78 // wait for load to ensure the window is ready for us to test |
|
79 domwindow.addEventListener("load", function _load(event) { |
|
80 let doc = domwindow.document; |
|
81 if (event.target != doc) |
|
82 return; |
|
83 |
|
84 domwindow.removeEventListener("load", _load, false); |
|
85 |
|
86 domwindow.addEventListener("unload", function _close(event) { |
|
87 if (event.target != doc) |
|
88 return; |
|
89 domwindow.removeEventListener("unload", _close, false); |
|
90 info("window has been closed"); |
|
91 waitForCondition(function() { |
|
92 return chats.selectedChat && chats.selectedChat.contentDocument && |
|
93 chats.selectedChat.contentDocument.readyState == "complete"; |
|
94 },function () { |
|
95 ok(chats.selectedChat, "should have a chatbox in our window again"); |
|
96 ok(chats.selectedChat.getAttribute("label") == chatTitle, |
|
97 "the new chatbox should show the title of the chat window again"); |
|
98 let testdiv = chats.selectedChat.contentDocument.getElementById("testdiv"); |
|
99 is(testdiv.getAttribute("test"), "2", "docshell should have been swapped"); |
|
100 chats.selectedChat.close(); |
|
101 waitForCondition(function() { |
|
102 return chats.children.length == 0; |
|
103 },function () { |
|
104 next(); |
|
105 }); |
|
106 }); |
|
107 }, false); |
|
108 |
|
109 is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened"); |
|
110 // window is loaded, but the docswap does not happen until after load, |
|
111 // and we have no event to wait on, so we'll wait for document state |
|
112 // to be ready |
|
113 let chatbox = doc.getElementById("chatter"); |
|
114 waitForCondition(function() { |
|
115 return chats.selectedChat == null && |
|
116 chatbox.contentDocument && |
|
117 chatbox.contentDocument.readyState == "complete"; |
|
118 },function() { |
|
119 ok(chatbox.getAttribute("label") == chatTitle, |
|
120 "detached window should show the title of the chat window"); |
|
121 let testdiv = chatbox.contentDocument.getElementById("testdiv"); |
|
122 is(testdiv.getAttribute("test"), "1", "docshell should have been swapped"); |
|
123 testdiv.setAttribute("test", "2"); |
|
124 // swap the window back to the chatbar |
|
125 let swap = doc.getAnonymousElementByAttribute(chatbox, "anonid", "swap"); |
|
126 swap.click(); |
|
127 }, domwindow); |
|
128 }, false); |
|
129 } |
|
130 }); |
|
131 |
|
132 port.postMessage({topic: "test-init", data: { id: 1 }}); |
|
133 }, |
|
134 |
|
135 testCloseOnLogout: function(next) { |
|
136 let chats = document.getElementById("pinnedchats"); |
|
137 const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html"; |
|
138 let port = SocialSidebar.provider.getWorkerPort(); |
|
139 ok(port, "provider has a port"); |
|
140 port.postMessage({topic: "test-init"}); |
|
141 port.onmessage = function (e) { |
|
142 let topic = e.data.topic; |
|
143 switch (topic) { |
|
144 case "got-chatbox-visibility": |
|
145 // chatbox is open, lets detach. The new chat window will be caught in |
|
146 // the window watcher below |
|
147 let doc = chats.selectedChat.contentDocument; |
|
148 // This message is (sometimes!) received a second time |
|
149 // before we start our tests from the onCloseWindow |
|
150 // callback. |
|
151 if (doc.location == "about:blank") |
|
152 return; |
|
153 info("chatbox is open, detach from window"); |
|
154 let swap = document.getAnonymousElementByAttribute(chats.selectedChat, "anonid", "swap"); |
|
155 swap.click(); |
|
156 break; |
|
157 } |
|
158 } |
|
159 |
|
160 Services.wm.addListener({ |
|
161 onWindowTitleChange: function() {}, |
|
162 onCloseWindow: function(xulwindow) {}, |
|
163 onOpenWindow: function(xulwindow) { |
|
164 let domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|
165 .getInterface(Components.interfaces.nsIDOMWindow); |
|
166 Services.wm.removeListener(this); |
|
167 // wait for load to ensure the window is ready for us to test, make sure |
|
168 // we're not getting called for about:blank |
|
169 domwindow.addEventListener("load", function _load(event) { |
|
170 let doc = domwindow.document; |
|
171 if (event.target != doc) |
|
172 return; |
|
173 domwindow.removeEventListener("load", _load, false); |
|
174 |
|
175 domwindow.addEventListener("unload", function _close(event) { |
|
176 if (event.target != doc) |
|
177 return; |
|
178 domwindow.removeEventListener("unload", _close, false); |
|
179 ok(true, "window has been closed"); |
|
180 next(); |
|
181 }, false); |
|
182 |
|
183 is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened"); |
|
184 // window is loaded, but the docswap does not happen until after load, |
|
185 // and we have no event to wait on, so we'll wait for document state |
|
186 // to be ready |
|
187 let chatbox = doc.getElementById("chatter"); |
|
188 waitForCondition(function() { |
|
189 return chats.children.length == 0 && |
|
190 chatbox.contentDocument && |
|
191 chatbox.contentDocument.readyState == "complete"; |
|
192 },function() { |
|
193 // logout, we should get unload next |
|
194 port.postMessage({topic: "test-logout"}); |
|
195 port.close(); |
|
196 }, domwindow); |
|
197 |
|
198 }, false); |
|
199 } |
|
200 }); |
|
201 |
|
202 port.postMessage({topic: "test-worker-chat", data: chatUrl}); |
|
203 }, |
|
204 |
|
205 testReattachTwice: function(next) { |
|
206 let chats = document.getElementById("pinnedchats"); |
|
207 const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html"; |
|
208 let chatBoxCount = 0, reattachCount = 0; |
|
209 let port = SocialSidebar.provider.getWorkerPort(); |
|
210 ok(port, "provider has a port"); |
|
211 port.postMessage({topic: "test-init"}); |
|
212 port.onmessage = function (e) { |
|
213 let topic = e.data.topic; |
|
214 switch (topic) { |
|
215 case "got-chatbox-visibility": |
|
216 // chatbox is open, lets detach. The new chat window will be caught in |
|
217 // the window watcher below |
|
218 let doc = chats.selectedChat.contentDocument; |
|
219 // This message is (sometimes!) received a second time |
|
220 // before we start our tests from the onCloseWindow |
|
221 // callback. |
|
222 if (doc.location == "about:blank") |
|
223 return; |
|
224 if (++chatBoxCount != 2) { |
|
225 // open the second chat window |
|
226 port.postMessage({topic: "test-worker-chat", data: chatUrl + "?id=2"}); |
|
227 return; |
|
228 } |
|
229 info("chatbox is open, detach from window"); |
|
230 let chat1 = chats.firstChild; |
|
231 let chat2 = chat1.nextSibling; |
|
232 document.getAnonymousElementByAttribute(chat1, "anonid", "swap").click(); |
|
233 document.getAnonymousElementByAttribute(chat2, "anonid", "swap").click(); |
|
234 break; |
|
235 } |
|
236 }; |
|
237 |
|
238 let firstChatWindowDoc; |
|
239 Services.wm.addListener({ |
|
240 onWindowTitleChange: function() {}, |
|
241 onCloseWindow: function(xulwindow) {}, |
|
242 onOpenWindow: function(xulwindow) { |
|
243 let listener = this; |
|
244 let domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|
245 .getInterface(Components.interfaces.nsIDOMWindow); |
|
246 // wait for load to ensure the window is ready for us to test, make sure |
|
247 // we're not getting called for about:blank |
|
248 domwindow.addEventListener("load", function _load(event) { |
|
249 let doc = domwindow.document; |
|
250 if (event.target != doc) |
|
251 return; |
|
252 domwindow.removeEventListener("load", _load, false); |
|
253 |
|
254 domwindow.addEventListener("unload", function _close(event) { |
|
255 if (event.target != doc) |
|
256 return; |
|
257 domwindow.removeEventListener("unload", _close, false); |
|
258 ok(true, "window has been closed"); |
|
259 waitForCondition(function() { |
|
260 return chats.selectedChat && chats.selectedChat.contentDocument && |
|
261 chats.selectedChat.contentDocument.readyState == "complete"; |
|
262 }, function () { |
|
263 ++reattachCount; |
|
264 if (reattachCount == 1) { |
|
265 info("reattaching second chat window"); |
|
266 let chatbox = firstChatWindowDoc.getElementById("chatter"); |
|
267 firstChatWindowDoc.getAnonymousElementByAttribute(chatbox, "anonid", "swap").click(); |
|
268 firstChatWindowDoc = null; |
|
269 } |
|
270 else if (reattachCount == 2) { |
|
271 is(chats.children.length, 2, "both chat windows should be reattached"); |
|
272 chats.removeAll(); |
|
273 waitForCondition(() => chats.children.length == 0, function () { |
|
274 info("no chat window left"); |
|
275 is(chats.chatboxForURL.size, 0, "chatboxForURL map should be empty"); |
|
276 next(); |
|
277 }); |
|
278 } |
|
279 }, "waited too long for the window to reattach"); |
|
280 }, false); |
|
281 |
|
282 is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened"); |
|
283 if (!firstChatWindowDoc) { |
|
284 firstChatWindowDoc = doc; |
|
285 return; |
|
286 } |
|
287 Services.wm.removeListener(listener); |
|
288 |
|
289 // window is loaded, but the docswap does not happen until after load, |
|
290 // and we have no event to wait on, so we'll wait for document state |
|
291 // to be ready |
|
292 let chatbox = doc.getElementById("chatter"); |
|
293 waitForCondition(function() { |
|
294 return chats.children.length == 0 && |
|
295 chatbox.contentDocument && |
|
296 chatbox.contentDocument.readyState == "complete"; |
|
297 },function() { |
|
298 info("reattaching chat window"); |
|
299 doc.getAnonymousElementByAttribute(chatbox, "anonid", "swap").click(); |
|
300 }, "waited too long for the chat window to be detached"); |
|
301 |
|
302 }, false); |
|
303 } |
|
304 }); |
|
305 |
|
306 port.postMessage({topic: "test-worker-chat", data: chatUrl + "?id=1"}); |
|
307 } |
|
308 }; |