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

"use strict";

// Test Page.addScriptToEvaluateOnNewDocument and Page.removeScriptToEvaluateOnNewDocument
//
// TODO Bug 1601695 - Schedule script evaluation and check for correct frame id

const WORLD = "testWorld";

add_task(async function uniqueIdForAddedScripts({ client }) {
  const { Page, Runtime } = client;

  await loadURL(PAGE_URL);

  const { identifier: id1 } = await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 1;",
  });
  is(typeof id1, "string", "Script id should be a string");
  ok(id1.length, "Script id is non-empty");

  const { identifier: id2 } = await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 1;",
  });
  ok(id2.length, "Script id is non-empty");
  isnot(id1, id2, "Two scripts should have different ids");

  await Runtime.enable();

  // flush event for PAGE_URL default context
  await Runtime.executionContextCreated();
  await checkIsolatedContextAfterLoad(client, PAGE_FRAME_URL, []);
});

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

  await loadURL(PAGE_URL);

  const { identifier: id1 } = await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 1;",
  });
  is(typeof id1, "string", "Script id should be a string");
  ok(id1.length, "Script id is non-empty");

  await loadURL(PAGE_FRAME_URL);

  const { identifier: id2 } = await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 2;",
  });
  ok(id2.length, "Script id is non-empty");
  isnot(id1, id2, "Two scripts should have different ids");
});

add_task(async function addWithIsolatedWorldAndNavigate({ client }) {
  const { Page, Runtime } = client;

  await Page.enable();
  await Runtime.enable();

  const contextsCreated = recordContextCreated(Runtime, 3);

  const loadEventFired = Page.loadEventFired();
  const { frameId } = await Page.navigate({ url: PAGE_URL });
  await loadEventFired;

  // flush context-created events for the steps above
  await contextsCreated;

  await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 1;",
    worldName: WORLD,
  });

  const isolatedId = await Page.createIsolatedWorld({
    frameId,
    worldName: WORLD,
    grantUniversalAccess: true,
  });

  const contexts = await checkIsolatedContextAfterLoad(client, PAGE_FRAME_URL);
  isnot(contexts[1].id, isolatedId, "The context has a new id");
});

add_task(async function addWithIsolatedWorldNavigateTwice({ client }) {
  const { Page, Runtime } = client;

  await Runtime.enable();

  await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 1;",
    worldName: WORLD,
  });

  await checkIsolatedContextAfterLoad(client, PAGE_URL);
  await checkIsolatedContextAfterLoad(client, PAGE_FRAME_URL);
});

add_task(async function addTwoScriptsWithIsolatedWorld({ client }) {
  const { Page, Runtime } = client;

  await Runtime.enable();

  const names = [WORLD, "A_whole_new_world"];
  await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 1;",
    worldName: names[0],
  });
  await Page.addScriptToEvaluateOnNewDocument({
    source: "1 + 8;",
    worldName: names[1],
  });

  await checkIsolatedContextAfterLoad(client, PAGE_URL, names);
});

function recordContextCreated(Runtime, expectedCount) {
  return new Promise(resolve => {
    const ctx = [];
    const unsubscribe = Runtime.executionContextCreated(payload => {
      ctx.push(payload.context);
      info(
        `Runtime.executionContextCreated: ${payload.context.auxData.type} ` +
          `(${payload.context.origin})`
      );
      if (ctx.length > expectedCount) {
        unsubscribe();
        resolve(ctx);
      }
    });
    timeoutPromise(1000).then(() => {
      unsubscribe();
      resolve(ctx);
    });
  });
}

async function checkIsolatedContextAfterLoad(client, url, names = [WORLD]) {
  const { Page, Runtime } = client;

  await Page.enable();

  // At least the default context will get created
  const expected = names.length + 1;

  const contextsCreated = recordContextCreated(Runtime, expected);
  const frameNavigated = Page.frameNavigated();
  const { frameId } = await Page.navigate({ url });
  await frameNavigated;
  const contexts = await contextsCreated;

  is(contexts.length, expected, "Expected number of contexts got created");
  is(contexts[0].auxData.frameId, frameId, "Expected frame id found");
  is(contexts[0].auxData.isDefault, true, "Got default context");
  is(contexts[0].auxData.type, "default", "Got default context");
  is(contexts[0].name, "", "Get context with empty name");

  names.forEach((name, index) => {
    is(contexts[index + 1].name, name, "Get context with expected name");
    is(contexts[index + 1].auxData.frameId, frameId, "Expected frame id found");
    is(contexts[index + 1].auxData.isDefault, false, "Got isolated context");
    is(contexts[index + 1].auxData.type, "isolated", "Got isolated context");
  });

  return contexts;
}