Introduce DEBUG module which traces public API calls

This patch improves on DEBUG module to trace all puppeteer's
public API calls.

References #89.
This commit is contained in:
Andrey Lushnikov 2017-07-18 20:53:00 -07:00
parent f154d537f7
commit 55acae40fd
8 changed files with 55 additions and 1 deletions

View File

@ -65,3 +65,8 @@ browser.newPage().then(async page => {
browser.close(); browser.close();
}); });
``` ```
Tips-n-tricks:
- `DEBUG=*,-*:protocol node script.js` - dump everything BUT protocol messages
- `DEBUG=*:page node script.js` - dump only Page's API calls
- `DEBUG=*:mouse,*:keyboard node script.js` - dump only Mouse and Keyboard API calls

View File

@ -16,6 +16,7 @@
let {Duplex} = require('stream'); let {Duplex} = require('stream');
let path = require('path'); let path = require('path');
let helper = require('./helper');
let removeRecursive = require('rimraf').sync; let removeRecursive = require('rimraf').sync;
let Page = require('./Page'); let Page = require('./Page');
let childProcess = require('child_process'); let childProcess = require('child_process');
@ -139,6 +140,7 @@ class Browser {
} }
module.exports = Browser; module.exports = Browser;
helper.tracePublicAPI(Browser);
function waitForRemoteDebuggingPort(chromeProcess) { function waitForRemoteDebuggingPort(chromeProcess) {
const rl = readline.createInterface({ input: chromeProcess.stderr }); const rl = readline.createInterface({ input: chromeProcess.stderr });

View File

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
const helper = require('./helper');
class Dialog { class Dialog {
/** /**
* @param {!Connection} client * @param {!Connection} client
@ -67,3 +69,4 @@ Dialog.Type = {
}; };
module.exports = Dialog; module.exports = Dialog;
helper.tracePublicAPI(Dialog);

View File

@ -358,5 +358,6 @@ class Frame {
this._parentFrame = null; this._parentFrame = null;
} }
} }
helper.tracePublicAPI(Frame);
module.exports = FrameManager; module.exports = FrameManager;

View File

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
const helper = require('./helper');
class Keyboard { class Keyboard {
/** /**
* @param {!Connection} client * @param {!Connection} client
@ -236,3 +238,4 @@ function codeForKey(key) {
} }
module.exports = Keyboard; module.exports = Keyboard;
helper.tracePublicAPI(Keyboard);

View File

@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
let EventEmitter = require('events'); const EventEmitter = require('events');
const helper = require('./helper');
class NetworkManager extends EventEmitter { class NetworkManager extends EventEmitter {
/** /**
@ -280,6 +281,7 @@ class Body {
return content.buffer; return content.buffer;
} }
} }
helper.tracePublicAPI(Body);
class Request extends Body { class Request extends Body {
/** /**
@ -300,6 +302,7 @@ class Request extends Body {
return this._response; return this._response;
} }
} }
helper.tracePublicAPI(Request);
class Response extends Body { class Response extends Body {
/** /**
@ -324,6 +327,7 @@ class Response extends Body {
return this._request; return this._request;
} }
} }
helper.tracePublicAPI(Response);
class InterceptedRequest { class InterceptedRequest {
/** /**

View File

@ -721,3 +721,4 @@ Page.Events = {
Page.Viewport; Page.Viewport;
module.exports = Page; module.exports = Page;
helper.tracePublicAPI(Page);

View File

@ -91,6 +91,41 @@ class Helper {
}); });
} }
} }
/**
* @param {!Object} classType
*/
static tracePublicAPI(classType) {
let className = classType.prototype.constructor.name;
className = className.substring(0, 1).toLowerCase() + className.substring(1);
const debug = require('debug')(`puppeteer:${className}`);
if (!debug.enabled)
return;
for (let methodName of Reflect.ownKeys(classType.prototype)) {
const method = Reflect.get(classType.prototype, methodName);
if (methodName === 'constructor' || methodName.startsWith('_') || typeof method !== 'function')
continue;
Reflect.set(classType.prototype, methodName, function(...args) {
let argsText = args.map(stringifyArgument).join(', ');
let callsite = `${className}.${methodName}(${argsText})`;
debug(callsite);
return method.call(this, ...args);
});
}
/**
* @param {!Object} arg
* @return {string}
*/
function stringifyArgument(arg) {
if (typeof arg !== 'function')
return JSON.stringify(arg);
let text = arg.toString().split('\n').map(line => line.trim()).join('');
if (text.length > 20)
text = text.substring(0, 20) + '…';
return `"${text}"`;
}
}
} }
module.exports = Helper; module.exports = Helper;