diff --git a/package.json b/package.json index a0537d9b8c..6344d2681e 100644 --- a/package.json +++ b/package.json @@ -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 .", diff --git a/src/chromium/crCoverage.ts b/src/chromium/crCoverage.ts index 87045080c5..2568bc8bcc 100644 --- a/src/chromium/crCoverage.ts +++ b/src/chromium/crCoverage.ts @@ -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; diff --git a/src/page.ts b/src/page.ts index a014be026d..1cfe984a91 100644 --- a/src/page.ts +++ b/src/page.ts @@ -560,23 +560,9 @@ export class Worker { } } -export class Coverage { - startJSCoverage(options: { - resetOnNavigation?: boolean; - reportAnonymousScripts?: boolean; - }): Promise { - throw new Error('not implemented'); - } - - stopJSCoverage(): Promise { - throw new Error('not implemented'); - } - - startCSSCoverage(options: { resetOnNavigation?: boolean; } = {}): Promise { - throw new Error('not implemented'); - } - - stopCSSCoverage(): Promise { - throw new Error('not implemented'); - } +export interface Coverage { + startJSCoverage(options?: types.JSCoverageOptions): Promise; + stopJSCoverage(): Promise; + startCSSCoverage(options?: types.CSSCoverageOptions): Promise; + stopCSSCoverage(): Promise; } diff --git a/src/types.ts b/src/types.ts index 602cff00b8..ad0f11964a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -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, +}; diff --git a/test/chromium/chromium.spec.js b/test/chromium/chromium.spec.js index dd6eec8e49..47408a6607 100644 --- a/test/chromium/chromium.spec.js +++ b/test/chromium/chromium.spec.js @@ -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 diff --git a/test/click.spec.js b/test/click.spec.js index d0bd619e83..b2d19118cf 100644 --- a/test/click.spec.js +++ b/test/click.spec.js @@ -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'); }); diff --git a/test/test.js b/test/test.js index b1bf5183df..e42dbd2793 100644 --- a/test/test.js +++ b/test/test.js @@ -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); diff --git a/test/utils.js b/test/utils.js index 22e5f26a28..6d0e601a73 100644 --- a/test/utils.js +++ b/test/utils.js @@ -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))