//! ๐Ÿ” DEBUGGING COMPREHENSIVE TEST - ROA2WEB Real Issues Detection //! Created: 2025-08-04 //! Purpose: Find and fix REAL problems, not just "passing tests" import { test, expect } from '@playwright/test'; import { LoginPage } from '../page-objects/LoginPage.js'; test.describe('๐Ÿ” ROA2WEB Real Issues Debugging Suite', () => { let loginPage; let networkRequests = []; let consoleErrors = []; let apiResponses = []; test.beforeEach(async ({ page }) => { // Reset monitoring arrays networkRequests = []; consoleErrors = []; apiResponses = []; // Setup comprehensive monitoring page.on('request', request => { networkRequests.push({ url: request.url(), method: request.method(), headers: request.headers(), postData: request.postData(), timestamp: new Date().toISOString() }); }); page.on('response', response => { apiResponses.push({ url: response.url(), status: response.status(), statusText: response.statusText(), headers: response.headers(), timestamp: new Date().toISOString() }); // Log failed requests immediately if (response.status() >= 400) { console.log(`โŒ API Error: ${response.status()} ${response.url()}`); } }); page.on('console', msg => { if (msg.type() === 'error') { const error = { type: msg.type(), text: msg.text(), location: msg.location(), timestamp: new Date().toISOString() }; consoleErrors.push(error); console.log(`๐Ÿ”ฅ Console Error: ${msg.text()}`); } }); page.on('pageerror', err => { consoleErrors.push({ type: 'pageerror', text: err.message, stack: err.stack, timestamp: new Date().toISOString() }); console.log(`๐Ÿ’ฅ Page Error: ${err.message}`); }); loginPage = new LoginPage(page); await loginPage.navigate(); }); test('๐Ÿงช REAL AUTH FLOW - Find FormData vs JSON Issues', async ({ page }) => { console.log('\n๐Ÿ” === TESTING REAL AUTHENTICATION FLOW ==='); // Fill real credentials (update these with actual test credentials) const username = 'test_user'; const password = 'test_password'; await page.fill('#username', username); await page.fill('#password input', password); // Monitor the actual request being sent const [response] = await Promise.all([ page.waitForResponse('**/auth/login'), page.click('button[type="submit"]') ]); // CRITICAL: Analyze the actual request format const request = response.request(); const postData = request.postData(); const contentType = request.headers()['content-type']; console.log('\n๐Ÿ“Š === REQUEST ANALYSIS ==='); console.log('Content-Type:', contentType); console.log('Request Method:', request.method()); console.log('Request Body:', postData); console.log('Response Status:', response.status()); // Check if FormData or JSON is being sent if (contentType && contentType.includes('application/json')) { console.log('โœ… Sending JSON (correct)'); try { const jsonData = JSON.parse(postData); expect(jsonData).toHaveProperty('username'); expect(jsonData).toHaveProperty('password'); } catch (e) { console.log('โŒ Invalid JSON format'); } } else if (contentType && contentType.includes('multipart/form-data')) { console.log('โš ๏ธ Sending FormData (may cause issues)'); } else { console.log('โ“ Unknown content type:', contentType); } // Check response if (response.status() === 422) { const responseBody = await response.text(); console.log('๐Ÿšจ 422 Validation Error:', responseBody); } // Generate comprehensive monitoring report console.log('\n๐Ÿ“ˆ === MONITORING REPORT ==='); console.log(`Network Requests: ${networkRequests.length}`); console.log(`API Responses: ${apiResponses.length}`); console.log(`Console Errors: ${consoleErrors.length}`); // Take screenshot for analysis await page.screenshot({ path: 'debug-auth-flow.png', fullPage: true }); }); test('๐Ÿ”ง LOGIN BUTTON STATE - Debug Disabled Logic', async ({ page }) => { console.log('\n๐Ÿ” === DEBUGGING LOGIN BUTTON STATE ==='); // Test initial state const initialDisabled = await page.locator('button[type="submit"]').isDisabled(); console.log('Initial button disabled:', initialDisabled); // Test empty fields await page.fill('#username', ''); await page.fill('#password input', ''); const emptyFieldsDisabled = await page.locator('button[type="submit"]').isDisabled(); console.log('Empty fields - button disabled:', emptyFieldsDisabled); // Test with only username await page.fill('#username', 'test'); const usernameOnlyDisabled = await page.locator('button[type="submit"]').isDisabled(); console.log('Username only - button disabled:', usernameOnlyDisabled); // Test with both fields await page.fill('#password input', 'password'); const bothFieldsDisabled = await page.locator('button[type="submit"]').isDisabled(); console.log('Both fields - button disabled:', bothFieldsDisabled); // Check form validation state const formValidation = await page.evaluate(() => { const usernameInput = document.getElementById('username'); const passwordInput = document.querySelector('#password input'); const button = document.querySelector('button[type="submit"]'); return { usernameValue: usernameInput?.value, passwordValue: passwordInput?.value, buttonDisabled: button?.disabled, buttonClasses: button?.className, usernameValid: usernameInput?.checkValidity(), passwordValid: passwordInput?.checkValidity() }; }); console.log('Form validation state:', JSON.stringify(formValidation, null, 2)); // Take screenshot of current state await page.screenshot({ path: 'debug-button-state.png' }); }); test('๐Ÿšจ ERROR MESSAGE FORMAT - Debug Toast Issues', async ({ page }) => { console.log('\n๐Ÿ” === DEBUGGING ERROR MESSAGE FORMAT ==='); // Force a network error by using wrong endpoint await page.route('**/auth/login', async route => { await route.fulfill({ status: 500, contentType: 'application/json', body: JSON.stringify({ detail: 'Server error for testing' }) }); }); await page.fill('#username', 'test'); await page.fill('#password input', 'test'); await page.click('button[type="submit"]'); // Wait for error message and analyze its content await page.waitForTimeout(2000); // Wait for toast to appear // Check various possible error message selectors const errorSelectors = [ '.error-message', '.p-toast-message-error', '.p-toast-message-text', '.p-toast-summary', '.p-toast-detail' ]; for (const selector of errorSelectors) { const elements = await page.locator(selector).all(); for (let i = 0; i < elements.length; i++) { const text = await elements[i].textContent(); if (text && text.trim()) { console.log(`Error message found in ${selector}[${i}]:`, text); } } } // Check all visible text content that might contain error messages const allText = await page.evaluate(() => { const textNodes = []; const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, null, false ); let node; while ((node = walker.nextNode())) { const text = node.textContent.trim(); if (text.toLowerCase().includes('eroare') || text.toLowerCase().includes('error') || text.toLowerCase().includes('conectare')) { textNodes.push(text); } } return textNodes; }); console.log('All error-related text found:', allText); // Take screenshot of error state await page.screenshot({ path: 'debug-error-messages.png' }); }); test('๐ŸŒ NETWORK MONITORING - Real API Behavior', async ({ page }) => { console.log('\n๐Ÿ” === COMPREHENSIVE NETWORK MONITORING ==='); // Test various scenarios const testScenarios = [ { name: 'Valid Login', username: 'valid_user', password: 'valid_pass' }, { name: 'Invalid Credentials', username: 'invalid', password: 'invalid' }, { name: 'Empty Credentials', username: '', password: '' } ]; for (const scenario of testScenarios) { console.log(`\n--- Testing: ${scenario.name} ---`); // Clear form await page.fill('#username', ''); await page.fill('#password input', ''); // Fill credentials if provided if (scenario.username) await page.fill('#username', scenario.username); if (scenario.password) await page.fill('#password input', scenario.password); // Reset monitoring arrays for this scenario networkRequests.length = 0; apiResponses.length = 0; consoleErrors.length = 0; // Try to submit (if button is enabled) const isDisabled = await page.locator('button[type="submit"]').isDisabled(); if (!isDisabled) { try { const [response] = await Promise.all([ page.waitForResponse('**/auth/login', { timeout: 5000 }), page.click('button[type="submit"]') ]); console.log(`Response Status: ${response.status()}`); const responseBody = await response.text(); console.log(`Response Body: ${responseBody.substring(0, 200)}...`); } catch (error) { console.log(`No API call made: ${error.message}`); } } else { console.log('Button is disabled - no API call expected'); } // Wait a bit for any async operations await page.waitForTimeout(1000); console.log(`Network requests: ${networkRequests.length}`); console.log(`Console errors: ${consoleErrors.length}`); } }); test.afterEach(async () => { // Generate final report console.log('\n๐Ÿ“‹ === FINAL TEST REPORT ==='); console.log(`Total Network Requests: ${networkRequests.length}`); console.log(`Total API Responses: ${apiResponses.length}`); console.log(`Total Console Errors: ${consoleErrors.length}`); if (consoleErrors.length > 0) { console.log('\n๐Ÿšจ Console Errors Found:'); consoleErrors.forEach((error, index) => { console.log(`${index + 1}. ${error.text}`); }); } if (apiResponses.some(r => r.status >= 400)) { console.log('\nโŒ Failed API Requests:'); apiResponses .filter(r => r.status >= 400) .forEach(response => { console.log(`${response.status} ${response.url}`); }); } }); });