Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

313 lines
10 KiB
JavaScript

const puppeteer = require('puppeteer');
const fs = require('fs').promises;
const { getPuppeteerLaunchOptions } = require('./puppeteer_config');
const BASE_URL = 'http://127.0.0.1:5000';
const TIMEOUT = 60000;
// Color codes for output
const colors = {
info: '\x1b[36m',
success: '\x1b[32m',
warning: '\x1b[33m',
error: '\x1b[31m',
section: '\x1b[34m',
reset: '\x1b[0m'
};
function log(message, type = 'info') {
const timestamp = new Date().toLocaleTimeString();
console.log(`${colors[type]}[${timestamp}] ${message}${colors.reset}`);
}
async function ensureAuthenticated(page, username, password) {
log('Checking authentication status...', 'info');
// Check if already authenticated
try {
await page.goto(`${BASE_URL}/`, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('a.logout-btn', { timeout: 3000 });
log('Already authenticated', 'success');
return true;
} catch {
log('Not authenticated, need to register...', 'warning');
}
// Skip login attempt (it usually fails for new users) and go straight to registration
log('Registering new user...', 'info');
// Navigate to registration page
await page.goto(`${BASE_URL}/auth/register`, { waitUntil: 'domcontentloaded' });
// Wait for form to be ready
await page.waitForSelector('#username', { visible: true });
await page.type('#username', username);
await page.type('#password', password);
await page.type('#confirm_password', password);
// Check the acknowledge checkbox if present
const acknowledgeCheckbox = await page.$('#acknowledge');
if (acknowledgeCheckbox) {
await acknowledgeCheckbox.click();
}
await page.click('button[type="submit"]');
// Wait for navigation after registration
await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
const finalUrl = page.url();
if (finalUrl === `${BASE_URL}/` || finalUrl.includes('/home')) {
log('Registration successful', 'success');
return true;
}
log(`Registration may have failed, current URL: ${finalUrl}`, 'warning');
return false;
}
async function startResearch(page, query) {
log(`Starting research: "${query}"`, 'info');
await page.goto(`${BASE_URL}/`, { waitUntil: 'domcontentloaded' });
// Wait for form to be ready - try multiple selectors
try {
await page.waitForSelector('#query, #research_query, input[name="query"]', { visible: true, timeout: 5000 });
} catch {
log('Research form not found with expected selectors', 'warning');
}
// Type research query - use correct selector
const queryInput = await page.$('#query') || await page.$('#research_query') || await page.$('input[name="query"]');
if (queryInput) {
await queryInput.type(query);
} else {
throw new Error('Could not find query input field');
}
// Submit form - use correct button selector
const submitButton = await page.$('#start-research-btn') || await page.$('#submit-research') || await page.$('button[type="submit"]');
if (submitButton) {
await submitButton.click();
} else {
throw new Error('Could not find submit button');
}
// Wait for navigation to research page
await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
// Wait for research to start
await page.waitForSelector('.research-status, .status-indicator', { visible: true });
log('Research started', 'success');
// Get research ID from URL
const url = page.url();
const match = url.match(/\/research\/(\d+)/);
return match ? match[1] : null;
}
async function waitForResearchProgress(page, _maxWaitTime = 5000) {
log('Checking research submission...', 'info');
// In CI, we don't wait for research to complete
// Just verify it was submitted
await new Promise(resolve => setTimeout(resolve, 3000));
try {
const currentUrl = page.url();
if (currentUrl.includes('/progress/') || currentUrl.includes('/research/')) {
log('Research submitted successfully', 'success');
return true;
}
} catch {
log('Could not check research status', 'warning');
}
log('Continuing without waiting for research completion', 'info');
return true;
}
async function captureMetricsDashboard(page) {
log('Navigating to metrics dashboard...', 'info');
// Navigate to metrics page
await page.goto(`${BASE_URL}/metrics`, { waitUntil: 'domcontentloaded' });
// Wait for metrics to load
await page.waitForSelector('.metrics-container, .dashboard-container', { visible: true });
// Give charts time to render
await new Promise(resolve => setTimeout(resolve, 3000));
// Capture metrics data
const metricsData = await page.evaluate(() => {
const data = {
timestamp: new Date().toISOString(),
url: window.location.href,
tokenUsage: {},
searchMetrics: {},
charts: {},
rawText: ''
};
// Get token usage stats
const tokenStats = document.querySelectorAll('.token-stats, .usage-stats, .metric-card');
tokenStats.forEach(stat => {
const label = stat.querySelector('.metric-label, .stat-label, h3, h4');
const value = stat.querySelector('.metric-value, .stat-value, .value, p');
if (label && value) {
data.tokenUsage[label.textContent.trim()] = value.textContent.trim();
}
});
// Get search engine stats
const searchStats = document.querySelectorAll('.search-stats, .engine-stats');
searchStats.forEach(stat => {
const engine = stat.querySelector('.engine-name, h4');
const count = stat.querySelector('.call-count, .count');
if (engine && count) {
data.searchMetrics[engine.textContent.trim()] = count.textContent.trim();
}
});
// Check for chart elements
const charts = document.querySelectorAll('canvas, .chart-container');
data.charts.count = charts.length;
data.charts.types = Array.from(charts).map(c => c.className || c.tagName);
// Get all text content from metrics page
data.rawText = document.body.innerText;
return data;
});
// Log what we found
log('\n=== METRICS DASHBOARD DATA ===', 'section');
log('Token Usage:', 'info');
console.log(metricsData.tokenUsage);
log('\nSearch Metrics:', 'info');
console.log(metricsData.searchMetrics);
log('\nCharts found: ' + metricsData.charts.count, 'info');
// Check if we have any data
const hasTokenData = Object.keys(metricsData.tokenUsage).length > 0;
const hasSearchData = Object.keys(metricsData.searchMetrics).length > 0;
if (!hasTokenData && !hasSearchData) {
log('\nRAW PAGE CONTENT:', 'warning');
console.log(metricsData.rawText.substring(0, 1000) + '...');
}
// Save metrics data
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const dataPath = `./metrics-data-${timestamp}.json`;
await fs.writeFile(dataPath, JSON.stringify(metricsData, null, 2));
log(`Metrics data saved: ${dataPath}`, 'success');
return {
hasTokenData,
hasSearchData,
metricsData
};
}
async function testMetricsVerification() {
const browser = await puppeteer.launch(getPuppeteerLaunchOptions());
const page = await browser.newPage();
page.setDefaultTimeout(TIMEOUT);
// Log console messages
page.on('console', msg => {
if (msg.type() === 'error') {
log(`Browser console error: ${msg.text()}`, 'error');
}
});
try {
// Create unique user
const timestamp = Date.now();
const username = `metrics_test_${timestamp}`;
const password = 'T3st!Secure#2024$LDR';
log(`\n=== METRICS VERIFICATION TEST ===`, 'section');
log(`Username: ${username}`, 'info');
log(`Password: (secure password with special characters)`, 'info');
// Authenticate
await ensureAuthenticated(page, username, password);
// Start a research
log('\n=== STARTING RESEARCH ===', 'section');
const researchId = await startResearch(page, "What are the benefits of solar energy?");
log(`Research ID: ${researchId}`, 'info');
// Wait for some progress
await waitForResearchProgress(page);
// Navigate around to generate more activity
log('\n=== GENERATING ACTIVITY ===', 'section');
// Go to history page
await page.goto(`${BASE_URL}/history`, { waitUntil: 'domcontentloaded' });
log('Visited history page', 'success');
await new Promise(resolve => setTimeout(resolve, 2000));
// Go back to research page
if (researchId) {
await page.goto(`${BASE_URL}/research/${researchId}`, { waitUntil: 'domcontentloaded' });
log('Returned to research page', 'success');
await new Promise(resolve => setTimeout(resolve, 3000));
}
// Go to settings
await page.goto(`${BASE_URL}/settings`, { waitUntil: 'domcontentloaded' });
log('Visited settings page', 'success');
await new Promise(resolve => setTimeout(resolve, 2000));
// Capture metrics dashboard
log('\n=== CAPTURING METRICS ===', 'section');
const { hasTokenData, hasSearchData } = await captureMetricsDashboard(page);
// Verify results
log('\n=== VERIFICATION RESULTS ===', 'section');
if (hasTokenData) {
log('✅ Token usage metrics are displayed', 'success');
} else {
log('❌ No token usage metrics found', 'error');
}
if (hasSearchData) {
log('✅ Search engine metrics are displayed', 'success');
} else {
log('❌ No search engine metrics found', 'error');
}
if (hasTokenData || hasSearchData) {
log('\n✅ METRICS DASHBOARD IS WORKING!', 'success');
} else {
log('\n❌ METRICS DASHBOARD IS NOT DISPLAYING DATA', 'error');
}
} catch (error) {
log(`\n❌ Test failed: ${error.message}`, 'error');
console.error(error);
process.exitCode = 1;
} finally {
// Close browser properly
await browser.close();
}
}
// Run the test
testMetricsVerification().catch(err => {
console.error('❌ Unhandled error:', err);
process.exitCode = 1;
});