Bug 1543095 - Implement Page.frameNavigated. r=ato

Differential Revision: https://phabricator.services.mozilla.com/D27522

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexandre Poirot 2019-04-30 11:09:30 +00:00
Родитель 19ce910c3c
Коммит 5a549b8d58
3 изменённых файлов: 133 добавлений и 2 удалений

Просмотреть файл

@ -34,6 +34,8 @@ class Page extends ContentProcessDomain {
async enable() {
if (!this.enabled) {
this.enabled = true;
this.chromeEventHandler.addEventListener("DOMWindowCreated", this,
{mozSystemGroup: true});
this.chromeEventHandler.addEventListener("DOMContentLoaded", this,
{mozSystemGroup: true});
this.chromeEventHandler.addEventListener("pageshow", this,
@ -43,6 +45,8 @@ class Page extends ContentProcessDomain {
disable() {
if (this.enabled) {
this.chromeEventHandler.removeEventListener("DOMWindowCreated", this,
{mozSystemGroup: true});
this.chromeEventHandler.removeEventListener("DOMContentLoaded", this,
{mozSystemGroup: true});
this.chromeEventHandler.removeEventListener("pageshow", this,
@ -64,7 +68,9 @@ class Page extends ContentProcessDomain {
this.docShell.QueryInterface(Ci.nsIWebNavigation);
this.docShell.loadURI(url, opts);
return {frameId: "42"};
return {
frameId: this.content.windowUtils.outerWindowID,
};
}
getFrameTree() {
@ -86,10 +92,28 @@ class Page extends ContentProcessDomain {
return this.content.location.href;
}
handleEvent({type}) {
handleEvent({type, target}) {
if (target.defaultView != this.content) {
// Ignore iframes for now
return;
}
const timestamp = Date.now();
const frameId = target.defaultView.windowUtils.outerWindowID;
const url = target.location.href;
switch (type) {
case "DOMWindowCreated":
this.emit("Page.frameNavigated", {
frame: {
id: frameId,
// frameNavigated is only emitted for the top level document
// so that it never has a parent.
parentId: null,
url,
},
});
break;
case "DOMContentLoaded":
this.emit("Page.domContentEventFired", {timestamp});
break;

Просмотреть файл

@ -8,5 +8,6 @@ skip-if = debug || asan # bug 1546945
[browser_cdp.js]
[browser_main_target.js]
[browser_page_frameNavigated.js]
[browser_tabs.js]
[browser_target.js]

Просмотреть файл

@ -0,0 +1,106 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/* global getCDP */
const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
const {RemoteAgentError} = ChromeUtils.import("chrome://remote/content/Error.jsm");
// Test the Page navigation events
const TEST_URI = "data:text/html;charset=utf-8,default-test-page";
add_task(async function() {
try {
await testCDP();
} catch (e) {
// Display better error message with the server side stacktrace
// if an error happened on the server side:
if (e.response) {
throw RemoteAgentError.fromJSON(e.response);
} else {
throw e;
}
}
});
async function testCDP() {
// Open a test page, to prevent debugging the random default page
await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URI);
// Start the CDP server
RemoteAgent.init();
RemoteAgent.tabs.start();
RemoteAgent.listen(Services.io.newURI("http://localhost:9222"));
// Retrieve the chrome-remote-interface library object
const CDP = await getCDP();
// Connect to the server
const client = await CDP({
target(list) {
// Ensure debugging the right target, i.e. the one for our test tab.
return list.find(target => target.url == TEST_URI);
},
});
ok(true, "CDP client has been instantiated");
const {Page} = client;
// turn on navigation related events, such as DOMContentLoaded et al.
await Page.enable();
ok(true, "Page domain has been enabled");
const promises = [];
const resolutions = new Map();
function recordPromise(name, promise) {
promise.then(event => {
ok(true, `Received Page.${name}`);
resolutions.set(name, event);
});
promises.push(promise);
}
recordPromise("frameStoppedLoading", Page.frameStoppedLoading());
recordPromise("navigatedWithinDocument", Page.navigatedWithinDocument());
recordPromise("domContentEventFired", Page.domContentEventFired());
recordPromise("loadEventFired", Page.loadEventFired());
recordPromise("frameNavigated", Page.frameNavigated());
const url = "data:text/html;charset=utf-8,test-page";
const { frameId } = await Page.navigate({ url });
ok(true, "A new page has been loaded");
ok(frameId, "Page.navigate returned a frameId");
// Wait for all the promises to resolve
await Promise.all(promises);
// Assert the order in which they resolved
const expectedResolutions = [
"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 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 same than the one " +
"returned by Page.navigate");
is(frameNavigated.frame.name, undefined, "frameNavigated name isn't implemented yet");
is(frameNavigated.frame.url, url, "frameNavigated url is the same being given to " +
"Page.navigate");
await client.close();
ok(true, "The client is closed");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
await RemoteAgent.close();
}