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
283 lines
9.7 KiB
JavaScript
283 lines
9.7 KiB
JavaScript
/**
|
|
* UI Tests for Library Document Management
|
|
* Tests document viewing, searching, and management in the Library.
|
|
*/
|
|
|
|
const puppeteer = require('puppeteer');
|
|
const AuthHelper = require('../auth_helper');
|
|
const { getPuppeteerLaunchOptions } = require('../puppeteer_config');
|
|
|
|
const BASE_URL = process.env.TEST_BASE_URL || 'http://127.0.0.1:5000';
|
|
const TIMEOUT = 30000;
|
|
|
|
// Helper function for delays (Puppeteer doesn't have waitForTimeout like Playwright)
|
|
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
describe('Library Documents UI Tests', () => {
|
|
let browser;
|
|
let page;
|
|
let authHelper;
|
|
|
|
beforeAll(async () => {
|
|
browser = await puppeteer.launch(getPuppeteerLaunchOptions());
|
|
});
|
|
|
|
afterAll(async () => {
|
|
if (browser) {
|
|
await browser.close();
|
|
}
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
page = await browser.newPage();
|
|
page.setDefaultTimeout(TIMEOUT);
|
|
authHelper = new AuthHelper(page, BASE_URL);
|
|
|
|
// Authenticate before each test
|
|
await page.goto(BASE_URL, { waitUntil: 'domcontentloaded' });
|
|
await authHelper.ensureAuthenticated();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
if (page) {
|
|
await page.close();
|
|
}
|
|
});
|
|
|
|
describe('Library Page Load', () => {
|
|
test('should load library page', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
const pageTitle = await page.title();
|
|
expect(pageTitle.toLowerCase()).toContain('library');
|
|
});
|
|
|
|
test('should display navigation elements', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Check for main navigation elements
|
|
const mainNav = await page.$('nav, .navbar, .sidebar');
|
|
expect(mainNav).toBeTruthy();
|
|
|
|
// Check for library-specific navigation
|
|
const libraryNav = await page.$('.library-nav, .collection-sidebar, [role="navigation"]');
|
|
// Library nav is optional but page should load
|
|
const pageContent = await page.content();
|
|
expect(pageContent.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test('should show search functionality', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for search input
|
|
const searchInput = await page.$(
|
|
'input[type="search"], input[name="query"], .search-input, #library-search'
|
|
);
|
|
|
|
// Search should be available
|
|
expect(searchInput).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
describe('Document Search', () => {
|
|
test('should allow entering search query', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
const searchInput = await page.$(
|
|
'input[type="search"], input[name="query"], .search-input'
|
|
);
|
|
|
|
if (searchInput) {
|
|
await searchInput.type('test query');
|
|
|
|
const inputValue = await page.$eval(
|
|
'input[type="search"], input[name="query"], .search-input',
|
|
el => el.value
|
|
);
|
|
expect(inputValue).toBe('test query');
|
|
}
|
|
});
|
|
|
|
test('should submit search form', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
const searchInput = await page.$(
|
|
'input[type="search"], input[name="query"], .search-input'
|
|
);
|
|
|
|
if (searchInput) {
|
|
await searchInput.type('machine learning');
|
|
|
|
// Submit search
|
|
await page.keyboard.press('Enter');
|
|
|
|
// Wait for results or loading state
|
|
await delay(2000);
|
|
|
|
// Check for results or empty state
|
|
const pageContent = await page.content();
|
|
const hasResults = pageContent.includes('result') ||
|
|
pageContent.includes('document') ||
|
|
pageContent.includes('No results');
|
|
|
|
expect(hasResults).toBeTruthy();
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('Document Viewer', () => {
|
|
test('should open document when clicked', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for a document link
|
|
const documentLink = await page.$(
|
|
'.document-item a, [data-document-id], .doc-title'
|
|
);
|
|
|
|
if (documentLink) {
|
|
const initialUrl = page.url();
|
|
await documentLink.click();
|
|
await delay(1000);
|
|
|
|
const newUrl = page.url();
|
|
// URL should change or modal should open
|
|
const urlChanged = newUrl !== initialUrl;
|
|
const modalOpened = await page.$('.modal.show, .document-viewer');
|
|
|
|
expect(urlChanged || modalOpened).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test('should display document content', async () => {
|
|
// Navigate to a specific document if available
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
const documentLink = await page.$(
|
|
'.document-item a, [data-document-id]'
|
|
);
|
|
|
|
if (documentLink) {
|
|
await documentLink.click();
|
|
await delay(2000);
|
|
|
|
// Look for document content area
|
|
const contentArea = await page.$(
|
|
'.document-content, .doc-viewer, .pdf-viewer, .text-content'
|
|
);
|
|
|
|
// Content area should exist if document was opened
|
|
const pageContent = await page.content();
|
|
expect(pageContent.length).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('Document Actions', () => {
|
|
test('should show document action menu', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for action menu button
|
|
const actionButton = await page.$(
|
|
'.doc-actions, .dropdown-toggle, [data-action="more"]'
|
|
);
|
|
|
|
if (actionButton) {
|
|
await actionButton.click();
|
|
|
|
// Menu should appear
|
|
const menu = await page.$('.dropdown-menu.show, .action-menu');
|
|
expect(menu).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test('should allow document deletion', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for delete option
|
|
const deleteButton = await page.$(
|
|
'button[data-action="delete-doc"], .delete-doc-btn'
|
|
);
|
|
|
|
if (deleteButton) {
|
|
await deleteButton.click();
|
|
|
|
// Should show confirmation
|
|
const confirmDialog = await page.$('.confirm-dialog, .modal-confirm');
|
|
expect(confirmDialog).toBeTruthy();
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('RAG Integration', () => {
|
|
test('should show RAG search option', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for RAG/semantic search option
|
|
const ragOption = await page.$(
|
|
'.rag-search, [data-action="semantic-search"], .ai-search'
|
|
);
|
|
|
|
// RAG search may be available
|
|
const pageContent = await page.content();
|
|
const hasRagFeature = ragOption !== null ||
|
|
pageContent.includes('semantic') ||
|
|
pageContent.includes('AI search') ||
|
|
pageContent.includes('RAG');
|
|
|
|
// Just verify page loaded
|
|
expect(pageContent.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test('should show index status', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for index status indicator
|
|
const indexStatus = await page.$(
|
|
'.index-status, [data-testid="rag-status"], .embedding-status'
|
|
);
|
|
|
|
// Status may or may not be visible
|
|
const pageContent = await page.content();
|
|
expect(pageContent.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('Download Manager', () => {
|
|
test('should show download queue link', async () => {
|
|
await page.goto(`${BASE_URL}/library/`, { waitUntil: 'domcontentloaded' });
|
|
|
|
// Look for download queue link
|
|
const downloadQueueLink = await page.$(
|
|
'a[href*="downloads"], .download-queue-link'
|
|
);
|
|
|
|
const pageContent = await page.content();
|
|
const hasDownloadFeature = downloadQueueLink !== null ||
|
|
pageContent.includes('download') ||
|
|
pageContent.includes('queue');
|
|
|
|
expect(pageContent.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test('should open download queue page', async () => {
|
|
// Navigate directly to downloads page
|
|
await page.goto(`${BASE_URL}/library/downloads`, { waitUntil: 'domcontentloaded' });
|
|
const pageTitle = await page.title();
|
|
const pageContent = await page.content();
|
|
|
|
// Should load without error
|
|
expect(pageContent.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
// Run tests
|
|
if (require.main === module) {
|
|
const { execSync } = require('child_process');
|
|
try {
|
|
execSync(`npx jest ${__filename} --testTimeout=60000`, { stdio: 'inherit' });
|
|
} catch {
|
|
process.exit(1);
|
|
}
|
|
}
|