/** * 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, { waitUntil: 'networkidle', 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, '/') // Wait for the app to fully load with network resilience await page.waitForSelector('h1', { timeout: 15000 }) await expect(page.locator('h1')).toContainText('Plex Playlist') }) test('should have welcome message', async ({ page }) => { await navigateWithRetry(page, '/') // Wait for the welcome message to appear with network resilience await page.waitForSelector('p', { timeout: 15000 }) await expect(page.locator('p')).toContainText('Welcome to the Plex Playlist Manager') }) 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, '/') // Wait for app to fully load with extra time for network instability await page.waitForLoadState('networkidle') // Give extra time for any async operations in unstable networks await page.waitForTimeout(process.env.CI ? 3000 : 1000) expect(errors).toHaveLength(0) }) })