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

317 lines
14 KiB
JavaScript

const puppeteer = require('puppeteer');
const { browserConfig } = require('./browser_config');
const AuthHelper = require('./auth_helper');
const { getPuppeteerLaunchOptions } = require('./puppeteer_config');
const { setupDefaultModel } = require('./model_helper');
(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(` Browser error: ${msg.text()}`);
}
});
try {
// Register and login
const auth = new AuthHelper(page);
const username = 'metrics_' + Date.now();
const password = 'T3st!Secure#2024$LDR';
console.log('Creating user:', username);
await auth.register(username, password);
console.log('\n=== TESTING LLM DIRECTLY FIRST ===\n');
// First make a direct LLM API call to generate some early metrics
await page.evaluate(async () => {
try {
const response = await fetch('/api/v1/quick_summary', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: 'What is JavaScript? Give a very brief answer.',
iterations: 1,
search_tool: 'wikipedia'
})
});
console.log('API Response status:', response.status);
console.log('API Response headers:', response.headers);
let data;
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
data = await response.json();
} else {
data = await response.text();
}
console.log('LLM API Response:', data);
if (response.ok && typeof data === 'object' && data.summary) {
console.log('✅ LLM query successful, tokens should be tracked');
console.log('Summary preview:', data.summary.substring(0, 100) + '...');
} else {
console.log('❌ LLM query failed with status:', response.status);
console.log('Error details:', data);
}
} catch (error) {
console.log('Error calling LLM API:', error.toString());
}
});
// Wait for metrics to be processed
await new Promise(resolve => setTimeout(resolve, 2000));
console.log('\n=== CHECKING INITIAL METRICS ===\n');
// Navigate to metrics page to check if the LLM call was tracked
await page.goto('http://127.0.0.1:5000/metrics', { waitUntil: 'domcontentloaded' });
const initialMetrics = await page.evaluate(() => {
const content = {
title: document.title,
totalTokens: document.querySelector('[data-metric="total-tokens"]')?.textContent ||
document.querySelector('.metric-value')?.textContent || 'not found',
metrics: Array.from(document.querySelectorAll('.metric-item, [class*="metric"]')).slice(0, 5).map(el => el.textContent.trim())
};
return content;
});
console.log('Initial metrics page:', JSON.stringify(initialMetrics, null, 2));
console.log('\n=== CONFIGURING SETTINGS FOR FASTER TEST ===\n');
// Navigate to settings page to configure iterations and questions
await page.goto('http://127.0.0.1:5000/settings', { waitUntil: 'domcontentloaded' });
// Set iterations to 1
await page.evaluate(() => {
const iterationsInput = document.querySelector('input[name="search.iterations"]') ||
document.querySelector('#search\\.iterations');
if (iterationsInput) {
iterationsInput.value = '1';
iterationsInput.dispatchEvent(new Event('change', { bubbles: true }));
console.log('Set iterations to 1');
}
});
// Set questions per iteration to 1
await page.evaluate(() => {
const questionsInput = document.querySelector('input[name="search.questions_per_iteration"]') ||
document.querySelector('#search\\.questions_per_iteration');
if (questionsInput) {
questionsInput.value = '1';
questionsInput.dispatchEvent(new Event('change', { bubbles: true }));
console.log('Set questions to 1');
}
});
// Save settings
const saveButton = await page.$('button[type="submit"]');
if (saveButton) {
await saveButton.click();
console.log('Settings saved');
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log('\n=== STARTING RESEARCH ===\n');
// Navigate to home
await page.goto('http://127.0.0.1:5000/', { waitUntil: 'domcontentloaded' });
// Fill form with a simple query
await page.type('#query', 'What is Node.js?');
// Setup the default model
await setupDefaultModel(page);
// Set search engine
await page.evaluate(() => {
const searchInput = document.querySelector('#search_engine');
if (searchInput) {
searchInput.value = 'searxng';
const inputEvent = new Event('input', { bubbles: true });
searchInput.dispatchEvent(inputEvent);
console.log('Set search engine to:', searchInput.value);
}
});
// Wait a bit for UI to update
await new Promise(resolve => setTimeout(resolve, 500));
// Submit
await page.click('button[type="submit"]');
// Wait for navigation
await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
// Check where we ended up
const url = page.url();
console.log('After submission URL:', url);
if (url.includes('/progress/')) {
console.log('✅ Research submitted successfully!');
const researchId = url.split('/progress/')[1];
console.log('Research ID:', researchId);
// Monitor progress for up to 90 seconds
const startTime = Date.now();
const maxWaitTime = 90000; // 90 seconds for faster test
let isComplete = false;
while (!isComplete && (Date.now() - startTime) < maxWaitTime) {
// Get progress page content
const progressContent = await page.evaluate(() => {
const content = {
status: document.querySelector('.status')?.textContent.trim() ||
document.querySelector('[class*="status"]')?.textContent.trim() || 'not found',
progressBar: document.querySelector('.progress-bar')?.style.width ||
document.querySelector('[class*="progress-bar"]')?.style.width || 'not found',
currentTask: document.querySelector('.current-task')?.textContent.trim() ||
document.querySelector('[class*="current-task"]')?.textContent.trim() || 'not found'
};
return content;
});
console.log(`Progress: ${progressContent.progressBar} - ${progressContent.currentTask}`);
// Check if complete
if (progressContent.status.toLowerCase().includes('complete') ||
progressContent.status.toLowerCase().includes('finished') ||
progressContent.progressBar === '100%') {
isComplete = true;
console.log('\n✅ Research completed!');
}
// Wait 3 seconds before checking again
await new Promise(resolve => setTimeout(resolve, 3000));
}
console.log('\n=== CHECKING METRICS AFTER RESEARCH ===\n');
// Navigate to metrics page
await page.goto('http://127.0.0.1:5000/metrics', { waitUntil: 'domcontentloaded' });
// Wait for metrics to load
await new Promise(resolve => setTimeout(resolve, 2000));
// Get detailed metrics
const finalMetrics = await page.evaluate(() => {
const getTextContent = (selector) => {
const el = document.querySelector(selector);
return el ? el.textContent.trim() : 'not found';
};
const content = {
title: document.title,
// Try different selectors for metrics
totalTokens: getTextContent('[data-metric="total-tokens"]') ||
getTextContent('.total-tokens') ||
getTextContent('#total-tokens'),
totalCalls: getTextContent('[data-metric="total-calls"]') ||
getTextContent('.total-calls') ||
getTextContent('#total-calls'),
totalCost: getTextContent('[data-metric="total-cost"]') ||
getTextContent('.total-cost') ||
getTextContent('#total-cost'),
// Get all metric cards
metricCards: Array.from(document.querySelectorAll('.metric-card, .ldr-card')).map(card => {
return {
title: card.querySelector('.card-title, h5, h6')?.textContent.trim() || '',
value: card.querySelector('.metric-value, .display-4, .h2')?.textContent.trim() || '',
text: card.textContent.trim()
};
}).filter(card => card.title || card.value),
// Get any tables
tables: Array.from(document.querySelectorAll('table')).map(table => {
const headers = Array.from(table.querySelectorAll('th')).map(th => th.textContent.trim());
const firstRow = table.querySelector('tbody tr');
const firstRowData = firstRow ? Array.from(firstRow.querySelectorAll('td')).map(td => td.textContent.trim()) : [];
return {
headers,
firstRow: firstRowData,
rowCount: table.querySelectorAll('tbody tr').length
};
})
};
return content;
});
console.log('Final metrics page:', JSON.stringify(finalMetrics, null, 2));
// Check if metrics were recorded
if (finalMetrics.metricCards.length > 0 || finalMetrics.tables.some(t => t.rowCount > 0)) {
console.log('\n✅ Metrics are being tracked!');
// Try to get specific token counts
const hasTokenData = finalMetrics.metricCards.some(card =>
card.text.toLowerCase().includes('token') &&
card.value && card.value !== '0' && card.value !== 'not found'
);
if (hasTokenData) {
console.log('✅ Token usage data found in metrics!');
} else {
console.log('⚠️ No token usage data found in metrics cards');
}
} else {
console.log('\n❌ No metrics data found on page');
}
// Also check the cost analytics page
console.log('\n=== CHECKING COST ANALYTICS ===\n');
await page.goto('http://127.0.0.1:5000/metrics/costs', { waitUntil: 'domcontentloaded' });
const costMetrics = await page.evaluate(() => {
const content = {
title: document.title,
hasData: document.querySelectorAll('table tbody tr').length > 0,
tableRows: document.querySelectorAll('table tbody tr').length,
firstRowData: (() => {
const firstRow = document.querySelector('table tbody tr');
if (!firstRow) return null;
return Array.from(firstRow.querySelectorAll('td')).map(td => td.textContent.trim());
})()
};
return content;
});
console.log('Cost analytics page:', JSON.stringify(costMetrics, null, 2));
if (costMetrics.hasData) {
console.log('✅ Cost data is being tracked!');
} else {
console.log('⚠️ No cost data found');
}
} else {
console.log('❌ Failed to submit research');
// Check for errors
const errors = await page.evaluate(() => {
return Array.from(document.querySelectorAll('.error, .alert')).map(el => el.textContent);
});
console.log('Errors found:', errors);
}
} catch (error) {
console.error('Test failed:', error);
process.exitCode = 1;
} finally {
console.log('\n=== TEST COMPLETE ===\n');
await browser.close();
}
})().catch(err => {
console.error('Unhandled error:', err);
process.exitCode = 1;
});