summaryrefslogtreecommitdiffstats
path: root/remote/test/browser/page/browser_frameAttached.js
blob: bb181feadb3b28d05b3daef5932e2d9cdff6711f (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
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const DOC = toDataURL("<div>foo</div>");
const DOC_IFRAME_MULTI = toDataURL(`
  <iframe src='data:text/html,foo'></iframe>
  <iframe src='data:text/html,bar'></iframe>
`);
const DOC_IFRAME_NESTED = toDataURL(`
  <iframe src="${DOC_IFRAME_MULTI}"></iframe>
`);

add_task(async function noEventWhenPageDomainDisabled({ client }) {
  await runFrameAttachedTest(client, 0, async () => {
    info("Navigate to a page with nested iframes");
    await loadURL(DOC_IFRAME_NESTED);
  });
});

add_task(async function noEventAfterPageDomainDisabled({ client }) {
  const { Page } = client;

  await Page.enable();
  await Page.disable();

  await runFrameAttachedTest(client, 0, async () => {
    info("Navigate to a page with nested iframes");
    await loadURL(DOC_IFRAME_NESTED);
  });
});

add_task(async function noEventWhenNavigatingWithNoFrames({ client }) {
  const { Page } = client;

  info("Navigate to a page with iframes");
  await loadURL(DOC_IFRAME_NESTED);

  await Page.enable();

  await runFrameAttachedTest(client, 0, async () => {
    info("Navigate to a page with no iframes");
    await loadURL(DOC);
  });
});

add_task(async function eventWhenNavigatingWithFrames({ client }) {
  const { Page } = client;

  await Page.enable();

  await runFrameAttachedTest(client, 2, async () => {
    info("Navigate to a page with iframes");
    await loadURL(DOC_IFRAME_MULTI);
  });
});

add_task(async function eventWhenNavigatingWithNestedFrames({ client }) {
  const { Page } = client;

  await Page.enable();

  await runFrameAttachedTest(client, 3, async () => {
    info("Navigate to a page with nested iframes");
    await loadURL(DOC_IFRAME_NESTED);
  });
});

add_task(async function eventWhenAttachingFrame({ client }) {
  const { Page } = client;

  await Page.enable();

  await runFrameAttachedTest(client, 1, async () => {
    await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
      const frame = content.document.createElement("iframe");
      frame.src = "data:text/html,frame content";
      const loaded = new Promise(resolve => (frame.onload = resolve));
      content.document.body.appendChild(frame);
      await loaded;
    });
  });
});

async function runFrameAttachedTest(client, expectedEventCount, callback) {
  const { Page } = client;

  const ATTACHED = "Page.frameAttached";

  const history = new RecordEvents(expectedEventCount);
  history.addRecorder({
    event: Page.frameAttached,
    eventName: ATTACHED,
    messageFn: payload => {
      return `Received ${ATTACHED} for frame id ${payload.frameId}`;
    },
  });

  const framesBefore = await getFlattenedFrameTree(client);
  await callback();
  const framesAfter = await getFlattenedFrameTree(client);

  const frameAttachedEvents = await history.record();

  if (expectedEventCount == 0) {
    is(frameAttachedEvents.length, 0, "Got no frame attached event");
    return;
  }

  // check how many frames were attached or detached
  const count = Math.abs(framesBefore.size - framesAfter.size);

  is(count, expectedEventCount, "Expected amount of frames attached");
  is(
    frameAttachedEvents.length,
    count,
    "Received the expected amount of frameAttached events"
  );

  // extract the new or removed frames
  const framesAll = new Map([...framesBefore, ...framesAfter]);
  const expectedFrames = new Map(
    [...framesAll].filter(([key, _value]) => {
      return !framesBefore.has(key) && framesAfter.has(key);
    })
  );

  frameAttachedEvents.forEach(({ payload }) => {
    const { frameId, parentFrameId } = payload;

    info(`Check frame id ${frameId}`);
    const expectedFrame = expectedFrames.get(frameId);

    ok(expectedFrame, `Found expected frame with id ${frameId}`);
    is(
      frameId,
      expectedFrame.id,
      "Got expected frame id for frameAttached event"
    );
    is(
      parentFrameId,
      expectedFrame.parentId,
      "Got expected parent frame id for frameAttached event"
    );
  });
}