summaryrefslogtreecommitdiffstats
path: root/testing/mochitest/document-builder.sjs
diff options
context:
space:
mode:
Diffstat (limited to 'testing/mochitest/document-builder.sjs')
-rw-r--r--testing/mochitest/document-builder.sjs97
1 files changed, 97 insertions, 0 deletions
diff --git a/testing/mochitest/document-builder.sjs b/testing/mochitest/document-builder.sjs
new file mode 100644
index 0000000000..b8c9ef21e7
--- /dev/null
+++ b/testing/mochitest/document-builder.sjs
@@ -0,0 +1,97 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+Cu.importGlobalProperties(["URLSearchParams"]);
+
+function loadHTMLFromFile(path) {
+ // Load the HTML to return in the response from file.
+ // Since it's relative to the cwd of the test runner, we start there and
+ // append to get to the actual path of the file.
+ const testHTMLFile =
+ // eslint-disable-next-line mozilla/use-services
+ Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties)
+ .get("CurWorkD", Ci.nsIFile);
+ const dirs = path.split("/");
+ for (let i = 0; i < dirs.length; i++) {
+ testHTMLFile.append(dirs[i]);
+ }
+
+ const testHTMLFileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ testHTMLFileStream.init(testHTMLFile, -1, 0, 0);
+ const testHTML = NetUtil.readInputStreamToString(
+ testHTMLFileStream,
+ testHTMLFileStream.available()
+ );
+
+ return testHTML;
+}
+
+/**
+ * document-builder.sjs can be used to dynamically build documents that will be used in
+ * mochitests. It does handle the following GET parameters:
+ * - file: The path to an (X)HTML file whose content will be used as a response.
+ * Example: document-builder.sjs?file=/tests/dom/security/test/csp/file_web_manifest_mixed_content.html
+ * - html: A string representation of the HTML document you want to get.
+ * Example: document-builder.sjs?html=<h1>Hello</h1>
+ * - headers: A <key:value> string representation of headers that will be set on the response
+ * This is only applied when the html GET parameter is passed as well
+ * Example: document-builder.sjs?headers=Cross-Origin-Opener-Policy:same-origin&html=<h1>Hello</h1>
+ * document-builder.sjs?headers=X-Header1:a&headers=X-Header2:b&html=<h1>Multiple headers</h1>
+ * - delay: Delay the response by X millisecond.
+ */
+async function handleRequest(request, response) {
+ response.processAsync();
+
+ const queryString = new URLSearchParams(request.queryString);
+ const html = queryString.get("html");
+ const delay = queryString.get("delay");
+
+ if (delay) {
+ await new Promise(resolve => {
+ let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ timer.initWithCallback(
+ () => {
+ // to avoid garbage collection
+ timer = null;
+ resolve();
+ },
+ delay,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+ });
+ }
+
+ response.setHeader("Cache-Control", "no-cache", false);
+ if (html) {
+ response.setHeader("Content-Type", "text/html", false);
+
+ if (queryString.has("headers")) {
+ for (const header of queryString.getAll("headers")) {
+ const [key, value] = header.split(":");
+ response.setHeader(key, value, false);
+ }
+ }
+
+ response.write(html);
+ } else {
+ const path = queryString.get("file");
+ const doc = loadHTMLFromFile(path);
+ response.setHeader(
+ "Content-Type",
+ path.endsWith(".xhtml") ? "application/xhtml+xml" : "text/html",
+ false
+ );
+ // This is a hack to set the correct id for the content document that is to be
+ // loaded in the iframe.
+ response.write(doc.replace(`id="body"`, `id="default-iframe-body-id"`));
+ }
+
+ response.finish();
+}