fix: fetch script sources for V8 coverage on network-loaded scripts

The @bgotink/playwright-coverage library's mixinCoverage fixture relies on
script.source being present in V8 coverage data, but Playwright only includes
source for inline scripts, not network-loaded ones. Since Vite bundles are
served over HTTP, all coverage entries had null sources, resulting in 0/0
coverage.

Replace mixinCoverage with a custom page fixture that:
1. Starts/stops V8 JS coverage as before
2. After stopping, fetches the source text for any network-loaded script
   that is missing its source
3. Writes the enriched coverage data as an attachment for the reporter
This commit is contained in:
bymyself
2026-04-07 00:10:39 -07:00
parent 6aae5c7647
commit 8b3feb2abb

View File

@@ -1,7 +1,7 @@
import type { APIRequestContext, Locator, Page } from '@playwright/test'
import { test as base } from '@playwright/test'
import { mixinFixtures as mixinCoverage } from '@bgotink/playwright-coverage'
import { config as dotenvConfig } from 'dotenv'
import { promises as fs } from 'fs'
import { NodeBadgeMode } from '../../src/types/nodeSource'
import { ComfyActionbar } from '@e2e/helpers/actionbar'
@@ -401,12 +401,43 @@ export class ComfyPage {
export const testComfySnapToGridGridSize = 50
const baseWithCoverage = mixinCoverage(base)
const COLLECT_COVERAGE = process.env.COLLECT_COVERAGE === 'true'
const COVERAGE_ATTACHMENT = '@bgotink/playwright-coverage'
export const comfyPageFixture = baseWithCoverage.extend<{
export const comfyPageFixture = base.extend<{
comfyPage: ComfyPage
comfyMouse: ComfyMouse
collectCoverage: boolean
}>({
collectCoverage: [COLLECT_COVERAGE, { option: true }],
page: async ({ page, collectCoverage, browserName }, use, testInfo) => {
if (browserName !== 'chromium' || !collectCoverage) {
return use(page)
}
await page.coverage.startJSCoverage({ resetOnNavigation: false })
await use(page)
const entries = await page.coverage.stopJSCoverage()
for (const entry of entries) {
if (typeof entry.source !== 'string' && entry.url.startsWith('http')) {
try {
const resp = await fetch(entry.url)
if (resp.ok) (entry as Record<string, unknown>).source = await resp.text()
} catch {}
}
}
const resultFile = testInfo.outputPath('v8-coverage.json')
await fs.writeFile(resultFile, JSON.stringify({ result: entries }))
testInfo.attachments.push({
name: COVERAGE_ATTACHMENT,
contentType: 'application/json',
path: resultFile
})
},
comfyPage: async ({ page, request }, use, testInfo) => {
const comfyPage = new ComfyPage(page, request)