const puppeteer = require('puppeteer'); const AuthHelper = require('./auth_helper'); const fs = require('fs'); const { getPuppeteerLaunchOptions } = require('./puppeteer_config'); async function testCostAnalytics() { let browser; const results = { success: false, errors: [], networkErrors: [], consoleErrors: [], apiResponses: {}, }; try { console.log('šŸš€ Starting Cost Analytics test...'); browser = await puppeteer.launch(getPuppeteerLaunchOptions()); const page = await browser.newPage(); const baseUrl = 'http://127.0.0.1:5000'; const authHelper = new AuthHelper(page, baseUrl); // Intercept network requests to debug API calls await page.setRequestInterception(true); page.on('request', (request) => { console.log(`šŸ“” Network Request: ${request.method()} ${request.url()}`); request.continue(); }); // Monitor network responses page.on('response', async (response) => { const url = response.url(); const status = response.status(); console.log(`šŸ“Ø Network Response: ${status} ${url}`); if (url.includes('/metrics/api/')) { try { const responseText = await response.text(); results.apiResponses[url] = { status, response: responseText.substring(0, 500) // First 500 chars }; console.log(`šŸ“Š API Response for ${url}:`, responseText.substring(0, 200)); } catch (e) { console.log(`āŒ Failed to read response for ${url}:`, e.message); } } }); // Monitor console messages page.on('console', msg => { const text = msg.text(); console.log(`šŸ–„ļø Console ${msg.type()}: ${text}`); if (msg.type() === 'error') { results.consoleErrors.push(text); } }); // Monitor network failures page.on('requestfailed', request => { const error = `Network failed: ${request.url()} - ${request.failure().errorText}`; console.log(`āŒ ${error}`); results.networkErrors.push(error); }); // Ensure authenticated before accessing cost analytics await authHelper.ensureAuthenticated(); // Wait a bit to ensure session is established await new Promise(resolve => setTimeout(resolve, 1000)); console.log('šŸ“„ Navigating to cost analytics page...'); const response = await page.goto('http://127.0.0.1:5000/metrics/costs', { waitUntil: 'domcontentloaded', timeout: 30000 }); if (!response.ok()) { throw new Error(`Page failed to load: ${response.status()} ${response.statusText()}`); } // Wait for page elements console.log('ā³ Waiting for page elements...'); await page.waitForSelector('.cost-analytics-container', { timeout: 10000 }); // Check if loading state is present const loadingElement = await page.$('#loading'); const isLoading = await page.evaluate(el => el && el.style.display !== 'none', loadingElement); console.log(`šŸ“Š Loading state visible: ${isLoading}`); // Wait a bit and check state again await new Promise(resolve => setTimeout(resolve, 1000)); // Check for error state const errorElement = await page.$('#error'); const hasError = await page.evaluate(el => el && el.style.display !== 'none', errorElement); console.log(`āŒ Error state visible: ${hasError}`); // Check for content state const contentElement = await page.$('#cost-content'); const hasContent = await page.evaluate(el => el && el.style.display !== 'none', contentElement); console.log(`āœ… Content state visible: ${hasContent}`); // Check for no-data state const noDataElement = await page.$('#no-data'); const hasNoData = await page.evaluate(el => el && el.style.display !== 'none', noDataElement); console.log(`šŸ“­ No-data state visible: ${hasNoData}`); // Try to manually trigger the API call to debug console.log('šŸ”§ Manually testing API call...'); const apiResponse = await page.evaluate(async () => { try { const resp = await fetch('/metrics/api/cost-analytics?period=7d'); const data = await resp.json(); return { success: true, status: resp.status, data }; } catch (error) { return { success: false, error: error.message }; } }); console.log('šŸ” Manual API test result:', JSON.stringify(apiResponse, null, 2)); // Check for specific cost data elements const totalCostElement = await page.$('#total-cost'); const totalCostText = totalCostElement ? await page.evaluate(el => el.textContent, totalCostElement) : 'Not found'; console.log(`šŸ’° Total cost display: "${totalCostText}"`); const localSavingsElement = await page.$('#local-savings'); const localSavingsText = localSavingsElement ? await page.evaluate(el => el.textContent, localSavingsElement) : 'Not found'; console.log(`šŸ  Local savings display: "${localSavingsText}"`); // Test time period buttons console.log('šŸ•’ Testing time period buttons...'); const timePeriodButtons = await page.$$('.time-range-btn'); console.log(`šŸ“Š Found ${timePeriodButtons.length} time period buttons`); if (timePeriodButtons.length > 1) { // Click on 30d button to test functionality await timePeriodButtons[1].click(); await new Promise(resolve => setTimeout(resolve, 1000)); } results.success = true; console.log('āœ… Cost Analytics test completed successfully!'); } catch (error) { console.error('āŒ Test failed:', error.message); results.errors.push(error.message); } finally { if (browser) { await browser.close(); } } // Write detailed results const resultsPath = './results/cost-analytics-test-results.json'; fs.mkdirSync('./results', { recursive: true }); fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2)); console.log(`šŸ“„ Detailed results saved: ${resultsPath}`); return results; } // Create results directory const resultsDir = './results'; fs.mkdirSync(resultsDir, { recursive: true }); // Run the test testCostAnalytics().then(results => { console.log('\nšŸ“‹ Test Summary:'); console.log(`āœ… Success: ${results.success}`); console.log(`āŒ Errors: ${results.errors.length}`); console.log(`🌐 Network Errors: ${results.networkErrors.length}`); console.log(`šŸ–„ļø Console Errors: ${results.consoleErrors.length}`); console.log(`šŸ“” API Responses: ${Object.keys(results.apiResponses).length}`); if (results.errors.length > 0) { console.log('\nāŒ Errors encountered:'); results.errors.forEach(error => console.log(` - ${error}`)); } if (results.networkErrors.length > 0) { console.log('\n🌐 Network Errors:'); results.networkErrors.forEach(error => console.log(` - ${error}`)); } if (results.consoleErrors.length > 0) { console.log('\nšŸ–„ļø Console Errors:'); results.consoleErrors.forEach(error => console.log(` - ${error}`)); } process.exit(results.success ? 0 : 1); }).catch(error => { console.error('šŸ’„ Test runner failed:', error); process.exit(1); });