mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-04-09 23:04:02 +02:00
Add code coverage for font tests
This commit is contained in:
parent
30ed527a80
commit
e2af2b83c3
13
.github/workflows/font_tests.yml
vendored
13
.github/workflows/font_tests.yml
vendored
@ -59,3 +59,16 @@ jobs:
|
||||
|
||||
- name: Run font tests
|
||||
run: npx gulp fonttest --headless
|
||||
|
||||
- name: Run font tests with code coverage
|
||||
run: npx gulp fonttest --headless --coverage --coverage-output build/coverage/font
|
||||
|
||||
- name: Upload results to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
files: ./build/coverage/font/lcov.info
|
||||
flags: fonttest
|
||||
name: codecov-umbrella
|
||||
verbose: true
|
||||
@ -731,6 +731,15 @@ function runTests(testsName, { bot = false, xfaOnly = false } = {}) {
|
||||
if (process.argv.includes("--headless")) {
|
||||
args.push("--headless");
|
||||
}
|
||||
if (process.argv.includes("--coverage")) {
|
||||
args.push("--coverage");
|
||||
}
|
||||
if (process.argv.includes("--coverage-output")) {
|
||||
args.push(
|
||||
"--coverage-output",
|
||||
process.argv[process.argv.indexOf("--coverage-output") + 1]
|
||||
);
|
||||
}
|
||||
|
||||
const testProcess = startNode(args, { cwd: TEST_DIR, stdio: "inherit" });
|
||||
testProcess.on("close", function (code) {
|
||||
|
||||
237
package-lock.json
generated
237
package-lock.json
generated
@ -20,6 +20,7 @@
|
||||
"autoprefixer": "^10.4.24",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-add-header-comment": "^1.0.3",
|
||||
"babel-plugin-istanbul": "^7.0.1",
|
||||
"c8": "^10.1.3",
|
||||
"cached-iterable": "^0.3.0",
|
||||
"caniuse-lite": "^1.0.30001769",
|
||||
@ -42,6 +43,9 @@
|
||||
"gulp-sourcemaps": "^3.0.0",
|
||||
"gulp-zip": "^6.1.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"istanbul-lib-coverage": "^3.2.2",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-reports": "^3.2.0",
|
||||
"jasmine": "^5.13.0",
|
||||
"jsdoc": "^4.0.5",
|
||||
"jstransformer-nunjucks": "^1.2.0",
|
||||
@ -2382,6 +2386,113 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
"integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.3.1",
|
||||
"find-up": "^4.1.0",
|
||||
"get-package-type": "^0.1.0",
|
||||
"js-yaml": "^3.13.1",
|
||||
"resolve-from": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
|
||||
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/schema": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
|
||||
@ -4037,6 +4148,26 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/babel-plugin-istanbul": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz",
|
||||
"integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"workspaces": [
|
||||
"test/babel-8"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.0.0",
|
||||
"@istanbuljs/load-nyc-config": "^1.0.0",
|
||||
"@istanbuljs/schema": "^0.1.3",
|
||||
"istanbul-lib-instrument": "^6.0.2",
|
||||
"test-exclude": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-polyfill-corejs2": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz",
|
||||
@ -7109,6 +7240,13 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@ -7223,6 +7361,16 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-package-type": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
|
||||
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
@ -8248,6 +8396,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
@ -8921,6 +9081,36 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-lib-instrument": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
|
||||
"integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@istanbuljs/schema": "^0.1.3",
|
||||
"istanbul-lib-coverage": "^3.2.0",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-lib-instrument/node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-lib-report": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
|
||||
@ -10592,6 +10782,16 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
@ -13314,6 +13514,43 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
|
||||
"integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@istanbuljs/schema": "^0.1.2",
|
||||
"glob": "^7.1.4",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/text-decoder": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"autoprefixer": "^10.4.24",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-add-header-comment": "^1.0.3",
|
||||
"babel-plugin-istanbul": "^7.0.1",
|
||||
"c8": "^10.1.3",
|
||||
"cached-iterable": "^0.3.0",
|
||||
"caniuse-lite": "^1.0.30001769",
|
||||
@ -37,6 +38,9 @@
|
||||
"gulp-sourcemaps": "^3.0.0",
|
||||
"gulp-zip": "^6.1.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"istanbul-lib-coverage": "^3.2.2",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-reports": "^3.2.0",
|
||||
"jasmine": "^5.13.0",
|
||||
"jsdoc": "^4.0.5",
|
||||
"jstransformer-nunjucks": "^1.2.0",
|
||||
|
||||
@ -21,6 +21,9 @@ import {
|
||||
verifyManifestFiles,
|
||||
} from "./downloadutils.mjs";
|
||||
import fs from "fs";
|
||||
import istanbulCoverage from "istanbul-lib-coverage";
|
||||
import istanbulReportGenerator from "istanbul-reports";
|
||||
import libReport from "istanbul-lib-report";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import puppeteer from "puppeteer";
|
||||
@ -29,6 +32,8 @@ import { translateFont } from "./font/ttxdriver.mjs";
|
||||
import { WebServer } from "./webserver.mjs";
|
||||
import yargs from "yargs";
|
||||
|
||||
const __dirname = import.meta.dirname;
|
||||
|
||||
function parseOptions() {
|
||||
const parsedArgs = yargs(process.argv)
|
||||
.usage("Usage: $0")
|
||||
@ -117,6 +122,16 @@ function parseOptions() {
|
||||
describe: "Error if verifying the manifest files fails.",
|
||||
type: "boolean",
|
||||
})
|
||||
.option("coverage", {
|
||||
default: false,
|
||||
describe: "Enable code coverage collection.",
|
||||
type: "boolean",
|
||||
})
|
||||
.option("coverageOutput", {
|
||||
default: "build/coverage",
|
||||
describe: "The directory where to store code coverage data.",
|
||||
type: "string",
|
||||
})
|
||||
.option("testfilter", {
|
||||
alias: "t",
|
||||
default: [],
|
||||
@ -1057,6 +1072,7 @@ function startServer() {
|
||||
host,
|
||||
port: options.port,
|
||||
cacheExpirationTime: 3600,
|
||||
coverageEnabled: global.coverageEnabled || false,
|
||||
});
|
||||
server.start();
|
||||
}
|
||||
@ -1069,17 +1085,79 @@ function getSession(browser) {
|
||||
return sessions.find(session => session.name === browser);
|
||||
}
|
||||
|
||||
async function writeCoverageData(outputDirectory) {
|
||||
try {
|
||||
console.log("\n### Writing code coverage data");
|
||||
|
||||
// Merge coverage from all sessions
|
||||
const mergedCoverage = istanbulCoverage.createCoverageMap();
|
||||
for (const session of sessions) {
|
||||
if (session.coverage) {
|
||||
mergedCoverage.merge(
|
||||
istanbulCoverage.createCoverageMap(session.coverage)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// create a context for report generation
|
||||
const context = libReport.createContext({
|
||||
dir: path.join(__dirname, "..", outputDirectory),
|
||||
coverageMap: mergedCoverage,
|
||||
});
|
||||
|
||||
const report = istanbulReportGenerator.create("lcovonly", {
|
||||
projectRoot: path.join(__dirname, ".."),
|
||||
});
|
||||
report.execute(context);
|
||||
|
||||
console.log(`Total files covered: ${Object.keys(mergedCoverage).length}`);
|
||||
} catch (err) {
|
||||
console.error("Failed to write coverage data:", err);
|
||||
}
|
||||
}
|
||||
|
||||
async function closeSession(browser) {
|
||||
for (const session of sessions) {
|
||||
if (session.name !== browser) {
|
||||
continue;
|
||||
}
|
||||
if (session.browser !== undefined) {
|
||||
// Collect coverage before closing (works with both Chrome and Firefox)
|
||||
if (global.coverageEnabled) {
|
||||
try {
|
||||
const pages = await session.browser.pages();
|
||||
if (pages.length > 0) {
|
||||
const page = pages[0];
|
||||
|
||||
// Extract window.__coverage__ which is populated by
|
||||
// babel-plugin-istanbul
|
||||
const coverage = await page.evaluate(() => window.__coverage__);
|
||||
|
||||
if (coverage && Object.keys(coverage).length > 0) {
|
||||
session.coverage = coverage;
|
||||
console.log(
|
||||
`Collected coverage from ${browser}: ${Object.keys(coverage).length} files`
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
`Failed to collect coverage for ${browser}:`,
|
||||
err.message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await session.browser.close();
|
||||
}
|
||||
session.closed = true;
|
||||
const allClosed = sessions.every(s => s.closed);
|
||||
if (allClosed) {
|
||||
// Write coverage data if enabled
|
||||
if (global.coverageEnabled) {
|
||||
await writeCoverageData(global.coverageOutput);
|
||||
}
|
||||
|
||||
if (tempDir) {
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
@ -1113,6 +1191,15 @@ async function main() {
|
||||
stats = [];
|
||||
}
|
||||
|
||||
if (options.coverage) {
|
||||
global.coverageEnabled = true;
|
||||
console.log("\n### Code coverage enabled for browser tests");
|
||||
if (options.coverageOutput) {
|
||||
global.coverageOutput = options.coverageOutput;
|
||||
console.log(`### Code coverage output file: ${options.coverageOutput}`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (options.downloadOnly) {
|
||||
await ensurePDFsDownloaded();
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
// PLEASE NOTE: This code is intended for development purposes only and
|
||||
// should NOT be used in production environments.
|
||||
|
||||
import babel from "@babel/core";
|
||||
import fs from "fs";
|
||||
import fsPromises from "fs/promises";
|
||||
import http from "http";
|
||||
@ -43,7 +44,7 @@ const MIME_TYPES = {
|
||||
const DEFAULT_MIME_TYPE = "application/octet-stream";
|
||||
|
||||
class WebServer {
|
||||
constructor({ root, host, port, cacheExpirationTime }) {
|
||||
constructor({ root, host, port, cacheExpirationTime, coverageEnabled }) {
|
||||
const cwdURL = pathToFileURL(process.cwd()) + "/";
|
||||
this.rootURL = new URL(`${root || "."}/`, cwdURL);
|
||||
this.host = host || "localhost";
|
||||
@ -52,6 +53,7 @@ class WebServer {
|
||||
this.verbose = false;
|
||||
this.cacheExpirationTime = cacheExpirationTime || 0;
|
||||
this.disableRangeRequests = false;
|
||||
this.coverageEnabled = coverageEnabled || false;
|
||||
this.hooks = {
|
||||
GET: [crossOriginHandler, redirectHandler],
|
||||
POST: [],
|
||||
@ -190,7 +192,7 @@ class WebServer {
|
||||
if (this.verbose) {
|
||||
console.log(url);
|
||||
}
|
||||
this.#serveFile(response, localURL, fileSize);
|
||||
await this.#serveFile(response, localURL, fileSize, url);
|
||||
}
|
||||
|
||||
async #serveDirectoryIndex(response, url, localUrl) {
|
||||
@ -288,7 +290,50 @@ class WebServer {
|
||||
response.end("</body></html>");
|
||||
}
|
||||
|
||||
#serveFile(response, fileURL, fileSize) {
|
||||
async #serveFile(response, fileURL, fileSize, url) {
|
||||
// Check if we should instrument this file for coverage
|
||||
const shouldInstrument =
|
||||
this.coverageEnabled &&
|
||||
url &&
|
||||
/\.m?js$/.test(fileURL.pathname) &&
|
||||
(url.pathname.startsWith("/src/") || url.pathname.startsWith("/web/")) &&
|
||||
!url.pathname.includes("/test/");
|
||||
|
||||
if (shouldInstrument) {
|
||||
try {
|
||||
// Read the file content
|
||||
const content = await fsPromises.readFile(fileURL, "utf8");
|
||||
|
||||
// Transform with Babel and istanbul plugin
|
||||
const result = babel.transformSync(content, {
|
||||
filename: fileURL.pathname,
|
||||
plugins: ["babel-plugin-istanbul"],
|
||||
sourceMaps: false,
|
||||
});
|
||||
|
||||
const instrumentedCode = result.code;
|
||||
const instrumentedSize = Buffer.byteLength(instrumentedCode, "utf8");
|
||||
|
||||
// Serve the instrumented code
|
||||
response.setHeader("Content-Type", "application/javascript");
|
||||
response.setHeader("Content-Length", instrumentedSize);
|
||||
if (this.cacheExpirationTime > 0) {
|
||||
const expireTime = new Date();
|
||||
expireTime.setSeconds(
|
||||
expireTime.getSeconds() + this.cacheExpirationTime
|
||||
);
|
||||
response.setHeader("Expires", expireTime.toUTCString());
|
||||
}
|
||||
response.writeHead(200);
|
||||
response.end(instrumentedCode, "utf8");
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error(`Failed to instrument ${fileURL.pathname}:`, error);
|
||||
// Fall through to serve the original file
|
||||
}
|
||||
}
|
||||
|
||||
// Serve the file normally
|
||||
const stream = fs.createReadStream(fileURL, { flags: "rs" });
|
||||
stream.on("error", error => {
|
||||
response.writeHead(500);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user