diff options
Diffstat (limited to 'testing/mochitest/document-builder.sjs')
-rw-r--r-- | testing/mochitest/document-builder.sjs | 97 |
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(); +} |