Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
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
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

269 lines
9.3 KiB
JavaScript

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');
}