test: make api coverage checker work (#517)

This commit is contained in:
Dmitry Gozman 2020-01-16 17:46:50 -08:00 committed by Andrey Lushnikov
parent 5bbb87bd07
commit 82057ac610
8 changed files with 57 additions and 59 deletions

View File

@ -23,6 +23,8 @@
"lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe --ext js,ts ./src || eslint --ext js,ts ./src) && npm run tsc && npm run doc",
"doc": "node utils/doclint/cli.js",
"coverage": "cross-env COVERAGE=true npm run unit",
"fcoverage": "cross-env COVERAGE=true BROWSER=firefox npm run unit",
"wcoverage": "cross-env COVERAGE=true BROWSER=webkit npm run unit",
"tsc": "tsc -p .",
"build": "node utils/runWebpack.js --mode='development' && tsc -p .",
"watch": "node utils/runWebpack.js --mode='development' --watch --silent | tsc -w -p .",

View File

@ -21,6 +21,7 @@ import { Protocol } from './protocol';
import { EVALUATION_SCRIPT_URL } from './crExecutionContext';
import { Coverage } from '../page';
import * as types from '../types';
type CoverageEntry = {
url: string,
@ -28,20 +29,16 @@ type CoverageEntry = {
ranges : {start: number, end: number}[]
};
export class CRCoverage extends Coverage {
export class CRCoverage implements Coverage {
private _jsCoverage: JSCoverage;
private _cssCoverage: CSSCoverage;
constructor(client: CRSession) {
super();
this._jsCoverage = new JSCoverage(client);
this._cssCoverage = new CSSCoverage(client);
}
async startJSCoverage(options: {
resetOnNavigation?: boolean;
reportAnonymousScripts?: boolean;
}) {
async startJSCoverage(options?: types.JSCoverageOptions) {
return await this._jsCoverage.start(options);
}
@ -49,7 +46,7 @@ export class CRCoverage extends Coverage {
return await this._jsCoverage.stop();
}
async startCSSCoverage(options: { resetOnNavigation?: boolean; } = {}) {
async startCSSCoverage(options?: types.CSSCoverageOptions) {
return await this._cssCoverage.start(options);
}
@ -76,10 +73,7 @@ class JSCoverage {
this._resetOnNavigation = false;
}
async start(options: {
resetOnNavigation?: boolean;
reportAnonymousScripts?: boolean;
} = {}) {
async start(options: types.JSCoverageOptions = {}) {
assert(!this._enabled, 'JSCoverage is already enabled');
const {
resetOnNavigation = true,
@ -173,7 +167,7 @@ class CSSCoverage {
this._resetOnNavigation = false;
}
async start(options: { resetOnNavigation?: boolean; } = {}) {
async start(options: types.CSSCoverageOptions = {}) {
assert(!this._enabled, 'CSSCoverage is already enabled');
const {resetOnNavigation = true} = options;
this._resetOnNavigation = resetOnNavigation;

View File

@ -560,23 +560,9 @@ export class Worker {
}
}
export class Coverage {
startJSCoverage(options: {
resetOnNavigation?: boolean;
reportAnonymousScripts?: boolean;
}): Promise<void> {
throw new Error('not implemented');
}
stopJSCoverage(): Promise<types.CoverageEntry[]> {
throw new Error('not implemented');
}
startCSSCoverage(options: { resetOnNavigation?: boolean; } = {}): Promise<void> {
throw new Error('not implemented');
}
stopCSSCoverage(): Promise<types.CoverageEntry[]> {
throw new Error('not implemented');
}
export interface Coverage {
startJSCoverage(options?: types.JSCoverageOptions): Promise<void>;
stopJSCoverage(): Promise<types.CoverageEntry[]>;
startCSSCoverage(options?: types.CSSCoverageOptions): Promise<void>;
stopCSSCoverage(): Promise<types.CoverageEntry[]>;
}

View File

@ -120,3 +120,12 @@ export type CoverageEntry = {
text: string,
ranges : {start: number, end: number}[]
};
export type CSSCoverageOptions = {
resetOnNavigation?: boolean,
};
export type JSCoverageOptions = {
resetOnNavigation?: boolean,
reportAnonymousScripts?: boolean,
};

View File

@ -53,7 +53,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
it('should contain browser target', async({browser}) => {
const targets = browser.targets();
const browserTarget = targets.find(target => target.type() === 'browser');
expect(browserTarget).toBeTruthy();
expect(browserTarget).toBe(browser.browserTarget());
});
it('should be able to use the default page in the browser', async({page, server, browser}) => {
// The pages will be the testing page and the original newtab page

View File

@ -241,8 +241,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
window.double = true;
});
});
const button = await page.$('button');
await button.dblclick();
await page.dblclick('button');
expect(await page.evaluate('double')).toBe(true);
expect(await page.evaluate('result')).toBe('Clicked');
});

View File

@ -77,34 +77,41 @@ beforeEach(async({server, httpsServer}) => {
httpsServer.reset();
});
const products = ['WebKit', 'Firefox', 'Chromium'];
let product;
let events;
if (process.env.BROWSER === 'firefox') {
describe('Firefox', () => {
testRunner.loadTests(require('./playwright.spec.js'), {
product: 'Firefox',
playwrightPath: utils.projectRoot(),
testRunner,
});
});
product = 'Firefox';
events = {
...require('../lib/events').Events,
...require('../lib/chromium/events').Events,
};
} else if (process.env.BROWSER === 'webkit') {
describe('WebKit', () => {
testRunner.loadTests(require('./playwright.spec.js'), {
product: 'WebKit',
playwrightPath: utils.projectRoot(),
testRunner,
});
});
product = 'WebKit';
events = require('../lib/events').Events;
} else {
describe('Chromium', () => {
testRunner.loadTests(require('./playwright.spec.js'), {
product: 'Chromium',
playwrightPath: utils.projectRoot(),
testRunner,
});
if (process.env.COVERAGE)
utils.recordAPICoverage(testRunner, require('../lib/api').Chromium, require('../lib/chromium/events').Events);
});
product = 'Chromium';
events = require('../lib/events').Events;
}
describe(product, () => {
testRunner.loadTests(require('./playwright.spec.js'), {
product,
playwrightPath: utils.projectRoot(),
testRunner,
});
if (process.env.COVERAGE) {
const api = require('../lib/api');
const filteredApi = {};
Object.keys(api).forEach(name => {
if (products.some(p => name.startsWith(p)) && !name.startsWith(product))
return;
filteredApi[name] = api[name];
});
utils.recordAPICoverage(testRunner, filteredApi, events);
}
});
if (process.env.CI && testRunner.hasFocusedTestsOrSuites()) {
console.error('ERROR: "focused" tests/suites are prohibitted on bots. Remove any "fit"/"fdescribe" declarations.');
process.exit(1);

View File

@ -76,8 +76,9 @@ const utils = module.exports = {
const coverage = new Map();
for (const [className, classType] of Object.entries(api))
traceAPICoverage(coverage, events, className, classType);
testRunner.describe(COVERAGE_TESTSUITE_NAME, () => {
testRunner.it('should call all API methods', () => {
const focus = testRunner.hasFocusedTestsOrSuites();
(focus ? testRunner.fdescribe : testRunner.describe)(COVERAGE_TESTSUITE_NAME, () => {
(focus ? testRunner.fit : testRunner.it)('should call all API methods', () => {
const missingMethods = [];
for (const method of coverage.keys()) {
if (!coverage.get(method))