mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-18 19:01:20 -08:00
test: [ENG-08] add verified TS coverage and paired performance reports
This commit is contained in:
1 parent
8ed0a5228c
commit
4a9a26d4fc
38 files changed
+24335
-61
No files matched your search
@@ -0,0 +1,30 @@
|
||||
# Paired performance and cleanup
|
||||
|
||||
Run `yarn test:package` first. Set `ARTPLAYER_BROWSER_ARTIFACTS` to the resulting
|
||||
`refactor/.cache/packages/run-*/browser-artifacts.json`, then run
|
||||
`yarn test:performance`. The command starts its own local server; do not run it
|
||||
alongside other browser tests or CPU-heavy builds. All three engines run with one
|
||||
worker, no trace/video recording and the same media and viewport within a pair.
|
||||
|
||||
Each engine runs three alternating published/candidate pairs. Each side retains
|
||||
one warm-up and five timed samples for both core and core + chapter, followed by
|
||||
separate instrumented resource probes. `scripts/performance-fixture.mjs` adapts
|
||||
only the frozen BASE-06 fixture's script URLs and report transport. Its original
|
||||
files remain unchanged and their existing baseline tests still run.
|
||||
|
||||
The candidate must come from an isolated package installation. Artifact hashes,
|
||||
source snapshots, package inputs and build tools are checked before measurement;
|
||||
an old candidate cannot silently stand in for changed source. Raw, gzip 9 and
|
||||
Brotli 6 compare matching modern, legacy and ESM files from the same installation.
|
||||
Timing uses the exact JS files selected by the artifact map.
|
||||
|
||||
Reports are in `refactor/.cache/performance/run-<engine>-*/report.json` and
|
||||
`summary.md`. Playwright evidence is in `refactor/.cache/performance/browser/`.
|
||||
CI uploads both and appends summaries to the workflow run. Failed or incomplete
|
||||
runs remain recorded and are not promoted to a passing baseline.
|
||||
|
||||
A successful test proves the measurement contract and candidate resource cleanup.
|
||||
`review-required` means size or timing thresholds were exceeded; it is not release
|
||||
approval. CORE-22 and release reviews must resolve the corresponding risks before
|
||||
publishing. These counters do not measure native heap/GPU memory, real mobile
|
||||
hardware or screen-reader behavior. See `refactor/coverage-performance.md`.
|
||||
@@ -0,0 +1,72 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { compareArtifactSizes, verifyPerformanceArtifacts } from '../../scripts/performance-artifacts.mjs'
|
||||
import { validatePairedPerformance } from '../../scripts/performance-report.mjs'
|
||||
import { performanceSummary } from '../../scripts/performance-summary.mjs'
|
||||
import { expect, test } from '../browser/fixtures.js'
|
||||
|
||||
const root = fileURLToPath(new URL('../../', import.meta.url))
|
||||
|
||||
test('installed core and chapter: three paired timing groups with strict candidate cleanup', async ({ page, browser, browserName, request, diagnostics }, testInfo) => {
|
||||
const artifacts = verifyPerformanceArtifacts(root, process.env.ARTPLAYER_BROWSER_ARTIFACTS)
|
||||
const manifest = await (await request.get('/test/manifest.json')).json()
|
||||
for (const input of artifacts.inputs) {
|
||||
const resource = manifest.resources[`/candidate/${input.name}.js`]
|
||||
expect(resource.source.kind).toBe('artifact')
|
||||
expect(resource.sha256).toBe(input.sha256)
|
||||
}
|
||||
const output = path.join(root, 'refactor/.cache/performance')
|
||||
fs.mkdirSync(output, { recursive: true })
|
||||
const directory = fs.mkdtempSync(path.join(output, `run-${browserName}-`))
|
||||
const report = {
|
||||
schemaVersion: 1,
|
||||
task: 'ENG-08',
|
||||
capturedAt: new Date().toISOString(),
|
||||
environment: { browser: browserName, version: browser.version(), platform: process.platform, node: process.version },
|
||||
inputs: artifacts.inputs,
|
||||
toolchain: artifacts.toolchain,
|
||||
manifest,
|
||||
sizes: await compareArtifactSizes(root, artifacts),
|
||||
runs: [],
|
||||
status: 'incomplete',
|
||||
}
|
||||
const file = path.join(directory, 'report.json')
|
||||
const save = () => fs.writeFileSync(file, `${JSON.stringify(report, null, 2)}\n`)
|
||||
save()
|
||||
try {
|
||||
for (let group = 0; group < 3; group++) {
|
||||
for (const variant of group % 2 ? ['candidate', 'published'] : ['published', 'candidate']) {
|
||||
await page.goto(`/test/performance.html?variant=${variant}`)
|
||||
await page.bringToFront()
|
||||
await page.locator('#run').click()
|
||||
await page.waitForFunction(() => window.artplayerPerformanceReport, null, { timeout: 25000 })
|
||||
const measurements = await page.evaluate(() => window.artplayerPerformanceReport)
|
||||
report.runs.push({ group, variant, measurements })
|
||||
save()
|
||||
}
|
||||
}
|
||||
Object.assign(report, validatePairedPerformance(report))
|
||||
report.reviewRequired ||= report.sizes.some(item => item.reviewSignals.length > 0)
|
||||
expect(diagnostics.errors).toEqual([])
|
||||
expect(diagnostics.consoleErrors).toEqual([])
|
||||
report.status = report.reviewRequired ? 'review-required' : 'passed'
|
||||
save()
|
||||
const summary = performanceSummary(report)
|
||||
fs.writeFileSync(path.join(directory, 'summary.md'), summary)
|
||||
await testInfo.attach('performance-summary', { body: summary, contentType: 'text/markdown' })
|
||||
if (process.env.GITHUB_STEP_SUMMARY)
|
||||
fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary)
|
||||
}
|
||||
catch (error) {
|
||||
report.status = 'failed'
|
||||
report.failure = error.message
|
||||
save()
|
||||
throw error
|
||||
}
|
||||
finally {
|
||||
await testInfo.attach('paired-performance', { path: file, contentType: 'application/json' })
|
||||
process.stdout.write(`Paired performance (${browserName}): ${path.relative(root, file)}; ${report.status}\n`)
|
||||
}
|
||||
})
|
||||
Reference in new issue
Block a user