summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/test/browser_layoutHelpers_getBoxQuads2.js
blob: 051b2c5a7ab4e8caafa110bf622fdcd5eee30f6a (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

// Tests that getBoxQuadsFromWindowOrigin works across process
// boundaries.
//
// The test forces a fission window, because there is some
// imprecision in the APZ transforms for non-fission windows,
// and the getBoxQuadsFromWindowOrigin is designed specifically
// to be used by a fission browser.
//
// This test embeds a number of documents within iframes,
// with a variety of borders and padding. Each iframe hosts
// a document in different domain than its container.
//
// The innermost documents have a 50px x 50px div with a
// 50px margin. So relative to its own iframe, the offset
// for the div should be 50, 50.
//
// Here's the embedding diagram:
// +-- A -----------------------------------------------------+
// |                                                          |
// | +- div -----+                                            |
// | | 100 x 100 |                                            |
// | +-----------+                                            |
// |                                                          |
// | +- div 20px margin ------------------------------------+ |
// | |                                                      | |
// | | +- B: iframe 10px border -+ +- D: iframe 40px pad -+ | |
// | | |     250 x 250           | |     250 x 250        | | |
// | | |     50px margin         | |     50px margin      | | |
// | | |                         | |                      | | |
// | | | +- C: iframe ---+       | | +- E: iframe ---+    | | |
// | | | |     150 x 150 |       | | |     150 x 150 |    | | |
// | | | +---------------+       | | +---------------+    | | |
// | | +-------------------------+ +----------------------+ | |
// | +------------------------------------------------------+ |
// +----------------------------------------------------------+
//
// The following checks are made:
// C-div relative to A should have offset 130, 230.
// E-div relative to A should have offset 430, 260.
//
// This tests the most likely cases for the code that handles
// relativeToTopLevelBrowsingContextId. It does not check these
// cases:
// 1) A css-transform'ed iframe.
// 2) An abspos iframe.
// 3) An iframe embedded in an SVG.

"use strict";
/* import-globals-from ../../../../gfx/layers/apz/test/mochitest/apz_test_utils.js */

const TEST_URI = TEST_URI_ROOT_SSL + "doc_layoutHelpers_getBoxQuads2-a.html";

add_task(async function () {
  info("Opening a fission window.");
  const fissionWin = await BrowserTestUtils.openNewBrowserWindow({
    remote: true,
    fission: true,
  });

  info("Load APZ test utils.");
  loadHelperScript(
    "../../../../gfx/layers/apz/test/mochitest/apz_test_utils.js"
  );
  info("Load paint_listener.");
  loadHelperScript("../../../../../tests/SimpleTest/paint_listener.js");

  info("Open a new tab.");
  const tab = await BrowserTestUtils.openNewForegroundTab(
    fissionWin.gBrowser,
    TEST_URI
  );

  info("Running tests");

  ok(waitUntilApzStable, "waitUntilApzStable is defined.");
  await waitUntilApzStable();

  await ContentTask.spawn(tab.linkedBrowser, null, async function () {
    const win = content.window;
    const doc = content.document;
    const refNode = doc.documentElement;
    const iframeB = doc.getElementById("b");
    const iframeD = doc.getElementById("d");

    // Get the offset of the reference node to the window origin. We'll use
    // this offset later to adjust the quads we get from the iframes.
    const refQuad = refNode.getBoxQuadsFromWindowOrigin()[0];
    const offsetX = refQuad.p1.x;
    const offsetY = refQuad.p1.y;
    info(`Reference node is offset (${offsetX}, ${offsetY}) from window.`);

    function postAndReceiveMessage(iframe) {
      return new Promise(resolve => {
        const onmessage = event => {
          if (event.data.quad) {
            win.removeEventListener("message", onmessage);
            resolve(event.data.quad);
          }
        };
        win.addEventListener("message", onmessage, { capture: false });
        iframe.contentWindow.postMessage({ callGetBoxQuads: true }, "*");
      });
    }

    // Bug 1624659: Our checks are not always precise, though for these test
    // cases they should align precisely to css pixels. For now we use an
    // epsilon and a locally-defined isfuzzy to compensate. We can't use
    // SimpleTest.isfuzzy, because it's not bridged to the ContentTask.
    // If that is ever bridged, we can remove the isfuzzy definition here and
    // everything should "just work".
    function isfuzzy(actual, expected, epsilon, msg) {
      if (actual >= expected - epsilon && actual <= expected + epsilon) {
        ok(true, msg);
      } else {
        // This will trigger the usual failure message for is.
        is(actual, expected, msg);
      }
    }

    const ADDITIVE_EPSILON = 1;
    const checksToMake = [
      {
        msg: "C-div",
        iframe: iframeB,
        left: 130,
        top: 230,
        right: 180,
        bottom: 280,
      },
      {
        msg: "E-div",
        iframe: iframeD,
        left: 430,
        top: 260,
        right: 480,
        bottom: 310,
      },
    ];

    for (const { msg, iframe, left, top, right, bottom } of checksToMake) {
      info("Checking " + msg + ".");
      const quad = await postAndReceiveMessage(iframe);
      const bounds = quad.getBounds();
      info(
        `Quad bounds is (${bounds.left}, ${bounds.top}) to (${bounds.right}, ${bounds.bottom}).`
      );
      isfuzzy(
        bounds.left - offsetX,
        left,
        ADDITIVE_EPSILON,
        msg + " quad left position is as expected."
      );
      isfuzzy(
        bounds.top - offsetY,
        top,
        ADDITIVE_EPSILON,
        msg + " quad top position is as expected."
      );
      isfuzzy(
        bounds.right - offsetX,
        right,
        ADDITIVE_EPSILON,
        msg + " quad right position is as expected."
      );
      isfuzzy(
        bounds.bottom - offsetY,
        bottom,
        ADDITIVE_EPSILON,
        msg + " quad bottom position is as expected."
      );
    }
  });

  fissionWin.gBrowser.removeCurrentTab();

  await BrowserTestUtils.closeWindow(fissionWin);

  // Clean up the properties added to window by paint_listener.js.
  delete window.waitForAllPaintsFlushed;
  delete window.waitForAllPaints;
  delete window.promiseAllPaintsDone;
});