browser/base/content/test/social/browser_social_chatwindow.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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 }

mercurial