toolkit/devtools/server/tests/browser/browser_navigateEvents.js

changeset 0
6474c204b198
     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 +}

mercurial