chore: remove checkCoverage script (#30552)

We do not benefit from it for many years already.
This commit is contained in:
Dmitry Gozman 2024-04-25 14:00:14 -07:00 committed by GitHub
parent 9bd2aea130
commit 086ea79c25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 5 additions and 248 deletions

View File

@ -44,8 +44,6 @@ jobs:
if: matrix.os == 'ubuntu-latest'
- run: npm run etest
if: matrix.os != 'ubuntu-latest'
- run: node tests/config/checkCoverage.js electron
if: ${{ !cancelled() && matrix.os == 'ubuntu-latest' }}
- name: Azure Login
uses: azure/login@v2
if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }}

View File

@ -59,7 +59,6 @@ jobs:
- run: npm run build
- run: npx playwright install --with-deps ${{ matrix.browser }} chromium
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test -- --project=${{ matrix.browser }}-*
- run: node tests/config/checkCoverage.js ${{ matrix.browser }}
- name: Azure Login
uses: azure/login@v2
if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }}

View File

@ -47,7 +47,6 @@ jobs:
- run: npm run build
- run: npx playwright install --with-deps ${{ matrix.browser }} chromium
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test -- --project=${{ matrix.browser }}-*
- run: node tests/config/checkCoverage.js ${{ matrix.browser }}
- name: Azure Login
uses: azure/login@v2
if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }}
@ -1099,7 +1098,6 @@ jobs:
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test -- --project=chromium-*
env:
PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW: 1
- run: node tests/config/checkCoverage.js chromium
- name: Azure Login
uses: azure/login@v2
if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }}

View File

