devtools/server/tests/mochitest/test_getProcess.html
author Michael Ratcliffe <mratcliffe@mozilla.com>
Fri, 09 Mar 2018 15:36:45 +0000
changeset 408107 2c8540f7800fcaae3599e6c64154ba9e5ac95f17
parent 407713 49cce2c9e2ab21606a9abcdc0ab0af991806957f
child 408109 e5cca677e835e18e0eb74499d5c0448497aa779c
permissions -rw-r--r--
Bug 1443457 - Stop referencing the addon-sdk loader in devtools code r=jdescottes MozReview-Commit-ID: 7lwCG8JT7cV

<SDOCTYPv HTM.>
<html>
<!--
Bug 1060093 - Test DebuggerServer.getProcess
-->
<head>
  <meta charset="utf-8">
  <title>Mozilla Bug</title>
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<pre id="test">
<script type="application/javascript">
"use strict";

let {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
let {DebuggerClient} = require("devtools/shared/client/debugger-client");
let {DebuggerServer} = require("devtools/server/main");
let Services = require("Services");

window.onload = function () {
  SimpleTest.waitForExplicitFinish();

  SpecialPowers.pushPrefEnv({
    "set": [
      // Always log packets when running tests.
      ["devtools.debugger.log", true],
      // Enabled mozbrowser frame to support remote=true
      ["dom.mozBrowserFramesEnabled", true],
      // Allows creating a branch new process when creation the iframe
      ["dom.ipc.processCount", 10],
    ]
  }, runTests);
};

function runTests() {
  // Instantiate a minimal server
  DebuggerServer.init();
  DebuggerServer.allowChromeProcess = true;
  if (!DebuggerServer.createRootActor) {
    DebuggerServer.registerAllActors();
  }

  let client, iframe, processCount;

  function connect() {
    // Fake a first connection to the content process
    let transport = DebuggerServer.connectPipe();
    client = new DebuggerClient(transport);
    client.connect().then(listProcess);
  }

  function listProcess() {
    // Call listProcesses in order to start receiving new process notifications
    client.addListener("processListChanged", function listener() {
      client.removeListener("processListChanged", listener);
      ok(true, "Received processListChanged event");
      getProcess();
    });
    client.mainRoot.listProcesses(response => {
      processCount = response.processes.length;
      // Create a remote iframe to spawn a new process
      createRemoteIframe();
    });
  }

  function createRemoteIframe() {
    iframe = document.createElement("iframe");
    iframe.mozbrowser = true;
    iframe.setAttribute("remote", "true");
    iframe.setAttribute("src", "data:text/html,foo");
    document.body.appendChild(iframe);
  }

  function getProcess() {
    client.mainRoot.listProcesses(response => {
      ok(response.processes.length >= 2, "Got at least the parent process and one child");
      is(response.processes.length, processCount + 1,
         "Got one additional process on the second call to listProcesses");

      // Connect to the first content processe available
      let content = response.processes.filter(p => (!p.parent))[0];

      client.getProcess(content.id).then(({form: actor}) => {
        ok(actor.consoleActor, "Got the console actor");
        ok(actor.chromeDebugger, "Got the thread actor");

        // Ensure sending at least one request to an actor...
        client.request({
          to: actor.consoleActor,
          type: "evaluateJS",
          text: "var a = 42; a"
        }, function ({result}) {
          ok(result, 42, "console.eval worked");

          getProcessAgain(actor, content.id);
        });
      });
    });
  }

  // Assert that calling client.getProcess against the same process id is
  // returning the same actor.
  function getProcessAgain(firstActor, id) {
    client.getProcess(id).then(response => {
      let actor = response.form;
      is(actor, firstActor,
         "Second call to getProcess with the same id returns the same form");
      closeClient();
    });
  }

  function processScript() {
    ChromeUtils.import("resource://gre/modules/Services.jsm");
    let listener = function () {
      Services.obs.removeObserver(listener, "devtools:loader:destroy");
      sendAsyncMessage("test:getProcess-destroy", null);
    };
    Services.obs.addObserver(listener, "devtools:loader:destroy");
  }

  function closeClient() {
    let onLoaderDestroyed = new Promise(done => {
      let processListener = function () {
        Services.ppmm.removeMessageListener("test:getProcess-destroy", processListener);
        done();
      };
      Services.ppmm.addMessageListener("test:getProcess-destroy", processListener);
    });
    let script = "data:,(" + processScript + ")()";
    Services.ppmm.loadProcessScript(script, true);
    client.close();

    onLoaderDestroyed.then(function () {
      Services.ppmm.removeDelayedProcessScript(script);
      info("Loader destroyed in the content process");

      cleanup();
    });
  }

  function cleanup() {
    DebuggerServer.destroy();
    iframe.remove();
    SimpleTest.finish();
  }

  connect();
}

</script>
</pre>
</body>
</html>