const puppeteer = require('puppeteer'); const { expect } = require('chai'); const BASE_URL = process.env.BASE_URL || 'http://localhost:5000'; const TEST_USER = `test_user_${Date.now()}`; const TEST_PASSWORD = 'testpass123'; const TEST_API_KEY = 'sk-or-v1-test1234567890abcdef'; describe('API Key Settings Test', function() { this.timeout(60000); // 60 second timeout let browser; let page; let dialogMessages = []; before(async () => { browser = await puppeteer.launch({ headless: process.env.HEADLESS !== 'false', args: ['--no-sandbox', '--disable-setuid-sandbox'], devtools: process.env.DEBUG === 'true' }); page = await browser.newPage(); // Set viewport await page.setViewport({ width: 1280, height: 800 }); // Capture console logs page.on('console', msg => { console.log(`Browser console [${msg.type()}]:`, msg.text()); }); // Capture any dialogs (alert, confirm, prompt) page.on('dialog', async dialog => { const message = dialog.message(); const type = dialog.type(); console.log(`Dialog detected [${type}]: ${message}`); dialogMessages.push({ type, message }); // Take a screenshot when dialog appears try { await page.screenshot({ path: `dialog_${type}_${Date.now()}.png`, fullPage: true }); } catch (e) { console.error('Failed to capture dialog screenshot:', e); } // Accept the dialog to continue await dialog.accept(); }); // Capture page errors page.on('pageerror', error => { console.error('Page error:', error.message); }); }); after(async () => { if (browser) { await browser.close(); } }); it('should register a new user', async () => { await page.goto(`${BASE_URL}/register`); // Fill registration form await page.waitForSelector('#username'); await page.type('#username', TEST_USER); await page.type('#password', TEST_PASSWORD); await page.type('#confirm_password', TEST_PASSWORD); // Submit form await page.click('button[type="submit"]'); // Wait for redirect to login or dashboard await page.waitForNavigation(); // Check if we need to login after registration if (page.url().includes('/login')) { await page.type('#username', TEST_USER); await page.type('#password', TEST_PASSWORD); await page.click('button[type="submit"]'); await page.waitForNavigation(); } console.log('User registered and logged in successfully'); }); it('should navigate to settings and capture current API key state', async () => { // Navigate to settings await page.goto(`${BASE_URL}/settings`); await page.waitForSelector('.settings-form', { timeout: 10000 }); // Wait for settings to load await new Promise(resolve => setTimeout(resolve, 2000)); // Find the API key field const apiKeySelector = 'input[name="llm.openai_endpoint.api_key"], input[id*="openai-endpoint-api-key"]'; await page.waitForSelector(apiKeySelector); // Get current value const currentValue = await page.$eval(apiKeySelector, el => el.value); console.log('Current API key value:', currentValue); // Take screenshot of initial state await page.screenshot({ path: 'settings_initial_state.png', fullPage: true }); expect(dialogMessages.length).to.equal(0, 'No dialogs should appear on initial load'); }); it('should enter API key and capture any dialogs', async () => { dialogMessages = []; // Reset dialog messages const apiKeySelector = 'input[name="llm.openai_endpoint.api_key"], input[id*="openai-endpoint-api-key"]'; // Clear the field first await page.click(apiKeySelector, { clickCount: 3 }); await page.keyboard.press('Backspace'); // Type the new API key console.log('Typing API key...'); await page.type(apiKeySelector, TEST_API_KEY); // Wait a bit to see if any dialog appears await new Promise(resolve => setTimeout(resolve, 1000)); // Check if any dialogs appeared while typing if (dialogMessages.length > 0) { console.log('Dialogs captured while typing:', dialogMessages); } // Verify the value was entered const enteredValue = await page.$eval(apiKeySelector, el => el.value); console.log('Entered API key value:', enteredValue); expect(enteredValue).to.equal(TEST_API_KEY); }); it('should save settings and capture any dialogs', async () => { dialogMessages = []; // Reset dialog messages // Find and click save button const saveButtonSelector = 'button[type="submit"]:not([type="reset"])'; await page.waitForSelector(saveButtonSelector); console.log('Clicking save button...'); // Take screenshot before save await page.screenshot({ path: 'settings_before_save.png', fullPage: true }); await page.click(saveButtonSelector); // Wait for save to complete await new Promise(resolve => setTimeout(resolve, 3000)); // Check if any dialogs appeared during save if (dialogMessages.length > 0) { console.log('Dialogs captured during save:', dialogMessages); // If there's a user selection dialog, this is the bug const userDialog = dialogMessages.find(d => d.message.toLowerCase().includes('user') || d.message.toLowerCase().includes('which') ); if (userDialog) { console.error('BUG DETECTED: User selection dialog appeared!'); console.error('Dialog details:', userDialog); } } // Take screenshot after save await page.screenshot({ path: 'settings_after_save.png', fullPage: true }); }); it('should verify API key was saved correctly', async () => { // Reload the page to check if the key persisted await page.reload(); await page.waitForSelector('.settings-form', { timeout: 10000 }); // Wait for settings to load await new Promise(resolve => setTimeout(resolve, 2000)); const apiKeySelector = 'input[name="llm.openai_endpoint.api_key"], input[id*="openai-endpoint-api-key"]'; await page.waitForSelector(apiKeySelector); // Get the value after reload const savedValue = await page.$eval(apiKeySelector, el => el.value); console.log('API key value after reload:', savedValue); // Check if it's still the placeholder or actual key if (savedValue === 'OPENAI_ENDPOINT_API_KEY') { console.error('BUG: API key was not saved! Still showing placeholder.'); } else if (savedValue === TEST_API_KEY) { console.log('SUCCESS: API key was saved correctly!'); } else if (savedValue === '********' || savedValue.includes('*')) { console.log('API key appears to be masked for security'); // Try to make a research request to verify it works await verifyApiKeyWorks(page); } // Take final screenshot await page.screenshot({ path: 'settings_final_state.png', fullPage: true }); }); it('should test research with the saved API key', async () => { // Navigate to research page await page.goto(`${BASE_URL}/`); await page.waitForSelector('#queryInput', { timeout: 10000 }); // Enter a test query await page.type('#queryInput', 'test query'); // Select the provider const providerSelector = 'select[name="model_provider"], #model_provider'; if (await page.$(providerSelector)) { await page.select(providerSelector, 'openai_endpoint'); } // Start research await page.click('#submitBtn'); // Wait for response await new Promise(resolve => setTimeout(resolve, 5000)); // Check for authentication errors const pageContent = await page.content(); if (pageContent.includes('401') || pageContent.includes('authentication') || pageContent.includes('No auth credentials')) { console.error('BUG: API key not working! Getting authentication error.'); // Take screenshot of error await page.screenshot({ path: 'research_auth_error.png', fullPage: true }); } else { console.log('API key appears to be working for research'); } }); }); async function verifyApiKeyWorks() { console.log('Verifying API key functionality...'); // This would make an actual API call to verify the key works // For now, we'll just log that we would verify it } // Run the test if (require.main === module) { console.log('Running API Key Settings Test...'); console.log(`Testing against: ${BASE_URL}`); console.log('Set HEADLESS=false to see the browser'); console.log('Set DEBUG=true to open devtools'); }