Files
Pulse/scripts/take-all-screenshots.js
2025-10-11 23:29:47 +00:00

238 lines
7.5 KiB
JavaScript

const { chromium, devices } = require('@playwright/test');
const fs = require('fs').promises;
const path = require('path');
const PULSE_URL = process.env.PULSE_URL || 'http://localhost:7655';
const OUTPUT_DIR = path.join(__dirname, '..', 'docs', 'images');
async function ensureOutputDir() {
try {
await fs.mkdir(OUTPUT_DIR, { recursive: true });
} catch (error) {
console.error('Error creating output directory:', error);
}
}
async function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function takeScreenshot(page, name, options = {}) {
const { selector = null, fullPage = false } = options;
await wait(1500); // Wait for animations
let screenshotOptions = {
type: 'png',
path: path.join(OUTPUT_DIR, `${name}.png`)
};
if (selector) {
const element = await page.locator(selector).first();
await element.waitFor({ state: 'visible', timeout: 10000 });
screenshotOptions = {
...screenshotOptions,
clip: await element.boundingBox()
};
} else if (fullPage) {
screenshotOptions.fullPage = true;
}
await page.screenshot(screenshotOptions);
console.log(`✅ Saved ${name}.png`);
}
async function clickAndWait(page, selector, waitTime = 1000) {
try {
const element = page.locator(selector).first();
if (await element.count() > 0) {
await element.click();
await wait(waitTime);
return true;
}
} catch (e) {
console.log(`Could not click ${selector}: ${e.message}`);
}
return false;
}
async function ensureDarkTheme(page) {
try {
// Wait a bit for theme system to initialize
await wait(1000);
// First check if we're already in dark mode
const isDarkMode = await page.evaluate(() => {
return document.documentElement.classList.contains('dark');
});
console.log(`Current theme mode: ${isDarkMode ? 'dark' : 'light'}`);
if (!isDarkMode) {
// Try to find and click the theme toggle
// Look for common theme toggle selectors
const themeSelectors = [
'button[aria-label="Toggle theme"]',
'button[title*="theme" i]',
'button[aria-label*="theme" i]',
'button:has(svg[class*="moon"])',
'button:has(svg[class*="sun"])',
'.theme-toggle',
'button:has-text("Theme")',
'[data-theme-toggle]'
];
for (const selector of themeSelectors) {
try {
const element = page.locator(selector).first();
if (await element.count() > 0) {
await element.click();
await wait(1000); // Wait for theme transition
// Verify dark mode is now active
const nowDark = await page.evaluate(() => {
return document.documentElement.classList.contains('dark');
});
if (nowDark) {
console.log('✅ Successfully switched to dark theme');
return;
}
}
} catch (e) {
// Continue trying other selectors
}
}
// If no toggle found, try to force dark mode via localStorage or class
await page.evaluate(() => {
document.documentElement.classList.remove('light');
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
localStorage.setItem('pulse-theme', 'dark');
});
console.log('⚠️ Forced dark mode via DOM manipulation');
} else {
console.log('✅ Already in dark mode');
}
} catch (e) {
console.log('Could not set dark theme:', e.message);
}
}
async function main() {
await ensureOutputDir();
const browser = await chromium.launch({
headless: true
});
// Desktop screenshots
const desktopContext = await browser.newContext({
viewport: { width: 1440, height: 900 }
});
const page = await desktopContext.newPage();
try {
console.log(`📸 Starting screenshot capture for ${PULSE_URL}`);
// Navigate to Pulse
await page.goto(PULSE_URL, { waitUntil: 'networkidle' });
await wait(3000);
// Ensure dark theme
await ensureDarkTheme(page);
// 1. Dashboard Screenshot
console.log('📸 Capturing dashboard...');
await takeScreenshot(page, '01-dashboard');
// 2. Storage View
console.log('📸 Capturing storage view...');
const storageClicked = await clickAndWait(page, 'button:has-text("Storage"), a:has-text("Storage"), [role="tab"]:has-text("Storage")', 2000);
if (storageClicked) {
await takeScreenshot(page, '02-storage');
}
// 3. Backups View
console.log('📸 Capturing backups view...');
const backupsClicked = await clickAndWait(page, 'button:has-text("Backups"), a:has-text("Backups"), [role="tab"]:has-text("Backups")', 2000);
if (backupsClicked) {
await takeScreenshot(page, '03-backups');
}
// 4. Alerts View
console.log('📸 Capturing alerts view...');
const alertsClicked = await clickAndWait(page, 'button:has-text("Alerts"), a:has-text("Alerts"), [role="tab"]:has-text("Alerts")', 2000);
if (alertsClicked) {
await takeScreenshot(page, '04-alerts');
// 5. Try to capture Alert History if available
console.log('📸 Looking for alert history...');
const historyClicked = await clickAndWait(page, 'button:has-text("History"), button:has-text("Alert History"), [role="tab"]:has-text("History")', 2000);
if (historyClicked) {
await takeScreenshot(page, '05-alert-history');
} else {
// If no history tab, just use alerts view
await fs.copyFile(
path.join(OUTPUT_DIR, '04-alerts.png'),
path.join(OUTPUT_DIR, '05-alert-history.png')
);
console.log('✅ Used alerts view for alert history');
}
}
// 6. Settings View
console.log('📸 Capturing settings view...');
const settingsClicked = await clickAndWait(page, 'button:has-text("Settings"), a:has-text("Settings"), [aria-label="Settings"], .settings-icon', 2000);
if (settingsClicked) {
await takeScreenshot(page, '06-settings');
} else {
// Try clicking a gear icon
await clickAndWait(page, 'svg[class*="settings"], svg[class*="gear"], button:has(svg[class*="settings"])', 2000);
await takeScreenshot(page, '06-settings');
}
// 7. Dark Mode Screenshot (go back to dashboard for a clean dark mode shot)
console.log('📸 Capturing dark mode view...');
await clickAndWait(page, 'button:has-text("Dashboard"), a:has-text("Dashboard"), [role="tab"]:has-text("Dashboard")', 2000);
await wait(1000);
await takeScreenshot(page, '07-dark-mode');
// Close desktop context
await desktopContext.close();
// 8. Mobile Screenshot
console.log('📸 Capturing mobile view...');
const mobileContext = await browser.newContext({
...devices['iPhone 12'],
viewport: { width: 390, height: 844 }
});
const mobilePage = await mobileContext.newPage();
await mobilePage.goto(PULSE_URL, { waitUntil: 'networkidle' });
await wait(2000);
// Ensure dark theme on mobile
await ensureDarkTheme(mobilePage);
await takeScreenshot(mobilePage, '08-mobile');
await mobileContext.close();
console.log('✨ Screenshot capture complete!');
console.log(`📁 Screenshots saved to: ${OUTPUT_DIR}`);
} catch (error) {
console.error('❌ Error during screenshot capture:', error);
// Take error screenshot
await takeScreenshot(page, 'error-state');
} finally {
await browser.close();
}
}
// Run the script
main().catch(console.error);