import { test, expect, type Response, type ConsoleMessage } from '@playwright/test'; test.describe('Homepage Links Test', () => { test('Click all links on homepage and check for errors', async ({ page }) => { // Listen for failed requests (e.g., 404s) const failedRequests: { url: string; status: number }[] = []; page.on('response', response => { if (response.status() >= 400) { failedRequests.push({ url: response.url(), status: response.status() }); } }); // Listen for console errors const consoleErrors: string[] = []; page.on('console', msg => { if (msg.type() === 'error') { consoleErrors.push(msg.text()); } }); // Navigate to homepage await page.goto('/'); // Wait for page to load await page.waitForLoadState('networkidle'); // Get all links const links = page.locator('a'); const linkCount = await links.count(); console.log(`Found ${linkCount} links on homepage.`); for (let i = 0; i < linkCount; i++) { const link = links.nth(i); const href = await link.getAttribute('href'); const text = await link.textContent() || ''; if (!href || href.startsWith('#') || href.startsWith('mailto:') || href.startsWith('tel:')) { console.log(`Skipping non-navigational link: ${text} (${href})`); continue; } console.log(`Clicking link ${i + 1}/${linkCount}: "${text}" -> ${href}`); // For each link, create temporary listeners const linkFailedRequests: { url: string; status: number }[] = []; const linkConsoleErrors: string[] = []; const linkResponseHandler = (response: Response) => { if (response.status() >= 400) { linkFailedRequests.push({ url: response.url(), status: response.status() }); } }; const linkConsoleHandler = (msg: ConsoleMessage) => { if (msg.type() === 'error') { linkConsoleErrors.push(msg.text()); } }; page.on('response', linkResponseHandler); page.on('console', linkConsoleHandler); let currentUrl = page.url(); try { // Hover and click await link.hover(); await link.click({ force: true }); // Wait for navigation or load await page.waitForTimeout(2000); currentUrl = page.url(); // Remove temporary handlers page.removeListener('response', linkResponseHandler); page.removeListener('console', linkConsoleHandler); // Check for errors during this click expect(linkFailedRequests.length).toBe(0); expect(linkConsoleErrors.length).toBe(0); console.log(`✓ Link "${text}" successful: ${currentUrl}`); } catch (error: unknown) { // Remove handlers page.removeListener('response', linkResponseHandler); page.removeListener('console', linkConsoleHandler); console.error(`✗ Error clicking link "${text}": ${(error as Error).message}`); } // Go back to homepage if navigated away if (currentUrl !== page.url() && !currentUrl.includes('/')) { await page.goBack({ waitUntil: 'networkidle' }); } } // Final checks expect(failedRequests.length).toBe(0); expect(consoleErrors.length).toBe(0); console.log('All links tested successfully.'); }); });