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
269 lines
9.3 KiB
JavaScript
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');
|
|
}
|