All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 4m39s
Build & Deploy / 🧪 QA (push) Successful in 2m31s
Build & Deploy / 🏗️ Build (push) Successful in 5m23s
Build & Deploy / 🚀 Deploy (push) Successful in 50s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 3s
110 lines
4.0 KiB
TypeScript
110 lines
4.0 KiB
TypeScript
import puppeteer from 'puppeteer';
|
|
|
|
const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
|
|
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026';
|
|
|
|
async function run() {
|
|
console.log(`🚀 Smoke Test: ${targetUrl}`);
|
|
|
|
const browser = await puppeteer.launch({
|
|
headless: true,
|
|
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || undefined,
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
});
|
|
const page = await browser.newPage();
|
|
|
|
try {
|
|
// 1. Login via Gatekeeper
|
|
console.log('🔑 Authenticating...');
|
|
await page.goto(targetUrl, { waitUntil: 'networkidle2' });
|
|
|
|
const isGatekeeper = await page.$('input[name="password"]');
|
|
if (isGatekeeper) {
|
|
await page.type('input[name="password"]', gatekeeperPassword);
|
|
await Promise.all([
|
|
page.waitForNavigation({ waitUntil: 'networkidle2' }),
|
|
page.click('button[type="submit"]'),
|
|
]);
|
|
}
|
|
|
|
// 2. Check Key Pages & Assets
|
|
const pages = ['/', '/de/kontakt', '/en/contact', '/de/blog'];
|
|
for (const p of pages) {
|
|
console.log(`📄 Checking ${p}...`);
|
|
const res = await page.goto(`${targetUrl}${p}`, { waitUntil: 'domcontentloaded' });
|
|
const status = res?.status();
|
|
if (status !== 200 && status !== 304 && status !== 307 && status !== 308) {
|
|
throw new Error(`Page ${p} returned ${status}`);
|
|
}
|
|
|
|
// Check for broken images (using in-page fetch to preserve session and avoid heavy navigation)
|
|
const images = await page.$$eval('img', (imgs) => imgs.map((img) => img.src).filter(Boolean));
|
|
console.log(` Checking ${images.length} images...`);
|
|
|
|
const brokenImages = await page.evaluate(async (urls) => {
|
|
const broken: string[] = [];
|
|
await Promise.all(
|
|
urls.map(async (url) => {
|
|
if (url.includes('openstreetmap.org') || url.includes('unpkg.com')) return;
|
|
try {
|
|
const res = await fetch(url, { method: 'HEAD' });
|
|
if (res.status >= 400) {
|
|
// Diagnostic: check if the raw source is available
|
|
const rawUrlMatch = url.match(/[?&]url=([^&]+)/);
|
|
if (rawUrlMatch) {
|
|
const rawPath = decodeURIComponent(rawUrlMatch[1]);
|
|
const baseUrl = new URL(url).origin;
|
|
const rawUrl = `${baseUrl}${rawPath}`;
|
|
const rawRes = await fetch(rawUrl, { method: 'HEAD' });
|
|
broken.push(`${url} (Status: ${res.status}, Raw Status: ${rawRes.status})`);
|
|
} else {
|
|
broken.push(`${url} (Status: ${res.status})`);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
broken.push(`${url} (Fetch failed)`);
|
|
}
|
|
}),
|
|
);
|
|
return broken;
|
|
}, images);
|
|
|
|
if (brokenImages.length > 0) {
|
|
throw new Error(
|
|
`Found ${brokenImages.length} broken images on ${p}:\n${brokenImages.join('\n')}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
// 3. Test Contact Form
|
|
console.log('📝 Testing Contact Form...');
|
|
await page.goto(`${targetUrl}/de/kontakt`, { waitUntil: 'networkidle2' });
|
|
|
|
await page.type('input[name="name"]', 'Smoke Test');
|
|
await page.type('input[name="email"]', 'smoke@mintel.me');
|
|
await page.type('textarea[name="message"]', 'Automated smoke test submission.');
|
|
|
|
await Promise.all([
|
|
page.waitForSelector('[role="alert"]', { timeout: 10000 }),
|
|
page.click('button[type="submit"]'),
|
|
]);
|
|
|
|
const alertText = await page.$eval('[role="alert"]', (el) => el.textContent);
|
|
console.log(`🔔 Alert: ${alertText}`);
|
|
|
|
if (alertText?.toLowerCase().includes('error') || alertText?.toLowerCase().includes('fehler')) {
|
|
throw new Error(`Form submission failed: ${alertText}`);
|
|
}
|
|
|
|
console.log('✅ Smoke test passed!');
|
|
process.exit(0);
|
|
} catch (err: any) {
|
|
console.error(`❌ Smoke test failed: ${err.message}`);
|
|
process.exit(1);
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
run();
|