52 lines
3.5 KiB
JavaScript
52 lines
3.5 KiB
JavaScript
// Screenshots and checks of the store gallery pages (/themes/, /plugins/) of the built site.
|
|
// Usage: (cd apps/web && bun run build && npx vite preview --port 1481) then
|
|
// node scripts/gallery-shots.mjs [baseUrl] [outDir]
|
|
import { chromium } from 'playwright';
|
|
import { mkdirSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
|
|
const base = process.argv[2] ?? 'http://127.0.0.1:1481';
|
|
const out = process.argv[3] ?? join(import.meta.dirname, '..', '..', '..', 'verification', 'store');
|
|
mkdirSync(out, { recursive: true });
|
|
const failures = [];
|
|
const check = (label, ok, detail = '') => { console.log(`${ok ? 'ok ' : 'FAIL'} ${label}${detail ? ` (${detail})` : ''}`); if (!ok) failures.push(label); };
|
|
const browser = await chromium.launch();
|
|
for (const [page, kind] of [['themes', 'theme'], ['plugins', 'plugin']]) {
|
|
for (const [label, viewport] of [['desktop', { width: 1360, height: 1000 }], ['mobile', { width: 390, height: 844 }]]) {
|
|
const tab = await browser.newPage({ viewport });
|
|
const broken = [];
|
|
tab.on('response', res => { if (res.status() >= 400) broken.push(`${res.status()} ${res.url()}`); });
|
|
tab.on('pageerror', error => failures.push(`${page}: ${error.message}`));
|
|
await tab.goto(`${base}/${page}/`);
|
|
await tab.waitForLoadState('networkidle');
|
|
const cards = await tab.locator('.gal-card').count();
|
|
const links = await tab.locator('a[href^="waybetter://install?kind="]').evaluateAll(as => as.map(a => a.getAttribute('href')));
|
|
const images = await tab.locator('.gal-img').evaluateAll(imgs => imgs.filter(img => img.naturalWidth === 0).length);
|
|
if (label === 'desktop') {
|
|
check(`${page}: cards`, cards >= (kind === 'theme' ? 13 : 14), `${cards}`);
|
|
check(`${page}: every card has an install link`, links.length === cards && links.every(href => href.startsWith(`waybetter://install?kind=${kind}&url=https%3A%2F%2Fwaybetter.fyi%2Fstore%2F`)));
|
|
check(`${page}: previews load`, images === 0, `${images} broken`);
|
|
check(`${page}: no 4xx/5xx`, broken.filter(b => !b.includes('/v1/')).length === 0, broken.join(', '));
|
|
check(`${page}: downloads point at the store files`, (await tab.locator('a[download]').count()) === cards);
|
|
if (kind === 'plugin') check('plugins: permission chips', (await tab.locator('.gal-perms li').count()) >= cards);
|
|
}
|
|
check(`${page} ${label}: no horizontal scroll`, await tab.evaluate(() => document.documentElement.scrollWidth <= innerWidth + 1));
|
|
await tab.screenshot({ path: join(out, `site-${page}-${label}.png`), fullPage: label === 'desktop' ? false : false });
|
|
if (label === 'desktop') {
|
|
await tab.locator('.gal-filters button').nth(1).click();
|
|
const shown = await tab.locator('.gal-card:not([hidden])').count();
|
|
check(`${page}: category filter`, shown > 0 && shown < cards, `${shown}`);
|
|
await tab.locator('.gal-filters button').first().click();
|
|
await tab.locator('[data-gallery-search]').fill(kind === 'theme' ? 'nord' : 'regex');
|
|
check(`${page}: search`, (await tab.locator('.gal-card:not([hidden])').count()) === 1);
|
|
await tab.locator('[data-gallery-search]').fill('');
|
|
await tab.evaluate(() => scrollTo(0, 560));
|
|
await tab.waitForTimeout(200);
|
|
await tab.screenshot({ path: join(out, `site-${page}-grid.png`) });
|
|
}
|
|
await tab.close();
|
|
}
|
|
}
|
|
await browser.close();
|
|
console.log(failures.length ? `\n${failures.length} failure(s):\n- ${failures.join('\n- ')}` : '\nall checks passed');
|
|
process.exit(failures.length ? 1 : 0);
|