summaryrefslogtreecommitdiffstats
path: root/remote/shared/test/browser/head.js
blob: 7960d99c9cb69e7e63e57686ef38ca848a2e6202 (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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/**
 * Add a new tab in a given browser, pointing to a given URL and automatically
 * register the cleanup function to remove it at the end of the test.
 *
 * @param {Browser} browser
 *     The browser element where the tab should be added.
 * @param {string} url
 *     The URL for the tab.
 * @param {object=} options
 *     Options object to forward to BrowserTestUtils.addTab.
 * @returns {Tab}
 *     The created tab.
 */
function addTab(browser, url, options) {
  const tab = BrowserTestUtils.addTab(browser, url, options);
  registerCleanupFunction(() => browser.removeTab(tab));
  return tab;
}

/**
 * Check if a given navigation is valid and has the expected url.
 *
 * @param {object} navigation
 *     The navigation to validate.
 * @param {string} expectedUrl
 *     The expected url for the navigation.
 */
function assertNavigation(navigation, expectedUrl) {
  ok(!!navigation, "Retrieved a navigation");
  is(navigation.url, expectedUrl, "Navigation has the expected URL");
  is(
    typeof navigation.navigationId,
    "string",
    "Navigation has a string navigationId"
  );
}

/**
 * Check a pair of navigation events have the expected URL, navigation id and
 * navigable id. The pair is expected to be ordered as follows: navigation-started
 * and then navigation-stopped.
 *
 * @param {Array<object>} events
 *     The pair of events to validate.
 * @param {string} url
 *     The expected url for the navigation.
 * @param {string} navigationId
 *     The expected navigation id.
 * @param {string} navigableId
 *     The expected navigable id.
 * @param {boolean} isSameDocument
 *     If the navigation should be a same document navigation.
 */
function assertNavigationEvents(
  events,
  url,
  navigationId,
  navigableId,
  isSameDocument
) {
  const expectedEvents = isSameDocument ? 1 : 2;

  const navigationEvents = events.filter(
    e => e.data.navigationId == navigationId
  );
  is(
    navigationEvents.length,
    expectedEvents,
    `Found ${expectedEvents} events for navigationId ${navigationId}`
  );

  if (isSameDocument) {
    // Check there are no navigation-started/stopped events.
    ok(!navigationEvents.some(e => e.name === "navigation-started"));
    ok(!navigationEvents.some(e => e.name === "navigation-stopped"));

    const locationChanged = navigationEvents.find(
      e => e.name === "location-changed"
    );
    is(locationChanged.name, "location-changed", "event has the expected name");
    is(locationChanged.data.url, url, "event has the expected url");
    is(
      locationChanged.data.navigableId,
      navigableId,
      "event has the expected navigable"
    );
  } else {
    // Check there is no location-changed event.
    ok(!navigationEvents.some(e => e.name === "location-changed"));

    const started = navigationEvents.find(e => e.name === "navigation-started");
    const stopped = navigationEvents.find(e => e.name === "navigation-stopped");

    // Check navigation-started
    is(started.name, "navigation-started", "event has the expected name");
    is(started.data.url, url, "event has the expected url");
    is(
      started.data.navigableId,
      navigableId,
      "event has the expected navigable"
    );

    // Check navigation-stopped
    is(stopped.name, "navigation-stopped", "event has the expected name");
    is(stopped.data.url, url, "event has the expected url");
    is(
      stopped.data.navigableId,
      navigableId,
      "event has the expected navigable"
    );
  }
}

/**
 * Assert that the given navigations all have unique/different ids.
 *
 * @param {Array<object>} navigations
 *     The navigations to validate.
 */
function assertUniqueNavigationIds(...navigations) {
  const ids = navigations.map(navigation => navigation.navigationId);
  is(new Set(ids).size, ids.length, "Navigation ids are all different");
}

/**
 * Create a document-builder based page with an iframe served by a given domain.
 *
 * @param {string} domain
 *     The domain which should serve the page.
 * @returns {string}
 *     The URI for the page.
 */
function createFrame(domain) {
  return createFrameForUri(
    `https://${domain}/document-builder.sjs?html=frame-${domain}`
  );
}

/**
 * Create the markup for an iframe pointing to a given URI.
 *
 * @param {string} uri
 *     The uri for the iframe.
 * @returns {string}
 *     The iframe markup.
 */
function createFrameForUri(uri) {
  return `<iframe src="${encodeURI(uri)}"></iframe>`;
}

/**
 * Create the URL for a test page containing nested iframes
 *
 * @returns {string}
 *     The test page url.
 */
function createTestPageWithFrames() {
  // Create the markup for an example.net frame nested in an example.com frame.
  const NESTED_FRAME_MARKUP = createFrameForUri(
    `https://example.org/document-builder.sjs?html=${createFrame(
      "example.net"
    )}`
  );

  // Combine the nested frame markup created above with an example.com frame.
  const TEST_URI_MARKUP = `${NESTED_FRAME_MARKUP}${createFrame("example.com")}`;

  // Create the test page URI on example.org.
  return `https://example.org/document-builder.sjs?html=${encodeURI(
    TEST_URI_MARKUP
  )}`;
}

/**
 * Load the provided url in an existing browser.
 *
 * @param {Browser} browser
 *     The browser element where the URL should be loaded.
 * @param {string} url
 *     The URL to load.
 * @param {object=} options
 * @param {boolean} options.includeSubFrames
 *     Whether we should monitor load of sub frames. Defaults to false.
 * @param {boolean} options.maybeErrorPage
 *     Whether we might reach an error page or not. Defaults to false.
 * @returns {Promise}
 *     Promise which will resolve when the page is loaded with the expected url.
 */
async function loadURL(browser, url, options = {}) {
  const { includeSubFrames = false, maybeErrorPage = false } = options;
  const loaded = BrowserTestUtils.browserLoaded(
    browser,
    includeSubFrames,
    url,
    maybeErrorPage
  );
  BrowserTestUtils.startLoadingURIString(browser, url);
  return loaded;
}