chore: import upstream snapshot with attribution
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
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
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
const AuthHelper = require('./auth_helper');
|
||||
const { getPuppeteerLaunchOptions } = require('./puppeteer_config');
|
||||
|
||||
// Color codes for terminal output
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
bright: '\x1b[1m',
|
||||
red: '\x1b[31m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m'
|
||||
};
|
||||
|
||||
function log(message, type = 'info') {
|
||||
const timestamp = new Date().toISOString();
|
||||
const prefix = {
|
||||
info: `${colors.blue}ℹ`,
|
||||
success: `${colors.green}✓`,
|
||||
error: `${colors.red}ERROR:`,
|
||||
warn: `${colors.yellow}⚠`
|
||||
}[type] || '';
|
||||
|
||||
console.log(`${prefix}[${timestamp}] ${message}${colors.reset}`);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
let browser;
|
||||
let authHelper;
|
||||
|
||||
try {
|
||||
// Test configuration
|
||||
const TEST_API_KEY_1 = 'enter-save-test-key-12345';
|
||||
const TEST_API_KEY_2 = 'enter-save-changed-67890';
|
||||
const BASE_URL = 'http://localhost:5000';
|
||||
|
||||
log(`${colors.bright}=== Testing API Key Save with Enter Key ===${colors.reset}`, 'info');
|
||||
|
||||
// Launch browser
|
||||
browser = await puppeteer.launch(getPuppeteerLaunchOptions());
|
||||
|
||||
log('Browser launched in visible mode', 'success');
|
||||
|
||||
const page = await browser.newPage();
|
||||
await page.setViewport({ width: 1920, height: 1080 });
|
||||
|
||||
// Log browser console errors
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
log(`Browser console: ${msg.text()}`, 'error');
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for page dialogs (alerts, confirms)
|
||||
page.on('dialog', async dialog => {
|
||||
log(`Dialog appeared: ${dialog.message()}`, 'warn');
|
||||
await dialog.accept();
|
||||
});
|
||||
|
||||
// Initialize auth helper
|
||||
authHelper = new AuthHelper(page);
|
||||
|
||||
// Create test user
|
||||
const timestamp = Date.now();
|
||||
const testUsername = `enter_test_${timestamp}`;
|
||||
const testPassword = 'testpass123';
|
||||
|
||||
log(`Creating user: ${testUsername}`, 'info');
|
||||
|
||||
// Register and login
|
||||
await authHelper.register(testUsername, testPassword);
|
||||
const isAuthenticated = await authHelper.isLoggedIn();
|
||||
if (!isAuthenticated) {
|
||||
throw new Error('Failed to authenticate after registration');
|
||||
}
|
||||
log('User authenticated successfully', 'success');
|
||||
|
||||
// Navigate to settings page
|
||||
log('Navigating to settings page...', 'info');
|
||||
await page.goto(`${BASE_URL}/settings`, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Wait a bit for page to fully load
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Take initial screenshot
|
||||
await page.screenshot({
|
||||
path: `/tmp/enter_key_test_initial_${timestamp}.png`,
|
||||
fullPage: false
|
||||
});
|
||||
log('Screenshot saved: Initial settings page', 'info');
|
||||
|
||||
// Find the API key input field
|
||||
log('Looking for OpenAI Endpoint API key field...', 'info');
|
||||
|
||||
const apiKeySelectors = [
|
||||
'input[name="llm.openai_endpoint.api_key"]',
|
||||
'input[id="llm.openai_endpoint.api_key"]',
|
||||
'input[data-setting="llm.openai_endpoint.api_key"]',
|
||||
'#llm\\.openai_endpoint\\.api_key'
|
||||
];
|
||||
|
||||
let apiKeyInput = null;
|
||||
for (const selector of apiKeySelectors) {
|
||||
try {
|
||||
apiKeyInput = await page.$(selector);
|
||||
if (apiKeyInput) {
|
||||
log(`Found API key input with selector: ${selector}`, 'success');
|
||||
break;
|
||||
}
|
||||
} catch {
|
||||
// Continue with next selector
|
||||
}
|
||||
}
|
||||
|
||||
if (!apiKeyInput) {
|
||||
throw new Error('Could not find OpenAI Endpoint API key input field');
|
||||
}
|
||||
|
||||
// Scroll the input into view
|
||||
await apiKeyInput.evaluate(el => el.scrollIntoView({ behavior: 'smooth', block: 'center' }));
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
|
||||
// Clear any existing value and type the first API key
|
||||
log(`Clearing field and typing API key: ${TEST_API_KEY_1}`, 'info');
|
||||
await apiKeyInput.click({ clickCount: 3 });
|
||||
await page.keyboard.press('Backspace');
|
||||
await apiKeyInput.type(TEST_API_KEY_1);
|
||||
|
||||
// Take screenshot before pressing Enter
|
||||
await page.screenshot({
|
||||
path: `/tmp/enter_key_test_before_enter_${timestamp}.png`,
|
||||
fullPage: false
|
||||
});
|
||||
log('Screenshot saved: Before pressing Enter', 'info');
|
||||
|
||||
// Press Enter to save
|
||||
log('Pressing Enter to save...', 'info');
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// Wait for any save operation to complete
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Take screenshot after Enter
|
||||
await page.screenshot({
|
||||
path: `/tmp/enter_key_test_after_enter_${timestamp}.png`,
|
||||
fullPage: false
|
||||
});
|
||||
log('Screenshot saved: After pressing Enter', 'info');
|
||||
|
||||
// Check for any success messages or indicators
|
||||
const successIndicators = [
|
||||
'.alert-success',
|
||||
'.success-message',
|
||||
'[class*="success"]',
|
||||
'.saved-indicator',
|
||||
'.toast-success'
|
||||
];
|
||||
|
||||
let successFound = false;
|
||||
for (const selector of successIndicators) {
|
||||
const element = await page.$(selector);
|
||||
if (element) {
|
||||
const text = await element.evaluate(el => el.textContent);
|
||||
log(`Success indicator found: ${text}`, 'success');
|
||||
successFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the value persisted by reloading
|
||||
log('Reloading page to check persistence...', 'info');
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Find the input again
|
||||
apiKeyInput = null;
|
||||
for (const selector of apiKeySelectors) {
|
||||
apiKeyInput = await page.$(selector);
|
||||
if (apiKeyInput) break;
|
||||
}
|
||||
|
||||
if (apiKeyInput) {
|
||||
const currentValue = await apiKeyInput.evaluate(el => el.value);
|
||||
log(`Value after reload: ${currentValue ? '***' + currentValue.slice(-5) : 'empty'}`, 'info');
|
||||
|
||||
// Now try the second API key
|
||||
log(`Trying second API key: ${TEST_API_KEY_2}`, 'info');
|
||||
await apiKeyInput.click({ clickCount: 3 });
|
||||
await page.keyboard.press('Backspace');
|
||||
await apiKeyInput.type(TEST_API_KEY_2);
|
||||
|
||||
// Try different save methods
|
||||
log('Testing different save triggers...', 'info');
|
||||
|
||||
// Method 1: Press Enter
|
||||
log('Method 1: Pressing Enter', 'info');
|
||||
await page.keyboard.press('Enter');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// Method 2: Tab away (blur event)
|
||||
log('Method 2: Tabbing away from field', 'info');
|
||||
await page.keyboard.press('Tab');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// Method 3: Click elsewhere
|
||||
log('Method 3: Clicking elsewhere on page', 'info');
|
||||
await page.click('body');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
// Check if there's a form around the input
|
||||
const formInfo = await page.evaluate(() => {
|
||||
const input = document.querySelector('input[name="llm.openai_endpoint.api_key"]');
|
||||
if (!input) return null;
|
||||
|
||||
const form = input.closest('form');
|
||||
return {
|
||||
hasForm: !!form,
|
||||
formAction: form?.action,
|
||||
formMethod: form?.method,
|
||||
inputType: input.type,
|
||||
hasOnChange: !!input.onchange,
|
||||
hasOnKeyPress: !!input.onkeypress,
|
||||
dataAttributes: Object.keys(input.dataset || {})
|
||||
};
|
||||
});
|
||||
|
||||
log(`Form analysis: ${JSON.stringify(formInfo, null, 2)}`, 'info');
|
||||
|
||||
// Final screenshot
|
||||
await page.screenshot({
|
||||
path: `/tmp/enter_key_test_final_${timestamp}.png`,
|
||||
fullPage: false
|
||||
});
|
||||
log('Screenshot saved: Final state', 'info');
|
||||
|
||||
log('Test completed - check screenshots to see results', 'success');
|
||||
log('Note: Browser is left open for manual inspection', 'info');
|
||||
|
||||
// Keep browser open for manual inspection
|
||||
log('Browser will remain open for 30 seconds...', 'info');
|
||||
await new Promise(resolve => setTimeout(resolve, 30000));
|
||||
|
||||
} catch (error) {
|
||||
log(`Test failed: ${error.message}`, 'error');
|
||||
console.error(error);
|
||||
|
||||
// Take error screenshot
|
||||
if (browser) {
|
||||
const page = (await browser.pages())[0];
|
||||
if (page) {
|
||||
await page.screenshot({
|
||||
path: `/tmp/enter_key_test_error_${Date.now()}.png`,
|
||||
fullPage: false
|
||||
});
|
||||
log('Error screenshot saved', 'info');
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
} finally {
|
||||
if (browser) {
|
||||
await browser.close();
|
||||
log('Browser closed', 'success');
|
||||
}
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user