import { test, expect } from '@playwright/test'; test.describe('Game Analysis Feature', () => { test.beforeEach(async ({ page }) => { // Set a mock API key in localStorage BEFORE any page loads await page.addInitScript(() => { localStorage.setItem('gemini_api_key', 'mock-api-key-for-testing'); }); // Mock the LLM API await page.route('**/api/v1/llm/chat', async (route) => { const request = route.request(); const postData = request.postDataJSON(); let reply = "Let me analyze this position for you."; if (postData.message?.includes('ANALYSIS MODE')) { reply = "I'll help you understand this game. Let's go through it move by move."; } else if (postData.message?.includes('Move')) { reply = "This is an interesting move. Let me explain the key ideas."; } await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ reply }), }); }); }); test('should navigate to analysis mode', async ({ page }) => { // Navigate directly to analysis page await page.goto('/analysis'); // Should be on analysis page await expect(page).toHaveURL('/analysis'); // Should see the chessboard (react-chessboard uses SVG/images, not canvas) // Look for the textarea which is always visible in analysis mode await expect(page.locator('textarea').first()).toBeVisible({ timeout: 10000 }); }); test('should analyze a PGN game', async ({ page }) => { await page.goto('/analysis'); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); // Give Stockfish time to initialize // Should see the chessboard (react-chessboard uses SVG/images, not canvas) await expect(page.locator('textarea').first()).toBeVisible({ timeout: 20000 }); // Should see PGN input const pgnInput = page.locator('textarea').first(); await expect(pgnInput).toBeVisible(); // Enter a simple PGN (just moves) const scholarsPgn = `1. e4 e5 2. Bc4 Nc6 3. Qh5 Nf6`; await pgnInput.fill(scholarsPgn); // Wait for the game to load automatically await page.waitForTimeout(2000); // Should see navigation controls const nextButton = page.locator('button').filter({ has: page.locator('svg') }).filter({ hasText: '' }); // Just verify the textarea is still visible after loading await expect(page.locator('textarea').first()).toBeVisible(); }); test('should analyze a FEN position', async ({ page }) => { await page.goto('/analysis'); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); // Give Stockfish time to initialize const fenInput = page.locator('textarea').first(); // Enter a FEN position await fenInput.fill('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'); // Wait for position to load await page.waitForTimeout(2000); // Should see the chessboard (react-chessboard uses SVG/images, not canvas) await expect(page.locator('textarea').first()).toBeVisible({ timeout: 20000 }); }); test('should navigate through moves in analysis', async ({ page }) => { await page.goto('/analysis'); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); // Give Stockfish time to initialize // Enter a PGN with multiple moves const pgnInput = page.locator('textarea').first(); await pgnInput.fill('1. e4 e5 2. Nf3 Nc6 3. Bb5'); // Wait for game to load await page.waitForTimeout(2000); // Should see the chessboard (react-chessboard uses SVG/images, not canvas) await expect(page.locator('textarea').first()).toBeVisible({ timeout: 20000 }); // Look for navigation buttons (they use icons, not text) const buttons = page.locator('button').filter({ has: page.locator('svg') }); // Just verify we have navigation buttons await expect(buttons.first()).toBeVisible(); }); test('should display analysis interface', async ({ page }) => { await page.goto('/analysis'); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); // Give Stockfish time to initialize // Should see the chessboard (react-chessboard uses SVG/images, not canvas) await expect(page.locator('textarea').first()).toBeVisible({ timeout: 20000 }); // Should see input area await expect(page.locator('textarea').first()).toBeVisible(); // Should see evaluation bar (or check for evaluation-related elements) const evaluationElement = page.locator('text=Evaluation').or(page.locator('[class*="evaluation"]')); if (await evaluationElement.count() > 0) { await expect(evaluationElement.first()).toBeVisible(); } }); test('should allow switching board orientation in analysis', async ({ page }) => { await page.goto('/analysis'); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); // Give Stockfish time to initialize // Should see the chessboard (react-chessboard uses SVG/images, not canvas) await expect(page.locator('textarea').first()).toBeVisible({ timeout: 20000 }); // Look for orientation buttons (White/Black) const whiteButton = page.locator('button').filter({ hasText: /white/i }); const blackButton = page.locator('button').filter({ hasText: /black/i }); // At least one orientation button should be visible const orientationButtons = page.locator('button').filter({ hasText: /white|black/i }); if (await orientationButtons.count() > 0) { await expect(orientationButtons.first()).toBeVisible(); } }); });