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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
const BLANK_PAGE =
"data:text/html;charset=utf-8,<!DOCTYPE html><title>Blank</title>Blank page";
/**
* Use a tagged template literal to create a page extraction actor test. This spins
* up an http server that serves the markup in a new tab. The page extractor can then
* be used on the page.
*
* @param {TemplateStringsArray} strings - The literal string parts.
* @param {...any} values - The interpolated expressions.
*/
async function html(strings, ...values) {
// Convert the arguments into markup.
let markup = "";
for (let i = 0; i < strings.length; i++) {
markup += strings[i];
if (i < values.length) {
markup += values[i];
}
}
markup = `<!DOCTYPE html><body>${markup}</body>`;
const { url, serverClosed } = serveOnce(markup);
const tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
url,
true // waitForLoad
);
const actor =
tab.linkedBrowser.browsingContext.currentWindowGlobal.getActor(
"PageExtractor"
);
return {
/**
* @type {PageExtractorParent}
*/
actor,
/**
* Get a new page extractor, which can change when navigating pages.
*
* @returns {PageExtractorParent}
*/
getPageExtractor() {
return tab.linkedBrowser.browsingContext.currentWindowGlobal.getActor(
"PageExtractor"
);
},
async cleanup() {
info("Cleaning up");
await serverClosed;
BrowserTestUtils.removeTab(tab);
},
};
}
/**
* Start an HTTP server that serves page.html with the provided HTML.
*
* @param {string} html
*/
function serveOnce(html) {
/** @type {import("../../../../../netwerk/test/httpserver/httpd.sys.mjs")} */
const { HttpServer } = ChromeUtils.importESModule(
"resource://testing-common/httpd.sys.mjs"
);
info("Create server");
const server = new HttpServer();
const { promise, resolve } = Promise.withResolvers();
server.registerPathHandler("/page.html", (_request, response) => {
info("Request received for: " + url);
response.setHeader("Content-Type", "text/html");
response.write(html);
resolve(server.stop());
});
server.start(-1);
let { primaryHost, primaryPort } = server.identity;
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
const url = `http://${primaryHost}:${primaryPort}/page.html`;
info("Server listening for: " + url);
return { url, serverClosed: promise };
}
/**
* Click the reader-mode button if the reader-mode button is available.
* Fails if the reader-mode button is hidden.
*/
async function toggleReaderMode() {
const readerButton = document.getElementById("reader-mode-button");
await BrowserTestUtils.waitForMutationCondition(
readerButton,
{ attributes: true, attributeFilter: ["hidden"] },
() => readerButton.hidden === false
);
readerButton.getAttribute("readeractive")
? info("Exiting reader mode")
: info("Entering reader mode");
const readyPromise = readerButton.getAttribute("readeractive")
? BrowserTestUtils.waitForMutationCondition(
readerButton,
{ attributes: true, attributeFilter: ["readeractive"] },
() => !readerButton.getAttribute("readeractive")
)
: BrowserTestUtils.waitForContentEvent(
gBrowser.selectedBrowser,
"AboutReaderContentReady"
);
click(readerButton, "Clicking the reader-mode button");
await readyPromise;
}
function click(button, message) {
info(message);
if (button.hidden) {
throw new Error("The button was hidden when trying to click it.");
}
button.click();
}
/**
* @param {string} file
*/
async function openSupportFile(file) {
// Support files can be served up from example.com
const url_prefix = "https://example.com/browser/";
const path_prefix = "toolkit/components/pageextractor/tests/browser/";
const url = url_prefix + path_prefix + file;
// Start the tab at a blank page.
const tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
BLANK_PAGE,
true // waitForLoad
);
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url);
await BrowserTestUtils.browserLoaded(
tab.linkedBrowser,
/* includeSubFrames */ false,
url
);
async function cleanup() {
if (url.endsWith(".pdf")) {
// Wait for the PDFViewerApplication to be closed before removing the
// tab to avoid spurious errors and potential intermittents.
await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
const viewer = content.wrappedJSObject.PDFViewerApplication;
await viewer.testingClose();
});
}
BrowserTestUtils.removeTab(tab);
}
return {
cleanup,
/**
* @returns {PageExtractorParent}
*/
getPageExtractor() {
return tab.linkedBrowser.browsingContext.currentWindowGlobal.getActor(
"PageExtractor"
);
},
};
}
|