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

219 lines
8.1 KiB
JavaScript

/**
* Collections Auto-Index Toggle UI Test
*
* Tests the auto-index toggle on the collections page that controls
* whether documents are automatically indexed when uploaded or downloaded.
*
* What this tests:
* - Toggle loads initial state from settings API
* - Toggle changes persist to settings API
* - Toggle reflects correct state after page reload
* - Error handling when API calls fail
*
* Prerequisites: Web server running on http://127.0.0.1:5000
*
* Usage: node tests/ui_tests/test_collections_auto_index.js
*/
const puppeteer = require('puppeteer');
const AuthHelper = require('./auth_helper');
const { getPuppeteerLaunchOptions, takeScreenshot } = require('./puppeteer_config');
const BASE_URL = 'http://127.0.0.1:5000';
const COLLECTIONS_URL = `${BASE_URL}/library/collections`;
const SETTINGS_API_KEY = 'research_library.auto_index_enabled';
async function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function runTests() {
const browser = await puppeteer.launch(getPuppeteerLaunchOptions());
const page = await browser.newPage();
const authHelper = new AuthHelper(page, BASE_URL);
let passed = 0;
let failed = 0;
// Monitor console errors
const consoleErrors = [];
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
console.log(' Browser console error:', msg.text());
}
});
// Monitor network errors
const networkErrors = [];
page.on('response', response => {
if (response.status() >= 400) {
networkErrors.push({ status: response.status(), url: response.url() });
}
});
try {
console.log('🧪 Testing Collections Auto-Index Toggle\n');
// Authenticate first
console.log('📝 Authenticating...');
await authHelper.ensureAuthenticated();
console.log('✅ Authenticated\n');
// Test 1: Toggle exists on collections page
console.log('Test 1: Toggle exists on collections page');
await page.goto(COLLECTIONS_URL, { waitUntil: 'domcontentloaded', timeout: 30000 });
await delay(2000); // Wait for JS to load and execute
const toggleExists = await page.$('#auto-index-toggle');
if (toggleExists) {
console.log(' ✅ Toggle element found');
passed++;
} else {
console.log(' ❌ Toggle element not found');
failed++;
}
// Test 2: Toggle has associated label with tooltip
console.log('\nTest 2: Toggle has label with tooltip');
const labelExists = await page.$('label.ldr-checkbox-label');
const hasTooltip = await page.evaluate(() => {
const span = document.querySelector('label.ldr-checkbox-label .ldr-help-tooltip');
return span !== null;
});
if (labelExists && hasTooltip) {
console.log(' ✅ Label with tooltip exists');
passed++;
} else {
console.log(` ❌ Label (${!!labelExists}) or tooltip (${hasTooltip}) missing`);
failed++;
}
// Test 3: Toggle loads initial state from API
console.log('\nTest 3: Toggle loads state from settings API');
// Get the current setting value directly from API
const apiResponse = await page.evaluate(async (key) => {
const response = await fetch(`/settings/api/${key}`);
return response.json();
}, SETTINGS_API_KEY);
const toggleChecked = await page.evaluate(() => {
return document.getElementById('auto-index-toggle').checked;
});
const expectedChecked = apiResponse.value === true || apiResponse.value === 'true';
if (toggleChecked === expectedChecked) {
console.log(` ✅ Toggle state (${toggleChecked}) matches API value (${apiResponse.value})`);
passed++;
} else {
console.log(` ❌ Toggle state (${toggleChecked}) does not match API value (${apiResponse.value})`);
failed++;
}
// Test 4: Toggle change persists to API
console.log('\nTest 4: Toggle change persists to API');
const initialState = toggleChecked;
// Click the toggle to change state
await page.click('#auto-index-toggle');
await delay(1000); // Wait for API call
// Verify state changed in UI
const newToggleState = await page.evaluate(() => {
return document.getElementById('auto-index-toggle').checked;
});
// Verify state changed in API
const newApiResponse = await page.evaluate(async (key) => {
const response = await fetch(`/settings/api/${key}`);
return response.json();
}, SETTINGS_API_KEY);
const expectedNewState = newApiResponse.value === true || newApiResponse.value === 'true';
if (newToggleState !== initialState && newToggleState === expectedNewState) {
console.log(` ✅ Toggle changed from ${initialState} to ${newToggleState} and API reflects this`);
passed++;
} else {
console.log(` ❌ Toggle change failed: UI=${newToggleState}, API=${newApiResponse.value}, expected different from ${initialState}`);
failed++;
}
// Test 5: State persists after page reload
console.log('\nTest 5: State persists after page reload');
const stateBeforeReload = newToggleState;
await page.reload({ waitUntil: 'domcontentloaded', timeout: 30000 });
await delay(2000); // Wait for JS to load state
const stateAfterReload = await page.evaluate(() => {
return document.getElementById('auto-index-toggle').checked;
});
if (stateAfterReload === stateBeforeReload) {
console.log(` ✅ State persisted after reload: ${stateAfterReload}`);
passed++;
} else {
console.log(` ❌ State changed after reload: was ${stateBeforeReload}, now ${stateAfterReload}`);
failed++;
}
// Test 6: Toggle back to original state
console.log('\nTest 6: Toggle back to original state');
await page.click('#auto-index-toggle');
await delay(1000);
const restoredState = await page.evaluate(() => {
return document.getElementById('auto-index-toggle').checked;
});
if (restoredState === initialState) {
console.log(` ✅ Restored to original state: ${restoredState}`);
passed++;
} else {
console.log(` ❌ Failed to restore: expected ${initialState}, got ${restoredState}`);
failed++;
}
// Test 7: No console or network errors during tests
console.log('\nTest 7: No critical errors during tests');
const criticalConsoleErrors = consoleErrors.filter(e =>
!e.includes('favicon') && !e.includes('404')
);
const criticalNetworkErrors = networkErrors.filter(e =>
!e.url.includes('favicon') && e.status >= 500
);
if (criticalConsoleErrors.length === 0 && criticalNetworkErrors.length === 0) {
console.log(' ✅ No critical errors');
passed++;
} else {
console.log(` ❌ Found errors: ${criticalConsoleErrors.length} console, ${criticalNetworkErrors.length} network`);
criticalConsoleErrors.forEach(e => console.log(` Console: ${e}`));
criticalNetworkErrors.forEach(e => console.log(` Network: ${e.status} ${e.url}`));
failed++;
}
// Take screenshot for debugging
await takeScreenshot(page, '/tmp/collections_auto_index_test.png');
} catch (error) {
console.error('\n❌ Test error:', error.message);
await takeScreenshot(page, '/tmp/collections_auto_index_error.png');
failed++;
} finally {
await browser.close();
}
// Summary
console.log('\n' + '='.repeat(50));
console.log(`📊 Results: ${passed} passed, ${failed} failed`);
console.log('='.repeat(50));
process.exit(failed > 0 ? 1 : 0);
}
runTests();