import {test,expect} from '@playwright/test'; import jsQR from 'jsqr'; import {PNG} from 'pngjs'; import fs from 'node:fs'; const url='https://huggingface.co/datasets/evalstate/mcp-clients'; test('themes scan, export and validate; responsive layout',async({page})=>{ await page.setViewportSize({width:1440,height:1150}); await page.goto('http://localhost:5173'); await expect(page.locator('#qr svg')).toBeVisible(); for(const theme of ['phosphor','amber','ice']){ await page.locator(`[data-theme=${theme}]`).click(); await page.screenshot({path:`previews/${theme}.png`,fullPage:true}); const downloadPromise=page.waitForEvent('download');await page.locator('#png').click(); const download=await downloadPromise;await download.saveAs(`previews/qr-${theme}.png`); const png=PNG.sync.read(fs.readFileSync(`previews/qr-${theme}.png`)); const decoded=jsQR(new Uint8ClampedArray(png.data),png.width,png.height); expect(decoded?.data).toBe(url); } const svgDownload=page.waitForEvent('download');await page.locator('#svg').click();await (await svgDownload).saveAs('previews/qr-ice.svg'); await page.locator('#url').fill('javascript:alert(1)');await expect(page.locator('#png')).toBeDisabled();await expect(page.locator('#qr svg')).toHaveCount(0); await page.locator('#url').fill(url);await page.locator('#logo').uncheck();await expect(page.locator('#qr image')).toHaveCount(0); await page.locator('#logo').check();await page.locator('[data-theme=phosphor]').click(); await page.setViewportSize({width:390,height:844});await page.screenshot({path:'previews/mobile.png',fullPage:true}); expect(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth)).toBe(true); }); test('logo sizes and optional custom header exports scan',async({page})=>{ await page.goto('http://localhost:5173');await expect(page.locator('#qr svg')).toBeVisible(); await page.locator('#header-text').fill('MY DATASET & FRIENDS'); await expect(page.locator('#header-preview')).toHaveText('MY DATASET & FRIENDS'); for(const theme of ['phosphor','amber','ice']){ await page.locator(`[data-theme=${theme}]`).click(); for(const size of [12,17,22,26]){ await page.locator('#logo-size').fill(String(size)); await expect(page.locator('#size-value')).toHaveText(`${size}%`); const pending=page.waitForEvent('download');await page.locator('#png').click();const file=await (await pending).path(); const png=PNG.sync.read(fs.readFileSync(file));expect(png.height).toBe(1136);expect(jsQR(new Uint8ClampedArray(png.data),png.width,png.height)?.data).toBe(url); } } const pending=page.waitForEvent('download');await page.locator('#svg').click();const text=fs.readFileSync(await (await pending).path(),'utf8');expect(text).toContain('MY DATASET <HF> & FRIENDS');expect(text).not.toContain('SCAN TO CONNECT'); await page.locator('#include-header').uncheck();await expect(page.locator('.card-top')).toBeHidden();await expect(page.locator('#header-text')).toBeDisabled(); const bare=page.waitForEvent('download');await page.locator('#png').click();const png=PNG.sync.read(fs.readFileSync(await (await bare).path()));expect(png.height).toBe(1024);expect(jsQR(new Uint8ClampedArray(png.data),png.width,png.height)?.data).toBe(url); await page.locator('#logo').uncheck();await expect(page.locator('#logo-size')).toBeDisabled(); });