rename from toolkit/components/extensions/test/mochitest/test_ext_webrequest_responseBody.html
rename to toolkit/components/extensions/test/xpcshell/test_ext_webRequest_responseBody.js
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_responseBody.html
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_responseBody.js
@@ -1,23 +1,27 @@
-<!DOCTYPE html>
+"use strict";
+
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+/* eslint-disable no-shadow */
+
+ChromeUtils.import("resource://gre/modules/Timer.jsm");
+ChromeUtils.import("resource://gre/modules/osfile.jsm");
+ChromeUtils.import("resource://testing-common/ExtensionTestCommon.jsm");
-<html>
-<head>
- <meta charset="utf-8">
- <title>WebRequest response body filter test</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";
+Cu.importGlobalProperties(["URL"]);
+
+const HOSTS = new Set([
+ "example.com",
+]);
+
+const server = createHttpServer({hosts: HOSTS});
+
+const BASE_URL = "http://example.com";
+const FETCH_ORIGIN = "http://example.com/data/file_sample.html";
const SEQUENTIAL = false;
const PARTS = [
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
@@ -32,16 +36,57 @@ const PARTS = [
"Excepteur sint occaecat cupidatat non proident, <br>",
"sunt in culpa qui officia deserunt mollit anim id est laborum.<br>",
`
</body>
</html>`,
].map(part => `${part}\n`);
const TIMEOUT = AppConstants.DEBUG ? 4000 : 800;
+
+function delay(timeout = TIMEOUT) {
+ return new Promise(resolve => setTimeout(resolve, timeout));
+}
+
+server.registerPathHandler("/slow_response.sjs", async (request, response) => {
+ response.processAsync();
+
+ response.setHeader("Content-Type", "text/html", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ await delay();
+
+ for (let part of PARTS) {
+ try {
+ response.write(part);
+ } catch (e) {
+ // This fails if we attempt to write data after the connection has
+ // been closed.
+ break;
+ }
+ await delay();
+ }
+
+ response.finish();
+});
+
+server.registerPathHandler("/lorem.html.gz", async (request, response) => {
+ response.processAsync();
+
+ response.setHeader("Content-Type", "Content-Type: text/html; charset=utf-8", false);
+ response.setHeader("Content-Encoding", "gzip", false);
+
+ let data = await OS.File.read(do_get_file("data/lorem.html.gz").path);
+ response.write(String.fromCharCode(...new Uint8Array(data)));
+
+ response.finish();
+});
+
+server.registerDirectory("/data/", do_get_file("data"));
+
const TASKS = [
{
url: "slow_response.sjs",
task(filter, resolve, num) {
let decoder = new TextDecoder("utf-8");
browser.test.assertEq("uninitialized", filter.status,
`(${num}): Got expected initial status`);
@@ -69,50 +114,50 @@ const TASKS = [
filter.write(event.data);
if (n == 3) {
filter.suspend();
browser.test.assertEq("suspended", filter.status,
`(${num}): Got expected suspended status`);
- let fail = event => {
+ let fail = () => {
browser.test.fail(`(${num}): Got unexpected data event while suspended`);
};
filter.addEventListener("data", fail);
- await new Promise(resolve => setTimeout(resolve, TIMEOUT * 3));
+ await delay(TIMEOUT * 3);
browser.test.assertEq("suspended", filter.status,
`(${num}): Got expected suspended status`);
filter.removeEventListener("data", fail);
filter.resume();
browser.test.assertEq("transferringdata", filter.status,
`(${num}): Got expected resumed status`);
} else if (n > 4) {
filter.disconnect();
- filter.addEventListener("data", event => {
+ filter.addEventListener("data", () => {
browser.test.fail(`(${num}): Got unexpected data event while disconnected`);
});
browser.test.assertEq("disconnected", filter.status,
`(${num}): Got expected disconnected status`);
resolve();
}
};
filter.onerror = event => {
browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
};
},
verify(response) {
- is(response, PARTS.join(""), "Got expected final HTML");
+ equal(response, PARTS.join(""), "Got expected final HTML");
},
},
{
url: "slow_response.sjs",
task(filter, resolve, num) {
let decoder = new TextDecoder("utf-8");
filter.onstop = event => {
@@ -130,30 +175,30 @@ const TASKS = [
}
n++;
filter.write(event.data);
if (n == 3) {
filter.suspend();
- await new Promise(resolve => setTimeout(resolve, TIMEOUT * 3));
+ await delay(TIMEOUT * 3);
filter.disconnect();
resolve();
}
};
filter.onerror = event => {
browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
};
},
verify(response) {
- is(response, PARTS.join(""), "Got expected final HTML");
+ equal(response, PARTS.join(""), "Got expected final HTML");
},
},
{
url: "slow_response.sjs",
task(filter, resolve, num) {
let encoder = new TextEncoder("utf-8");
filter.onstop = event => {
@@ -176,17 +221,17 @@ const TASKS = [
checkState("suspended");
filter.suspend();
checkState("suspended");
filter.resume();
checkState("transferringdata");
filter.suspend();
checkState("suspended");
- await new Promise(resolve => setTimeout(resolve, TIMEOUT * 3));
+ await delay(TIMEOUT * 3);
checkState("suspended");
filter.disconnect();
checkState("disconnected");
for (let method of ["suspend", "resume", "close"]) {
browser.test.assertThrows(
() => {
@@ -209,17 +254,17 @@ const TASKS = [
}
};
filter.onerror = event => {
browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
};
},
verify(response) {
- is(response, PARTS.join(""), "Got expected final HTML");
+ equal(response, PARTS.join(""), "Got expected final HTML");
},
},
{
url: "slow_response.sjs",
task(filter, resolve, num) {
let encoder = new TextEncoder("utf-8");
let decoder = new TextDecoder("utf-8");
@@ -272,17 +317,17 @@ const TASKS = [
}
};
filter.onerror = event => {
browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
};
},
verify(response) {
- is(response, PARTS.slice(0, 3).join(""), "Got expected final HTML");
+ equal(response, PARTS.slice(0, 3).join(""), "Got expected final HTML");
},
},
{
url: "lorem.html.gz",
task(filter, resolve, num) {
let response = "";
let decoder = new TextDecoder("utf-8");
@@ -313,24 +358,22 @@ const TASKS = [
filter.write(event.data);
};
filter.onerror = event => {
browser.test.fail(`(${num}): Got unexpected error event: ${filter.error}`);
};
},
verify(response) {
- is(response, PARTS.join(""), "Got expected final HTML");
+ equal(response, PARTS.join(""), "Got expected final HTML");
},
},
];
function serializeTest(test, num) {
- /* globals ExtensionTestCommon */
-
let url = `${test.url}?test_num=${num}`;
let task = ExtensionTestCommon.serializeFunction(test.task);
return `{url: ${JSON.stringify(url)}, task: ${task}}`;
}
add_task(async function() {
function background(TASKS) {
@@ -355,45 +398,46 @@ add_task(async function() {
details => {
for (let [num, test] of TASKS.entries()) {
if (details.url.endsWith(test.url)) {
runTest(test, num, details);
break;
}
}
}, {
- urls: ["http://mochi.test/*?test_num=*"],
+ urls: ["http://example.com/*?test_num=*"],
},
["blocking"]);
}
let extension = ExtensionTestUtils.loadExtension({
background: `
const PARTS = ${JSON.stringify(PARTS)};
const TIMEOUT = ${TIMEOUT};
+ ${delay}
+
(${background})([${TASKS.map(serializeTest)}])
`,
manifest: {
permissions: [
"webRequest",
"webRequestBlocking",
- "http://mochi.test/",
+ "http://example.com/",
],
},
});
await extension.startup();
async function runTest(test, num) {
- let url = `${test.url}?test_num=${num}`;
+ let url = `${BASE_URL}/${test.url}?test_num=${num}`;
- let resp = await fetch(url);
- let body = await resp.text();
+ let body = await ExtensionTestUtils.fetch(FETCH_ORIGIN, url);
await extension.awaitMessage(`finished-${num}`);
info(`Verifying test #${num}: ${url}`);
await test.verify(body);
}
if (SEQUENTIAL) {
@@ -404,16 +448,18 @@ add_task(async function() {
await Promise.all(TASKS.map(runTest));
}
await extension.unload();
});
// Test that registering a listener for a cached response does not cause a crash.
add_task(async function test_cachedResponse() {
+ Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
+
let extension = ExtensionTestUtils.loadExtension({
background() {
browser.webRequest.onHeadersReceived.addListener(
data => {
let filter = browser.webRequest.filterResponseData(data.requestId);
filter.onstop = event => {
filter.close();
@@ -421,35 +467,35 @@ add_task(async function test_cachedRespo
filter.ondata = event => {
filter.write(event.data);
};
if (data.fromCache) {
browser.test.sendMessage("from-cache");
}
}, {
- urls: ["http://mochi.test/*/file_sample.html?r=*"],
+ urls: ["http://example.com/*/file_sample.html?r=*"],
},
["blocking"]);
},
manifest: {
permissions: [
"webRequest",
"webRequestBlocking",
- "http://mochi.test/",
+ "http://example.com/",
],
},
});
await extension.startup();
- let url = `file_sample.html?r=${Math.random()}`;
- await fetch(url);
- await fetch(url);
+ let url = `${BASE_URL}/data/file_sample.html?r=${Math.random()}`;
+ await ExtensionTestUtils.fetch(FETCH_ORIGIN, url);
+ await ExtensionTestUtils.fetch(FETCH_ORIGIN, url);
await extension.awaitMessage("from-cache");
await extension.unload();
});
// Test that finishing transferring data doesn't overwrite an existing closing/closed state.
add_task(async function test_late_close() {
let extension = ExtensionTestUtils.loadExtension({
@@ -466,40 +512,40 @@ add_task(async function test_late_close(
};
filter.ondata = event => {
filter.write(event.data);
filter.close();
browser.test.sendMessage(`done-${data.url}`);
};
}, {
- urls: ["http://mochi.test/*/file_sample.html?*"],
+ urls: ["http://example.com/*/file_sample.html?*"],
},
["blocking"]);
},
manifest: {
permissions: [
"webRequest",
"webRequestBlocking",
- "http://mochi.test/",
+ "http://example.com/",
],
},
});
await extension.startup();
// This issue involves a race, so several requests in parallel to increase
// the chances of triggering it.
let urls = [];
for (let i = 0; i < 32; i++) {
- urls.push(new URL(`file_sample.html?r=${Math.random()}`, location).href);
+ urls.push(`${BASE_URL}/data/file_sample.html?r=${Math.random()}`);
}
- await Promise.all(urls.map(url => fetch(url)));
+ await Promise.all(urls.map(url => ExtensionTestUtils.fetch(FETCH_ORIGIN, url)));
await Promise.all(urls.map(url => extension.awaitMessage(`done-${url}`)));
await extension.unload();
});
add_task(async function test_permissions() {
let extension = ExtensionTestUtils.loadExtension({
background() {
@@ -507,17 +553,17 @@ add_task(async function test_permissions
undefined,
browser.webRequest.filterResponseData,
"filterResponseData is undefined without blocking permissions");
},
manifest: {
permissions: [
"webRequest",
- "http://mochi.test/",
+ "http://example.com/",
],
},
});
await extension.startup();
await extension.unload();
});
@@ -534,20 +580,17 @@ add_task(async function test_invalidId()
browser.test.notifyPass("invalid-request-id");
},
manifest: {
permissions: [
"webRequest",
"webRequestBlocking",
- "http://mochi.test/",
+ "http://example.com/",
],
},
});
await extension.startup();
await extension.awaitFinish("invalid-request-id");
await extension.unload();
});
-</script>
-</body>
-</html>