head.js (3752B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 /* eslint no-unused-vars: [2, {"vars": "local"}] */ 4 5 "use strict"; 6 7 // Import the inspector's head.js first (which itself imports shared-head.js). 8 Services.scriptloader.loadSubScript( 9 "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", 10 this 11 ); 12 13 /** 14 * Is the given node visible in the page (rendered in the frame tree). 15 * 16 * @param {DOMNode} 17 * @return {boolean} 18 */ 19 function isNodeVisible(node) { 20 return !!node.getClientRects().length; 21 } 22 23 /** 24 * Wait for the boxmodel-view-updated event. 25 * 26 * @param {InspectorPanel} inspector 27 * The instance of InspectorPanel currently loaded in the toolbox. 28 * @param {boolean} waitForSelectionUpdate 29 * Should the boxmodel-view-updated event come from a new selection. 30 * @return {Promise} a promise 31 */ 32 async function waitForUpdate(inspector, waitForSelectionUpdate) { 33 /** 34 * While the highlighter is visible (mouse over the fields of the box model editor), 35 * reflow events are prevented; see ReflowActor -> setIgnoreLayoutChanges() 36 * The box model view updates in response to reflow events. 37 * To ensure reflow events are fired, hide the highlighter. 38 */ 39 await inspector.highlighters.hideHighlighterType( 40 inspector.highlighters.TYPES.BOXMODEL 41 ); 42 43 return new Promise(resolve => { 44 inspector.on("boxmodel-view-updated", function onUpdate(reasons) { 45 // Wait for another update event if we are waiting for a selection related event. 46 if (waitForSelectionUpdate && !reasons.includes("new-selection")) { 47 return; 48 } 49 50 inspector.off("boxmodel-view-updated", onUpdate); 51 resolve(); 52 }); 53 }); 54 } 55 56 /** 57 * Wait for both boxmode-view-updated and markuploaded events. 58 * 59 * @return {Promise} a promise that resolves when both events have been received. 60 */ 61 function waitForMarkupLoaded(inspector) { 62 return Promise.all([ 63 waitForUpdate(inspector), 64 inspector.once("markuploaded"), 65 ]); 66 } 67 68 function getStyle(browser, selector, propertyName) { 69 return SpecialPowers.spawn( 70 browser, 71 [selector, propertyName], 72 async function (_selector, _propertyName) { 73 return content.document 74 .querySelector(_selector) 75 .style.getPropertyValue(_propertyName); 76 } 77 ); 78 } 79 80 function setStyle(browser, selector, propertyName, value) { 81 return SpecialPowers.spawn( 82 browser, 83 [selector, propertyName, value], 84 async function (_selector, _propertyName, _value) { 85 content.document.querySelector(_selector).style[_propertyName] = _value; 86 } 87 ); 88 } 89 90 /** 91 * The box model doesn't participate in the inspector's update mechanism, so simply 92 * calling the default selectNode isn't enough to guarantee that the box model view has 93 * finished updating. We also need to wait for the "boxmodel-view-updated" event. 94 */ 95 var _selectNode = selectNode; 96 selectNode = async function (node, inspector, reason) { 97 const onUpdate = waitForUpdate(inspector, true); 98 await _selectNode(node, inspector, reason); 99 await onUpdate; 100 }; 101 102 /** 103 * Wait until the provided element's text content matches the provided text. 104 * Based on the waitFor helper, see documentation in 105 * devtools/client/shared/test/shared-head.js 106 * 107 * @param {DOMNode} element 108 * The element to check. 109 * @param {string} expectedText 110 * The text that is expected to be set as textContent of the element. 111 */ 112 async function waitForElementTextContent(element, expectedText) { 113 await waitFor( 114 () => element.textContent === expectedText, 115 `Couldn't get "${expectedText}" as the text content of the given element` 116 ); 117 ok(true, `Found the expected text (${expectedText}) for the given element`); 118 }