From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- devtools/client/inspector/computed/test/head.js | 267 ++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 devtools/client/inspector/computed/test/head.js (limited to 'devtools/client/inspector/computed/test/head.js') diff --git a/devtools/client/inspector/computed/test/head.js b/devtools/client/inspector/computed/test/head.js new file mode 100644 index 0000000000..6d9a0f5b01 --- /dev/null +++ b/devtools/client/inspector/computed/test/head.js @@ -0,0 +1,267 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint no-unused-vars: [2, {"vars": "local"}] */ + +"use strict"; + +// Import the inspector's head.js first (which itself imports shared-head.js). +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", + this +); + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.defaultColorUnit"); +}); + +/** + * Dispatch the copy event on the given element + */ +function fireCopyEvent(element) { + const evt = element.ownerDocument.createEvent("Event"); + evt.initEvent("copy", true, true); + element.dispatchEvent(evt); +} + +/** + * Get references to the name and value span nodes corresponding to a given + * property name in the computed-view + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {String} name + * The name of the property to retrieve + * @return an object {nameSpan, valueSpan} + */ +function getComputedViewProperty(view, name) { + let prop; + for (const property of view.styleDocument.querySelectorAll( + "#computed-container .computed-property-view" + )) { + const nameSpan = property.querySelector(".computed-property-name"); + const valueSpan = property.querySelector(".computed-property-value"); + + if (nameSpan.firstChild.textContent === name) { + prop = { nameSpan, valueSpan }; + break; + } + } + return prop; +} + +/** + * Get an instance of PropertyView from the computed-view. + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {String} name + * The name of the property to retrieve + * @return {PropertyView} + */ +function getComputedViewPropertyView(view, name) { + let propView; + for (const propertyView of view.propertyViews) { + if (propertyView._propertyInfo.name === name) { + propView = propertyView; + break; + } + } + return propView; +} + +/** + * Get a reference to the computed-property-content element for a given property name in + * the computed-view. + * A computed-property-content element always follows (nextSibling) the property itself + * and is only shown when the twisty icon is expanded on the property. + * A computed-property-content element contains matched rules, with selectors, + * properties, values and stylesheet links + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {String} name + * The name of the property to retrieve + * @return {Promise} A promise that resolves to the property matched rules + * container + */ +var getComputedViewMatchedRules = async function (view, name) { + let expander; + let propertyContent; + for (const property of view.styleDocument.querySelectorAll( + "#computed-container .computed-property-view" + )) { + const nameSpan = property.querySelector(".computed-property-name"); + if (nameSpan.firstChild.textContent === name) { + expander = property.querySelector(".computed-expandable"); + propertyContent = property.nextSibling; + break; + } + } + + if (!expander.hasAttribute("open")) { + // Need to expand the property + const onExpand = view.inspector.once("computed-view-property-expanded"); + expander.click(); + await onExpand; + + await waitFor(() => expander.hasAttribute("open")); + } + + return propertyContent; +}; + +/** + * Get the text value of the property corresponding to a given name in the + * computed-view + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {String} name + * The name of the property to retrieve + * @return {String} The property value + */ +function getComputedViewPropertyValue(view, name, propertyName) { + return getComputedViewProperty(view, name, propertyName).valueSpan + .textContent; +} + +/** + * Expand a given property, given its index in the current property list of + * the computed view + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {Number} index + * The index of the property to be expanded + * @return a promise that resolves when the property has been expanded, or + * rejects if the property was not found + */ +function expandComputedViewPropertyByIndex(view, index) { + info("Expanding property " + index + " in the computed view"); + const expandos = view.styleDocument.querySelectorAll(".computed-expandable"); + if (!expandos.length || !expandos[index]) { + return Promise.reject(); + } + + const onExpand = view.inspector.once("computed-view-property-expanded"); + expandos[index].click(); + return onExpand; +} + +/** + * Get a rule-link from the computed-view given its index + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {Number} index + * The index of the link to be retrieved + * @return {DOMNode} The link at the given index, if one exists, null otherwise + */ +function getComputedViewLinkByIndex(view, index) { + const links = view.styleDocument.querySelectorAll( + ".rule-link .computed-link" + ); + return links[index]; +} + +/** + * Trigger the select all action in the computed view. + * + * @param {CssComputedView} view + * The instance of the computed view panel + */ +function selectAllText(view) { + info("Selecting all the text"); + view.contextMenu._onSelectAll(); +} + +/** + * Select all the text, copy it, and check the content in the clipboard. + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {String} expectedPattern + * A regular expression used to check the content of the clipboard + */ +async function copyAllAndCheckClipboard(view, expectedPattern) { + selectAllText(view); + const contentDoc = view.styleDocument; + const prop = contentDoc.querySelector( + "#computed-container .computed-property-view" + ); + + try { + info("Trigger a copy event and wait for the clipboard content"); + await waitForClipboardPromise( + () => fireCopyEvent(prop), + () => checkClipboard(expectedPattern) + ); + } catch (e) { + failClipboardCheck(expectedPattern); + } +} + +/** + * Select some text, copy it, and check the content in the clipboard. + * + * @param {CssComputedView} view + * The instance of the computed view panel + * @param {Object} positions + * The start and end positions of the text to be selected. This must be an object + * like this: + * { start: {prop: 1, offset: 0}, end: {prop: 3, offset: 5} } + * @param {String} expectedPattern + * A regular expression used to check the content of the clipboard + */ +async function copySomeTextAndCheckClipboard(view, positions, expectedPattern) { + info("Testing selection copy"); + + const contentDocument = view.styleDocument; + const props = contentDocument.querySelectorAll( + "#computed-container .computed-property-view" + ); + + info("Create the text selection range"); + const range = contentDocument.createRange(); + range.setStart(props[positions.start.prop], positions.start.offset); + range.setEnd(props[positions.end.prop], positions.end.offset); + contentDocument.defaultView.getSelection().addRange(range); + + try { + info("Trigger a copy event and wait for the clipboard content"); + await waitForClipboardPromise( + () => fireCopyEvent(props[0]), + () => checkClipboard(expectedPattern) + ); + } catch (e) { + failClipboardCheck(expectedPattern); + } +} + +function checkClipboard(expectedPattern) { + const actual = SpecialPowers.getClipboardData("text/plain"); + const expectedRegExp = new RegExp(expectedPattern, "g"); + return expectedRegExp.test(actual); +} + +function failClipboardCheck(expectedPattern) { + // Format expected text for comparison + const terminator = Services.appinfo.OS == "WINNT" ? "\r\n" : "\n"; + expectedPattern = expectedPattern.replace(/\[\\r\\n\][+*]/g, terminator); + expectedPattern = expectedPattern.replace(/\\\(/g, "("); + expectedPattern = expectedPattern.replace(/\\\)/g, ")"); + + let actual = SpecialPowers.getClipboardData("text/plain"); + + // Trim the right hand side of our strings. This is because expectedPattern + // accounts for windows sometimes adding a newline to our copied data. + expectedPattern = expectedPattern.trimRight(); + actual = actual.trimRight(); + + dump( + "TEST-UNEXPECTED-FAIL | Clipboard text does not match expected ... " + + "results (escaped for accurate comparison):\n" + ); + info("Actual: " + escape(actual)); + info("Expected: " + escape(expectedPattern)); +} -- cgit v1.2.3