feat(PINE-29): E2E index/collection management tests - #27
Conversation
Implemented comprehensive E2E tests for connection management: Pinecone Tests: - Connection modal display and form validation - Required field validation - Error handling for invalid API keys - Successful connection with valid credentials - Collections/indexes display after connection - Disconnect functionality - Reconnection after disconnect - Profile saving and loading - Unreachable URL error handling Qdrant/Weaviate Tests: - Skeleton tests with test.skip() and TODO comments - Will be enabled when adapter system is integrated Test Features: - Uses Docker test containers from docker-compose.test.yml - Leverages existing e2e/electron.setup.ts helpers - Auto-skips tests requiring real API keys when not available - Comprehensive error path testing Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive E2E tests for index/collection operations: - List indexes/collections after connecting - View index/collection stats (vector count, dimensions) - Create new collection with provider-specific settings - Delete collection (with confirmation) - Refresh collection list Implementation: - 8 active Pinecone tests covering full index lifecycle - 13 skipped Qdrant/Weaviate tests with TODO comments - Uses existing e2e/ infrastructure from PINE-28 - Tests use window.electronAPI for IPC communication - Proper test isolation with unique profile/index names Test coverage: ✅ Pinecone: List, stats, create, delete, refresh, error handling 🔲 Qdrant: Pending adapter integration 🔲 Weaviate: Pending adapter integration References: PINE-29 Related: IndexesPanel.tsx, IndexConfigView.tsx Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
📝 WalkthroughWalkthroughThis pull request introduces comprehensive end-to-end testing infrastructure for an Electron app managing vector database connections. Two major Playwright test suites (connection-flow and index-collection-management) were added, alongside documentation detailing test coverage, with Pinecone fully implemented and Qdrant/Weaviate scaffolded. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@e2e/index-collection-management.spec.ts`:
- Around line 185-198: Replace the fixed 5s sleep used via page.waitForTimeout
with a polling loop that repeatedly calls the Pinecone API (use the same call
site: page.evaluate invoking (window as any).electronAPI.pinecone.listIndexes or
describeIndex with testProfileId) and checks the created index's status.ready
flag for the index matching testIndexName; poll at ~1s intervals up to a
reasonable timeout (e.g. 60s) and only proceed to the expect assertions once
status.ready is true (fail the test if timeout is reached).
🧹 Nitpick comments (3)
e2e/connection-flow.spec.ts (2)
92-103: Consider usingtest.skipannotation for conditional tests.The current pattern of checking
hasRealApiKeyinside each test and callingtest.skip()works but is verbose and repeated across multiple tests. Consider using Playwright's conditional skip annotation or a custom fixture.♻️ Alternative approach using test.skip condition
// Option 1: Use test.skip with a condition at the test level const hasRealApiKey = !!process.env.PINECONE_API_KEY && process.env.PINECONE_API_KEY !== 'dummy-key-for-local-testing' test.describe('Pinecone Connection Flow', () => { test('should successfully connect with valid credentials', async () => { test.skip(!hasRealApiKey, 'Requires real PINECONE_API_KEY') // ... test body }) })// Option 2: Use test.describe.configure to skip entire describe block test.describe('Pinecone Connection Flow - Real API', () => { test.skip(!hasRealApiKey) // All tests in this block will be skipped if no API key })
121-122: Consider replacing hardcoded timeouts with condition-based waits.Hardcoded
waitForTimeoutcalls can lead to flaky tests. Where possible, poll for a condition that indicates readiness.♻️ Example: Poll until connection is ready
// Instead of: await page.waitForTimeout(2000) // Use a polling approach: await expect(async () => { const indexes = await page.evaluate(async (id) => { return await (window as any).electronAPI.pinecone.listIndexes(id) }, profileId) expect(Array.isArray(indexes)).toBe(true) }).toPass({ timeout: 10000 })e2e/index-collection-management.spec.ts (1)
25-26: Add cleanup for test-created index to prevent resource leaks.The
testIndexNameis created in one test and deleted in another. If the delete test is skipped (e.g., due to test filtering) or fails, the index may remain in the Pinecone account. Consider adding anafterAllhook to clean up any created test indexes.♻️ Add afterAll cleanup hook
test.describe('Pinecone Index Management', () => { let testProfileId: string let testIndexName: string test.beforeAll(async () => { // ... existing setup }) + test.afterAll(async () => { + const { page } = electronContext + + // Cleanup any test indexes that may have been created + if (testIndexName && testProfileId) { + try { + await page.evaluate(async ({ id, name }) => { + try { + await (window as any).electronAPI.pinecone.deleteIndex(id, name) + } catch { + // Index may already be deleted or not exist + } + }, { id: testProfileId, name: testIndexName }) + } catch { + // Ignore cleanup errors + } + } + })Also applies to: 155-235
| // Wait for index to be created and become ready | ||
| // Pinecone indexes can take a while to initialize | ||
| await page.waitForTimeout(5000) | ||
|
|
||
| // Verify index was created by listing indexes | ||
| const indexes = await page.evaluate(async (id) => { | ||
| return await (window as any).electronAPI.pinecone.listIndexes(id) | ||
| }, testProfileId) | ||
|
|
||
| const createdIndex = indexes.find((idx: any) => idx.name === testIndexName) | ||
| expect(createdIndex).toBeDefined() | ||
| expect(createdIndex?.dimension).toBe(384) | ||
| expect(createdIndex?.metric).toBe('cosine') | ||
| }) |
There was a problem hiding this comment.
Index creation timeout may be insufficient.
Pinecone serverless indexes can take 30-60+ seconds to become ready. The 5-second wait at line 187 may not be sufficient, leading to flaky tests. Consider polling for the index's status.ready property.
🔧 Suggested approach: Poll for index readiness
- // Wait for index to be created and become ready
- // Pinecone indexes can take a while to initialize
- await page.waitForTimeout(5000)
-
- // Verify index was created by listing indexes
- const indexes = await page.evaluate(async (id) => {
- return await (window as any).electronAPI.pinecone.listIndexes(id)
- }, testProfileId)
+ // Poll for index to become ready (can take 30-60+ seconds)
+ await expect(async () => {
+ const indexes = await page.evaluate(async (id) => {
+ return await (window as any).electronAPI.pinecone.listIndexes(id)
+ }, testProfileId)
+ const createdIndex = indexes.find((idx: any) => idx.name === testIndexName)
+ expect(createdIndex).toBeDefined()
+ expect(createdIndex?.status?.ready).toBe(true)
+ }).toPass({ timeout: 90000, intervals: [5000] })
+
+ const indexes = await page.evaluate(async (id) => {
+ return await (window as any).electronAPI.pinecone.listIndexes(id)
+ }, testProfileId)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Wait for index to be created and become ready | |
| // Pinecone indexes can take a while to initialize | |
| await page.waitForTimeout(5000) | |
| // Verify index was created by listing indexes | |
| const indexes = await page.evaluate(async (id) => { | |
| return await (window as any).electronAPI.pinecone.listIndexes(id) | |
| }, testProfileId) | |
| const createdIndex = indexes.find((idx: any) => idx.name === testIndexName) | |
| expect(createdIndex).toBeDefined() | |
| expect(createdIndex?.dimension).toBe(384) | |
| expect(createdIndex?.metric).toBe('cosine') | |
| }) | |
| // Poll for index to become ready (can take 30-60+ seconds) | |
| await expect(async () => { | |
| const indexes = await page.evaluate(async (id) => { | |
| return await (window as any).electronAPI.pinecone.listIndexes(id) | |
| }, testProfileId) | |
| const createdIndex = indexes.find((idx: any) => idx.name === testIndexName) | |
| expect(createdIndex).toBeDefined() | |
| expect(createdIndex?.status?.ready).toBe(true) | |
| }).toPass({ timeout: 90000, intervals: [5000] }) | |
| const indexes = await page.evaluate(async (id) => { | |
| return await (window as any).electronAPI.pinecone.listIndexes(id) | |
| }, testProfileId) | |
| const createdIndex = indexes.find((idx: any) => idx.name === testIndexName) | |
| expect(createdIndex).toBeDefined() | |
| expect(createdIndex?.dimension).toBe(384) | |
| expect(createdIndex?.metric).toBe('cosine') |
🤖 Prompt for AI Agents
In `@e2e/index-collection-management.spec.ts` around lines 185 - 198, Replace the
fixed 5s sleep used via page.waitForTimeout with a polling loop that repeatedly
calls the Pinecone API (use the same call site: page.evaluate invoking (window
as any).electronAPI.pinecone.listIndexes or describeIndex with testProfileId)
and checks the created index's status.ready flag for the index matching
testIndexName; poll at ~1s intervals up to a reasonable timeout (e.g. 60s) and
only proceed to the expect assertions once status.ready is true (fail the test
if timeout is reached).
- Fix index creation timeout: use polling (90s) instead of fixed 5s wait - Add gitleaks:allow comments to prevent false positives on test API keys - Index creation now properly waits for status.ready=true Addresses review comments from PRs #27, #29 Co-authored-by: Stepan Arsentjev <stepandel@users.noreply.github.com>
* fix: address E2E test review issues - Fix index creation timeout: use polling (90s) instead of fixed 5s wait - Add gitleaks:allow comments to prevent false positives on test API keys - Index creation now properly waits for status.ready=true Addresses review comments from PRs #27, #29 * fix: address remaining E2E review issues - Add teardown in namespace-operations.spec.ts to delete test-created namespaces/vectors - Change vector-browsing.spec.ts to create dedicated test namespace with known metadata instead of reusing existing namespace - Fix forEach callbacks in vector-browsing.spec.ts to use explicit block bodies instead of implicit returns - Use test.describe.serial for stateful index create/delete tests in index-collection-management.spec.ts - Replace fixed sleeps with polling in index-collection-management.spec.ts Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Stepan Arsentjev <stepandel@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Summary
Comprehensive E2E tests for index/collection operations.
Pinecone Tests (7 Active)
Qdrant & Weaviate Tests (13 Skipped)
test.skip()and detailed TODO commentsTest Features
window.electronAPIIPC methodsPINECONE_API_KEY)Closes PINE-29
Summary by CodeRabbit
Tests
Documentation