Bug 1625961 - Use the ResourceWatcher API to fetch Root NodeFront r=ochameau,nchevobbe

Depends on D62625

Differential Revision: https://phabricator.services.mozilla.com/D72668
This commit is contained in:
Julian Descottes 2020-05-10 18:41:58 +00:00
Родитель 917859d20b
Коммит 0d4c2cbb28
7 изменённых файлов: 164 добавлений и 44 удалений

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

@ -166,6 +166,7 @@ function Inspector(toolbox) {
this.onHostChanged = this.onHostChanged.bind(this);
this.onMarkupLoaded = this.onMarkupLoaded.bind(this);
this.onNewSelection = this.onNewSelection.bind(this);
this.onResourceAvailable = this.onResourceAvailable.bind(this);
this.onRootNodeAvailable = this.onRootNodeAvailable.bind(this);
this.onPanelWindowResize = this.onPanelWindowResize.bind(this);
this.onShowBoxModelHighlighterForNode = this.onShowBoxModelHighlighterForNode.bind(
@ -200,6 +201,10 @@ Inspector.prototype = {
this._onTargetDestroyed
);
await this.toolbox.resourceWatcher.watch(
[this.toolbox.resourceWatcher.TYPES.ROOT_NODE],
this.onResourceAvailable
);
// Store the URL of the target page prior to navigation in order to ensure
// telemetry counts in the Grid Inspector are not double counted on reload.
this.previousURL = this.currentTarget.url;
@ -222,8 +227,6 @@ Inspector.prototype = {
this._getCssProperties(),
this._getAccessibilityFront(),
]);
this.walker.watchRootNode(this.onRootNodeAvailable);
},
_onTargetDestroyed({ type, targetFront, isTopLevel }) {
@ -1279,6 +1282,16 @@ Inspector.prototype = {
}
},
onResourceAvailable: function({ resourceType, targetFront, resource }) {
if (resourceType === this.toolbox.resourceWatcher.TYPES.ROOT_NODE) {
// Note: the resource (ie the root node here) will be fetched from the
// walker later on in _getDefaultNodeForSelection.
// We should update the inspector to directly use the node front
// provided here. Bug 1635461.
this.onRootNodeAvailable();
}
},
/**
* Reset the inspector on new root mutation.
*/

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

@ -121,45 +121,3 @@ add_task(async function testCallingWatchSuccessivelyWithoutReload() {
// cleanup
walker.unwatchRootNode(onAvailable);
});
/**
* Test that the watchRootNode API provides the expected node fronts.
*/
add_task(async function testRootNodeFrontIsCorrect() {
const { walker } = await initInspectorFront(`data:text/html,<div id=div1>`);
const browser = gBrowser.selectedBrowser;
info("Call watchRootNode");
let rootNodeResolve;
let rootNodePromise = new Promise(r => (rootNodeResolve = r));
const onAvailable = rootNodeFront => rootNodeResolve(rootNodeFront);
await walker.watchRootNode(onAvailable);
info("Wait until onAvailable has been called");
const root1 = await rootNodePromise;
ok(!!root1, "onAvailable has been called with a valid argument");
info("Check we can query an expected node under the retrieved root");
const div1 = await walker.querySelector(root1, "div");
is(div1.getAttribute("id"), "div1", "Correct root node retrieved");
info("Reload the selected browser");
rootNodePromise = new Promise(r => (rootNodeResolve = r));
browser.reload();
const root2 = await rootNodePromise;
ok(
root1 !== root2,
"onAvailable has been called with a different node front after reload"
);
info("Navigate to another URL");
rootNodePromise = new Promise(r => (rootNodeResolve = r));
BrowserTestUtils.loadURI(browser, `data:text/html,<div id=div2>`);
const root3 = await rootNodePromise;
info("Check we can query an expected node under the retrieved root");
const div2 = await walker.querySelector(root3, "div");
is(div2.getAttribute("id"), "div2", "Correct root node retrieved");
walker.unwatchRootNode(onAvailable);
});

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

@ -6,4 +6,5 @@ DevToolsModules(
'console-messages.js',
'error-messages.js',
'platform-messages.js',
'root-node.js',
)

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

