1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/base/content/test/social/browser_chat_tearoff.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,308 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +function test() { 1.9 + requestLongerTimeout(2); // only debug builds seem to need more time... 1.10 + waitForExplicitFinish(); 1.11 + 1.12 + let manifest = { // normal provider 1.13 + name: "provider 1", 1.14 + origin: "https://example.com", 1.15 + sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", 1.16 + workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", 1.17 + iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" 1.18 + }; 1.19 + 1.20 + let postSubTest = function(cb) { 1.21 + let chats = document.getElementById("pinnedchats"); 1.22 + ok(chats.children.length == 0, "no chatty children left behind"); 1.23 + cb(); 1.24 + }; 1.25 + runSocialTestWithProvider(manifest, function (finishcb) { 1.26 + SocialSidebar.show(); 1.27 + ok(SocialSidebar.provider, "sidebar provider exists"); 1.28 + runSocialTests(tests, undefined, postSubTest, function() { 1.29 + finishcb(); 1.30 + }); 1.31 + }); 1.32 +} 1.33 + 1.34 +var tests = { 1.35 + testTearoffChat: function(next) { 1.36 + let chats = document.getElementById("pinnedchats"); 1.37 + let chatTitle; 1.38 + let port = SocialSidebar.provider.getWorkerPort(); 1.39 + ok(port, "provider has a port"); 1.40 + port.onmessage = function (e) { 1.41 + let topic = e.data.topic; 1.42 + switch (topic) { 1.43 + case "got-sidebar-message": 1.44 + port.postMessage({topic: "test-chatbox-open"}); 1.45 + break; 1.46 + case "got-chatbox-visibility": 1.47 + // chatbox is open, lets detach. The new chat window will be caught in 1.48 + // the window watcher below 1.49 + let doc = chats.selectedChat.contentDocument; 1.50 + // This message is (sometimes!) received a second time 1.51 + // before we start our tests from the onCloseWindow 1.52 + // callback. 1.53 + if (doc.location == "about:blank") 1.54 + return; 1.55 + chatTitle = doc.title; 1.56 + ok(chats.selectedChat.getAttribute("label") == chatTitle, 1.57 + "the new chatbox should show the title of the chat window"); 1.58 + let div = doc.createElement("div"); 1.59 + div.setAttribute("id", "testdiv"); 1.60 + div.setAttribute("test", "1"); 1.61 + doc.body.appendChild(div); 1.62 + let swap = document.getAnonymousElementByAttribute(chats.selectedChat, "anonid", "swap"); 1.63 + swap.click(); 1.64 + port.close(); 1.65 + break; 1.66 + case "got-chatbox-message": 1.67 + ok(true, "got chatbox message"); 1.68 + ok(e.data.result == "ok", "got chatbox windowRef result: "+e.data.result); 1.69 + chats.selectedChat.toggle(); 1.70 + break; 1.71 + } 1.72 + } 1.73 + 1.74 + Services.wm.addListener({ 1.75 + onWindowTitleChange: function() {}, 1.76 + onCloseWindow: function(xulwindow) {}, 1.77 + onOpenWindow: function(xulwindow) { 1.78 + var domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.79 + .getInterface(Components.interfaces.nsIDOMWindow); 1.80 + Services.wm.removeListener(this); 1.81 + // wait for load to ensure the window is ready for us to test 1.82 + domwindow.addEventListener("load", function _load(event) { 1.83 + let doc = domwindow.document; 1.84 + if (event.target != doc) 1.85 + return; 1.86 + 1.87 + domwindow.removeEventListener("load", _load, false); 1.88 + 1.89 + domwindow.addEventListener("unload", function _close(event) { 1.90 + if (event.target != doc) 1.91 + return; 1.92 + domwindow.removeEventListener("unload", _close, false); 1.93 + info("window has been closed"); 1.94 + waitForCondition(function() { 1.95 + return chats.selectedChat && chats.selectedChat.contentDocument && 1.96 + chats.selectedChat.contentDocument.readyState == "complete"; 1.97 + },function () { 1.98 + ok(chats.selectedChat, "should have a chatbox in our window again"); 1.99 + ok(chats.selectedChat.getAttribute("label") == chatTitle, 1.100 + "the new chatbox should show the title of the chat window again"); 1.101 + let testdiv = chats.selectedChat.contentDocument.getElementById("testdiv"); 1.102 + is(testdiv.getAttribute("test"), "2", "docshell should have been swapped"); 1.103 + chats.selectedChat.close(); 1.104 + waitForCondition(function() { 1.105 + return chats.children.length == 0; 1.106 + },function () { 1.107 + next(); 1.108 + }); 1.109 + }); 1.110 + }, false); 1.111 + 1.112 + is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened"); 1.113 + // window is loaded, but the docswap does not happen until after load, 1.114 + // and we have no event to wait on, so we'll wait for document state 1.115 + // to be ready 1.116 + let chatbox = doc.getElementById("chatter"); 1.117 + waitForCondition(function() { 1.118 + return chats.selectedChat == null && 1.119 + chatbox.contentDocument && 1.120 + chatbox.contentDocument.readyState == "complete"; 1.121 + },function() { 1.122 + ok(chatbox.getAttribute("label") == chatTitle, 1.123 + "detached window should show the title of the chat window"); 1.124 + let testdiv = chatbox.contentDocument.getElementById("testdiv"); 1.125 + is(testdiv.getAttribute("test"), "1", "docshell should have been swapped"); 1.126 + testdiv.setAttribute("test", "2"); 1.127 + // swap the window back to the chatbar 1.128 + let swap = doc.getAnonymousElementByAttribute(chatbox, "anonid", "swap"); 1.129 + swap.click(); 1.130 + }, domwindow); 1.131 + }, false); 1.132 + } 1.133 + }); 1.134 + 1.135 + port.postMessage({topic: "test-init", data: { id: 1 }}); 1.136 + }, 1.137 + 1.138 + testCloseOnLogout: function(next) { 1.139 + let chats = document.getElementById("pinnedchats"); 1.140 + const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html"; 1.141 + let port = SocialSidebar.provider.getWorkerPort(); 1.142 + ok(port, "provider has a port"); 1.143 + port.postMessage({topic: "test-init"}); 1.144 + port.onmessage = function (e) { 1.145 + let topic = e.data.topic; 1.146 + switch (topic) { 1.147 + case "got-chatbox-visibility": 1.148 + // chatbox is open, lets detach. The new chat window will be caught in 1.149 + // the window watcher below 1.150 + let doc = chats.selectedChat.contentDocument; 1.151 + // This message is (sometimes!) received a second time 1.152 + // before we start our tests from the onCloseWindow 1.153 + // callback. 1.154 + if (doc.location == "about:blank") 1.155 + return; 1.156 + info("chatbox is open, detach from window"); 1.157 + let swap = document.getAnonymousElementByAttribute(chats.selectedChat, "anonid", "swap"); 1.158 + swap.click(); 1.159 + break; 1.160 + } 1.161 + } 1.162 + 1.163 + Services.wm.addListener({ 1.164 + onWindowTitleChange: function() {}, 1.165 + onCloseWindow: function(xulwindow) {}, 1.166 + onOpenWindow: function(xulwindow) { 1.167 + let domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.168 + .getInterface(Components.interfaces.nsIDOMWindow); 1.169 + Services.wm.removeListener(this); 1.170 + // wait for load to ensure the window is ready for us to test, make sure 1.171 + // we're not getting called for about:blank 1.172 + domwindow.addEventListener("load", function _load(event) { 1.173 + let doc = domwindow.document; 1.174 + if (event.target != doc) 1.175 + return; 1.176 + domwindow.removeEventListener("load", _load, false); 1.177 + 1.178 + domwindow.addEventListener("unload", function _close(event) { 1.179 + if (event.target != doc) 1.180 + return; 1.181 + domwindow.removeEventListener("unload", _close, false); 1.182 + ok(true, "window has been closed"); 1.183 + next(); 1.184 + }, false); 1.185 + 1.186 + is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened"); 1.187 + // window is loaded, but the docswap does not happen until after load, 1.188 + // and we have no event to wait on, so we'll wait for document state 1.189 + // to be ready 1.190 + let chatbox = doc.getElementById("chatter"); 1.191 + waitForCondition(function() { 1.192 + return chats.children.length == 0 && 1.193 + chatbox.contentDocument && 1.194 + chatbox.contentDocument.readyState == "complete"; 1.195 + },function() { 1.196 + // logout, we should get unload next 1.197 + port.postMessage({topic: "test-logout"}); 1.198 + port.close(); 1.199 + }, domwindow); 1.200 + 1.201 + }, false); 1.202 + } 1.203 + }); 1.204 + 1.205 + port.postMessage({topic: "test-worker-chat", data: chatUrl}); 1.206 + }, 1.207 + 1.208 + testReattachTwice: function(next) { 1.209 + let chats = document.getElementById("pinnedchats"); 1.210 + const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html"; 1.211 + let chatBoxCount = 0, reattachCount = 0; 1.212 + let port = SocialSidebar.provider.getWorkerPort(); 1.213 + ok(port, "provider has a port"); 1.214 + port.postMessage({topic: "test-init"}); 1.215 + port.onmessage = function (e) { 1.216 + let topic = e.data.topic; 1.217 + switch (topic) { 1.218 + case "got-chatbox-visibility": 1.219 + // chatbox is open, lets detach. The new chat window will be caught in 1.220 + // the window watcher below 1.221 + let doc = chats.selectedChat.contentDocument; 1.222 + // This message is (sometimes!) received a second time 1.223 + // before we start our tests from the onCloseWindow 1.224 + // callback. 1.225 + if (doc.location == "about:blank") 1.226 + return; 1.227 + if (++chatBoxCount != 2) { 1.228 + // open the second chat window 1.229 + port.postMessage({topic: "test-worker-chat", data: chatUrl + "?id=2"}); 1.230 + return; 1.231 + } 1.232 + info("chatbox is open, detach from window"); 1.233 + let chat1 = chats.firstChild; 1.234 + let chat2 = chat1.nextSibling; 1.235 + document.getAnonymousElementByAttribute(chat1, "anonid", "swap").click(); 1.236 + document.getAnonymousElementByAttribute(chat2, "anonid", "swap").click(); 1.237 + break; 1.238 + } 1.239 + }; 1.240 + 1.241 + let firstChatWindowDoc; 1.242 + Services.wm.addListener({ 1.243 + onWindowTitleChange: function() {}, 1.244 + onCloseWindow: function(xulwindow) {}, 1.245 + onOpenWindow: function(xulwindow) { 1.246 + let listener = this; 1.247 + let domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.248 + .getInterface(Components.interfaces.nsIDOMWindow); 1.249 + // wait for load to ensure the window is ready for us to test, make sure 1.250 + // we're not getting called for about:blank 1.251 + domwindow.addEventListener("load", function _load(event) { 1.252 + let doc = domwindow.document; 1.253 + if (event.target != doc) 1.254 + return; 1.255 + domwindow.removeEventListener("load", _load, false); 1.256 + 1.257 + domwindow.addEventListener("unload", function _close(event) { 1.258 + if (event.target != doc) 1.259 + return; 1.260 + domwindow.removeEventListener("unload", _close, false); 1.261 + ok(true, "window has been closed"); 1.262 + waitForCondition(function() { 1.263 + return chats.selectedChat && chats.selectedChat.contentDocument && 1.264 + chats.selectedChat.contentDocument.readyState == "complete"; 1.265 + }, function () { 1.266 + ++reattachCount; 1.267 + if (reattachCount == 1) { 1.268 + info("reattaching second chat window"); 1.269 + let chatbox = firstChatWindowDoc.getElementById("chatter"); 1.270 + firstChatWindowDoc.getAnonymousElementByAttribute(chatbox, "anonid", "swap").click(); 1.271 + firstChatWindowDoc = null; 1.272 + } 1.273 + else if (reattachCount == 2) { 1.274 + is(chats.children.length, 2, "both chat windows should be reattached"); 1.275 + chats.removeAll(); 1.276 + waitForCondition(() => chats.children.length == 0, function () { 1.277 + info("no chat window left"); 1.278 + is(chats.chatboxForURL.size, 0, "chatboxForURL map should be empty"); 1.279 + next(); 1.280 + }); 1.281 + } 1.282 + }, "waited too long for the window to reattach"); 1.283 + }, false); 1.284 + 1.285 + is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened"); 1.286 + if (!firstChatWindowDoc) { 1.287 + firstChatWindowDoc = doc; 1.288 + return; 1.289 + } 1.290 + Services.wm.removeListener(listener); 1.291 + 1.292 + // window is loaded, but the docswap does not happen until after load, 1.293 + // and we have no event to wait on, so we'll wait for document state 1.294 + // to be ready 1.295 + let chatbox = doc.getElementById("chatter"); 1.296 + waitForCondition(function() { 1.297 + return chats.children.length == 0 && 1.298 + chatbox.contentDocument && 1.299 + chatbox.contentDocument.readyState == "complete"; 1.300 + },function() { 1.301 + info("reattaching chat window"); 1.302 + doc.getAnonymousElementByAttribute(chatbox, "anonid", "swap").click(); 1.303 + }, "waited too long for the chat window to be detached"); 1.304 + 1.305 + }, false); 1.306 + } 1.307 + }); 1.308 + 1.309 + port.postMessage({topic: "test-worker-chat", data: chatUrl + "?id=1"}); 1.310 + } 1.311 +};