diff --git a/tests/vendor/browser-coverage.test.mjs b/tests/vendor/browser-coverage.test.mjs index 39dcde57..a0336c49 100644 --- a/tests/vendor/browser-coverage.test.mjs +++ b/tests/vendor/browser-coverage.test.mjs @@ -27,3 +27,23 @@ test('browser coverage maps nested JS/MJS and excludes unrelated and traversal p const root = fileURLToPath(new URL('../../web/js/', import.meta.url)); assert.deepEqual(report.result.map(entry => fileURLToPath(entry.url)), [join(root, 'gallery.js'), join(root, 'shared/controls/button.mjs'), join(root, 'shared/panel.js')]); }); + +// #432: every raw file repeated each script's full source (about 84% of its bytes) and the coverage merge ran out of +// memory. c8 reads the source from the mapped file on disk, so the entries keep only the URL, id and functions. +test('browser coverage writes no script source, only what c8 maps', async t => { + const directory = mkdtempSync(join(tmpdir(), 'pm-browser-coverage-')); + const previous = process.env.PM_JS_COVERAGE; + process.env.PM_JS_COVERAGE = directory; + t.after(() => { + if (previous === undefined) delete process.env.PM_JS_COVERAGE; + else process.env.PM_JS_COVERAGE = previous; + rmSync(directory, { recursive: true, force: true }); + }); + const functions = [{ functionName: 'f', isBlockCoverage: true, ranges: [{ startOffset: 0, endOffset: 9, count: 1 }] }]; + await saveCoverage({ coverage: { stopJSCoverage: async () => [{ url: 'http://127.0.0.1:8765/prompt_manager/js/gallery.js', + scriptId: '7', source: 'x'.repeat(100_000), functions }] } }, 'chromium'); + const report = JSON.parse(readFileSync(join(directory, readdirSync(directory)[0]), 'utf8')); + assert.equal(report.result.length, 1); + assert.deepEqual(Object.keys(report.result[0]).sort(), ['functions', 'scriptId', 'url']); + assert.deepEqual(report.result[0].functions, functions); +}); diff --git a/tools/vendor/browser-coverage.mjs b/tools/vendor/browser-coverage.mjs index 4aaee07e..6655096c 100644 --- a/tools/vendor/browser-coverage.mjs +++ b/tools/vendor/browser-coverage.mjs @@ -12,7 +12,10 @@ export async function startCoverage(page, browserName) { export async function saveCoverage(page, browserName) { if (!process.env.PM_JS_COVERAGE || browserName !== 'chromium') return; const entries = await page.coverage.stopJSCoverage(); - const result = mapBrowserCoverage(entries, { urlPrefix: '/prompt_manager/js/', sourceRoot: join(repositoryRoot, 'web/js') }); + // The source is left out (#432): c8 reads it from the mapped file on disk, and repeating every script's text in every + // raw file made the coverage merge run out of memory. + const result = mapBrowserCoverage(entries, { urlPrefix: '/prompt_manager/js/', sourceRoot: join(repositoryRoot, 'web/js') }) + .map(({ source: _source, ...entry }) => entry); mkdirSync(process.env.PM_JS_COVERAGE, { recursive: true }); writeFileSync(join(process.env.PM_JS_COVERAGE, `browser-${randomUUID()}.json`), JSON.stringify({ result })); }