/** * End-to-end tests using Playwright */ import { test, expect } from '@playwright/test'; // Helper function for network-resilient page navigation async function navigateWithRetry(page: any, url: string, maxRetries = 3): Promise { for (let i = 0; i < maxRetries; i++) { try { await page.goto(url, { // Vite dev server maintains long-lived connections, so networkidle can flake in CI. waitUntil: 'domcontentloaded', timeout: process.env.CI ? 45000 : 30000, }); return; // Success } catch (error) { if (i === maxRetries - 1) throw error; // Last attempt failed console.log(`Navigation attempt ${i + 1} failed, retrying...`); await page.waitForTimeout(2000); // Wait before retry } } } test.describe('Plex Playlist App', () => { test('should display app title', async ({ page }) => { await navigateWithRetry(page, '/'); await expect(page.getByRole('heading', { level: 1 })).toHaveText('Plex Playlist'); }); test('should have welcome message', async ({ page }) => { await navigateWithRetry(page, '/'); await expect(page.getByText('Welcome to the Plex Playlist Manager')).toBeVisible(); }); test('should load without errors', async ({ page }) => { const errors: string[] = []; page.on('console', (msg) => { if (msg.type() === 'error') { // Filter out network-related errors that are acceptable in CI const errorText = msg.text(); if (!errorText.includes('net::') && !errorText.includes('Failed to fetch')) { errors.push(errorText); } } }); await navigateWithRetry(page, '/'); // Ensure document and app shell are loaded before checking browser errors. await page.waitForLoadState('domcontentloaded'); await expect(page.getByRole('heading', { level: 1 })).toBeVisible(); // Give extra time for any async operations in unstable networks await page.waitForTimeout(process.env.CI ? 3000 : 1000); expect(errors).toHaveLength(0); }); });