Skip to content

Commit

Permalink
Bug 1627977 - Use the ResourceWatcher API to fetch ConsoleService Log…
Browse files Browse the repository at this point in the history
…Messages. r=ochameau.

Differential Revision: https://phabricator.services.mozilla.com/D71348
  • Loading branch information
nchevobbe committed Apr 21, 2020
1 parent 4942261 commit d1f5364
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 39 deletions.
37 changes: 9 additions & 28 deletions devtools/client/webconsole/webconsole-connection-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class WebConsoleConnectionProxy {
this._connecter = null;

this._onPageError = this._onPageError.bind(this);
this._onLogMessage = this._onLogMessage.bind(this);
this._onNetworkEvent = this._onNetworkEvent.bind(this);
this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
this._onTabNavigated = this._onTabNavigated.bind(this);
Expand Down Expand Up @@ -140,7 +139,6 @@ class WebConsoleConnectionProxy {
_addWebConsoleFrontEventListeners() {
this.webConsoleFront.on("networkEvent", this._onNetworkEvent);
this.webConsoleFront.on("networkEventUpdate", this._onNetworkEventUpdate);
this.webConsoleFront.on("logMessage", this._onLogMessage);
this.webConsoleFront.on("pageError", this._onPageError);
this.webConsoleFront.on(
"lastPrivateContextExited",
Expand All @@ -160,7 +158,6 @@ class WebConsoleConnectionProxy {
_removeWebConsoleFrontEventListeners() {
this.webConsoleFront.off("networkEvent", this._onNetworkEvent);
this.webConsoleFront.off("networkEventUpdate", this._onNetworkEventUpdate);
this.webConsoleFront.off("logMessage", this._onLogMessage);
this.webConsoleFront.off("pageError", this._onPageError);
this.webConsoleFront.off(
"lastPrivateContextExited",
Expand All @@ -180,22 +177,22 @@ class WebConsoleConnectionProxy {
* went wrong.
*/
async _getCachedMessages() {
const messageTypes = ["PageError"];
if (this.webConsoleFront.traits.newCacheStructure) {
messageTypes.push("LogMessage");
}
const response = await this.webConsoleFront.getCachedMessages([
"PageError",
]);

const response = await this.webConsoleFront.getCachedMessages(messageTypes);
if (this.webConsoleFront.traits.newCacheStructure) {
messageTypes.push("LogMessage");
}
if (response.error) {
throw new Error(
`Web Console getCachedMessages error: ${response.error} ${response.message}`
);
}

return response.messages;
if (this.webConsoleFront.traits.newCacheStructure) {
return response.messages;
}

// On older server, we're also getting cached LogMessages, so we need to remove them
return response.messages.filter(message => message._type !== "LogMessage");
}

/**
Expand Down Expand Up @@ -224,22 +221,6 @@ class WebConsoleConnectionProxy {
this.dispatchMessageAdd(packet);
}

/**
* The "logMessage" message type handler. We redirect any message to the UI
* for displaying.
*
* @private
* @param object packet
* The message received from the server.
*/
_onLogMessage(packet) {
if (!this.webConsoleUI) {
return;
}
packet.type = "logMessage";
this.dispatchMessageAdd(packet);
}

_clearLogpointMessages(logpointId) {
if (this.webConsoleUI) {
this.webConsoleUI.wrapper.dispatchClearLogpointMessages(logpointId);
Expand Down
13 changes: 12 additions & 1 deletion devtools/client/webconsole/webconsole-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,10 @@ class WebConsoleUI {

const resourceWatcher = this.hud.resourceWatcher;
await resourceWatcher.watch(
[resourceWatcher.TYPES.CONSOLE_MESSAGES],
[
resourceWatcher.TYPES.CONSOLE_MESSAGES,
resourceWatcher.TYPES.PLATFORM_MESSAGES,
],
this._onResourceAvailable
);
}
Expand All @@ -345,6 +348,14 @@ class WebConsoleUI {
// or via ConsoleActor's `consoleAPICall` event.
resource.type = "consoleAPICall";
this.wrapper.dispatchMessageAdd(resource);
return;
}

if (resourceType == resourceWatcher.TYPES.PLATFORM_MESSAGES) {
// resource is the packet sent from `ConsoleActor.getCachedMessages().messages`
// or via ConsoleActor's `logMessage` event.
resource.type = "logMessage";
this.wrapper.dispatchMessageAdd(resource);
}
}

Expand Down
1 change: 1 addition & 0 deletions devtools/shared/resources/legacy-listeners/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

DevToolsModules(
'console-messages.js',
'platform-messages.js',
)
51 changes: 51 additions & 0 deletions devtools/shared/resources/legacy-listeners/platform-messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* 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,
}) {
// Only allow the top level target and processes.
// Frames can be ignored as logMessage are never sent to them anyway.
// Also ignore workers as they are not supported yet. (see bug 1592584)
const isAllowed = isTopLevel || targetType === targetList.TYPES.PROCESS;
if (!isAllowed) {
return;
}

const webConsoleFront = await targetFront.getFront("console");

// Request notifying about new messages. Here the "PageError" type start listening for
// both actual PageErrors (emitted as "pageError" events) as well as LogMessages (
// emitted as "logMessage" events). This function only set up the listener on the
// webConsoleFront for "logMessage".
await webConsoleFront.startListeners(["PageError"]);

// Fetch already existing messages
// /!\ The actor implementation requires to call startListeners("PageError") first /!\
// On older server (< v77), cached messages have to be retrieved at the same time as
// PageError messages.
const { messages } = await webConsoleFront.getCachedMessages([
webConsoleFront.traits.newCacheStructure ? "LogMessage" : "PageError",
]);

for (const message of messages) {
// On older server (< v77), we're also getting pageError cached messages, so we need
// to ignore those.
if (
!webConsoleFront.traits.newCacheStructure &&
message._type !== "LogMessage"
) {
continue;
}
onAvailable(message);
}

webConsoleFront.on("logMessage", onAvailable);
};
3 changes: 3 additions & 0 deletions devtools/shared/resources/resource-watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ class ResourceWatcher {

ResourceWatcher.TYPES = ResourceWatcher.prototype.TYPES = {
CONSOLE_MESSAGES: "console-messages",
PLATFORM_MESSAGES: "platform-messages",
};
module.exports = { ResourceWatcher };

Expand All @@ -309,4 +310,6 @@ module.exports = { ResourceWatcher };
const LegacyListeners = {
[ResourceWatcher.TYPES
.CONSOLE_MESSAGES]: require("devtools/shared/resources/legacy-listeners/console-messages"),
[ResourceWatcher.TYPES
.PLATFORM_MESSAGES]: require("devtools/shared/resources/legacy-listeners/platform-messages"),
};
1 change: 1 addition & 0 deletions devtools/shared/resources/tests/browser.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ support-files =
test_worker.js

[browser_resources_console_messages.js]
[browser_resources_platform_messages.js]
[browser_target_list_frames.js]
[browser_target_list_preffedoff.js]
[browser_target_list_processes.js]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//
// Reproduces assertions from: devtools/shared/webconsole/test/chrome/test_cached_messages.html

const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
Expand All @@ -17,18 +16,15 @@ add_task(async function() {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
const tab = await addTab("data:text/html,Console Messages");

// Create a TargetList for the test tab
const client = await createLocalClient();
const target = await client.mainRoot.getTab({ tab });
const targetList = new TargetList(client.mainRoot, target);
await targetList.startListening();

// Now create a ResourceWatcher
const resourceWatcher = new ResourceWatcher(targetList);
const {
client,
resourceWatcher,
targetList,
} = await initResourceWatcherAndTarget(tab);

await testMessages(tab.linkedBrowser, resourceWatcher);

await targetList.stopListening();
targetList.stopListening();
await client.close();
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Test the ResourceWatcher API around PLATFORM_MESSAGES
// Reproduces assertions from: devtools/shared/webconsole/test/chrome/test_nsiconsolemessage.html

const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");

add_task(async function() {
// Disable the preloaded process as it creates processes intermittently
// which forces the emission of RDP requests we aren't correctly waiting for.
await pushPref("dom.ipc.processPrelaunch.enabled", false);

const {
client,
resourceWatcher,
targetList,
} = await initResourceWatcherAndTarget();

const expectedMessages = [
"This is a cached message",
"This is another cached message",
"This is a live message",
"This is another live message",
];
const receivedMessages = [];

info(
"Log some messages *before* calling ResourceWatcher.watch in order to assert the behavior of already existing messages."
);
Services.console.logStringMessage(expectedMessages[0]);
Services.console.logStringMessage(expectedMessages[1]);

let done;
const onAllMessagesReceived = new Promise(resolve => (done = resolve));

await resourceWatcher.watch(
[ResourceWatcher.TYPES.PLATFORM_MESSAGES],
({ resourceType, targetFront, resource }) => {
if (!expectedMessages.includes(resource.message)) {
return;
}

receivedMessages.push(resource.message);
is(
resource.message,
expectedMessages[receivedMessages.length - 1],
`Received the expected «${resource.message}» message, in the expected order`
);

ok(
resource.timeStamp.toString().match(/^\d+$/),
"The resource has a timeStamp property"
);

if (receivedMessages.length == expectedMessages.length) {
done();
}
}
);

info(
"Now log messages *after* the call to ResourceWatcher.watch and after having received all existing messages"
);
Services.console.logStringMessage(expectedMessages[2]);
Services.console.logStringMessage(expectedMessages[3]);

info("Waiting for all expected messages to be received");
await onAllMessagesReceived;
ok(true, "All the expected messages were received");

Services.console.reset();
targetList.stopListening();
await client.close();
});
26 changes: 26 additions & 0 deletions devtools/shared/resources/tests/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,29 @@ async function createLocalClient() {
await client.connect();
return client;
}

async function initResourceWatcherAndTarget(tab) {
const { TargetList } = require("devtools/shared/resources/target-list");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");

// Create a TargetList for the test tab
const client = await createLocalClient();

let target;
if (tab) {
target = await client.mainRoot.getTab({ tab });
} else {
const descriptor = await client.mainRoot.getMainProcess();
target = await descriptor.getTarget();
}

const targetList = new TargetList(client.mainRoot, target);
await targetList.startListening();

// Now create a ResourceWatcher
const resourceWatcher = new ResourceWatcher(targetList);

return { client, resourceWatcher, targetList };
}

0 comments on commit d1f5364

Please sign in to comment.