summaryrefslogtreecommitdiffstats
path: root/devtools/server/tests/browser/browser_canvasframe_helper_04.js
blob: 85368ff2b5a22b941210cb234b09fa684e979e65 (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
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Test the CanvasFrameAnonymousContentHelper re-inserts the content when the
// page reloads.

const TEST_URL_1 =
  "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test 1";
const TEST_URL_2 =
  "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test 2";

add_task(async function () {
  const tab = await addTab(TEST_URL_1);
  await SpecialPowers.spawn(
    tab.linkedBrowser,
    [TEST_URL_2],
    async function (url2) {
      const { require } = ChromeUtils.importESModule(
        "resource://devtools/shared/loader/Loader.sys.mjs"
      );
      const {
        HighlighterEnvironment,
      } = require("resource://devtools/server/actors/highlighters.js");
      const {
        CanvasFrameAnonymousContentHelper,
      } = require("resource://devtools/server/actors/highlighters/utils/markup.js");
      let doc = content.document;

      const nodeBuilder = () => {
        const root = doc.createElement("div");
        const child = doc.createElement("div");
        child.style =
          "pointer-events:auto;width:200px;height:200px;background:red;";
        child.id = "child-element";
        child.className = "child-element";
        child.textContent = "test content";
        root.appendChild(child);
        return root;
      };

      info("Building the helper");
      const env = new HighlighterEnvironment();
      env.initFromWindow(doc.defaultView);
      const helper = new CanvasFrameAnonymousContentHelper(env, nodeBuilder);
      await helper.initialize();

      info("Get an element from the helper");
      const el = helper.getElement("child-element");

      info("Try to access the element");
      is(
        el.getAttribute("class"),
        "child-element",
        "The attribute is correct before navigation"
      );
      is(
        el.getTextContent(),
        "test content",
        "The text content is correct before navigation"
      );

      info("Add an event listener on the element");
      let mouseDownHandled = 0;
      const onMouseDown = (e, id) => {
        is(
          id,
          "child-element",
          "The mousedown event was triggered on the element"
        );
        mouseDownHandled++;
      };
      el.addEventListener("mousedown", onMouseDown);

      const once = function once(target, event) {
        return new Promise(done => {
          target.addEventListener(event, done, { once: true });
        });
      };

      const synthesizeMouseDown = function synthesizeMouseDown(x, y, win) {
        // We need to make sure the inserted anonymous content can be targeted by the
        // event right after having been inserted, and so we need to force a sync
        // reflow.
        win.document.documentElement.offsetWidth;
        EventUtils.synthesizeMouseAtPoint(x, y, { type: "mousedown" }, win);
      };

      info("Synthesizing an event on the element");
      let onDocMouseDown = once(doc, "mousedown");
      synthesizeMouseDown(100, 100, doc.defaultView);
      await onDocMouseDown;
      is(
        mouseDownHandled,
        1,
        "The mousedown event was handled once before navigation"
      );

      info("Navigating to a new page");
      const loaded = once(this, "load");
      content.location = url2;
      await loaded;

      // Wait for the next event tick to make sure the remaining part of the
      // test is not executed in the microtask checkpoint for load event
      // itself.  Otherwise the synthesizeMouseDown doesn't work.
      await new Promise(r => content.setTimeout(r, 0));

      // Update to the new document we just loaded
      doc = content.document;

      info("Try to access the element again");
      is(
        el.getAttribute("class"),
        "child-element",
        "The attribute is correct after navigation"
      );
      is(
        el.getTextContent(),
        "test content",
        "The text content is correct after navigation"
      );

      info("Synthesizing an event on the element again");
      onDocMouseDown = once(doc, "mousedown");
      synthesizeMouseDown(100, 100, doc.defaultView);
      await onDocMouseDown;
      is(
        mouseDownHandled,
        1,
        "The mousedown event was not handled after navigation"
      );

      info("Destroying the helper");
      env.destroy();
      helper.destroy();
    }
  );

  gBrowser.removeCurrentTab();
});