76 lines
3.3 KiB
TypeScript
76 lines
3.3 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
import JSZip from 'jszip'
|
|
|
|
const builderUrl = '/en/builder'
|
|
type WindowWithExport = Window & {
|
|
__captureExport?: boolean
|
|
__lastExport?: { html: string; css: string; js: string }
|
|
__lastBlob?: Blob
|
|
__exportPreview?: () => { html: string; css: string; js: string }
|
|
}
|
|
|
|
test('Export ZIP contains expected SEO/OG/Analytics meta in index.html', async ({ page }) => {
|
|
await page.goto(builderUrl)
|
|
// enable capture hook in app
|
|
await page.evaluate(() => {
|
|
const w = window as unknown as WindowWithExport
|
|
w.__captureExport = true
|
|
w.__lastBlob = undefined
|
|
})
|
|
|
|
// set SEO/Analytics/OG values
|
|
await page.getByLabel('SEO Title').fill('E2E SEO Title')
|
|
await page.getByLabel('SEO Description').fill('E2E SEO Description')
|
|
await page.getByLabel('OG Image URL').fill('https://example.com/e2e-og.png')
|
|
await page.getByLabel('GA4 Measurement ID').fill('G-E2E1234567')
|
|
await page.getByLabel('Meta Pixel ID').fill('9876543210')
|
|
|
|
// Prefer calling exporter directly for deterministic output
|
|
const exported = await page.evaluate(() => (window as unknown as WindowWithExport).__exportPreview?.() ?? null)
|
|
let indexHtml: string | null = exported?.html ?? null
|
|
|
|
// Fallback: also click Export to exercise button and capture via test hook
|
|
if (!indexHtml) {
|
|
await page.getByRole('button', { name: /Export/i }).click()
|
|
await page.waitForFunction(() => {
|
|
const w = window as unknown as WindowWithExport
|
|
return Boolean(w.__lastExport || w.__lastBlob)
|
|
}, { timeout: 20000 })
|
|
const exp2 = await page.evaluate(() => (window as unknown as WindowWithExport).__lastExport ?? null)
|
|
indexHtml = exp2?.html ?? null
|
|
}
|
|
|
|
// if not present, fall back to reading from ZIP blob (slower)
|
|
if (!indexHtml) {
|
|
await page.waitForFunction(() => Boolean((window as unknown as WindowWithExport).__lastBlob), { timeout: 20000 })
|
|
const base64 = await page.evaluate(async () => {
|
|
const blob: Blob | undefined = (window as unknown as WindowWithExport).__lastBlob
|
|
if (!blob) return null
|
|
const ab = await blob.arrayBuffer()
|
|
const bytes = new Uint8Array(ab)
|
|
return btoa(String.fromCharCode(...bytes))
|
|
})
|
|
expect(base64, 'export blob should be captured').not.toBeNull()
|
|
const buf = Buffer.from(base64 as string, 'base64')
|
|
const zip = await JSZip.loadAsync(buf)
|
|
const index = zip.file('index.html')
|
|
expect(index, 'index.html exists in zip').toBeTruthy()
|
|
indexHtml = await index!.async('string')
|
|
}
|
|
// assert we have HTML
|
|
expect(indexHtml).not.toBeNull()
|
|
|
|
// assertions: language, title/description, og tags, GA4 id presence
|
|
expect(indexHtml!).toContain('<html lang="en">')
|
|
expect(indexHtml!).toContain('<meta name="description" content="E2E SEO Description" />')
|
|
expect(indexHtml!).toContain('<meta property="og:title" content="E2E SEO Title" />')
|
|
expect(indexHtml!).toContain('<meta property="og:description" content="E2E SEO Description" />')
|
|
expect(indexHtml!).toContain('<meta property="og:image" content="https://example.com/e2e-og.png" />')
|
|
expect(indexHtml!).toContain('G-E2E1234567')
|
|
expect(indexHtml!).toContain('9876543210')
|
|
|
|
// accessibility scaffolding in exported HTML
|
|
expect(indexHtml!).toContain('<a href="#main" class="skip-link">')
|
|
expect(indexHtml!).toContain('<main id="main" role="main">')
|
|
})
|