const puppeteer = require('puppeteer'); const AuthHelper = require('./auth_helper'); const { getPuppeteerLaunchOptions } = require('./puppeteer_config'); async function testResearchResults() { console.log('šŸ” Testing research results error handling and structure...'); // Skip this test in CI if it's known to be unstable if (process.env.CI && process.env.SKIP_FLAKY_TESTS) { console.log('āš ļø Skipping flaky test in CI environment'); return true; } // CI runners can be slow; align navigation timeouts with other UI tests. const navTimeout = process.env.CI ? 30000 : 10000; const browser = await puppeteer.launch(getPuppeteerLaunchOptions()); const page = await browser.newPage(); const baseUrl = 'http://127.0.0.1:5000'; const authHelper = new AuthHelper(page, baseUrl); await page.setViewport({ width: 1400, height: 900 }); // Set default timeout for page operations page.setDefaultTimeout(60000); // 60 seconds default timeout // Listen to console errors page.on('console', msg => { if (msg.type() === 'error') { console.log(` Browser error: ${msg.text()}`); } }); // Listen to JavaScript errors page.on('pageerror', error => { console.log(`āŒ [JS ERROR] ${error.message}`); }); // Track network responses const responses = []; page.on('response', response => { responses.push({ url: response.url(), status: response.status() }); }); try { // First check if server is reachable try { await page.goto(baseUrl, { waitUntil: 'domcontentloaded', timeout: navTimeout }); } catch (connError) { if (connError.message.includes('ERR_CONNECTION_REFUSED')) { console.log('āŒ Server is not running on port 5000. Please start the server first.'); await browser.close(); return false; } throw connError; } // Authenticate first await authHelper.ensureAuthenticatedWithTimeout(); console.log('āœ… Logged in'); console.log('šŸ“„ Testing non-existent research ID (expecting proper error handling)...'); await page.goto(`${baseUrl}/results/99999`, { waitUntil: 'domcontentloaded', timeout: navTimeout }); console.log('āœ… Page loaded, checking error handling...'); // Wait for page to fully load await new Promise(resolve => setTimeout(resolve, 2000)); // Check page structure and error handling const pageInfo = await page.evaluate(() => { const title = document.title; const body = document.body; const errorElements = document.querySelectorAll('.error, .alert-danger, [class*="error"], .error-message'); const loadingElements = document.querySelectorAll('.loading, .spinner, [class*="loading"]'); const pageStructure = document.querySelector('.container, .main-content, main'); const sidebar = document.querySelector('.sidebar, nav'); // Get any error messages let errorMessage = ''; if (errorElements.length > 0) { errorMessage = Array.from(errorElements).map(el => el.textContent.trim()).join('; '); } return { title, hasBody: !!body, bodyVisible: body ? window.getComputedStyle(body).display !== 'none' : false, hasErrorHandling: errorElements.length > 0 || document.body.textContent.includes('not found') || document.body.textContent.includes('404'), errorMessage, hasLoadingIndicators: loadingElements.length > 0, hasPageStructure: !!pageStructure, hasSidebar: !!sidebar, httpStatus: window.performance.getEntriesByType('navigation')[0]?.responseStatus || 'unknown' }; }); // Check if we got a 404 response const mainPageResponse = responses.find(r => r.url.includes('/results/')); const got404 = mainPageResponse && mainPageResponse.status === 404; console.log('šŸ” Error Handling Analysis:'); console.log(` Title: ${pageInfo.title}`); console.log(` HTTP Status: ${got404 ? '404 (as expected)' : mainPageResponse?.status || 'unknown'}`); console.log(` Has proper error handling: ${pageInfo.hasErrorHandling}`); console.log(` Error message: ${pageInfo.errorMessage || 'No error message displayed'}`); console.log(` Has page structure: ${pageInfo.hasPageStructure}`); console.log(` Has sidebar/navigation: ${pageInfo.hasSidebar}`); // Take screenshot (skip in CI — diagnostic only) if (!process.env.CI) { await page.screenshot({ path: 'research_results_error_test.png', fullPage: true }); console.log('šŸ“ø Screenshot saved as research_results_error_test.png'); } // Now test the research results template structure by going to results listing console.log('\nšŸ“„ Testing research results listing page...'); await page.goto(`${baseUrl}/history/`, { waitUntil: 'domcontentloaded', timeout: navTimeout }); await new Promise(resolve => setTimeout(resolve, 2000)); const historyPageInfo = await page.evaluate(() => { const hasHistoryContainer = !!document.querySelector('.ldr-history-container, .research-history, [class*="history"]'); const hasSearchBox = !!document.querySelector('input[type="search"], input[placeholder*="search" i]'); const hasResultsList = !!document.querySelector('.results-list, .ldr-history-list, ul, table'); return { hasHistoryContainer, hasSearchBox, hasResultsList, pageTitle: document.title }; }); console.log('\nšŸ” History Page Analysis:'); console.log(` Title: ${historyPageInfo.pageTitle}`); console.log(` Has history container: ${historyPageInfo.hasHistoryContainer}`); console.log(` Has search functionality: ${historyPageInfo.hasSearchBox}`); console.log(` Has results list structure: ${historyPageInfo.hasResultsList}`); // Test is successful if: // 1. Error page shows proper error handling for non-existent research // 2. History page has proper structure const isWorking = pageInfo.hasErrorHandling && pageInfo.hasPageStructure && (historyPageInfo.hasHistoryContainer || historyPageInfo.hasResultsList); if (isWorking) { console.log('\nšŸŽ‰ Research results error handling and structure test passed!'); } else { console.log('\nšŸ’„ Research results test failed!'); if (!pageInfo.hasErrorHandling) console.log(' - Missing proper error handling for non-existent research'); if (!pageInfo.hasPageStructure) console.log(' - Missing basic page structure'); if (!historyPageInfo.hasHistoryContainer && !historyPageInfo.hasResultsList) { console.log(' - History page missing expected structure'); } } await browser.close(); return isWorking; } catch (error) { console.log(`āŒ Test failed: ${error.message}`); await browser.close(); return false; } } testResearchResults().then(success => { process.exit(success ? 0 : 1); }).catch(console.error);