import axios from 'axios'; import * as cheerio from 'cheerio'; import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; /** * PageSpeed Test Script * * 1. Fetches sitemap.xml from the target URL * 2. Extracts all URLs * 3. Runs Lighthouse CI on those URLs */ const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'https://testing.klz-cables.com'; const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; // Default limit to avoid infinite runs const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026'; async function main() { console.log(`\n๐Ÿš€ Starting PageSpeed test for: ${targetUrl}`); console.log(`๐Ÿ“Š Limit: ${limit} pages\n`); try { // 1. Fetch Sitemap const sitemapUrl = `${targetUrl.replace(/\/$/, '')}/sitemap.xml`; console.log(`๐Ÿ“ฅ Fetching sitemap from ${sitemapUrl}...`); // We might need to bypass gatekeeper for the sitemap fetch too const response = await axios.get(sitemapUrl, { headers: { 'Cookie': `klz_gatekeeper_session=${gatekeeperPassword}` }, validateStatus: (status) => status < 400 }); const $ = cheerio.load(response.data, { xmlMode: true }); let urls = $('url loc').map((i, el) => $(el).text()).get(); // Cleanup and filter urls = [...new Set(urls)].filter(u => u.startsWith('http')).sort(); console.log(`โœ… Found ${urls.length} URLs in sitemap.`); if (urls.length === 0) { console.error('โŒ No URLs found in sitemap. Is the site up?'); process.exit(1); } if (urls.length > limit) { console.log(`โš ๏ธ Too many pages (${urls.length}). Limiting to ${limit} representative pages.`); // Try to pick a variety: home, some products, some blog posts const home = urls.filter(u => u.endsWith('/de') || u.endsWith('/en') || u === targetUrl); const others = urls.filter(u => !home.includes(u)); urls = [...home, ...others.slice(0, limit - home.length)]; } console.log(`๐Ÿงช Pages to be tested:`); urls.forEach(u => console.log(` - ${u}`)); // 2. Prepare LHCI command // We use --collect.url multiple times const urlArgs = urls.map(u => `--collect.url="${u}"`).join(' '); // Handle authentication for staging/testing // Lighthouse can set cookies via --collect.settings.extraHeaders const extraHeaders = JSON.stringify({ 'Cookie': `klz_gatekeeper_session=${gatekeeperPassword}` }); console.log(`\n๐Ÿ—๏ธ Running Lighthouse CI...`); // Using a more robust way to execute and capture output const lhciCommand = `npx lhci collect ${urlArgs} --collect.settings.chromeFlags='--no-sandbox --disable-setuid-sandbox' --collect.settings.extraHeaders='${extraHeaders}' && npx lhci assert && npx lhci upload`; console.log(`๐Ÿ’ป Executing LHCI...`); try { const output = execSync(lhciCommand, { encoding: 'utf8', stdio: ['inherit', 'pipe', 'inherit'] // Pipe stdout so we can parse it }); console.log(output); // Extract report URL from LHCI output const reportMatch = output.match(/Sent to (https:\/\/storage\.googleapis\.com\/lighthouse-infrastructure\.appspot\.com\/reports\/[^\s]+)/); if (reportMatch && reportMatch[1]) { const reportUrl = reportMatch[1]; console.log(`\n๐Ÿ“Š Report URL: ${reportUrl}`); fs.writeFileSync('pagespeed-report-url.txt', reportUrl); } } catch (err: any) { console.error('โŒ LHCI execution failed.'); if (err.stdout) console.log(err.stdout); if (err.stderr) console.error(err.stderr); throw err; } console.log(`\nโœจ PageSpeed tests completed successfully!`); } catch (error: any) { console.error(`\nโŒ Error during PageSpeed test:`); if (axios.isAxiosError(error)) { console.error(`Status: ${error.response?.status}`); console.error(`StatusText: ${error.response?.statusText}`); console.error(`URL: ${error.config?.url}`); } else { console.error(error.message); } process.exit(1); } } main();