summaryrefslogtreecommitdiffstats
path: root/toolkit/components/webextensions/test/mochitest/test_ext_tab_teardown.html
blob: dc351e48a11840e13ae41f6de002a52bab17d8c1 (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
<!DOCTYPE HTML>
<html>
<head>
  <title>Test for extension tab teardown</title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
  <script type="text/javascript" src="head.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
</head>
<body>

<script>
"use strict";

// Test for tabs opened using tabs.create and window.open
function* runTabReloadAndCloseTest(extension) {
  let chromeScript = SpecialPowers.loadChromeScript(
      SimpleTest.getTestFileURL("file_teardown_test.js"));
  yield chromeScript.promiseOneMessage("chromescript-startup");
  function* getContextEvents() {
    chromeScript.sendAsyncMessage("get-context-events");
    let contextEvents = yield chromeScript.promiseOneMessage("context-events");
    dump(JSON.stringify(contextEvents));
    return contextEvents.filter(event => event.extensionId == extension.id);
  }

  extension.sendMessage("open extension page");
  let extensionPageUrl = yield extension.awaitMessage("extension page loaded");

  let contextEvents = yield* getContextEvents();
  is(contextEvents.length, 1, "ExtensionContext change for opening a tab");
  is(contextEvents[0].eventType, "load", "create ExtensionContext for tab");
  is(contextEvents[0].url, extensionPageUrl,
      "ExtensionContext URL after tab creation should be tab URL");

  extension.sendMessage("reload extension page");
  let extensionPageUrl2 = yield extension.awaitMessage("extension page loaded");

  is(extensionPageUrl, extensionPageUrl2,
      "The tab's URL is expected to not change after a page reload");

  contextEvents = yield* getContextEvents();
  is(contextEvents.length, 2, "ExtensionContext change after tab reload");
  is(contextEvents[0].eventType, "unload", "unload old ExtensionContext");
  is(contextEvents[0].url, extensionPageUrl,
      "ExtensionContext URL before reload should be tab URL");
  is(contextEvents[1].eventType, "load", "create new ExtensionContext for tab");
  is(contextEvents[1].url, extensionPageUrl2,
      "ExtensionContext URL after reload should be tab URL");

  extension.sendMessage("close extension page");
  yield extension.awaitMessage("closed extension page");

  contextEvents = yield* getContextEvents();
  is(contextEvents.length, 1, "ExtensionContext after closing tab");
  is(contextEvents[0].eventType, "unload", "unload tab's ExtensionContext");
  is(contextEvents[0].url, extensionPageUrl2,
      "ExtensionContext URL at closing tab should be tab URL");

  chromeScript.sendAsyncMessage("cleanup");
  chromeScript.destroy();
  yield extension.unload();
}

add_task(function* test_extension_page_tabs_create_reload_and_close() {
  function background() {
    let tabId;
    browser.test.onMessage.addListener(msg => {
      if (msg === "open extension page") {
        chrome.tabs.create({url: "page.html"}, tab => {
          tabId = tab.id;
        });
      } else if (msg === "reload extension page") {
        chrome.tabs.reload(tabId);
      } else if (msg === "close extension page") {
        chrome.tabs.remove(tabId, () => {
          browser.test.sendMessage("closed extension page");
        });
      }
    });
  }

  function pageScript() {
    browser.test.sendMessage("extension page loaded", document.URL);
  }

  let extensionData = {
    background,
    files: {
      "page.html": `<!DOCTYPE html><meta charset="utf-8"><script src="page.js"><\/script>`,
      "page.js": pageScript,
    },
  };

  let extension = ExtensionTestUtils.loadExtension(extensionData);
  yield extension.startup();

  yield* runTabReloadAndCloseTest(extension);
});

add_task(function* test_extension_page_window_open_reload_and_close() {
  // This tests whether a context that is opened via window.open is properly
  // disposed when the tab closes.
  // The background page cannot use window.open (bugzil.la/1282021), so we open
  // another extension page that manages the window.open-tab for testing.
  function background() {
    chrome.tabs.create({url: "window.open.html"});
  }

  function windowOpenScript() {
    let win;
    browser.test.onMessage.addListener(msg => {
      if (msg === "open extension page") {
        win = window.open("page.html");
      } else if (msg === "reload extension page") {
        win.location.reload();
      } else if (msg === "close extension page") {
        browser.tabs.onRemoved.addListener(function listener() {
          browser.tabs.onRemoved.removeListener(listener);
          browser.test.sendMessage("closed extension page");
        });
        win.close();
      }
    });
    browser.test.sendMessage("setup-intermediate-tab");
  }

  function pageScript() {
    browser.test.sendMessage("extension page loaded", document.URL);
  }

  let extensionData = {
    background,
    files: {
      "page.html": `<!DOCTYPE html><meta charset="utf-8"><script src="page.js"><\/script>`,
      "page.js": pageScript,
      "window.open.html": `<!DOCTYPE html><meta charset="utf-8"><script src="window.open.js"><\/script>`,
      "window.open.js": windowOpenScript,
    },
  };
  let extension = ExtensionTestUtils.loadExtension(extensionData);
  yield extension.startup();
  yield extension.awaitMessage("setup-intermediate-tab");
  yield* runTabReloadAndCloseTest(extension);
});
</script>

</body>
</html>