diff --git a/packages/ui/client/composables/client/static.ts b/packages/ui/client/composables/client/static.ts index 3756fa45b104..2c5373b7f945 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,9 @@ export function createStaticClient(): VitestClient { async function registerMetadata() { const res = await fetch(window.METADATA_PATH!) - metadata = parse(await res.text()) as HTMLReportMetadata + const compressedData = new Uint8Array(await res.arrayBuffer()) + const decompressed = strFromU8(decompressSync(compressedData)) + metadata = parse(decompressed) 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 4f23235b479b..403b96046307 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -538,11 +538,11 @@ importers: vite: ^4.0.0 vitest: workspace:* devDependencies: - '@sveltejs/vite-plugin-svelte': 2.0.0_svelte@3.57.0+vite@4.0.0 - '@testing-library/svelte': 3.2.2_svelte@3.57.0 + '@sveltejs/vite-plugin-svelte': 2.0.0_svelte@3.58.0+vite@4.0.0 + '@testing-library/svelte': 3.2.2_svelte@3.58.0 '@vitest/ui': link:../../packages/ui jsdom: 21.1.1 - svelte: 3.57.0 + svelte: 3.58.0 vite: 4.0.0 vitest: link:../../packages/vitest @@ -766,6 +766,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 @@ -783,6 +784,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 @@ -7219,7 +7221,7 @@ packages: string.prototype.matchall: 4.0.7 dev: true - /@sveltejs/vite-plugin-svelte/2.0.0_svelte@3.57.0+vite@4.0.0: + /@sveltejs/vite-plugin-svelte/2.0.0_svelte@3.58.0+vite@4.0.0: resolution: {integrity: sha512-oUFrYQarRv4fppmxdrv00qw3wX8Ycdj0uv33MfpRZyR8K67dyxiOcHnqkB0zSy5sDJA8RC/2aNtYhXJ8NINVHQ==} engines: {node: ^14.18.0 || >= 16} peerDependencies: @@ -7230,8 +7232,8 @@ packages: deepmerge: 4.2.2 kleur: 4.1.5 magic-string: 0.27.0 - svelte: 3.57.0 - svelte-hmr: 0.15.1_svelte@3.57.0 + svelte: 3.58.0 + svelte-hmr: 0.15.1_svelte@3.58.0 vite: 4.0.0 vitefu: 0.2.3_vite@4.0.0 transitivePeerDependencies: @@ -7355,14 +7357,14 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: true - /@testing-library/svelte/3.2.2_svelte@3.57.0: + /@testing-library/svelte/3.2.2_svelte@3.58.0: resolution: {integrity: sha512-IKwZgqbekC3LpoRhSwhd0JswRGxKdAGkf39UiDXTywK61YyLXbCYoR831e/UUC6EeNW4hiHPY+2WuovxOgI5sw==} engines: {node: '>= 10'} peerDependencies: svelte: 3.x dependencies: '@testing-library/dom': 8.17.1 - svelte: 3.57.0 + svelte: 3.58.0 dev: true /@testing-library/user-event/13.5.0: @@ -13546,6 +13548,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 @@ -20626,17 +20632,17 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte-hmr/0.15.1_svelte@3.57.0: + /svelte-hmr/0.15.1_svelte@3.58.0: resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: '>=3.19.0' dependencies: - svelte: 3.57.0 + svelte: 3.58.0 dev: true - /svelte/3.57.0: - resolution: {integrity: sha512-WMXEvF+RtAaclw0t3bPDTUe19pplMlfyKDsixbHQYgCWi9+O9VN0kXU1OppzrB9gPAvz4NALuoca2LfW2bOjTQ==} + /svelte/3.58.0: + resolution: {integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==} engines: {node: '>= 8'} dev: true diff --git a/test/reporters/tests/html.test.ts b/test/reporters/tests/html.test.ts index bab25eb8f1c0..716004cce9a7 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`), { encoding: 'base64' }) + const metaJson = zlib.gunzipSync(metaJsonGzipeed).toString() 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`), { encoding: 'base64' }) + const metaJson = zlib.gunzipSync(metaJsonGzipped).toString() 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) })