@ -30,7 +30,6 @@ export function rewriteErrorMessage<E extends Error>(e: E, newMessage: string):
}
const CORE_DIR = path.resolve(__dirname, '..', '..');
const COVERAGE_PATH = path.join(CORE_DIR, '..', '..', 'tests', 'config', 'coverage.js');
const internalStackPrefixes = [
CORE_DIR,
@ -61,8 +60,6 @@ export function captureLibraryStackTrace(): { frames: StackFrame[], apiName: str
const frame = parseStackTraceLine(line);
if (!frame || !frame.file)
return null;
if (!process.env.PWDEBUGIMPL && isTesting && frame.file.includes(COVERAGE_PATH))
return null;
const isPlaywrightLibrary = frame.file.startsWith(CORE_DIR);
const parsed: ParsedFrame = {
frame,

View File

@ -244,19 +244,16 @@ export function dependenciesForTestFile(filename: string): Set<string> {
return result;
}
// These two are only used in the dev mode, they are specifically excluding
// This is only used in the dev mode, specifically excluding
// files from packages/playwright*. In production mode, node_modules covers
// that.
const kPlaywrightInternalPrefix = path.resolve(__dirname, '../../../playwright');
const kPlaywrightCoveragePrefix = path.resolve(__dirname, '../../../../tests/config/coverage.js');
export function belongsToNodeModules(file: string) {
if (file.includes(`${path.sep}node_modules${path.sep}`))
return true;
if (file.startsWith(kPlaywrightInternalPrefix) && (file.endsWith('.js') || file.endsWith('.mjs')))
return true;
if (file.startsWith(kPlaywrightCoveragePrefix) && (file.endsWith('.js') || file.endsWith('.mjs')))
return true;
return false;
}

View File

@ -20,13 +20,12 @@ import type { CommonFixtures, CommonWorkerFixtures } from './commonFixtures';
import { commonFixtures } from './commonFixtures';
import type { ServerFixtures, ServerWorkerOptions } from './serverFixtures';
import { serverFixtures } from './serverFixtures';
import { coverageTest } from './coverageFixtures';
import { platformTest } from './platformFixtures';
import { testModeTest } from './testModeFixtures';
export const base = test;
export const baseTest = mergeTests(base, coverageTest, platformTest, testModeTest)
export const baseTest = mergeTests(base, platformTest, testModeTest)
.extend<CommonFixtures, CommonWorkerFixtures>(commonFixtures)
.extend<ServerFixtures, ServerWorkerOptions>(serverFixtures);

View File

@ -1,87 +0,0 @@
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const path = require('path');
const fs = require('fs');
const {installCoverageHooks} = require('./coverage');
const browserName = process.argv[2] || 'chromium';
let api = new Set(installCoverageHooks(browserName).coverage.keys());
// coverage exceptions
if (browserName === 'chromium') {
// Sometimes we already have a background page while launching, before adding a listener.
api.delete('browserContext.emit("backgroundpage")');
}
if (browserName !== 'chromium') {
// we don't have CDPSession in non-chromium browsers
api.delete('browser.newBrowserCDPSession');
api.delete('browser.startTracing');
api.delete('browser.stopTracing');
api.delete('browserContext.backgroundPages');
api.delete('browserContext.serviceWorkers');
api.delete('browserContext.newCDPSession');
api.delete('browserContext.emit("backgroundpage")');
api.delete('browserContext.emit("serviceworker")');
api.delete('cDPSession.send');
api.delete('cDPSession.detach');
api.delete('coverage.startJSCoverage');
api.delete('coverage.stopJSCoverage');
api.delete('coverage.startCSSCoverage');
api.delete('coverage.stopCSSCoverage');
api.delete('page.pdf');
}
// Some permissions tests are disabled in webkit. See permissions.jest.js
if (browserName === 'webkit')
api.delete('browserContext.clearPermissions');
// Response interception is not implemented in Firefox yet.
if (browserName === 'firefox')
api.delete('route.intercept');
const coverageDir = path.join(__dirname, '..', 'coverage-report');
const coveredMethods = new Set();
for (const file of getCoverageFiles(coverageDir)) {
for (const method of JSON.parse(fs.readFileSync(file, 'utf8')))
coveredMethods.add(method);
}
let success = true;
for (const method of api) {
if (coveredMethods.has(method))
continue;
// [Symbol.asyncDispose]
if (method.endsWith('.undefined'))
continue;
success = false;
console.log(`ERROR: Missing coverage for "${method}"`)
}
process.exit(success ? 0 : 1);
function * getCoverageFiles(dir) {
for (const entry of fs.readdirSync(dir, {withFileTypes: true})) {
if (entry.isDirectory())
yield * getCoverageFiles(path.join(dir, entry.name))
else
yield path.join(dir, entry.name);
}
}

View File

@ -1,95 +0,0 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
* Modifications copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @param {Map<string, boolean>} apiCoverage
* @param {Object} events
* @param {string} className
* @param {!Object} classType
*/
function traceAPICoverage(apiCoverage, api, events) {
const uninstalls = [];
for (const [name, classType] of Object.entries(api)) {
const className = name.substring(0, 1).toLowerCase() + name.substring(1);
for (const 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;
apiCoverage.set(`${className}.${methodName}`, false);
const override = function(...args) {
apiCoverage.set(`${className}.${methodName}`, true);
return method.call(this, ...args);
};
Object.defineProperty(override, 'name', { writable: false, value: methodName });
Reflect.set(classType.prototype, methodName, override);
uninstalls.push(() => Reflect.set(classType.prototype, methodName, method));
}
if (events[name]) {
for (const event of Object.values(events[name])) {
if (typeof event !== 'symbol')
apiCoverage.set(`${className}.emit(${JSON.stringify(event)})`, false);
}
const method = Reflect.get(classType.prototype, 'emit');
Reflect.set(classType.prototype, 'emit', function(event, ...args) {
if (typeof event !== 'symbol' && this.listenerCount(event))
apiCoverage.set(`${className}.emit(${JSON.stringify(event)})`, true);
return method.call(this, event, ...args);
});
uninstalls.push(() => Reflect.set(classType.prototype, 'emit', method));
}
}
return () => uninstalls.forEach(u => u());
}
/**
* @param {string} browserName
*/
function apiForBrowser(browserName) {
const events = require('../../packages/playwright-core/lib/client/events').Events;
const api = require('../../packages/playwright-core/lib/client/api');
const otherBrowsers = ['chromium', 'webkit', 'firefox'].filter(name => name.toLowerCase() !== browserName.toLowerCase());
const filteredKeys = Object.keys(api).filter(apiName => {
if (apiName.toLowerCase().startsWith('android'))
return browserName === 'android';
if (apiName.toLowerCase().startsWith('electron'))
return browserName === 'electron';
return browserName !== 'electron' && browserName !== 'android' &&
!otherBrowsers.some(otherName => apiName.toLowerCase().startsWith(otherName));
});
const filteredAPI = {};
for (const key of filteredKeys)
filteredAPI[key] = api[key];
return {
api: filteredAPI,
events
}
}
/**
* @param {string} browserName
*/
function installCoverageHooks(browserName) {
const {api, events} = apiForBrowser(browserName);
const coverage = new Map();
const uninstall = traceAPICoverage(coverage, api, events);
return {coverage, uninstall};
}
module.exports = {
installCoverageHooks,
};

View File

@ -1,42 +0,0 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as fs from 'fs';
import * as path from 'path';
import { installCoverageHooks } from './coverage';
import { test } from '@playwright/test';
export type CoverageWorkerOptions = {
coverageName?: string;
};
export const coverageTest = test.extend<{}, { __collectCoverage: void } & CoverageWorkerOptions>({
coverageName: [undefined, { scope: 'worker', option: true }],
__collectCoverage: [async ({ coverageName }, run, workerInfo) => {
if (!coverageName) {
await run();
return;
}
const { coverage, uninstall } = installCoverageHooks(coverageName);
await run();
uninstall();
const coveragePath = path.join(__dirname, '..', 'coverage-report', workerInfo.workerIndex + '.json');
const coverageJSON = Array.from(coverage.keys()).filter(key => coverage.get(key));
await fs.promises.mkdir(path.dirname(coveragePath), { recursive: true });
await fs.promises.writeFile(coveragePath, JSON.stringify(coverageJSON, undefined, 2), 'utf8');
}, { scope: 'worker', auto: true }],
});

View File

@ -19,13 +19,12 @@ loadEnv({ path: path.join(__dirname, '..', '..', '.env') });
import type { Config, PlaywrightTestOptions, PlaywrightWorkerOptions } from '@playwright/test';
import * as path from 'path';
import type { CoverageWorkerOptions } from '../config/coverageFixtures';
process.env.PWPAGE_IMPL = 'electron';
const outputDir = path.join(__dirname, '..', '..', 'test-results');
const testDir = path.join(__dirname, '..');
const config: Config<CoverageWorkerOptions & PlaywrightWorkerOptions & PlaywrightTestOptions> = {
const config: Config<PlaywrightWorkerOptions & PlaywrightTestOptions> = {
testDir,
outputDir,
timeout: 30000,
@ -54,7 +53,6 @@ config.projects.push({
name: 'electron-api',
use: {
browserName: 'chromium',
coverageName: 'electron',
},
testDir: path.join(testDir, 'electron'),
metadata,
@ -66,7 +64,6 @@ config.projects.push({
snapshotPathTemplate: '{testDir}/{testFileDir}/{testFileName}-snapshots/{arg}-chromium{ext}',
use: {
browserName: 'chromium',
coverageName: 'electron',
},
testDir: path.join(testDir, 'page'),
metadata,

View File

@ -21,7 +21,6 @@ import { type Config, type PlaywrightTestOptions, type PlaywrightWorkerOptions,
import * as path from 'path';
import type { TestModeWorkerOptions } from '../config/testModeFixtures';
import type { TestModeName } from '../config/testMode';
import type { CoverageWorkerOptions } from '../config/coverageFixtures';
type BrowserName = 'chromium' | 'firefox' | 'webkit';
@ -79,7 +78,7 @@ if (mode === 'service2') {
};
}
const config: Config<CoverageWorkerOptions & PlaywrightWorkerOptions & PlaywrightTestOptions & TestModeWorkerOptions> = {
const config: Config<PlaywrightWorkerOptions & PlaywrightTestOptions & TestModeWorkerOptions> = {
testDir,
outputDir,
expect: {
@ -124,7 +123,6 @@ for (const browserName of browserNames) {
devtools
},
trace: trace ? 'on' : undefined,
coverageName: browserName,
},
metadata: {
platform: process.platform,

View File

@ -19,13 +19,12 @@ loadEnv({ path: path.join(__dirname, '..', '..', '.env') });
import type { Config, PlaywrightTestOptions, PlaywrightWorkerOptions } from '@playwright/test';
import * as path from 'path';
import type { CoverageWorkerOptions } from '../config/coverageFixtures';
process.env.PWPAGE_IMPL = 'webview2';
const outputDir = path.join(__dirname, '..', '..', 'test-results');
const testDir = path.join(__dirname, '..');
const config: Config<CoverageWorkerOptions & PlaywrightWorkerOptions & PlaywrightTestOptions> = {
const config: Config<PlaywrightWorkerOptions & PlaywrightTestOptions> = {
testDir,
outputDir,
timeout: 30000,
@ -56,7 +55,6 @@ config.projects.push({
snapshotPathTemplate: '{testDir}/{testFileDir}/{testFileName}-snapshots/{arg}-chromium{ext}',
use: {
browserName: 'chromium',
coverageName: 'webview2',
},
testDir: path.join(testDir, 'page'),
metadata,