summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/outOfProcess/browser_controller.js
blob: f3c0217b901205b080ae09ca1853175d198d0b6b (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
function checkCommandState(testid, undoEnabled, copyEnabled, deleteEnabled) {
  is(
    !document.getElementById("cmd_undo").hasAttribute("disabled"),
    undoEnabled,
    testid + " undo"
  );
  is(
    !document.getElementById("cmd_copy").hasAttribute("disabled"),
    copyEnabled,
    testid + " copy"
  );
  is(
    !document.getElementById("cmd_delete").hasAttribute("disabled"),
    deleteEnabled,
    testid + " delete"
  );
}

function keyAndUpdate(key, eventDetails, updateEventsCount) {
  let updatePromise = BrowserTestUtils.waitForEvent(
    window,
    "commandupdate",
    false,
    () => {
      return --updateEventsCount == 0;
    }
  );
  EventUtils.synthesizeKey(key, eventDetails);
  return updatePromise;
}

add_task(async function test_controllers_subframes() {
  let tab = await BrowserTestUtils.openNewForegroundTab(
    gBrowser,
    OOP_BASE_PAGE_URI
  );
  let browser = tab.linkedBrowser;
  let browsingContexts = await initChildFrames(
    browser,
    "<input id='input'><br><br>"
  );

  gURLBar.focus();

  let canTabMoveFocusToRootElement = !SpecialPowers.getBoolPref(
    "dom.disable_tab_focus_to_root_element"
  );
  for (let stepNum = 0; stepNum < browsingContexts.length; stepNum++) {
    let useTab = stepNum > 0;
    // When canTabMoveFocusToRootElement is true, this kepress will move the
    // focus to a root element, which will trigger an extra "select" command
    // compare to the case when canTabMoveFocusToRootElement is false.
    await keyAndUpdate(
      useTab ? "VK_TAB" : "VK_F6",
      {},
      canTabMoveFocusToRootElement ? 6 : 4
    );

    // Since focus may be switching into a separate process here,
    // need to wait for the focus to have been updated.
    await SpecialPowers.spawn(browsingContexts[stepNum], [], () => {
      return ContentTaskUtils.waitForCondition(
        () => content.browsingContext.isActive && content.document.hasFocus()
      );
    });

    // Force the UI to update on platforms that don't
    // normally do so until menus are opened.
    if (AppConstants.platform != "macosx") {
      goUpdateGlobalEditMenuItems(true);
    }

    await SpecialPowers.spawn(
      browsingContexts[stepNum],
      [{ canTabMoveFocusToRootElement, useTab }],
      args => {
        // Both the tab key and document navigation with F6 will focus
        // the root of the document within the frame.
        // When dom.disable_tab_focus_to_root_element is true, only F6 will do this.
        let document = content.document;
        let expectedElement =
          args.canTabMoveFocusToRootElement || !args.useTab
            ? document.documentElement
            : document.getElementById("input");
        Assert.equal(document.activeElement, expectedElement, "root focused");
      }
    );

    if (canTabMoveFocusToRootElement || !useTab) {
      // XXX Currently, Copy is always enabled when the root (not an editor element)
      // is focused. Possibly that should only be true if a listener is present?
      checkCommandState(
        "step " + stepNum + " root focused",
        false,
        true,
        false
      );

      // Tab to the textbox.
      await keyAndUpdate("VK_TAB", {}, 1);
    }

    if (AppConstants.platform != "macosx") {
      goUpdateGlobalEditMenuItems(true);
    }

    await SpecialPowers.spawn(browsingContexts[stepNum], [], () => {
      Assert.equal(
        content.document.activeElement,
        content.document.getElementById("input"),
        "input focused"
      );
    });
    checkCommandState(
      "step " + stepNum + " input focused",
      false,
      false,
      false
    );

    // Type into the textbox.
    await keyAndUpdate("a", {}, 1);
    checkCommandState("step " + stepNum + " typed", true, false, false);

    await SpecialPowers.spawn(browsingContexts[stepNum], [], () => {
      Assert.equal(
        content.document.activeElement,
        content.document.getElementById("input"),
        "input focused"
      );
    });

    // Select all text; this causes the Copy and Delete commands to be enabled.
    await keyAndUpdate("a", { accelKey: true }, 1);
    if (AppConstants.platform != "macosx") {
      goUpdateGlobalEditMenuItems(true);
    }

    checkCommandState("step " + stepNum + " selected", true, true, true);

    // Now make sure that the text is selected.
    await SpecialPowers.spawn(browsingContexts[stepNum], [], () => {
      let input = content.document.getElementById("input");
      Assert.equal(input.value, "a", "text matches");
      Assert.equal(input.selectionStart, 0, "selectionStart matches");
      Assert.equal(input.selectionEnd, 1, "selectionEnd matches");
    });
  }

  BrowserTestUtils.removeTab(tab);
});