/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; // Test the Page navigation events const INITIAL_DOC = toDataURL("default-test-page"); const IFRAME_DOC = toDataURL( `` ); const RANDOM_ID_DOC = toDataURL( `` ); const promises = new Set(); const resolutions = new Map(); add_task(async function pageWithoutFrame({ client }) { await loadURL(INITIAL_DOC); const { Page } = client; // turn on navigation related events, such as DOMContentLoaded et al. await Page.enable(); info("Page domain has been enabled"); const { frameTree } = await Page.getFrameTree(); // Save the given `promise` resolution into the `promises` global Set function recordPromise(name, promise) { promise.then(event => { info(`Received Page.${name}`); resolutions.set(name, event); }); promises.add(promise); } // Record all Page events that we assert in this test function recordPromises() { recordPromise("frameStartedLoading", Page.frameStartedLoading()); recordPromise("frameNavigated", Page.frameNavigated()); recordPromise("domContentEventFired", Page.domContentEventFired()); recordPromise("loadEventFired", Page.loadEventFired()); recordPromise("navigatedWithinDocument", Page.navigatedWithinDocument()); recordPromise("frameStoppedLoading", Page.frameStoppedLoading()); } info("Test Page.navigate"); recordPromises(); const url = RANDOM_ID_DOC; const { frameId } = await Page.navigate({ url }); info("A new page has been requested"); ok(frameId, "Page.navigate returned a frameId"); is( frameId, frameTree.frame.id, "The Page.navigate's frameId is the same than getFrameTree's one" ); await assertNavigationEvents({ url, frameId }); const randomId1 = await getTestTabRandomId(); ok(!!randomId1, "Test tab has a valid randomId"); info("Test Page.reload"); recordPromises(); await Page.reload(); info("The page has been reloaded"); await assertNavigationEvents({ url, frameId }); const randomId2 = await getTestTabRandomId(); ok(!!randomId2, "Test tab has a valid randomId"); isnot( randomId2, randomId1, "Test tab randomId has been updated after reload" ); info("Test Page.navigate with the same URL still reloads the current page"); recordPromises(); await Page.navigate({ url }); info("The page has been reloaded"); await assertNavigationEvents({ url, frameId }); const randomId3 = await getTestTabRandomId(); ok(!!randomId3, "Test tab has a valid randomId"); isnot( randomId3, randomId2, "Test tab randomId has been updated after reload" ); }); add_task(async function pageWithSingleFrame({ client }) { const { Page } = client; await Page.enable(); // Store all frameNavigated events in an array const frameNavigatedEvents = []; Page.frameNavigated(e => frameNavigatedEvents.push(e)); info("Navigate to a page containing an iframe"); const onStoppedLoading = Page.frameStoppedLoading(); const { frameId } = await Page.navigate({ url: IFRAME_DOC }); await onStoppedLoading; is(frameNavigatedEvents.length, 2, "Received 2 frameNavigated events"); is( frameNavigatedEvents[0].frame.id, frameId, "Received the correct frameId for the frameNavigated event" ); }); async function assertNavigationEvents({ url, frameId }) { // Wait for all the promises to resolve await Promise.all(promises); // Assert the order in which they resolved const expectedResolutions = [ "frameStartedLoading", "frameNavigated", "domContentEventFired", "loadEventFired", "navigatedWithinDocument", "frameStoppedLoading", ]; Assert.deepEqual( [...resolutions.keys()], expectedResolutions, "Received various Page navigation events in the expected order" ); // Now assert the data exposed by each of these events const frameStartedLoading = resolutions.get("frameStartedLoading"); is( frameStartedLoading.frameId, frameId, "frameStartedLoading frameId is the same one" ); const frameNavigated = resolutions.get("frameNavigated"); ok( !frameNavigated.frame.parentId, "frameNavigated is for the top level document and has a null parentId" ); is(frameNavigated.frame.id, frameId, "frameNavigated id is the right one"); is( frameNavigated.frame.name, undefined, "frameNavigated name isn't implemented yet" ); is(frameNavigated.frame.url, url, "frameNavigated url is the right one"); const navigatedWithinDocument = resolutions.get("navigatedWithinDocument"); is( navigatedWithinDocument.frameId, frameId, "navigatedWithinDocument frameId is the same one" ); is( navigatedWithinDocument.url, url, "navigatedWithinDocument url is the same one" ); const frameStoppedLoading = resolutions.get("frameStoppedLoading"); is( frameStoppedLoading.frameId, frameId, "frameStoppedLoading frameId is the same one" ); promises.clear(); resolutions.clear(); } async function getTestTabRandomId() { return SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() { return content.wrappedJSObject.randomId; }); }