summaryrefslogtreecommitdiffstats
path: root/widget/headless/tests/test_headless.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /widget/headless/tests/test_headless.js
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'widget/headless/tests/test_headless.js')
-rw-r--r--widget/headless/tests/test_headless.js215
1 files changed, 215 insertions, 0 deletions
diff --git a/widget/headless/tests/test_headless.js b/widget/headless/tests/test_headless.js
new file mode 100644
index 0000000000..79486a9d8c
--- /dev/null
+++ b/widget/headless/tests/test_headless.js
@@ -0,0 +1,215 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+
+const gProfDir = do_get_profile();
+const server = new HttpServer();
+server.registerDirectory("/", do_get_cwd());
+server.start(-1);
+const ROOT = `http://localhost:${server.identity.primaryPort}`;
+const BASE = `${ROOT}/`;
+const HEADLESS_URL = `${BASE}/headless.html`;
+const HEADLESS_BUTTON_URL = `${BASE}/headless_button.html`;
+registerCleanupFunction(() => {
+ server.stop(() => {});
+});
+
+// Refrences to the progress listeners to keep them from being gc'ed
+// before they are called.
+const progressListeners = new Map();
+
+function loadContentWindow(windowlessBrowser, uri) {
+ return new Promise((resolve, reject) => {
+ let loadURIOptions = {
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ };
+ windowlessBrowser.loadURI(uri, loadURIOptions);
+ let docShell = windowlessBrowser.docShell;
+ let webProgress = docShell
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebProgress);
+ let progressListener = {
+ onLocationChange(progress, request, location, flags) {
+ // Ignore inner-frame events
+ if (progress != webProgress) {
+ return;
+ }
+ // Ignore events that don't change the document
+ if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
+ return;
+ }
+ let contentWindow = docShell.domWindow;
+ webProgress.removeProgressListener(progressListener);
+ progressListeners.delete(progressListener);
+ contentWindow.addEventListener(
+ "load",
+ event => {
+ resolve(contentWindow);
+ },
+ { once: true }
+ );
+ },
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIWebProgressListener",
+ "nsISupportsWeakReference",
+ ]),
+ };
+ progressListeners.set(progressListener, progressListener);
+ webProgress.addProgressListener(
+ progressListener,
+ Ci.nsIWebProgress.NOTIFY_LOCATION
+ );
+ });
+}
+
+add_task(async function test_snapshot() {
+ let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
+ let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_URL);
+ const contentWidth = 400;
+ const contentHeight = 300;
+ // Verify dimensions.
+ contentWindow.resizeTo(contentWidth, contentHeight);
+ equal(contentWindow.innerWidth, contentWidth);
+ equal(contentWindow.innerHeight, contentHeight);
+
+ // Snapshot the test page.
+ let canvas = contentWindow.document.createElementNS(
+ "http://www.w3.org/1999/xhtml",
+ "html:canvas"
+ );
+ let context = canvas.getContext("2d");
+ let width = contentWindow.innerWidth;
+ let height = contentWindow.innerHeight;
+ canvas.width = width;
+ canvas.height = height;
+ context.drawWindow(contentWindow, 0, 0, width, height, "rgb(255, 255, 255)");
+ let imageData = context.getImageData(0, 0, width, height).data;
+ ok(
+ imageData[0] === 0 &&
+ imageData[1] === 255 &&
+ imageData[2] === 0 &&
+ imageData[3] === 255,
+ "Page is green."
+ );
+
+ // Search for a blue pixel (a quick and dirty check to see if the blue text is
+ // on the page)
+ let found = false;
+ for (let i = 0; i < imageData.length; i += 4) {
+ if (imageData[i + 2] === 255) {
+ found = true;
+ break;
+ }
+ }
+ ok(found, "Found blue text on page.");
+
+ windowlessBrowser.close();
+});
+
+add_task(async function test_snapshot_widget_layers() {
+ let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
+ // nsIWindowlessBrowser inherits from nsIWebNavigation.
+ let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_URL);
+ const contentWidth = 1;
+ const contentHeight = 2;
+ // Verify dimensions.
+ contentWindow.resizeTo(contentWidth, contentHeight);
+ equal(contentWindow.innerWidth, contentWidth);
+ equal(contentWindow.innerHeight, contentHeight);
+
+ // Snapshot the test page.
+ let canvas = contentWindow.document.createElementNS(
+ "http://www.w3.org/1999/xhtml",
+ "html:canvas"
+ );
+ let context = canvas.getContext("2d");
+ let width = contentWindow.innerWidth;
+ let height = contentWindow.innerHeight;
+ canvas.width = width;
+ canvas.height = height;
+ context.drawWindow(
+ contentWindow,
+ 0,
+ 0,
+ width,
+ height,
+ "rgb(255, 255, 255)",
+ context.DRAWWINDOW_DRAW_CARET |
+ context.DRAWWINDOW_DRAW_VIEW |
+ context.DRAWWINDOW_USE_WIDGET_LAYERS
+ );
+ ok(true, "Snapshot with widget layers didn't crash.");
+
+ windowlessBrowser.close();
+});
+
+// Ensure keydown events are triggered on the windowless browser.
+add_task(async function test_keydown() {
+ let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
+ // nsIWindowlessBrowser inherits from nsIWebNavigation.
+ let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_URL);
+
+ let keydown = new Promise(resolve => {
+ contentWindow.addEventListener(
+ "keydown",
+ () => {
+ resolve();
+ },
+ { once: true }
+ );
+ });
+
+ let tip = Cc["@mozilla.org/text-input-processor;1"].createInstance(
+ Ci.nsITextInputProcessor
+ );
+ let begun = tip.beginInputTransactionForTests(contentWindow);
+ ok(
+ begun,
+ "nsITextInputProcessor.beginInputTransactionForTests() should succeed"
+ );
+ tip.keydown(
+ new contentWindow.KeyboardEvent("", {
+ key: "a",
+ code: "KeyA",
+ keyCode: contentWindow.KeyboardEvent.DOM_VK_A,
+ })
+ );
+
+ await keydown;
+ ok(true, "Send keydown didn't crash");
+
+ windowlessBrowser.close();
+});
+
+// Test dragging the mouse on a button to ensure the creation of the drag
+// service doesn't crash in headless.
+add_task(async function test_mouse_drag() {
+ let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
+ // nsIWindowlessBrowser inherits from nsIWebNavigation.
+ let contentWindow = await loadContentWindow(
+ windowlessBrowser,
+ HEADLESS_BUTTON_URL
+ );
+ contentWindow.resizeTo(400, 400);
+
+ let target = contentWindow.document.getElementById("btn");
+ let rect = target.getBoundingClientRect();
+ let left = rect.left;
+ let top = rect.top;
+
+ let utils = contentWindow.windowUtils;
+ utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
+ utils.sendMouseEvent("mousemove", left, top, 0, 1, 0, false, 0, 0);
+ // Wait for a turn of the event loop since the synthetic mouse event
+ // that creates the drag service is processed during the refresh driver.
+ await new Promise(r => {
+ executeSoon(r);
+ });
+ utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
+
+ ok(true, "Send mouse event didn't crash");
+
+ windowlessBrowser.close();
+});