summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/boxmodel/test/head.js
blob: f15424acfb445b1337bb9cb6d7cc1d580a491a78 (plain)
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
/* 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
);

Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
registerCleanupFunction(() => {
  Services.prefs.clearUserPref("devtools.toolbox.footer.height");
});

/**
 * Is the given node visible in the page (rendered in the frame tree).
 * @param {DOMNode}
 * @return {Boolean}
 */
function isNodeVisible(node) {
  return !!node.getClientRects().length;
}

/**
 * Wait for the boxmodel-view-updated event.
 *
 * @param  {InspectorPanel} inspector
 *         The instance of InspectorPanel currently loaded in the toolbox.
 * @param  {Boolean} waitForSelectionUpdate
 *         Should the boxmodel-view-updated event come from a new selection.
 * @return {Promise} a promise
 */
async function waitForUpdate(inspector, waitForSelectionUpdate) {
  /**
   * While the highlighter is visible (mouse over the fields of the box model editor),
   * reflow events are prevented; see ReflowActor -> setIgnoreLayoutChanges()
   * The box model view updates in response to reflow events.
   * To ensure reflow events are fired, hide the highlighter.
   */
  await inspector.highlighters.hideHighlighterType(
    inspector.highlighters.TYPES.BOXMODEL
  );

  return new Promise(resolve => {
    inspector.on("boxmodel-view-updated", function onUpdate(reasons) {
      // Wait for another update event if we are waiting for a selection related event.
      if (waitForSelectionUpdate && !reasons.includes("new-selection")) {
        return;
      }

      inspector.off("boxmodel-view-updated", onUpdate);
      resolve();
    });
  });
}

/**
 * Wait for both boxmode-view-updated and markuploaded events.
 *
 * @return {Promise} a promise that resolves when both events have been received.
 */
function waitForMarkupLoaded(inspector) {
  return Promise.all([
    waitForUpdate(inspector),
    inspector.once("markuploaded"),
  ]);
}

function getStyle(browser, selector, propertyName) {
  return SpecialPowers.spawn(
    browser,
    [selector, propertyName],
    async function (_selector, _propertyName) {
      return content.document
        .querySelector(_selector)
        .style.getPropertyValue(_propertyName);
    }
  );
}

function setStyle(browser, selector, propertyName, value) {
  return SpecialPowers.spawn(
    browser,
    [selector, propertyName, value],
    async function (_selector, _propertyName, _value) {
      content.document.querySelector(_selector).style[_propertyName] = _value;
    }
  );
}

/**
 * The box model doesn't participate in the inspector's update mechanism, so simply
 * calling the default selectNode isn't enough to guarantee that the box model view has
 * finished updating. We also need to wait for the "boxmodel-view-updated" event.
 */
var _selectNode = selectNode;
selectNode = async function (node, inspector, reason) {
  const onUpdate = waitForUpdate(inspector, true);
  await _selectNode(node, inspector, reason);
  await onUpdate;
};

/**
 * Wait until the provided element's text content matches the provided text.
 * Based on the waitFor helper, see documentation in
 * devtools/client/shared/test/shared-head.js
 *
 * @param {DOMNode} element
 *        The element to check.
 * @param {String} expectedText
 *        The text that is expected to be set as textContent of the element.
 */
async function waitForElementTextContent(element, expectedText) {
  await waitFor(
    () => element.textContent === expectedText,
    `Couldn't get "${expectedText}" as the text content of the given element`
  );
  ok(true, `Found the expected text (${expectedText}) for the given element`);
}