Source code

Revision control

Copy as Markdown

Other Tools

/* 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(
"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.
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;
}