Skip to content

Instantly share code, notes, and snippets.

@gilbarbara
Last active September 28, 2023 16:49
Show Gist options
  • Save gilbarbara/ca2b1a590bc8cc92c56ac882d11134b0 to your computer and use it in GitHub Desktop.
Save gilbarbara/ca2b1a590bc8cc92c56ac882d11134b0 to your computer and use it in GitHub Desktop.
Playwright coverage
import { join } from 'path';
export const TEMP_DIRECTORY = join(__dirname, '..', '.temp');
import { execSync } from 'child_process';
import { readdirSync, readFileSync, rmSync } from 'fs';
import { join } from 'path';
import { TEMP_DIRECTORY } from './config';
function generateCoverage() {
// eslint-disable-next-line no-console
console.log('Generating coverage...');
for (const directory of readdirSync(TEMP_DIRECTORY)) {
const TEST_DIRECTORY = join(TEMP_DIRECTORY, directory);
for (const file of readdirSync(TEST_DIRECTORY)) {
if (!file.startsWith('index')) {
continue;
}
const coverage = JSON.parse(readFileSync(join(TEST_DIRECTORY, file), 'utf-8'));
if (!Object.keys(coverage).length) {
continue;
}
execSync(`cp ${join(TEST_DIRECTORY, file)} coverage/coverage-${directory}.json`);
}
}
execSync('nyc report --reporter=lcov -t coverage --report-dir coverage');
rmSync(TEMP_DIRECTORY, { recursive: true });
}
generateCoverage();
{
"scripts": {
"e2e": "playwright test -c playwright-ct.config.ts",
"e2e:coverage": "COLLECT_COVERAGE=true npm run e2e && ts-node e2e/__coverage__/generateCoverage.ts",
}
}
import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { join } from 'path';
import v8toIstanbul from 'v8-to-istanbul';
import { TEMP_DIRECTORY } from './config';
export default async function saveCoverage(page: any, testName: string): Promise<void> {
try {
const coverage = await page.coverage.stopJSCoverage();
const TEST_DIRECTORY = join(TEMP_DIRECTORY, testName);
for (const entry of coverage) {
if (!entry.url || !entry.source) {
continue;
}
const scriptPath = `playwright/.cache${new URL(entry.url).pathname}`;
const converter = v8toIstanbul(scriptPath, 0, { source: entry.source }, filepath => {
const normalized = filepath.replace(/\\/g, '/');
return normalized.includes('node_modules/');
});
await converter.load();
converter.applyCoverage(entry.functions);
const data = converter.toIstanbul();
if (!existsSync(TEST_DIRECTORY)) {
mkdirSync(TEST_DIRECTORY, { recursive: true });
}
writeFileSync(
join(TEST_DIRECTORY, `${entry.url.split('/').pop()}.json`),
JSON.stringify(data, null, 2),
'utf-8',
);
}
// eslint-disable-next-line no-console
console.log(`Coverage saved for "${testName}"`);
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
}
import { expect, test } from '@playwright/experimental-ct-react';
import saveCoverage from './__coverage__/saveCoverage';
test('should run the component', async ({ browser, mount }) => {
const collectCoverage =
browser.browserType().name() === 'chromium' && process.env.COLLECT_COVERAGE === 'true';
if (collectCoverage) {
await page.coverage.startJSCoverage();
}
// mount the component
// run all the tests...
if (collectCoverage) {
await saveCoverage(page, 'standard');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment