summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/markup/test/browser_markup_events_toggle.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /devtools/client/inspector/markup/test/browser_markup_events_toggle.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/inspector/markup/test/browser_markup_events_toggle.js')
-rw-r--r--devtools/client/inspector/markup/test/browser_markup_events_toggle.js295
1 files changed, 295 insertions, 0 deletions
diff --git a/devtools/client/inspector/markup/test/browser_markup_events_toggle.js b/devtools/client/inspector/markup/test/browser_markup_events_toggle.js
new file mode 100644
index 0000000000..5e1e437298
--- /dev/null
+++ b/devtools/client/inspector/markup/test/browser_markup_events_toggle.js
@@ -0,0 +1,295 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+/* import-globals-from helper_events_test_runner.js */
+
+"use strict";
+
+// Test that event listeners can be disabled and re-enabled from the markup view event bubble.
+
+const TEST_URL = URL_ROOT_SSL + "doc_markup_events_toggle.html";
+
+loadHelperScript("helper_events_test_runner.js");
+
+add_task(async function () {
+ const { inspector, toolbox } = await openInspectorForURL(TEST_URL);
+ const { resourceCommand } = toolbox.commands;
+ await inspector.markup.expandAll();
+ await selectNode("#target", inspector);
+
+ info(
+ "Click on the target element to make sure the event listeners are properly set"
+ );
+ // There's a "mouseup" event listener that is `console.info` (so we can check "native" events).
+ // In order to know if it was called, we listen for the next console.info resource.
+ let { onResource: onConsoleInfoMessage } =
+ await resourceCommand.waitForNextResource(
+ resourceCommand.TYPES.CONSOLE_MESSAGE,
+ {
+ ignoreExistingResources: true,
+ predicate(resource) {
+ return resource.message.level == "info";
+ },
+ }
+ );
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+
+ let data = await getTargetElementHandledEventData();
+ is(data.click, 1, `target handled one "click" event`);
+ is(data.mousedown, 1, `target handled one "mousedown" event`);
+ await onConsoleInfoMessage;
+ ok(true, `the "mouseup" event listener (console.info) was called`);
+
+ info("Check that the event tooltip has the expected content");
+ const container = await getContainerForSelector("#target", inspector);
+ const eventTooltipBadge = container.elt.querySelector(
+ ".inspector-badge.interactive[data-event]"
+ );
+ ok(eventTooltipBadge, "The event tooltip badge is displayed");
+
+ const tooltip = inspector.markup.eventDetailsTooltip;
+ let onTooltipShown = tooltip.once("shown");
+ eventTooltipBadge.click();
+ await onTooltipShown;
+ ok(true, "The tooltip is shown");
+
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click [x]", "mousedown [x]", "mouseup [x]"],
+ "The expected events are displayed, all enabled"
+ );
+ ok(
+ !eventTooltipBadge.classList.contains("has-disabled-events"),
+ "The event badge does not have the has-disabled-events class"
+ );
+
+ const [clickHeader, mousedownHeader, mouseupHeader] =
+ getHeadersInEventTooltip(tooltip);
+
+ info("Uncheck the mousedown event checkbox");
+ await toggleEventListenerCheckbox(tooltip, mousedownHeader);
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click [x]", "mousedown []", "mouseup [x]"],
+ "mousedown checkbox was unchecked"
+ );
+ ok(
+ eventTooltipBadge.classList.contains("has-disabled-events"),
+ "Unchecking an event applied the has-disabled-events class to the badge"
+ );
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+ data = await getTargetElementHandledEventData();
+ is(data.click, 2, `target handled another "click" event…`);
+ is(data.mousedown, 1, `… but not a mousedown one`);
+
+ info(
+ "Check that the event badge style is reset when re-enabling all disabled events"
+ );
+ await toggleEventListenerCheckbox(tooltip, mousedownHeader);
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click [x]", "mousedown [x]", "mouseup [x]"],
+ "mousedown checkbox is checked again"
+ );
+ ok(
+ !eventTooltipBadge.classList.contains("has-disabled-events"),
+ "The event badge does not have the has-disabled-events class after re-enabling disabled event"
+ );
+ info("Disable mousedown again for the rest of the test");
+ await toggleEventListenerCheckbox(tooltip, mousedownHeader);
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click [x]", "mousedown []", "mouseup [x]"],
+ "mousedown checkbox is unchecked again"
+ );
+
+ info("Uncheck the click event checkbox");
+ await toggleEventListenerCheckbox(tooltip, clickHeader);
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click []", "mousedown []", "mouseup [x]"],
+ "click checkbox was unchecked"
+ );
+ ok(
+ eventTooltipBadge.classList.contains("has-disabled-events"),
+ "event badge still has the has-disabled-events class"
+ );
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+ data = await getTargetElementHandledEventData();
+ is(data.click, 2, `click event listener was disabled`);
+ is(data.mousedown, 1, `and mousedown still is disabled as well`);
+
+ info("Uncheck the mouseup event checkbox");
+ await toggleEventListenerCheckbox(tooltip, mouseupHeader);
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click []", "mousedown []", "mouseup []"],
+ "mouseup checkbox was unchecked"
+ );
+
+ ({ onResource: onConsoleInfoMessage } =
+ await resourceCommand.waitForNextResource(
+ resourceCommand.TYPES.CONSOLE_MESSAGE,
+ {
+ ignoreExistingResources: true,
+ predicate(resource) {
+ return resource.message.level == "info";
+ },
+ }
+ ));
+ const onTimeout = wait(500).then(() => "TIMEOUT");
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+ const raceResult = await Promise.race([onConsoleInfoMessage, onTimeout]);
+ is(
+ raceResult,
+ "TIMEOUT",
+ "The mouseup event didn't trigger a console.info call, meaning the event listener was disabled"
+ );
+
+ info("Re-enable the mousedown event");
+ await toggleEventListenerCheckbox(tooltip, mousedownHeader);
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click []", "mousedown [x]", "mouseup []"],
+ "mousedown checkbox is checked again"
+ );
+ ok(
+ eventTooltipBadge.classList.contains("has-disabled-events"),
+ "event badge still has the has-disabled-events class"
+ );
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+ data = await getTargetElementHandledEventData();
+ is(data.click, 2, `no additional "click" event were handled`);
+ is(
+ data.mousedown,
+ 2,
+ `but we did get a new "mousedown", the event listener was re-enabled`
+ );
+
+ info("Hide the tooltip and show it again");
+ const tooltipHidden = tooltip.once("hidden");
+ tooltip.hide();
+ await tooltipHidden;
+
+ onTooltipShown = tooltip.once("shown");
+ eventTooltipBadge.click();
+ await onTooltipShown;
+ ok(true, "The tooltip is shown again");
+
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click []", "mousedown [x]", "mouseup []"],
+ "Only mousedown checkbox is checked"
+ );
+
+ info("Re-enable mouseup events");
+ await toggleEventListenerCheckbox(
+ tooltip,
+ getHeadersInEventTooltip(tooltip).at(-1)
+ );
+ Assert.deepEqual(
+ getAsciiHeadersViz(tooltip),
+ ["click []", "mousedown [x]", "mouseup [x]"],
+ "mouseup is checked again"
+ );
+
+ ({ onResource: onConsoleInfoMessage } =
+ await resourceCommand.waitForNextResource(
+ resourceCommand.TYPES.CONSOLE_MESSAGE,
+ {
+ ignoreExistingResources: true,
+ predicate(resource) {
+ return resource.message.level == "info";
+ },
+ }
+ ));
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+ await onConsoleInfoMessage;
+ ok(true, "The mouseup event was re-enabled");
+ data = await getTargetElementHandledEventData();
+ is(data.click, 2, `"click" is still disabled`);
+ is(
+ data.mousedown,
+ 3,
+ `we received a new "mousedown" event as part of the click`
+ );
+
+ info("Close DevTools to check that event listeners are re-enabled");
+ await closeToolbox();
+ await safeSynthesizeMouseEventAtCenterInContentPage("#target");
+ data = await getTargetElementHandledEventData();
+ is(
+ data.click,
+ 3,
+ `a new "click" event was handled after the devtools was closed`
+ );
+ is(
+ data.mousedown,
+ 4,
+ `a new "mousedown" event was handled after the devtools was closed`
+ );
+});
+
+function getHeadersInEventTooltip(tooltip) {
+ return Array.from(tooltip.panel.querySelectorAll(".event-header"));
+}
+
+/**
+ * Get an array of string representing a header in its state, e.g.
+ * [
+ * "click [x]",
+ * "mousedown []",
+ * ]
+ *
+ * represents an event tooltip with a click and a mousedown event, where the mousedown
+ * event has been disabled.
+ *
+ * @param {EventTooltip} tooltip
+ * @returns Array<String>
+ */
+function getAsciiHeadersViz(tooltip) {
+ return getHeadersInEventTooltip(tooltip).map(
+ el =>
+ `${el.querySelector(".event-tooltip-event-type").textContent} [${
+ getHeaderCheckbox(el).checked ? "x" : ""
+ }]`
+ );
+}
+
+function getHeaderCheckbox(headerEl) {
+ return headerEl.querySelector("input[type=checkbox]");
+}
+
+async function toggleEventListenerCheckbox(tooltip, headerEl) {
+ const onEventToggled = tooltip.eventTooltip.once(
+ "event-tooltip-listener-toggled"
+ );
+ const checkbox = getHeaderCheckbox(headerEl);
+ const previousValue = checkbox.checked;
+ EventUtils.synthesizeMouseAtCenter(
+ getHeaderCheckbox(headerEl),
+ {},
+ headerEl.ownerGlobal
+ );
+ await onEventToggled;
+ is(checkbox.checked, !previousValue, "The checkbox was toggled");
+ is(
+ headerEl.classList.contains("content-expanded"),
+ false,
+ "Clicking on the checkbox did not expand the header"
+ );
+}
+
+/**
+ * @returns Promise<Object> The object keys are event names (e.g. "click", "mousedown"), and
+ * the values are number representing the number of time the event was handled.
+ * Note that "mouseup" isn't handled here.
+ */
+function getTargetElementHandledEventData() {
+ return SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
+ // In doc_markup_events_toggle.html , we count the events handled by the target in
+ // a stringified object in dataset.handledEvents.
+ return JSON.parse(
+ content.document.getElementById("target").dataset.handledEvents
+ );
+ });
+}