diff --git a/lib/helper.js b/lib/helper.js index 248ec465c55..c018f87952b 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -14,6 +14,8 @@ * limitations under the License. */ +/** @type {?Map} */ +let apiCoverage = null; class Helper { /** * @param {function()|string} fun @@ -116,16 +118,21 @@ class Helper { let className = classType.prototype.constructor.name; className = className.substring(0, 1).toLowerCase() + className.substring(1); const debug = require('debug')(`puppeteer:${className}`); - if (!debug.enabled) + if (!debug.enabled && !apiCoverage) return; for (let methodName of Reflect.ownKeys(classType.prototype)) { const method = Reflect.get(classType.prototype, methodName); if (methodName === 'constructor' || typeof methodName !== 'string' || methodName.startsWith('_') || typeof method !== 'function') continue; + if (apiCoverage) + apiCoverage.set(`${className}.${methodName}`, false); Reflect.set(classType.prototype, methodName, function(...args) { let argsText = args.map(stringifyArgument).join(', '); let callsite = `${className}.${methodName}(${argsText})`; - debug(callsite); + if (debug.enabled) + debug(callsite); + if (apiCoverage) + apiCoverage.set(`${className}.${methodName}`, true); return method.call(this, ...args); }); } @@ -163,6 +170,17 @@ class Helper { listener.emitter.removeListener(listener.eventName, listener.handler); listeners.splice(0, listeners.length); } + + /** + * @return {?Map} + */ + static publicAPICoverage() { + return apiCoverage; + } + + static recordPublicAPICoverage() { + apiCoverage = new Map(); + } } module.exports = Helper; diff --git a/package.json b/package.json index a5d07e80c7d..3798cf0fc13 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,11 @@ "debug-unit": "DEBUG_TEST=true node --inspect-brk ./node_modules/.bin/jasmine test/test.js", "test-phantom": "python third_party/phantomjs/test/run-tests.py", "test-doclint": "jasmine utils/doclint/test/test.js", - "test": "npm run lint --silent && npm run unit && npm run test-phantom && npm run test-doclint", + "test": "npm run lint --silent && npm run coverage && npm run test-phantom && npm run test-doclint", "install": "node install.js", "lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .) && npm run doc", - "doc": "node utils/doclint/cli.js" + "doc": "node utils/doclint/cli.js", + "coverage": "COVERAGE=true npm run unit" }, "author": "The Chromium Authors", "license": "SEE LICENSE IN LICENSE", diff --git a/test/test.js b/test/test.js index a41f1a50321..e2c5734da77 100644 --- a/test/test.js +++ b/test/test.js @@ -17,6 +17,9 @@ let fs = require('fs'); let rm = require('rimraf').sync; let path = require('path'); +let helper = require('../lib/helper'); +if (process.env.COVERAGE) + helper.recordPublicAPICoverage(); let Browser = require('../lib/Browser'); let SimpleServer = require('./server/SimpleServer'); let GoldenUtils = require('./golden-utils'); @@ -1345,6 +1348,24 @@ describe('Puppeteer', function() { }); }); +if (process.env.COVERAGE) { + describe('API', function(){ + let coverage = helper.publicAPICoverage(); + let disabled = new Set(); + if (headless) { + disabled.add('dialog.accept'); + disabled.add('dialog.dismiss'); + } else { + disabled.add('page.pdf'); + } + + for (let method of coverage.keys()) { + (disabled.has(method) ? xit : it)(`public method '${method}' was tested`, SX(async function(){ + expect(publicAPICoverage.get(method)).toBe(true); + })); + } + }); +} /** * @param {!EventEmitter} emitter * @param {string} eventName