mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
58 lines
2.8 KiB
TypeScript
58 lines
2.8 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { extractStaticAssets, verifyLocalExport } from '../../scripts/verify-export.mjs'
|
|
|
|
test('extractStaticAssets reconstructs split Flight chunk names as well as script and link tags', () => {
|
|
const html = [
|
|
'<!DOCTYPE html><html><head>',
|
|
'<link rel="stylesheet" href="/_next/static/chunks/05rbc.css?dpl=1"/>',
|
|
'<script src="/_next/static/chunks/main-app.js" async=""></script>',
|
|
'</head><body>',
|
|
'<script>self.__next_f.push([1,"[\\"/_next/static/chunks/split-chunk."])</script><script>self.__next_f.push([1,"js\\",\\"/_next/static/media/font.woff2\\"]"])</script>',
|
|
'</body></html>',
|
|
].join('')
|
|
|
|
expect(extractStaticAssets(html).sort()).toEqual([
|
|
'/_next/static/chunks/05rbc.css',
|
|
'/_next/static/chunks/main-app.js',
|
|
'/_next/static/chunks/split-chunk.js',
|
|
'/_next/static/media/font.woff2',
|
|
])
|
|
})
|
|
|
|
test('verifyLocalExport catches missing chunks, zero-byte chunks, and missing entry pages', async () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'hz-export-test-'))
|
|
try {
|
|
mkdirSync(join(dir, '_next', 'static', 'chunks'), { recursive: true })
|
|
const validHtml =
|
|
'<!DOCTYPE html><html><head><link rel="stylesheet" href="/_next/static/chunks/site.css"/><script src="/_next/static/chunks/app.js"></script></head><body>ok</body></html>'
|
|
for (const page of ['index.html', '404.html', 'beta.html', 'pricing.html', 'login.html']) {
|
|
writeFileSync(join(dir, page), validHtml)
|
|
}
|
|
writeFileSync(join(dir, '_next', 'static', 'chunks', 'app.js'), 'console.log(1)')
|
|
writeFileSync(join(dir, '_next', 'static', 'chunks', 'site.css'), 'body{}')
|
|
|
|
const clean = await verifyLocalExport(dir, { minHtmlPages: 5 })
|
|
expect(clean.errors).toEqual([])
|
|
expect(clean.assetCount).toBe(2)
|
|
|
|
// Zero-byte CSS chunk fails pre-publish verification
|
|
writeFileSync(join(dir, '_next', 'static', 'chunks', 'site.css'), '')
|
|
const emptyCss = await verifyLocalExport(dir, { minHtmlPages: 5 })
|
|
expect(emptyCss.errors.some((e) => e.includes('site.css') && e.includes('0 bytes'))).toBe(true)
|
|
|
|
// Missing JS chunk referenced in Flight payload fails pre-publish verification
|
|
writeFileSync(join(dir, '_next', 'static', 'chunks', 'site.css'), 'body{}')
|
|
writeFileSync(
|
|
join(dir, 'beta.html'),
|
|
validHtml + '<script>self.__next_f.push([1,"\\"/_next/static/chunks/missing-lazy.js\\""])</script>',
|
|
)
|
|
const missingJs = await verifyLocalExport(dir, { minHtmlPages: 5 })
|
|
expect(missingJs.errors.some((e) => e.includes('missing-lazy.js') && e.includes('missing from export'))).toBe(true)
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true })
|
|
}
|
|
})
|