From 7856ec12dce1def60b210dadb4364497c808c56b Mon Sep 17 00:00:00 2001 From: Valentin Semirulnik Date: Wed, 5 Apr 2023 23:03:01 +0300 Subject: [PATCH] feat: gzip html reporter's metadata (#3113) --- packages/ui/client/composables/client/static.ts | 11 ++++++++++- packages/ui/node/reporter.ts | 10 ++++++++-- packages/ui/package.json | 1 + packages/ui/vite.config.ts | 2 +- pnpm-lock.yaml | 6 ++++++ test/reporters/tests/html.test.ts | 11 +++++++---- 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/packages/ui/client/composables/client/static.ts b/packages/ui/client/composables/client/static.ts index 3756fa45b104..221bfb0de3c8 100644 --- a/packages/ui/client/composables/client/static.ts +++ b/packages/ui/client/composables/client/static.ts @@ -2,6 +2,7 @@ import type { BirpcReturn } from 'birpc' import type { VitestClient } from '@vitest/ws-client' import type { WebSocketHandlers } from 'vitest/src/api/types' import { parse } from 'flatted' +import { decompressSync, strFromU8 } from 'fflate' import type { File, ModuleGraphData, ResolvedConfig } from 'vitest/src/types' import { StateManager } from '../../../../vitest/src/node/state' @@ -72,7 +73,15 @@ export function createStaticClient(): VitestClient { async function registerMetadata() { const res = await fetch(window.METADATA_PATH!) - metadata = parse(await res.text()) as HTMLReportMetadata + const contentType = res.headers.get('content-type')?.toLowerCase() || '' + if (contentType.includes('application/gzip')) { + const compressed = new Uint8Array(await res.arrayBuffer()) + const decompressed = strFromU8(decompressSync(compressed)) + metadata = parse(decompressed) as HTMLReportMetadata + } + else { + metadata = parse(await res.text()) as HTMLReportMetadata + } const event = new Event('open') ctx.ws.dispatchEvent(event) } diff --git a/packages/ui/node/reporter.ts b/packages/ui/node/reporter.ts index 4351c364b2f2..09f866cbc59b 100644 --- a/packages/ui/node/reporter.ts +++ b/packages/ui/node/reporter.ts @@ -1,5 +1,7 @@ import { promises as fs } from 'node:fs' import { fileURLToPath } from 'node:url' +import { promisify } from 'node:util' +import { gzip, constants as zlibConstants } from 'node:zlib' import { basename, dirname, relative, resolve } from 'pathe' import c from 'picocolors' import fg from 'fast-glob' @@ -48,11 +50,15 @@ export default class HTMLReporter implements Reporter { const htmlFileName = basename(htmlFile) const htmlDir = resolve(this.ctx.config.root, dirname(htmlFile)) - const metaFile = resolve(htmlDir, 'html.meta.json') + const metaFile = resolve(htmlDir, 'html.meta.json.gz') await fs.mkdir(resolve(htmlDir, 'assets'), { recursive: true }) - await fs.writeFile(metaFile, report, 'utf-8') + const promiseGzip = promisify(gzip) + const data = await promiseGzip(report, { + level: zlibConstants.Z_BEST_COMPRESSION, + }) + await fs.writeFile(metaFile, data, 'base64') const ui = resolve(distDir, 'client') // copy ui const files = fg.sync('**/*', { cwd: ui }) diff --git a/packages/ui/package.json b/packages/ui/package.json index 1073005e4066..bc69b5969356 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -41,6 +41,7 @@ "dependencies": { "@vitest/utils": "workspace:*", "fast-glob": "^3.2.12", + "fflate": "^0.7.4", "flatted": "^3.2.7", "pathe": "^1.1.0", "picocolors": "^1.0.0", diff --git a/packages/ui/vite.config.ts b/packages/ui/vite.config.ts index aed35e025f93..9f4ad32e777e 100644 --- a/packages/ui/vite.config.ts +++ b/packages/ui/vite.config.ts @@ -65,7 +65,7 @@ export const config: UserConfig = { name: 'debug-html-report', apply: 'serve', transformIndexHtml(html) { - return html.replace('', ``) + return html.replace('', ``) }, }, ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 189ff1515116..2717ddf14d86 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -760,6 +760,7 @@ importers: cypress: ^12.3.0 d3-graph-controller: ^2.5.1 fast-glob: ^3.2.12 + fflate: ^0.7.4 flatted: ^3.2.7 floating-vue: ^2.0.0-y.0 pathe: ^1.1.0 @@ -777,6 +778,7 @@ importers: dependencies: '@vitest/utils': link:../utils fast-glob: 3.2.12 + fflate: 0.7.4 flatted: 3.2.7 pathe: 1.1.0 picocolors: 1.0.0 @@ -13545,6 +13547,10 @@ packages: resolution: {integrity: sha512-uJQyMrX5IJZkhoEUBQ3EjxkeiZkppBd5jS/fMTJmfZxLSiaQjv2zD0kTvuvkSH89uFvgSlB6ueGpjD3HWN7Bxw==} dev: true + /fflate/0.7.4: + resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} + dev: false + /figgy-pudding/3.5.2: resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==} dev: true diff --git a/test/reporters/tests/html.test.ts b/test/reporters/tests/html.test.ts index bab25eb8f1c0..cb5c60b3fb97 100644 --- a/test/reporters/tests/html.test.ts +++ b/test/reporters/tests/html.test.ts @@ -1,4 +1,5 @@ import fs from 'fs' +import zlib from 'zlib' import { resolve } from 'pathe' import { execa } from 'execa' import { describe, expect, it } from 'vitest' @@ -21,7 +22,8 @@ describe.skipIf(skip)('html reporter', async () => { }, stdio: 'inherit', }).catch(e => e) - const metaJson = fs.readFileSync(resolve(root, `${basePath}/html.meta.json`), { encoding: 'utf-8' }) + const metaJsonGzipeed = fs.readFileSync(resolve(root, `${basePath}/html.meta.json.gz`)) + const metaJson = zlib.gunzipSync(metaJsonGzipeed).toString('utf-8') const indexHtml = fs.readFileSync(resolve(root, `${basePath}/index.html`), { encoding: 'utf-8' }) const resultJson = parse(metaJson.replace(new RegExp(vitestRoot, 'g'), '')) resultJson.config = {} // doesn't matter for a test @@ -38,7 +40,7 @@ describe.skipIf(skip)('html reporter', async () => { expect(task.result.error).not.toBeDefined() expect(task.result.logs).not.toBeDefined() expect(resultJson).toMatchSnapshot(`tests are ${expected}`) - expect(indexHtml).toMatch('window.METADATA_PATH="html.meta.json"') + expect(indexHtml).toMatch('window.METADATA_PATH="html.meta.json.gz"') }, 120000) it('resolves to "failing" status for test file "json-fail"', async () => { @@ -52,7 +54,8 @@ describe.skipIf(skip)('html reporter', async () => { }, stdio: 'inherit', }).catch(e => e) - const metaJson = fs.readFileSync(resolve(root, `${basePath}/html.meta.json`), { encoding: 'utf-8' }) + const metaJsonGzipped = fs.readFileSync(resolve(root, `${basePath}/html.meta.json.gz`)) + const metaJson = zlib.gunzipSync(metaJsonGzipped).toString('utf-8') const indexHtml = fs.readFileSync(resolve(root, `${basePath}/index.html`), { encoding: 'utf-8' }) const resultJson = parse(metaJson.replace(new RegExp(vitestRoot, 'g'), '')) resultJson.config = {} // doesn't matter for a test @@ -77,6 +80,6 @@ describe.skipIf(skip)('html reporter', async () => { task.logs[0].taskId = 0 task.logs[0].time = 0 expect(resultJson).toMatchSnapshot(`tests are ${expected}`) - expect(indexHtml).toMatch('window.METADATA_PATH="html.meta.json"') + expect(indexHtml).toMatch('window.METADATA_PATH="html.meta.json.gz"') }, 120000) })