Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
5 let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
7 let manifests = [
8 {
9 name: "provider@example.com",
10 origin: "https://example.com",
11 sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html?example.com",
12 workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
13 iconURL: "chrome://branding/content/icon48.png"
14 },
15 {
16 name: "provider@test1",
17 origin: "https://test1.example.com",
18 sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html?test1",
19 workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
20 iconURL: "chrome://branding/content/icon48.png"
21 },
22 {
23 name: "provider@test2",
24 origin: "https://test2.example.com",
25 sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html?test2",
26 workerURL: "https://test2.example.com/browser/browser/base/content/test/social/social_worker.js",
27 iconURL: "chrome://branding/content/icon48.png"
28 }
29 ];
31 let chatId = 0;
32 function openChat(provider, callback) {
33 let chatUrl = provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
34 let port = provider.getWorkerPort();
35 port.onmessage = function(e) {
36 if (e.data.topic == "got-chatbox-message") {
37 port.close();
38 callback();
39 }
40 }
41 let url = chatUrl + "?" + (chatId++);
42 port.postMessage({topic: "test-init"});
43 port.postMessage({topic: "test-worker-chat", data: url});
44 gURLsNotRemembered.push(url);
45 }
47 function test() {
48 requestLongerTimeout(2); // only debug builds seem to need more time...
49 waitForExplicitFinish();
51 let oldwidth = window.outerWidth; // we futz with these, so we restore them
52 let oldleft = window.screenX;
53 window.moveTo(0, window.screenY)
54 let postSubTest = function(cb) {
55 let chats = document.getElementById("pinnedchats");
56 ok(chats.children.length == 0, "no chatty children left behind");
57 cb();
58 };
59 runSocialTestWithProvider(manifests, function (finishcb) {
60 ok(Social.enabled, "Social is enabled");
61 ok(Social.providers[0].getWorkerPort(), "provider 0 has port");
62 ok(Social.providers[1].getWorkerPort(), "provider 1 has port");
63 ok(Social.providers[2].getWorkerPort(), "provider 2 has port");
64 SocialSidebar.show();
65 runSocialTests(tests, undefined, postSubTest, function() {
66 window.moveTo(oldleft, window.screenY)
67 window.resizeTo(oldwidth, window.outerHeight);
68 finishcb();
69 });
70 });
71 }
73 var tests = {
74 testOpenCloseChat: function(next) {
75 let chats = document.getElementById("pinnedchats");
76 let port = SocialSidebar.provider.getWorkerPort();
77 ok(port, "provider has a port");
78 port.onmessage = function (e) {
79 let topic = e.data.topic;
80 switch (topic) {
81 case "got-sidebar-message":
82 port.postMessage({topic: "test-chatbox-open"});
83 break;
84 case "got-chatbox-visibility":
85 if (e.data.result == "hidden") {
86 ok(true, "chatbox got minimized");
87 chats.selectedChat.toggle();
88 } else if (e.data.result == "shown") {
89 ok(true, "chatbox got shown");
90 // close it now
91 let content = chats.selectedChat.content;
92 content.addEventListener("unload", function chatUnload() {
93 content.removeEventListener("unload", chatUnload, true);
94 ok(true, "got chatbox unload on close");
95 port.close();
96 next();
97 }, true);
98 chats.selectedChat.close();
99 }
100 break;
101 case "got-chatbox-message":
102 ok(true, "got chatbox message");
103 ok(e.data.result == "ok", "got chatbox windowRef result: "+e.data.result);
104 chats.selectedChat.toggle();
105 break;
106 }
107 }
108 port.postMessage({topic: "test-init", data: { id: 1 }});
109 },
110 testOpenMinimized: function(next) {
111 // In this case the sidebar opens a chat (without specifying minimized).
112 // We then minimize it and have the sidebar reopen the chat (again without
113 // minimized). On that second call the chat should open and no longer
114 // be minimized.
115 let chats = document.getElementById("pinnedchats");
116 let port = SocialSidebar.provider.getWorkerPort();
117 let seen_opened = false;
118 port.onmessage = function (e) {
119 let topic = e.data.topic;
120 switch (topic) {
121 case "test-init-done":
122 port.postMessage({topic: "test-chatbox-open"});
123 break;
124 case "chatbox-opened":
125 is(e.data.result, "ok", "the sidebar says it got a chatbox");
126 if (!seen_opened) {
127 // first time we got the opened message, so minimize the chat then
128 // re-request the same chat to be opened - we should get the
129 // message again and the chat should be restored.
130 ok(!chats.selectedChat.minimized, "chat not initially minimized")
131 chats.selectedChat.minimized = true
132 seen_opened = true;
133 port.postMessage({topic: "test-chatbox-open"});
134 } else {
135 // This is the second time we've seen this message - there should
136 // be exactly 1 chat open and it should no longer be minimized.
137 let chats = document.getElementById("pinnedchats");
138 ok(!chats.selectedChat.minimized, "chat no longer minimized")
139 chats.selectedChat.close();
140 is(chats.selectedChat, null, "should only have been one chat open");
141 port.close();
142 next();
143 }
144 }
145 }
146 port.postMessage({topic: "test-init", data: { id: 1 }});
147 },
148 testManyChats: function(next) {
149 // open enough chats to overflow the window, then check
150 // if the menupopup is visible
151 let port = SocialSidebar.provider.getWorkerPort();
152 let chats = document.getElementById("pinnedchats");
153 ok(port, "provider has a port");
154 ok(chats.menupopup.parentNode.collapsed, "popup nub collapsed at start");
155 port.postMessage({topic: "test-init"});
156 // we should *never* find a test box that needs more than this to cause
157 // an overflow!
158 let maxToOpen = 20;
159 let numOpened = 0;
160 let maybeOpenAnother = function() {
161 if (numOpened++ >= maxToOpen) {
162 ok(false, "We didn't find a collapsed chat after " + maxToOpen + "chats!");
163 closeAllChats();
164 next();
165 }
166 port.postMessage({topic: "test-chatbox-open", data: { id: numOpened }});
167 }
168 port.onmessage = function (e) {
169 let topic = e.data.topic;
170 switch (topic) {
171 case "got-chatbox-message":
172 if (!chats.menupopup.parentNode.collapsed) {
173 maybeOpenAnother();
174 break;
175 }
176 ok(true, "popup nub became visible");
177 // close our chats now
178 while (chats.selectedChat) {
179 chats.selectedChat.close();
180 }
181 ok(!chats.selectedChat, "chats are all closed");
182 port.close();
183 next();
184 break;
185 }
186 }
187 maybeOpenAnother();
188 },
189 testWorkerChatWindow: function(next) {
190 const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
191 let chats = document.getElementById("pinnedchats");
192 let port = SocialSidebar.provider.getWorkerPort();
193 ok(port, "provider has a port");
194 port.postMessage({topic: "test-init"});
195 port.onmessage = function (e) {
196 let topic = e.data.topic;
197 switch (topic) {
198 case "got-chatbox-message":
199 ok(true, "got a chat window opened");
200 ok(chats.selectedChat, "chatbox from worker opened");
201 while (chats.selectedChat) {
202 chats.selectedChat.close();
203 }
204 ok(!chats.selectedChat, "chats are all closed");
205 gURLsNotRemembered.push(chatUrl);
206 port.close();
207 next();
208 break;
209 }
210 }
211 ok(!chats.selectedChat, "chats are all closed");
212 port.postMessage({topic: "test-worker-chat", data: chatUrl});
213 },
214 testCloseSelf: function(next) {
215 let chats = document.getElementById("pinnedchats");
216 let port = SocialSidebar.provider.getWorkerPort();
217 ok(port, "provider has a port");
218 port.onmessage = function (e) {
219 let topic = e.data.topic;
220 switch (topic) {
221 case "test-init-done":
222 port.postMessage({topic: "test-chatbox-open"});
223 break;
224 case "got-chatbox-visibility":
225 is(e.data.result, "shown", "chatbox shown");
226 port.close(); // don't want any more visibility messages.
227 let chat = chats.selectedChat;
228 ok(chat.parentNode, "chat has a parent node before it is closed");
229 // ask it to close itself.
230 let doc = chat.contentDocument;
231 let evt = doc.createEvent("CustomEvent");
232 evt.initCustomEvent("socialTest-CloseSelf", true, true, {});
233 doc.documentElement.dispatchEvent(evt);
234 ok(!chat.parentNode, "chat is now closed");
235 port.close();
236 next();
237 break;
238 }
239 }
240 port.postMessage({topic: "test-init", data: { id: 1 }});
241 },
242 testSameChatCallbacks: function(next) {
243 let chats = document.getElementById("pinnedchats");
244 let port = SocialSidebar.provider.getWorkerPort();
245 let seen_opened = false;
246 port.onmessage = function (e) {
247 let topic = e.data.topic;
248 switch (topic) {
249 case "test-init-done":
250 port.postMessage({topic: "test-chatbox-open"});
251 break;
252 case "chatbox-opened":
253 is(e.data.result, "ok", "the sidebar says it got a chatbox");
254 if (seen_opened) {
255 // This is the second time we've seen this message - there should
256 // be exactly 1 chat open.
257 let chats = document.getElementById("pinnedchats");
258 chats.selectedChat.close();
259 is(chats.selectedChat, null, "should only have been one chat open");
260 port.close();
261 next();
262 } else {
263 // first time we got the opened message, so re-request the same
264 // chat to be opened - we should get the message again.
265 seen_opened = true;
266 port.postMessage({topic: "test-chatbox-open"});
267 }
268 }
269 }
270 port.postMessage({topic: "test-init", data: { id: 1 }});
271 },
273 // check removeAll does the right thing
274 testRemoveAll: function(next, mode) {
275 let port = SocialSidebar.provider.getWorkerPort();
276 port.postMessage({topic: "test-init"});
277 get3ChatsForCollapsing(mode || "normal", function() {
278 let chatbar = window.SocialChatBar.chatbar;
279 chatbar.removeAll();
280 // should be no evidence of any chats left.
281 is(chatbar.childNodes.length, 0, "should be no chats left");
282 checkPopup();
283 is(chatbar.selectedChat, null, "nothing should be selected");
284 is(chatbar.chatboxForURL.size, 0, "chatboxForURL map should be empty");
285 port.close();
286 next();
287 });
288 },
290 testRemoveAllMinimized: function(next) {
291 this.testRemoveAll(next, "minimized");
292 },
294 // Check what happens when you close the only visible chat.
295 testCloseOnlyVisible: function(next) {
296 let chatbar = window.SocialChatBar.chatbar;
297 let chatWidth = undefined;
298 let num = 0;
299 is(chatbar.childNodes.length, 0, "chatbar starting empty");
300 is(chatbar.menupopup.childNodes.length, 0, "popup starting empty");
302 makeChat("normal", "first chat", function() {
303 // got the first one.
304 checkPopup();
305 ok(chatbar.menupopup.parentNode.collapsed, "menu selection isn't visible");
306 // we kinda cheat here and get the width of the first chat, assuming
307 // that all future chats will have the same width when open.
308 chatWidth = chatbar.calcTotalWidthOf(chatbar.selectedChat);
309 let desired = chatWidth * 1.5;
310 resizeWindowToChatAreaWidth(desired, function(sizedOk) {
311 ok(sizedOk, "can't do any tests without this width");
312 checkPopup();
313 makeChat("normal", "second chat", function() {
314 is(chatbar.childNodes.length, 2, "now have 2 chats");
315 let first = chatbar.childNodes[0];
316 let second = chatbar.childNodes[1];
317 is(chatbar.selectedChat, first, "first chat is selected");
318 ok(second.collapsed, "second chat is currently collapsed");
319 // closing the first chat will leave enough room for the second
320 // chat to appear, and thus become selected.
321 chatbar.selectedChat.close();
322 is(chatbar.selectedChat, second, "second chat is selected");
323 closeAllChats();
324 next();
325 });
326 });
327 });
328 },
330 testShowWhenCollapsed: function(next) {
331 let port = SocialSidebar.provider.getWorkerPort();
332 port.postMessage({topic: "test-init"});
333 get3ChatsForCollapsing("normal", function(first, second, third) {
334 let chatbar = window.SocialChatBar.chatbar;
335 chatbar.showChat(first);
336 ok(!first.collapsed, "first should no longer be collapsed");
337 ok(second.collapsed || third.collapsed, false, "one of the others should be collapsed");
338 closeAllChats();
339 port.close();
340 next();
341 });
342 },
344 testActivity: function(next) {
345 let port = SocialSidebar.provider.getWorkerPort();
346 port.postMessage({topic: "test-init"});
347 get3ChatsForCollapsing("normal", function(first, second, third) {
348 let chatbar = window.SocialChatBar.chatbar;
349 is(chatbar.selectedChat, third, "third chat should be selected");
350 ok(!chatbar.selectedChat.hasAttribute("activity"), "third chat should have no activity");
351 // send an activity message to the second.
352 ok(!second.hasAttribute("activity"), "second chat should have no activity");
353 let chat2 = second.content;
354 let evt = chat2.contentDocument.createEvent("CustomEvent");
355 evt.initCustomEvent("socialChatActivity", true, true, {});
356 chat2.contentDocument.documentElement.dispatchEvent(evt);
357 // second should have activity.
358 ok(second.hasAttribute("activity"), "second chat should now have activity");
359 // select the second - it should lose "activity"
360 chatbar.selectedChat = second;
361 ok(!second.hasAttribute("activity"), "second chat should no longer have activity");
362 // Now try the first - it is collapsed, so the 'nub' also gets activity attr.
363 ok(!first.hasAttribute("activity"), "first chat should have no activity");
364 let chat1 = first.content;
365 let evt = chat1.contentDocument.createEvent("CustomEvent");
366 evt.initCustomEvent("socialChatActivity", true, true, {});
367 chat1.contentDocument.documentElement.dispatchEvent(evt);
368 ok(first.hasAttribute("activity"), "first chat should now have activity");
369 ok(chatbar.nub.hasAttribute("activity"), "nub should also have activity");
370 // first is collapsed, so use openChat to get it.
371 chatbar.openChat(SocialSidebar.provider, first.getAttribute("src"));
372 ok(!first.hasAttribute("activity"), "first chat should no longer have activity");
373 // The nub should lose the activity flag here too
374 todo(!chatbar.nub.hasAttribute("activity"), "Bug 806266 - nub should no longer have activity");
375 // TODO: tests for bug 806266 should arrange to have 2 chats collapsed
376 // then open them checking the nub is updated correctly.
377 // Now we will go and change the embedded browser in the second chat and
378 // ensure the activity magic still works (ie, check that the unload for
379 // the browser didn't cause our event handlers to be removed.)
380 ok(!second.hasAttribute("activity"), "second chat should have no activity");
381 let subiframe = chat2.contentDocument.getElementById("iframe");
382 subiframe.contentWindow.addEventListener("unload", function subunload() {
383 subiframe.contentWindow.removeEventListener("unload", subunload);
384 // ensure all other unload listeners have fired.
385 executeSoon(function() {
386 let evt = chat2.contentDocument.createEvent("CustomEvent");
387 evt.initCustomEvent("socialChatActivity", true, true, {});
388 chat2.contentDocument.documentElement.dispatchEvent(evt);
389 ok(second.hasAttribute("activity"), "second chat still has activity after unloading sub-iframe");
390 closeAllChats();
391 port.close();
392 next();
393 })
394 })
395 subiframe.setAttribute("src", "data:text/plain:new location for iframe");
396 });
397 },
399 testOnlyOneCallback: function(next) {
400 let chats = document.getElementById("pinnedchats");
401 let port = SocialSidebar.provider.getWorkerPort();
402 let numOpened = 0;
403 port.onmessage = function (e) {
404 let topic = e.data.topic;
405 switch (topic) {
406 case "test-init-done":
407 port.postMessage({topic: "test-chatbox-open"});
408 break;
409 case "chatbox-opened":
410 numOpened += 1;
411 port.postMessage({topic: "ping"});
412 break;
413 case "pong":
414 executeSoon(function() {
415 is(numOpened, 1, "only got one open message");
416 chats.removeAll();
417 port.close();
418 next();
419 });
420 }
421 }
422 port.postMessage({topic: "test-init", data: { id: 1 }});
423 },
425 testSecondTopLevelWindow: function(next) {
426 // Bug 817782 - check chats work in new top-level windows.
427 const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
428 let port = SocialSidebar.provider.getWorkerPort();
429 let secondWindow;
430 port.onmessage = function(e) {
431 if (e.data.topic == "test-init-done") {
432 secondWindow = OpenBrowserWindow();
433 secondWindow.addEventListener("load", function loadListener() {
434 secondWindow.removeEventListener("load", loadListener);
435 port.postMessage({topic: "test-worker-chat", data: chatUrl});
436 });
437 } else if (e.data.topic == "got-chatbox-message") {
438 // the chat was created - let's make sure it was created in the second window.
439 is(secondWindow.SocialChatBar.chatbar.childElementCount, 1);
440 secondWindow.close();
441 next();
442 }
443 }
444 port.postMessage({topic: "test-init"});
445 },
447 testChatWindowChooser: function(next) {
448 // Tests that when a worker creates a chat, it is opened in the correct
449 // window.
450 // open a chat (it will open in the main window)
451 ok(!window.SocialChatBar.hasChats, "first window should start with no chats");
452 openChat(SocialSidebar.provider, function() {
453 ok(window.SocialChatBar.hasChats, "first window has the chat");
454 // create a second window - this will be the "most recent" and will
455 // therefore be the window that hosts the new chat (see bug 835111)
456 let secondWindow = OpenBrowserWindow();
457 secondWindow.addEventListener("load", function loadListener() {
458 secondWindow.removeEventListener("load", loadListener);
459 ok(!secondWindow.SocialChatBar.hasChats, "second window has no chats");
460 openChat(SocialSidebar.provider, function() {
461 ok(secondWindow.SocialChatBar.hasChats, "second window now has chats");
462 is(window.SocialChatBar.chatbar.childElementCount, 1, "first window still has 1 chat");
463 window.SocialChatBar.chatbar.removeAll();
464 // now open another chat - it should still open in the second.
465 openChat(SocialSidebar.provider, function() {
466 ok(!window.SocialChatBar.hasChats, "first window has no chats");
467 ok(secondWindow.SocialChatBar.hasChats, "second window has a chat");
469 // focus the first window, and open yet another chat - it
470 // should open in the first window.
471 waitForFocus(function() {
472 openChat(SocialSidebar.provider, function() {
473 ok(window.SocialChatBar.hasChats, "first window has chats");
474 window.SocialChatBar.chatbar.removeAll();
475 ok(!window.SocialChatBar.hasChats, "first window has no chats");
477 let privateWindow = OpenBrowserWindow({private: true});
478 privateWindow.addEventListener("load", function loadListener() {
479 privateWindow.removeEventListener("load", loadListener);
481 // open a last chat - the focused window can't accept
482 // chats (it's a private window), so the chat should open
483 // in the window that was selected before. This is known
484 // to be broken on Linux.
485 openChat(SocialSidebar.provider, function() {
486 let os = Services.appinfo.OS;
487 const BROKEN_WM_Z_ORDER = os != "WINNT" && os != "Darwin";
488 let fn = BROKEN_WM_Z_ORDER ? todo : ok;
489 fn(window.SocialChatBar.hasChats, "first window has a chat");
490 window.SocialChatBar.chatbar.removeAll();
492 privateWindow.close();
493 secondWindow.close();
494 next();
495 });
496 });
497 });
498 });
499 window.focus();
500 });
501 });
502 })
503 });
504 },
505 testMultipleProviderChat: function(next) {
506 // test incomming chats from all providers
507 openChat(Social.providers[0], function() {
508 openChat(Social.providers[1], function() {
509 openChat(Social.providers[2], function() {
510 let chats = document.getElementById("pinnedchats");
511 waitForCondition(function() chats.children.length == Social.providers.length,
512 function() {
513 ok(true, "one chat window per provider opened");
514 // test logout of a single provider
515 let provider = Social.providers[2];
516 let port = provider.getWorkerPort();
517 port.postMessage({topic: "test-logout"});
518 waitForCondition(function() chats.children.length == Social.providers.length - 1,
519 function() {
520 chats.removeAll();
521 waitForCondition(function() chats.children.length == 0,
522 function() {
523 ok(!chats.selectedChat, "multiprovider chats are all closed");
524 port.close();
525 next();
526 },
527 "chat windows didn't close");
528 },
529 "chat window didn't close");
530 }, "chat windows did not open");
531 });
532 });
533 });
534 },
536 // XXX - note this must be the last test until we restore the login state
537 // between tests...
538 testCloseOnLogout: function(next) {
539 const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
540 let port = SocialSidebar.provider.getWorkerPort();
541 ok(port, "provider has a port");
542 let opened = false;
543 port.onmessage = function (e) {
544 let topic = e.data.topic;
545 switch (topic) {
546 case "test-init-done":
547 info("open first chat window");
548 port.postMessage({topic: "test-worker-chat", data: chatUrl});
549 break;
550 case "got-chatbox-message":
551 ok(true, "got a chat window opened");
552 if (opened) {
553 port.postMessage({topic: "test-logout"});
554 waitForCondition(function() document.getElementById("pinnedchats").firstChild == null,
555 function() {
556 port.close();
557 next();
558 },
559 "chat windows didn't close");
560 } else {
561 // open a second chat window
562 opened = true;
563 port.postMessage({topic: "test-worker-chat", data: chatUrl+"?id=1"});
564 }
565 break;
566 }
567 }
568 // make sure a user profile is set for this provider as chat windows are
569 // only closed on *change* of the profile data rather than merely setting
570 // profile data.
571 port.postMessage({topic: "test-set-profile"});
572 port.postMessage({topic: "test-init"});
573 }
574 }