#!/usr/bin/env node /** * Capture page screenshot using Playwright. * Logs in and captures the dashboard (or specified path). * * Usage: node scripts/capture-page.mjs [path] * path: optional, e.g. /dashboard, /admin, /contacts (default: /dashboard) * * Requires: npm install -D @playwright/test && npx playwright install chromium */ import { chromium } from 'playwright'; import { writeFileSync, mkdirSync } from 'fs'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const BASE_URL = process.env.CAPTURE_BASE_URL || 'https://zerp.atmata-group.com'; const LOGIN_EMAIL = process.env.CAPTURE_EMAIL || 'admin@system.local'; const LOGIN_PASSWORD = process.env.CAPTURE_PASSWORD || 'Admin@123'; const OUTPUT_DIR = join(__dirname, '..', 'assets'); const DEFAULT_PATH = process.argv[2] || '/dashboard'; async function capture() { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1920, height: 1080 }, ignoreHTTPSErrors: true, }); try { const page = await context.newPage(); // Navigate to login console.log(`Navigating to ${BASE_URL}/login...`); await page.goto(`${BASE_URL}/login`, { waitUntil: 'networkidle', timeout: 30000 }); // Login console.log('Logging in...'); await page.fill('input[type="email"], input[name="email"]', LOGIN_EMAIL); await page.fill('input[type="password"], input[name="password"]', LOGIN_PASSWORD); await page.click('button[type="submit"], button:has-text("تسجيل الدخول"), button:has-text("Login")'); // Wait for redirect to dashboard await page.waitForURL(/\/(dashboard|admin|$)/, { timeout: 15000 }).catch(() => {}); // Navigate to target path if not already there const targetUrl = `${BASE_URL}${DEFAULT_PATH.startsWith('/') ? '' : '/'}${DEFAULT_PATH}`; if (!page.url().includes(DEFAULT_PATH)) { console.log(`Navigating to ${targetUrl}...`); await page.goto(targetUrl, { waitUntil: 'networkidle', timeout: 15000 }); } await page.waitForLoadState('networkidle'); await page.waitForTimeout(2000); // Let any async content render mkdirSync(OUTPUT_DIR, { recursive: true }); const filename = `capture-${DEFAULT_PATH.replace(/\//g, '-') || 'dashboard'}-${Date.now()}.png`; const filepath = join(OUTPUT_DIR, filename); await page.screenshot({ path: filepath, fullPage: true }); console.log(`Screenshot saved: ${filepath}`); // Also save a fixed name for easy reference const latestPath = join(OUTPUT_DIR, 'capture-latest.png'); await page.screenshot({ path: latestPath, fullPage: true }); console.log(`Latest screenshot: ${latestPath}`); } finally { await browser.close(); } } capture().catch((err) => { console.error('Capture failed:', err); process.exit(1); });