Source code

Revision control

Other Tools

1
<!DOCTYPE HTML>
2
<html>
3
<head>
4
<title>Tabs sendMessage Test</title>
5
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
6
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
7
<script type="text/javascript" src="head.js"></script>
8
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
9
</head>
10
<body>
11
12
<script type="text/javascript">
13
"use strict";
14
15
add_task(async function tabsSendMessageReply() {
16
let extension = ExtensionTestUtils.loadExtension({
17
manifest: {
18
"permissions": ["tabs"],
19
20
"content_scripts": [{
21
"matches": ["http://example.com/"],
22
"js": ["content-script.js"],
23
"run_at": "document_start",
24
}],
25
},
26
27
background: async function() {
28
let firstTab;
29
let promiseResponse = new Promise(resolve => {
30
browser.runtime.onMessage.addListener((msg, sender, respond) => {
31
if (msg == "content-script-ready") {
32
let tabId = sender.tab.id;
33
34
Promise.all([
35
promiseResponse,
36
37
browser.tabs.sendMessage(tabId, "respond-now"),
38
browser.tabs.sendMessage(tabId, "respond-now-2"),
39
new Promise(resolve => browser.tabs.sendMessage(tabId, "respond-soon", resolve)),
40
browser.tabs.sendMessage(tabId, "respond-promise"),
41
browser.tabs.sendMessage(tabId, "respond-never"),
42
new Promise(resolve => {
43
browser.runtime.sendMessage("respond-never", response => { resolve(response); });
44
}),
45
46
browser.tabs.sendMessage(tabId, "respond-error").catch(error => Promise.resolve({error})),
47
browser.tabs.sendMessage(tabId, "throw-error").catch(error => Promise.resolve({error})),
48
49
browser.tabs.sendMessage(firstTab, "no-listener").catch(error => Promise.resolve({error})),
50
]).then(([response, respondNow, respondNow2, respondSoon, respondPromise, respondNever, respondNever2, respondError, throwError, noListener]) => {
51
browser.test.assertEq("expected-response", response, "Content script got the expected response");
52
53
browser.test.assertEq("respond-now", respondNow, "Got the expected immediate response");
54
browser.test.assertEq("respond-now-2", respondNow2, "Got the expected immediate response from the second listener");
55
browser.test.assertEq("respond-soon", respondSoon, "Got the expected delayed response");
56
browser.test.assertEq("respond-promise", respondPromise, "Got the expected promise response");
57
browser.test.assertEq(undefined, respondNever, "Got the expected no-response resolution");
58
browser.test.assertEq(undefined, respondNever2, "Got the expected no-response resolution");
59
60
browser.test.assertEq("respond-error", respondError.error.message, "Got the expected error response");
61
browser.test.assertEq("throw-error", throwError.error.message, "Got the expected thrown error response");
62
63
browser.test.assertEq("Could not establish connection. Receiving end does not exist.",
64
noListener.error.message,
65
"Got the expected no listener response");
66
67
return browser.tabs.remove(tabId);
68
}).then(() => {
69
browser.test.notifyPass("sendMessage");
70
});
71
72
return Promise.resolve("expected-response");
73
} else if (msg[0] == "got-response") {
74
resolve(msg[1]);
75
}
76
});
77
});
78
79
let tabs = await browser.tabs.query({currentWindow: true, active: true});
80
firstTab = tabs[0].id;
81
browser.tabs.create({url: "http://example.com/"});
82
},
83
84
files: {
85
"content-script.js": async function() {
86
browser.runtime.onMessage.addListener((msg, sender, respond) => {
87
if (msg == "respond-now") {
88
respond(msg);
89
} else if (msg == "respond-soon") {
90
setTimeout(() => { respond(msg); }, 0);
91
return true;
92
} else if (msg == "respond-promise") {
93
return Promise.resolve(msg);
94
} else if (msg == "respond-never") {
95
return undefined;
96
} else if (msg == "respond-error") {
97
return Promise.reject(new Error(msg));
98
} else if (msg == "throw-error") {
99
throw new Error(msg);
100
}
101
});
102
103
browser.runtime.onMessage.addListener((msg, sender, respond) => {
104
if (msg == "respond-now") {
105
respond("hello");
106
} else if (msg == "respond-now-2") {
107
respond(msg);
108
}
109
});
110
111
let response = await browser.runtime.sendMessage("content-script-ready");
112
browser.runtime.sendMessage(["got-response", response]);
113
},
114
},
115
});
116
117
await extension.startup();
118
119
await extension.awaitFinish("sendMessage");
120
121
await extension.unload();
122
});
123
124
125
add_task(async function tabsSendHidden() {
126
let extension = ExtensionTestUtils.loadExtension({
127
manifest: {
128
"permissions": ["tabs"],
129
130
"content_scripts": [{
131
"matches": ["http://example.com/content*"],
132
"js": ["content-script.js"],
133
"run_at": "document_start",
134
}],
135
},
136
137
background: async function() {
138
let resolveContent;
139
browser.runtime.onMessage.addListener((msg, sender) => {
140
if (msg[0] == "content-ready") {
141
resolveContent(msg[1]);
142
}
143
});
144
145
let awaitContent = url => {
146
return new Promise(resolve => {
147
resolveContent = resolve;
148
}).then(result => {
149
browser.test.assertEq(url, result, "Expected content script URL");
150
});
151
};
152
153
try {
154
const URL1 = "http://example.com/content1.html";
155
const URL2 = "http://example.com/content2.html";
156
157
let tab = await browser.tabs.create({url: URL1});
158
await awaitContent(URL1);
159
160
let url = await browser.tabs.sendMessage(tab.id, URL1);
161
browser.test.assertEq(URL1, url, "Should get response from expected content window");
162
163
await browser.tabs.update(tab.id, {url: URL2});
164
await awaitContent(URL2);
165
166
url = await browser.tabs.sendMessage(tab.id, URL2);
167
browser.test.assertEq(URL2, url, "Should get response from expected content window");
168
169
// Repeat once just to be sure the first message was processed by all
170
// listeners before we exit the test.
171
url = await browser.tabs.sendMessage(tab.id, URL2);
172
browser.test.assertEq(URL2, url, "Should get response from expected content window");
173
174
await browser.tabs.remove(tab.id);
175
176
browser.test.notifyPass("contentscript-bfcache-window");
177
} catch (error) {
178
browser.test.fail(`Error: ${error} :: ${error.stack}`);
179
browser.test.notifyFail("contentscript-bfcache-window");
180
}
181
},
182
183
files: {
184
"content-script.js": function() {
185
// Store this in a local variable to make sure we don't touch any
186
// properties of the possibly-hidden content window.
187
let href = window.location.href;
188
189
browser.runtime.onMessage.addListener((msg, sender) => {
190
browser.test.assertEq(href, msg, "Should be in the expected content window");
191
192
return Promise.resolve(href);
193
});
194
195
browser.runtime.sendMessage(["content-ready", href]);
196
},
197
},
198
});
199
200
await extension.startup();
201
202
await extension.awaitFinish("contentscript-bfcache-window");
203
204
await extension.unload();
205
});
206
207
208
add_task(async function tabsSendMessageNoExceptionOnNonExistentTab() {
209
let extension = ExtensionTestUtils.loadExtension({
210
manifest: {
211
"permissions": ["tabs"],
212
},
213
214
async background() {
216
let tab = await browser.tabs.create({url});
217
218
try {
219
browser.tabs.sendMessage(tab.id, "message");
220
browser.tabs.sendMessage(tab.id + 100, "message");
221
} catch (e) {
222
browser.test.fail("no exception should be raised on tabs.sendMessage to nonexistent tabs");
223
}
224
225
await browser.tabs.remove(tab.id);
226
227
browser.test.notifyPass("tabs.sendMessage");
228
},
229
});
230
231
await Promise.all([
232
extension.startup(),
233
extension.awaitFinish("tabs.sendMessage"),
234
]);
235
236
await extension.unload();
237
});
238
239
</script>
240
241
</body>
242
</html>