summaryrefslogtreecommitdiffstats
path: root/devtools/client/framework/test/browser_toolbox_frames_list.js
blob: f1d7ff0510d6625609b9d89439038059f0b5309f (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
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Check that the frames list gets updated as iframes are added/removed from the document,
// and during navigation.

const TEST_COM_URL =
  "https://example.com/document-builder.sjs?html=<div id=com>com";
const TEST_ORG_URL =
  `https://example.org/document-builder.sjs?html=<div id=org>org</div>` +
  `<iframe src="https://example.org/document-builder.sjs?html=example.org iframe"></iframe>` +
  `<iframe src="https://example.com/document-builder.sjs?html=example.com iframe"></iframe>`;

add_task(async function () {
  // Enable the frames button.
  await pushPref("devtools.command-button-frames.enabled", true);

  const tab = await addTab(TEST_COM_URL);

  const toolbox = await gDevTools.showToolboxForTab(tab, {
    toolId: "webconsole",
  });

  ok(
    !getFramesButton(toolbox),
    "Frames button is not rendered when there's no iframes in the page"
  );
  await checkFramesList(toolbox, []);

  info("Create a same origin (example.com) iframe");
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
    const comIframe = content.document.createElement("iframe");
    comIframe.src =
      "https://example.com/document-builder.sjs?html=example.com iframe";
    content.document.body.appendChild(comIframe);
  });

  await waitFor(() => getFramesButton(toolbox));
  ok(true, "Button is displayed when adding an iframe");

  info("Check the content of the frames list");
  await checkFramesList(toolbox, [
    TEST_COM_URL,
    "https://example.com/document-builder.sjs?html=example.com iframe",
  ]);

  info("Create a cross-process origin (example.org) iframe");
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
    const orgIframe = content.document.createElement("iframe");
    orgIframe.src =
      "https://example.org/document-builder.sjs?html=example.org iframe";
    content.document.body.appendChild(orgIframe);
  });

  info("Check that the content of the frames list was updated");
  try {
    await checkFramesList(toolbox, [
      TEST_COM_URL,
      "https://example.com/document-builder.sjs?html=example.com iframe",
      "https://example.org/document-builder.sjs?html=example.org iframe",
    ]);

    // If Fission is enabled and EFT is not, we shouldn't hit this line as `checkFramesList`
    // should throw (as remote frames are only displayed when EFT is enabled).
    ok(
      !isFissionEnabled() || isEveryFrameTargetEnabled(),
      "iframe picker should only display remote frames when EFT is enabled"
    );
  } catch (e) {
    ok(
      isFissionEnabled() && !isEveryFrameTargetEnabled(),
      "iframe picker displays remote frames only when EFT is enabled"
    );
    return;
  }

  info("Reload and check that the frames list is cleared");
  await reloadBrowser();
  await waitFor(() => !getFramesButton(toolbox));
  ok(
    true,
    "The button was hidden when reloading as the page does not have iframes"
  );
  await checkFramesList(toolbox, []);

  info("Navigate to a different origin, on a page with iframes");
  await navigateTo(TEST_ORG_URL);
  await checkFramesList(toolbox, [
    TEST_ORG_URL,
    "https://example.org/document-builder.sjs?html=example.org iframe",
    "https://example.com/document-builder.sjs?html=example.com iframe",
  ]);

  info("Check that frames list is updated when removing same-origin iframe");
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
    content.document.querySelector("iframe").remove();
  });
  await checkFramesList(toolbox, [
    TEST_ORG_URL,
    "https://example.com/document-builder.sjs?html=example.com iframe",
  ]);

  info("Check that frames list is updated when removing cross-origin iframe");
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
    content.document.querySelector("iframe").remove();
  });
  await waitFor(() => !getFramesButton(toolbox));
  ok(true, "The button was hidden when removing the last iframe on the page");
  await checkFramesList(toolbox, []);

  info("Check that the list does have expected items after reloading");
  await reloadBrowser();
  await waitFor(() => getFramesButton(toolbox));
  ok(true, "button is displayed after reloading");
  await checkFramesList(toolbox, [
    TEST_ORG_URL,
    "https://example.org/document-builder.sjs?html=example.org iframe",
    "https://example.com/document-builder.sjs?html=example.com iframe",
  ]);
});

function getFramesButton(toolbox) {
  return toolbox.doc.getElementById("command-button-frames");
}

async function checkFramesList(toolbox, expectedFrames) {
  const frames = await waitFor(() => {
    // items might be added in the list before their url is known, so exclude empty items.
    const f = getFramesLabels(toolbox).filter(t => t !== "");
    if (f.length !== expectedFrames.length) {
      return false;
    }

    return f;
  });

  is(
    JSON.stringify(frames.sort()),
    JSON.stringify(expectedFrames.sort()),
    "The expected frames are displayed"
  );
}

function getFramesLabels(toolbox) {
  return Array.from(
    toolbox.doc.querySelectorAll("#toolbox-frame-menu .command .label")
  ).map(el => el.textContent);
}