1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/devtools/server/tests/browser/browser_navigateEvents.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,169 @@ 1.4 + 1.5 +let Cu = Components.utils; 1.6 +let Cc = Components.classes; 1.7 +let Ci = Components.interfaces; 1.8 + 1.9 +const URL1 = MAIN_DOMAIN + "navigate-first.html"; 1.10 +const URL2 = MAIN_DOMAIN + "navigate-second.html"; 1.11 + 1.12 +let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {}); 1.13 +let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); 1.14 + 1.15 +let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; 1.16 +let events = devtools.require("sdk/event/core"); 1.17 + 1.18 +let client; 1.19 + 1.20 +// State machine to check events order 1.21 +let i = 0; 1.22 +function assertEvent(event, data) { 1.23 + let x = 0; 1.24 + switch(i++) { 1.25 + case x++: 1.26 + is(event, "request", "Get first page load"); 1.27 + is(data, URL1); 1.28 + break; 1.29 + case x++: 1.30 + is(event, "load-new-document", "Ask to load the second page"); 1.31 + break; 1.32 + case x++: 1.33 + is(event, "unload-dialog", "We get the dialog on first page unload"); 1.34 + break; 1.35 + case x++: 1.36 + is(event, "will-navigate", "The very first event is will-navigate on server side"); 1.37 + is(data.newURI, URL2, "newURI property is correct"); 1.38 + break; 1.39 + case x++: 1.40 + is(event, "tabNavigated", "Right after will-navigate, the client receive tabNavigated"); 1.41 + is(data.state, "start", "state is start"); 1.42 + is(data.url, URL2, "url property is correct"); 1.43 + break; 1.44 + case x++: 1.45 + is(event, "request", "Given that locally, the Debugger protocol is sync, the request happens after tabNavigated"); 1.46 + is(data, URL2); 1.47 + break; 1.48 + case x++: 1.49 + is(event, "DOMContentLoaded"); 1.50 + is(content.document.readyState, "interactive"); 1.51 + break; 1.52 + case x++: 1.53 + is(event, "load"); 1.54 + is(content.document.readyState, "complete"); 1.55 + break; 1.56 + case x++: 1.57 + is(event, "navigate", "Then once the second doc is loaded, we get the navigate event"); 1.58 + is(content.document.readyState, "complete", "navigate is emitted only once the document is fully loaded"); 1.59 + break; 1.60 + case x++: 1.61 + is(event, "tabNavigated", "Finally, the receive the client event"); 1.62 + is(data.state, "stop", "state is stop"); 1.63 + is(data.url, URL2, "url property is correct"); 1.64 + 1.65 + // End of test! 1.66 + cleanup(); 1.67 + break; 1.68 + } 1.69 +} 1.70 + 1.71 +function waitForOnBeforeUnloadDialog(browser, callback) { 1.72 + browser.addEventListener("DOMWillOpenModalDialog", function onModalDialog() { 1.73 + browser.removeEventListener("DOMWillOpenModalDialog", onModalDialog, true); 1.74 + 1.75 + executeSoon(() => { 1.76 + let stack = browser.parentNode; 1.77 + let dialogs = stack.getElementsByTagName("tabmodalprompt"); 1.78 + let {button0, button1} = dialogs[0].ui; 1.79 + callback(button0, button1); 1.80 + }); 1.81 + }, true); 1.82 +} 1.83 + 1.84 +let httpObserver = function (subject, topic, state) { 1.85 + let channel = subject.QueryInterface(Ci.nsIHttpChannel); 1.86 + let url = channel.URI.spec; 1.87 + // Only listen for our document request, as many other requests can happen 1.88 + if (url == URL1 || url == URL2) { 1.89 + assertEvent("request", url); 1.90 + } 1.91 +}; 1.92 +Services.obs.addObserver(httpObserver, "http-on-modify-request", false); 1.93 + 1.94 +function onDOMContentLoaded() { 1.95 + assertEvent("DOMContentLoaded"); 1.96 +} 1.97 +function onLoad() { 1.98 + assertEvent("load"); 1.99 +} 1.100 + 1.101 +function getServerTabActor(callback) { 1.102 + // Ensure having a minimal server 1.103 + if (!DebuggerServer.initialized) { 1.104 + DebuggerServer.init(function () { return true; }); 1.105 + DebuggerServer.addBrowserActors(); 1.106 + } 1.107 + 1.108 + // Connect to this tab 1.109 + let transport = DebuggerServer.connectPipe(); 1.110 + client = new DebuggerClient(transport); 1.111 + client.connect(function onConnect() { 1.112 + client.listTabs(function onListTabs(aResponse) { 1.113 + // Fetch the BrowserTabActor for this tab 1.114 + let actorID = aResponse.tabs[aResponse.selected].actor; 1.115 + client.attachTab(actorID, function(aResponse, aTabClient) { 1.116 + // !Hack! Retrieve a server side object, the BrowserTabActor instance 1.117 + let conn = transport._serverConnection; 1.118 + let tabActor = conn.getActor(actorID); 1.119 + callback(tabActor); 1.120 + }); 1.121 + }); 1.122 + }); 1.123 + 1.124 + client.addListener("tabNavigated", function (aEvent, aPacket) { 1.125 + assertEvent("tabNavigated", aPacket); 1.126 + }); 1.127 +} 1.128 + 1.129 +function test() { 1.130 + waitForExplicitFinish(); 1.131 + 1.132 + // Open a test tab 1.133 + addTab(URL1, function(doc) { 1.134 + getServerTabActor(function (tabActor) { 1.135 + // In order to listen to internal will-navigate/navigate events 1.136 + events.on(tabActor, "will-navigate", function (data) { 1.137 + assertEvent("will-navigate", data); 1.138 + }); 1.139 + events.on(tabActor, "navigate", function (data) { 1.140 + assertEvent("navigate", data); 1.141 + }); 1.142 + 1.143 + // Start listening for page load events 1.144 + let browser = gBrowser.selectedTab.linkedBrowser; 1.145 + browser.addEventListener("DOMContentLoaded", onDOMContentLoaded, true); 1.146 + browser.addEventListener("load", onLoad, true); 1.147 + 1.148 + // Listen for alert() call being made in navigate-first during unload 1.149 + waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) { 1.150 + assertEvent("unload-dialog"); 1.151 + // accept to quit this page to another 1.152 + btnLeave.click(); 1.153 + }); 1.154 + 1.155 + // Load another document in this doc to dispatch these events 1.156 + assertEvent("load-new-document"); 1.157 + content.location = URL2; 1.158 + }); 1.159 + 1.160 + }); 1.161 +} 1.162 + 1.163 +function cleanup() { 1.164 + let browser = gBrowser.selectedTab.linkedBrowser; 1.165 + browser.removeEventListener("DOMContentLoaded", onDOMContentLoaded); 1.166 + browser.removeEventListener("load", onLoad); 1.167 + client.close(function () { 1.168 + Services.obs.addObserver(httpObserver, "http-on-modify-request", false); 1.169 + DebuggerServer.destroy(); 1.170 + finish(); 1.171 + }); 1.172 +}