summaryrefslogtreecommitdiffstats
path: root/devtools/server/tests/browser/browser_directorscript_actors.js
blob: bdfc8f8f1dcff2653d511c3041e6323cd4e8ec84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const {DirectorManagerFront} = require("devtools/shared/fronts/director-manager");
const {DirectorRegistry} = require("devtools/server/actors/director-registry");

add_task(function* () {
  let browser = yield addTab(MAIN_DOMAIN + "director-script-target.html");
  let doc = browser.contentDocument;

  initDebuggerServer();
  let client = new DebuggerClient(DebuggerServer.connectPipe());
  let form = yield connectDebuggerClient(client);

  DirectorRegistry.clear();
  let directorManager = DirectorManagerFront(client, form);

  yield testDirectorScriptAttachEventAttributes(directorManager);
  yield testDirectorScriptMessagePort(directorManager);
  yield testDirectorScriptWindowEval(directorManager);
  yield testDirectorScriptUnloadOnDetach(directorManager);

  yield client.close();
  gBrowser.removeCurrentTab();
  DirectorRegistry.clear();
});

function* testDirectorScriptAttachEventAttributes(directorManager) {
  let attachEvent = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_attachEventAttributes",
    scriptCode: "(" + (function () {
      exports.attach = function () {};
    }).toString() + ")();",
    scriptOptions: {
      attachMethod: "attach"
    }
  });

  let { directorScriptId, url } = attachEvent;

  is(directorScriptId, "testDirectorScript_attachEventAttributes",
     "attach event should contains directorScriptId");
  is(url, MAIN_DOMAIN + "director-script-target.html");
}

function* testDirectorScriptMessagePort(directorManager) {
  let { port } = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_MessagePort",
    scriptCode: "(" + (function () {
      exports.attach = function ({port}) {
        port.onmessage = function (evt) {
          // echo messages
          evt.source.postMessage(evt.data);
        };
      };
    }).toString() + ")();",
    scriptOptions: {
      attachMethod: "attach"
    }
  });

  ok(port && port.postMessage, "testDirector_MessagePort port received");

  // exchange messages over the MessagePort
  let waitForMessagePortEvent = once(port, "message");
  // needs to explicit start the port
  port.start();

  var msg = { k1: "v1", k2: [1, 2, 3] };
  port.postMessage(msg);

  var reply = yield waitForMessagePortEvent;

  is(JSON.stringify(reply.data), JSON.stringify(msg), "echo reply received on the MessagePortClient");
}

function* testDirectorScriptWindowEval(directorManager) {
  let { port } = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_WindowEval",
    scriptCode: "(" + (function () {
      exports.attach = function ({window, port}) {
        var onpageloaded = function () {
          var globalVarValue = window.eval("globalAccessibleVar;");
          port.postMessage(globalVarValue);
        };

        if (window.document && window.document.readyState === "complete") {
          onpageloaded();
        } else {
          window.addEventListener("load", onpageloaded, false);
        }
      };
    }).toString() + ")();",
    scriptOptions: {
      attachMethod: "attach"
    }
  });

  ok(port, "testDirectorScript_WindowEval port received");

  // exchange messages over the MessagePort
  let waitForMessagePortEvent = once(port, "message");
  // needs to explicit start the port
  port.start();

  var portEvent = yield waitForMessagePortEvent;

  ok(portEvent.data !== "unsecure-eval", "window.eval should be wrapped and safe");
  is(portEvent.data, "global-value", "globalAccessibleVar should be accessible through window.eval");
}

function* testDirectorScriptUnloadOnDetach(directorManager) {
  let { port } = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_unloadOnDetach",
    scriptCode: "(" + (function () {
      exports.attach = function ({port, onUnload}) {
        onUnload(function () {
          port.postMessage("ONUNLOAD");
        });
      };
    }).toString() + ")();",
    scriptOptions: {
      attachMethod: "attach"
    }
  });

  ok(port, "testDirectorScript_unloadOnDetach port received");
  port.start();

  let waitForDetach = once(directorManager, "director-script-detach");
  let waitForMessage = once(port, "message");

  directorManager.disableByScriptIds(["testDirectorScript_unloadOnDetach"], {reload: false});

  let { directorScriptId } = yield waitForDetach;
  is(directorScriptId, "testDirectorScript_unloadOnDetach",
     "detach event should contains directorScriptId");

  let portEvent = yield waitForMessage;
  is(portEvent.data, "ONUNLOAD", "director-script's exports.onUnload called on detach");
}

function* installAndEnableDirectorScript(directorManager, directorScriptDef) {
  let { scriptId } = directorScriptDef;

  DirectorRegistry.install(scriptId, directorScriptDef);

  let waitForAttach = once(directorManager, "director-script-attach");
  let waitForError = once(directorManager, "director-script-error");

  directorManager.enableByScriptIds([scriptId], {reload: false});

  let attachOrErrorEvent = yield Promise.race([waitForAttach, waitForError]);

  return attachOrErrorEvent;
}