summaryrefslogtreecommitdiffstats
path: root/devtools/server/tests/browser/browser_directorscript_actors_error_events.js
blob: 0afe1638875d7640403c362b433719ba380989c2 (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
/* 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 testErrorOnRequire(directorManager);
  yield testErrorOnEvaluate(directorManager);
  yield testErrorOnAttach(directorManager);
  yield testErrorOnDetach(directorManager);

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

function* testErrorOnRequire(directorManager) {
  // director script require method should raise a "not implemented" exception
  let errorOnRequire = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_errorOnRequire",
    scriptCode: "(" + (function () {
      // this director script should generate an error event
      // because require raise a "not implemented" exception
      require("fake_module");
    }).toString() + ")();",
    scriptOptions: {}
  });

  assertIsDirectorScriptError(errorOnRequire);

  let { message } = errorOnRequire;
  is(message, "Error: NOT IMPLEMENTED", "error.message contains the expected error message");
}

function* testErrorOnEvaluate(directorManager) {
  // director scripts should send an error events if the director script raise an exception on
  // evaluation
  let errorOnEvaluate = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_errorOnEvaluate",
    scriptCode: "(" + (function () {
      // this will raise an exception evaluating
      // the director script
      raise.an_error.during.content_script.load();
    }).toString() + ")();",
    scriptOptions: {}
  });
  assertIsDirectorScriptError(errorOnEvaluate);
}

function* testErrorOnAttach(directorManager) {
  // director scripts should send an error events if the director script raise an exception on
  // evaluation
  let errorOnAttach = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_errorOnAttach",
    scriptCode: "(" + (function () {
      // this will raise an exception on evaluating
      // the director script
      module.exports = function () {
        raise.an_error.during.content_script.load();
      };
    }).toString() + ")();",
    scriptOptions: {}
  });
  assertIsDirectorScriptError(errorOnAttach);
}

function* testErrorOnDetach(directorManager) {
  // director scripts should send an error events if the director script raise an exception on
  // evaluation
  let attach = yield installAndEnableDirectorScript(directorManager, {
    scriptId: "testDirectorScript_errorOnDetach",
    scriptCode: "(" + (function () {
      module.exports = function ({onUnload}) {
        // this will raise an exception on unload the director script
        onUnload(function () {
          raise_an_error_onunload();
        });
      };
    }).toString() + ")();",
    scriptOptions: {}
  });

  let waitForDetach = once(directorManager, "director-script-detach");
  let waitForError = once(directorManager, "director-script-error");

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

  let detach = yield waitForDetach;
  let error = yield waitForError;
  ok(detach, "testDirectorScript_errorOnDetach detach event received");
  ok(error, "testDirectorScript_errorOnDetach detach error received");
  assertIsDirectorScriptError(error);
}

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;
}

function assertIsDirectorScriptError(error) {
  ok(!!error.message, "errors should contain a message");
  ok(!!error.stack, "errors should contain a stack trace");
  ok(!!error.fileName, "errors should contain a fileName");
  ok(typeof error.columnNumber == "number", "errors should contain a columnNumber");
  ok(typeof error.lineNumber == "number", "errors should contain a lineNumber");

  ok(!!error.directorScriptId, "errors should contain a directorScriptId");
}