@ -0,0 +1,20 @@
/* 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";
module.exports = async function({
targetList,
targetType,
targetFront,
isTopLevel,
onAvailable,
}) {
if (!isTopLevel) {
return;
}
const inspectorFront = await targetFront.getFront("inspector");
await inspectorFront.walker.watchRootNode(onAvailable);
};

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

@ -315,6 +315,7 @@ ResourceWatcher.TYPES = ResourceWatcher.prototype.TYPES = {
ERROR_MESSAGES: "error-messages",
PLATFORM_MESSAGES: "platform-messages",
DOCUMENT_EVENTS: "document-events",
ROOT_NODE: "root-node",
};
module.exports = { ResourceWatcher };
@ -344,4 +345,6 @@ const LegacyListeners = {
webConsoleFront.on("documentEvent", onAvailable);
await webConsoleFront.startListeners(["DocumentEvents"]);
},
[ResourceWatcher.TYPES
.ROOT_NODE]: require("devtools/shared/resources/legacy-listeners/root-node"),
};

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

@ -15,6 +15,7 @@ support-files =
[browser_resources_document_events.js]
[browser_resources_error_messages.js]
[browser_resources_platform_messages.js]
[browser_resources_root_node.js]
[browser_target_list_frames.js]
[browser_target_list_preffedoff.js]
[browser_target_list_processes.js]

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

@ -0,0 +1,124 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test the ResourceWatcher API around ROOT_NODE
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
/**
* This first test is a simplified version of
* devtools/server/tests/browser/browser_inspector_walker_watch_root_node.js
*
* The original test still asserts some scenarios using several watchRootNode
* call sites, which is not something we intend to support at the moment in the
* resource watcher.
*
* Otherwise this test checks the basic behavior of the resource when reloading
* an empty page.
*/
add_task(async function() {
// Open a test tab
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
const tab = await addTab("data:text/html,Root Node tests");
const {
client,
resourceWatcher,
targetList,
} = await initResourceWatcherAndTarget(tab);
const browser = gBrowser.selectedBrowser;
info("Call watch([ROOT_NODE], ...)");
let onAvailableCounter = 0;
const onAvailable = () => onAvailableCounter++;
await resourceWatcher.watch([ResourceWatcher.TYPES.ROOT_NODE], onAvailable);
info("Wait until onAvailable has been called");
await waitUntil(() => onAvailableCounter === 1);
is(onAvailableCounter, 1, "onAvailable has been called 1 time");
info("Reload the selected browser");
browser.reload();
info("Wait until the watch([ROOT_NODE], ...) callback has been called");
await waitUntil(() => onAvailableCounter === 2);
is(onAvailableCounter, 2, "onAvailable has been called 2 times");
info("Call unwatch([ROOT_NODE], ...) for the onAvailable callback");
resourceWatcher.unwatch([ResourceWatcher.TYPES.ROOT_NODE], onAvailable);
info("Reload the selected browser");
const reloaded = BrowserTestUtils.browserLoaded(browser);
browser.reload();
await reloaded;
is(onAvailableCounter, 2, "onAvailable was not called after calling unwatch");
// Cleanup
targetList.stopListening();
await client.close();
});
/**
* Test that the watchRootNode API provides the expected node fronts.
*/
add_task(async function testRootNodeFrontIsCorrect() {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
const tab = await addTab("data:text/html,<div id=div1>");
const {
client,
resourceWatcher,
targetList,
} = await initResourceWatcherAndTarget(tab);
const browser = gBrowser.selectedBrowser;
info("Call watch([ROOT_NODE], ...)");
let rootNodeResolve;
let rootNodePromise = new Promise(r => (rootNodeResolve = r));
const onAvailable = rootNodeFront => rootNodeResolve(rootNodeFront);
await resourceWatcher.watch([ResourceWatcher.TYPES.ROOT_NODE], onAvailable);
info("Wait until onAvailable has been called");
const { resource: root1, resourceType } = await rootNodePromise;
ok(!!root1, "onAvailable has been called with a valid argument");
is(
resourceType,
ResourceWatcher.TYPES.ROOT_NODE,
"The resource has the expected type"
);
info("Check we can query an expected node under the retrieved root");
const div1 = await root1.walkerFront.querySelector(root1, "div");
is(div1.getAttribute("id"), "div1", "Correct root node retrieved");
info("Reload the selected browser");
rootNodePromise = new Promise(r => (rootNodeResolve = r));
browser.reload();
const { resource: root2 } = await rootNodePromise;
ok(
root1 !== root2,
"onAvailable has been called with a different node front after reload"
);
info("Navigate to another URL");
rootNodePromise = new Promise(r => (rootNodeResolve = r));
BrowserTestUtils.loadURI(browser, `data:text/html,<div id=div3>`);
const { resource: root3 } = await rootNodePromise;
info("Check we can query an expected node under the retrieved root");
const div3 = await root3.walkerFront.querySelector(root3, "div");
is(div3.getAttribute("id"), "div3", "Correct root node retrieved");
// Cleanup
resourceWatcher.unwatch([ResourceWatcher.TYPES.ROOT_NODE], onAvailable);
targetList.stopListening();
await client.close();
});