Shumiland/scripts/check-browser.mjs
Vadym Samoilenko cca4ea1d55
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
feat: implement full frontend — all sections, components, Figma Code Connect
- All 8 home page sections: Hero, Locations slider, WhyParents accordion,
  Birthday pricing cards, Video, Gallery, Reviews slider, News
- UI components: NavLink, BtnPrimary, BtnGradient, BtnDetails, AccordionItem
- Layout: sticky Header (NavLink + BtnPrimary), Footer with logo
- Figma Code Connect: 5 components published (.figma.tsx + figma.config.json)
- Public assets: all Figma images and SVGs exported
- Pages: /kvytky, /lokatsii, /blog, /dni-narodzhennia, /grupovi-vidviduvannia
- Tests: Vitest unit/api suites, Playwright e2e screenshots
- Payload CMS: blocks, collections, seed data updates
- Hero negative-margin to extend behind sticky header
- Custom Tailwind breakpoints: lg=1440px, xl=1920px
- Fix ESLint config: drop FlatCompat, use eslint-config-next flat export
- Add tsconfig.tsbuildinfo, test-results/, agentdb.rvf* to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 16:40:56 +01:00

71 lines
2.6 KiB
JavaScript

import { chromium } from '@playwright/test'
import { existsSync, mkdirSync } from 'fs'
const PAGES = [
{ name: 'home', url: 'http://localhost:3000/' },
{ name: 'kvytky', url: 'http://localhost:3000/kvytky' },
{ name: 'checkout', url: 'http://localhost:3000/kvytky/checkout?tariff=123' },
{ name: 'lokatsii', url: 'http://localhost:3000/lokatsii' },
{ name: 'blog', url: 'http://localhost:3000/blog' },
{ name: 'birthday', url: 'http://localhost:3000/dni-narodzhennia' },
]
const SHOTS_DIR = '/tmp/shumiland-shots'
if (!existsSync(SHOTS_DIR)) mkdirSync(SHOTS_DIR, { recursive: true })
const browser = await chromium.launch({ headless: true })
const context = await browser.newContext({ viewport: { width: 1440, height: 900 } })
for (const { name, url } of PAGES) {
const page = await context.newPage()
const errors = []
const failedReqs = []
page.on('console', (msg) => {
if (msg.type() === 'error') errors.push(msg.text())
})
page.on('pageerror', (err) => errors.push(err.message))
page.on('requestfailed', (req) => {
failedReqs.push(`${req.url()}`)
})
console.log(`\n📸 ${url}`)
try {
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 15000 })
await page.waitForTimeout(2000)
const bgColor = await page.evaluate(() =>
window.getComputedStyle(document.body).backgroundColor,
)
const hasHeader = (await page.locator('header').count()) > 0
const hasFooter = (await page.locator('footer').count()) > 0
const imgStats = await page.evaluate(() => {
const imgs = Array.from(document.images)
return {
total: imgs.length,
failed: imgs
.filter((i) => !i.complete || i.naturalWidth === 0)
.map((i) => i.src)
.slice(0, 5),
}
})
console.log(` bg: ${bgColor} | header: ${hasHeader ? '✓' : '✗'} | footer: ${hasFooter ? '✓' : '✗'}`)
console.log(` images: ${imgStats.total} total, ${imgStats.failed.length} failed`)
if (imgStats.failed.length > 0) imgStats.failed.forEach((s) => console.log(`${s.slice(0, 80)}`))
if (errors.length > 0) errors.slice(0, 5).forEach((e) => console.log(` [ERR] ${e.slice(0, 120)}`))
if (failedReqs.length > 0) {
const cssOrJs = failedReqs.filter((r) => r.includes('.css') || r.includes('.js'))
if (cssOrJs.length > 0) cssOrJs.forEach((r) => console.log(` [FAIL REQ] ${r.slice(0, 100)}`))
}
await page.screenshot({ path: `${SHOTS_DIR}/${name}.png`, fullPage: false })
console.log(` screenshot → ${SHOTS_DIR}/${name}.png`)
} catch (e) {
console.log(` ERROR: ${e.message}`)
}
await page.close()
}
await browser.close()
console.log('\nDone.')