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
317 lines
14 KiB
JavaScript
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;
|
|
});
|