const puppeteer = require('puppeteer'); const { browserConfig } = require('./browser_config'); const AuthHelper = require('./auth_helper'); const { getPuppeteerLaunchOptions } = require('./puppeteer_config'); // NAVIGATION NOTE: Using 'domcontentloaded' instead of 'networkidle2' for page.goto() // because networkidle2 waits for no network activity for 500ms, but WebSocket // connections and background polling keep the network active, causing infinite hangs. // See: test_login_validation.js and auth_helper.js for detailed explanation. async function submitResearch(page, query, index) { console.log(`\nSubmitting: "${query}"`); // Navigate to home await page.goto('http://127.0.0.1:5000/', { waitUntil: 'domcontentloaded' }); // Capture page state before submission const pageInfo = await page.evaluate(() => { return { title: document.title, url: window.location.href, forms: document.querySelectorAll('form').length, queryInput: document.querySelector('#query') ? 'found' : 'not found', modelSelect: document.querySelector('#model') || document.querySelector('[name="model"]') ? 'found' : 'not found', submitButton: document.querySelector('button[type="submit"]') ? 'found' : 'not found', errorMessages: Array.from(document.querySelectorAll('.error, .alert-danger')).map(el => el.textContent), bodyText: document.body.innerText.substring(0, 500) }; }); console.log('Page state:', pageInfo); // Take screenshot before filling form (skip in CI — diagnostic only) if (!process.env.CI) { await page.screenshot({ path: `/tmp/before_submit_${index}.png` }); } // Fill form try { await page.waitForSelector('#query', { timeout: 5000 }); await page.evaluate(() => { document.querySelector('#query').value = ''; }); await page.type('#query', query); // Select model const modelSelected = await page.evaluate(() => { const modelSelect = document.querySelector('#model') || document.querySelector('[name="model"]') || document.querySelector('#model-select'); if (modelSelect) { modelSelect.value = 'llama3.1:8b'; modelSelect.dispatchEvent(new Event('change')); return true; } return false; }); console.log('Model selected:', modelSelected); } catch (e) { console.log('Error filling form:', e.message); // Log page content const pageContent = await page.evaluate(() => document.body.innerHTML); console.log('Page HTML (first 1000 chars):', pageContent.substring(0, 1000)); return null; } // Set up response listener before submitting const responsePromise = page.waitForResponse( response => response.url().includes('/api/start_research'), { timeout: 10000 } ); // Submit await page.click('button[type="submit"]'); try { const response = await responsePromise; const data = await response.json(); console.log(`Response:`, data); return data; } catch (e) { console.log(`Failed to get response: ${e.message}`); // Log current page state const errorPageInfo = await page.evaluate(() => { return { url: window.location.href, title: document.title, errors: Array.from(document.querySelectorAll('.error, .alert, [class*="error"]')).map(el => ({ class: el.className, text: el.textContent })), bodyText: document.body.innerText.substring(0, 1000) }; }); console.log('Error page state:', errorPageInfo); return null; } } (async () => { const browser = await puppeteer.launch(getPuppeteerLaunchOptions()); const page = await browser.newPage(); // Log console errors page.on('console', msg => { if (msg.type() === 'error') { console.log('PAGE ERROR:', msg.text()); } }); page.on('pageerror', error => { console.log('PAGE CRASH:', error.message); }); let testPassed = false; try { // Register and login const auth = new AuthHelper(page); console.log('Authenticating...'); await auth.ensureAuthenticatedWithTimeout(); console.log('\nSubmitting 5 researches to test queueing...\n'); const results = []; // Submit researches one by one for (let i = 1; i <= 5; i++) { const result = await submitResearch(page, `Research ${i} about topic ${i}`, i); if (result) { results.push(result); if (result.status === 'queued') { console.log(`✓ Research ${i} QUEUED at position ${result.queue_position}`); } else if (result.status === 'success') { console.log(`✓ Research ${i} STARTED`); } } // Small delay between submissions await new Promise(resolve => setTimeout(resolve, 500)); } // Summary console.log('\n=== SUMMARY ==='); const started = results.filter(r => r && r.status === 'success').length; const queued = results.filter(r => r && r.status === 'queued').length; const failed = results.filter(r => !r).length; console.log(`Started: ${started}`); console.log(`Queued: ${queued}`); console.log(`Failed: ${failed}`); // The test should pass if we have a reasonable distribution // In CI, network issues might cause some to fail if (started >= 1 && (started + queued) >= 3) { console.log('\n✅ SUCCESS: Queue system working correctly!'); testPassed = true; } else if (started >= 2) { console.log('\n✅ SUCCESS: Multiple researches started successfully'); testPassed = true; } else { console.log(`\n❌ FAILED: Only ${started} started, ${queued} queued, ${failed} failed`); } } catch (error) { console.error('Test failed:', error); } finally { await browser.close(); process.exit(testPassed ? 0 : 1); } })();