Bug 1709792 - [devtools] Support target switching in har automation. r=bomsy

* Stop memoizing web console front
* track navigations via DOCUMENT_EVENT's dom-complete
* await for HarAutomation async initialization from toolbox codebase

These changes help fix browser_harautomation_simple.js.
But this isn't enough as will-navigate can easily be missed.

Differential Revision: https://phabricator.services.mozilla.com/D114464
This commit is contained in:
Alexandre Poirot 2021-05-24 15:37:33 +00:00
Родитель 3c37b9918b
Коммит fa827a1cbe
3 изменённых файлов: 54 добавлений и 79 удалений

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

@ -959,7 +959,7 @@ Toolbox.prototype = {
await performanceFrontConnection;
}
this.initHarAutomation();
await this.initHarAutomation();
this.emit("ready");
this._resolveIsOpen();
@ -3967,13 +3967,13 @@ Toolbox.prototype = {
// HAR Automation
initHarAutomation() {
async initHarAutomation() {
const autoExport = Services.prefs.getBoolPref(
"devtools.netmonitor.har.enableAutoExportToFile"
);
if (autoExport) {
this.harAutomation = new HarAutomation();
this.harAutomation.initialize(this);
await this.harAutomation.initialize(this);
}
},
destroyHarAutomation() {

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

@ -40,11 +40,11 @@ function HarAutomation() {}
HarAutomation.prototype = {
// Initialization
initialize: function(toolbox) {
initialize: async function(toolbox) {
this.toolbox = toolbox;
this.commands = toolbox.commands;
this.startMonitoring(this.commands.client);
await this.startMonitoring();
},
destroy: function() {
@ -59,16 +59,26 @@ HarAutomation.prototype = {
// Automation
startMonitoring: async function(client, callback) {
if (!client) {
return;
}
this.devToolsClient = client;
this.webConsoleFront = await this.toolbox.target.getFront("console");
this.tabWatcher = new TabWatcher(this.commands, this);
this.tabWatcher.connect();
startMonitoring: async function() {
await this.toolbox.resourceCommand.watchResources(
[this.toolbox.resourceCommand.TYPES.DOCUMENT_EVENT],
{
onAvailable: resources => {
if (resources.find(r => r.name == "dom-complete")) {
this.pageLoadDone();
}
},
ignoreExistingResources: true,
}
);
await this.toolbox.commands.targetCommand.watchTargets(
[this.toolbox.commands.targetCommand.TYPES.FRAME],
({ targetFront }) => {
if (targetFront.isTopLevel) {
targetFront.on("will-navigate", this.pageLoadBegin.bind(this));
}
}
);
},
pageLoadBegin: function(response) {
@ -83,7 +93,6 @@ HarAutomation.prototype = {
// A page is about to be loaded, start collecting HTTP
// data from events sent from the backend.
this.collector = new HarCollector({
webConsoleFront: this.webConsoleFront,
commands: this.commands,
});
@ -199,46 +208,9 @@ HarAutomation.prototype = {
/**
* Fetches the full text of a string.
*/
getString: function(stringGrip) {
return this.webConsoleFront.getString(stringGrip);
},
};
// Helpers
function TabWatcher(commands, listener) {
this.target = commands.targetCommand.targetFront;
this.listener = listener;
this.onNavigate = this.onNavigate.bind(this);
this.onWillNavigate = this.onWillNavigate.bind(this);
}
TabWatcher.prototype = {
// Connection
connect: function() {
this.target.on("navigate", this.onNavigate);
this.target.on("will-navigate", this.onWillNavigate);
},
disconnect: function() {
if (!this.target) {
return;
}
this.target.off("navigate", this.onNavigate);
this.target.off("will-navigate", this.onWillNavigate);
},
// Event Handlers
onNavigate: function(packet) {
this.listener.pageLoadDone(packet);
},
onWillNavigate: function(packet) {
this.listener.pageLoadBegin(packet);
getString: async function(stringGrip) {
const webConsoleFront = await this.toolbox.target.getFront("console");
return webConsoleFront.getString(stringGrip);
},
};

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

@ -16,7 +16,6 @@ const trace = {
* HTTP requests executed by the page (including inner iframes).
*/
function HarCollector(options) {
this.webConsoleFront = options.webConsoleFront;
this.commands = options.commands;
this.onResourceAvailable = this.onResourceAvailable.bind(this);
@ -297,29 +296,28 @@ HarCollector.prototype = {
}
},
getData: function(actor, method, callback) {
return new Promise(resolve => {
if (!this.webConsoleFront[method]) {
console.error("HarCollector.getData: ERROR Unknown method!");
resolve();
}
async getData(actor, method, callback) {
const file = this.getFile(actor);
const file = this.getFile(actor);
trace.log(
"HarCollector.getData; REQUEST " + method + ", " + file.url,
file
);
trace.log(
"HarCollector.getData; REQUEST " + method + ", " + file.url,
file
);
// Bug 1519082: We don't create fronts for NetworkEvent actors,
// so that we have to do the request manually via DevToolsClient.request()
const packet = {
to: actor,
type: method,
};
const response = await this.commands.client.request(packet);
this.webConsoleFront[method](actor, response => {
trace.log(
"HarCollector.getData; RESPONSE " + method + ", " + file.url,
response
);
callback(response);
resolve(response);
});
});
trace.log(
"HarCollector.getData; RESPONSE " + method + ", " + file.url,
response
);
callback(response);
return response;
},
/**
@ -442,6 +440,10 @@ HarCollector.prototype = {
}
},
async getWebConsoleFront() {
return this.commands.targetCommand.targetFront.getFront("console");
},
/**
* Fetches the full text of a string.
*
@ -453,8 +455,9 @@ HarCollector.prototype = {
* A promise that is resolved when the full string contents
* are available, or rejected if something goes wrong.
*/
getString: function(stringGrip) {
const promise = this.webConsoleFront.getString(stringGrip);
getString: async function(stringGrip) {
const webConsoleFront = await this.getWebConsoleFront();
const promise = webConsoleFront.getString(stringGrip);
this.requests.push(promise);
return promise;
},