Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
7992bd9
fix(e2e): make labels tests resilient to existing data
patchmemory Feb 5, 2026
6f95c12
feat(map): integrate Labels and Neo4j schema into Map page visualization
patchmemory Feb 5, 2026
5d72656
chore(dev): update submodule pointer for completed task
patchmemory Feb 5, 2026
cae8558
feat(labels): add Arrows.app schema import/export functionality
patchmemory Feb 5, 2026
d930f1e
chore(dev): update submodule pointer for completed task
patchmemory Feb 5, 2026
fa2e000
fix(labels): fix Arrows import button and modal hiding issues
patchmemory Feb 5, 2026
2f381d2
fix(e2e): improve timing for arrows import test
patchmemory Feb 5, 2026
9e8f58c
fix(e2e): manually trigger input event for textarea fill
patchmemory Feb 5, 2026
c7ee21d
fix(e2e): fix modal timing and duplicate variable issues
patchmemory Feb 5, 2026
73cd7c2
fix(e2e): improve arrows import test reliability
patchmemory Feb 5, 2026
a645a9f
fix(labels): remove syntax error breaking Arrows buttons
patchmemory Feb 5, 2026
ad99014
debug(labels): add console logging to arrows import/export
patchmemory Feb 5, 2026
7f53c2d
fix(labels): implement custom modal for Arrows import + test cleanup
patchmemory Feb 5, 2026
b9c861e
fix(e2e): update labels-arrows tests for custom modal + add label cle…
patchmemory Feb 5, 2026
1bc6c28
feat(labels): add incoming relationships section to Labels UI
patchmemory Feb 5, 2026
6f8e098
chore(dev): update submodule with new expandable textarea task
patchmemory Feb 5, 2026
904d595
fix(labels): correct table name in cleanup + fix dropdown rendering
patchmemory Feb 5, 2026
825ee45
fix(e2e): check relationship input values instead of textContent
patchmemory Feb 5, 2026
858653b
feat(labels): show total relationship count with incoming/outgoing br…
patchmemory Feb 5, 2026
749bda5
feat(labels): make source labels clickable in incoming relationships
patchmemory Feb 5, 2026
e05568e
feat(labels): add navigation buttons to outgoing relationships
patchmemory Feb 5, 2026
33b9256
chore(dev): update submodule with Neo4j instance editing tasks
patchmemory Feb 6, 2026
00280c4
chore(dev): update submodule to sync ready-queue
patchmemory Feb 6, 2026
b7274ca
fix(neo4j): add missing get_neo4j_client function to neo4j_client module
patchmemory Feb 6, 2026
3b6913a
fix(neo4j): add execute_read and execute_write methods to Neo4jClient
patchmemory Feb 6, 2026
7add750
feat(labels): separate per-label and bulk Neo4j pull operations
patchmemory Feb 6, 2026
68862dc
refactor(labels): remove Push button and enhance Pull to include rela…
patchmemory Feb 6, 2026
67d9b61
feat(labels): add multi-select and batch operations
patchmemory Feb 6, 2026
ee0c15b
fix(labels): include relationships in Pull All operation
patchmemory Feb 6, 2026
1b39141
fix(labels): correct Neo4j relationship queries for all pull operations
patchmemory Feb 6, 2026
040b3cc
fix(labels): use MATCH pattern for Pull All relationships
patchmemory Feb 6, 2026
a3f1586
feat(labels): add comprehensive keyboard navigation
patchmemory Feb 6, 2026
bef5d11
fix(labels): enable button Enter key and add Shift+navigation selection
patchmemory Feb 6, 2026
9e34112
fix(labels): proper shift+navigation selection anchor tracking
patchmemory Feb 6, 2026
48271cc
style(labels): change "New Label" button to "+ Label" with bold text
patchmemory Feb 6, 2026
a23de4a
feat(labels): add adjustable divider between panels
patchmemory Feb 6, 2026
a291227
feat(ui): comprehensive keyboard navigation for Labels page
patchmemory Feb 6, 2026
3c72e7e
test: add comprehensive unit tests for labels API operations
patchmemory Feb 6, 2026
47e0737
feat(links): implement wizard visual summary and fix settings E2E tests
patchmemory Feb 6, 2026
04be807
feat(labels): add EDA file import functionality
patchmemory Feb 6, 2026
6bdfb6d
chore(dev): update submodule pointer for eda-file-interpreter task
patchmemory Feb 6, 2026
d2a31a7
refactor(labels): consolidate EDA import into unified Import modal
patchmemory Feb 6, 2026
70c8158
fix(labels): add missing EDA import endpoint
patchmemory Feb 6, 2026
c739bdd
chore(dev): update submodule pointer for completed eda-file-interpreter
patchmemory Feb 6, 2026
1bb128b
chore(dev): switch submodule to main branch
patchmemory Feb 6, 2026
614e2a7
chore(dev): merge feature branch and update submodule pointer
patchmemory Feb 6, 2026
4057d44
feat(settings): implement API endpoint registry for Links integration
patchmemory Feb 6, 2026
1ec8e33
Merge task: API endpoint registry for Links (#settings-api-endpoints)
patchmemory Feb 6, 2026
8afdf3b
feat(settings): add API Endpoint Registry for Links integration
patchmemory Feb 6, 2026
29675f1
feat(ui): rebrand logo and page titles to -SciDK->
patchmemory Feb 6, 2026
4948aa5
feat(links): implement table format registry for CSV/TSV/Excel/Parque…
patchmemory Feb 6, 2026
055064b
test(links): add comprehensive unit tests for table format registry
patchmemory Feb 6, 2026
f257e04
test(links): add E2E tests for table format registry
patchmemory Feb 6, 2026
5c43ab4
chore(dev): update submodule pointer for completed task:ui/links/sett…
patchmemory Feb 6, 2026
11ff8b3
feat(links): implement hybrid fuzzy matching with rapidfuzz and Neo4j…
patchmemory Feb 6, 2026
98e1c6c
test(links): add comprehensive tests for fuzzy matching
patchmemory Feb 6, 2026
85af95e
chore(dev): update submodule pointer for completed task:ui/links/sett…
patchmemory Feb 6, 2026
90222ee
fix(e2e): add baseURL fallback to fuzzy matching tests
patchmemory Feb 6, 2026
da0af2d
refactor(ui): rename Links to Integrations throughout codebase
patchmemory Feb 6, 2026
6113f37
chore(dev): update submodule pointer for completed task:ui/integratio…
patchmemory Feb 6, 2026
ae91809
fix(ui): change nav item from 'Integrate' to 'Integrations' for noun …
patchmemory Feb 6, 2026
0ff7941
feat(ui/labels): implement three-column layout with statistics panel
patchmemory Feb 6, 2026
ee07fdd
feat(ui/labels): add read-only/edit mode toggle
patchmemory Feb 6, 2026
93283bf
feat(ui/labels): add instance browser UI and API endpoints
patchmemory Feb 6, 2026
0307e51
feat(services): implement instance management methods in LabelService
patchmemory Feb 6, 2026
d940904
fix(ui/labels): improve error handling and debug logging
patchmemory Feb 6, 2026
494e89b
debug: add extensive console logging to track initialization
patchmemory Feb 6, 2026
cf5c1df
fix(ui/labels): resolve duplicate variable declaration causing JavaSc…
patchmemory Feb 6, 2026
04ffa14
feat(ui/labels): implement editable cells and push functionality for …
patchmemory Feb 6, 2026
7d739c7
test(labels): add tests for instance management API endpoints
patchmemory Feb 6, 2026
f4c3e92
feat(ui/labels): improve UX with better collapse buttons, relationshi…
patchmemory Feb 6, 2026
9196c74
chore: update dev submodule with future enhancements documentation
patchmemory Feb 6, 2026
71714f2
fix(ui/labels): correct relationship formatting to read as proper tri…
patchmemory Feb 6, 2026
fa6395e
style(ui/labels): refine relationship formatting with em dash and emp…
patchmemory Feb 6, 2026
e256ddb
feat(ui/labels): add keyboard navigation for properties and relations…
patchmemory Feb 6, 2026
0d85e47
chore(dev): update submodule to include completed task status
patchmemory Feb 6, 2026
48ecd7c
fix(ui/labels): improve keyboard navigation focus isolation and stand…
patchmemory Feb 6, 2026
db5618c
Merge branch 'main' into task/task-ui/labels/three-column-layout-with…
patchmemory Feb 6, 2026
e3b870c
chore(dev): update submodule to latest (d71bf7f) with task index sync
patchmemory Feb 8, 2026
dff1985
fix(deps): add pandas and rapidfuzz to pyproject.toml dependencies
patchmemory Feb 8, 2026
b9b4d3a
chore(deps): add beautifulsoup4 to requirements.txt for consistency
patchmemory Feb 8, 2026
1a13512
fix(e2e): remove duplicate links test files and fix wizard navigation…
patchmemory Feb 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions DEMO_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,42 @@ The test suite creates temporary test data. You can reference `tests/conftest.py
- Read-only: checked (recommended for demo)
3. Click **"Create Mount"**

### API Endpoints (for Links Integration)

1. Navigate to **Settings** > **Links** section
2. Scroll to "API Endpoint Mappings"
3. Configure a new endpoint:
- **Name**: Descriptive name (e.g., "Users API")
- **URL**: Full API endpoint URL (e.g., `https://api.example.com/users`)
- **Auth Method**: Select authentication type:
- `None`: No authentication
- `Bearer Token`: OAuth/JWT bearer token
- `API Key`: API key in X-API-Key header
- **Auth Value**: Enter token/key if authentication is required
- **JSONPath** (optional): Extract specific data (e.g., `$.data[*]`)
- **Maps to Label** (optional): Target Label for imported data
4. Click **"Test Connection"** to verify the endpoint
5. Click **"Save Endpoint"** to register it

**Using API Endpoints in Links:**
- Registered endpoints appear in the Links wizard
- Select an endpoint as a data source when creating links
- Field mappings automatically populate from endpoint configuration

**Security Notes:**
- Auth tokens are encrypted at rest in the settings database
- For production, set `SCIDK_API_ENCRYPTION_KEY` environment variable
- Without this variable, an ephemeral key is generated (not persistent across restarts)

**Example: JSONPlaceholder Test API**
```
Name: JSONPlaceholder Users
URL: https://jsonplaceholder.typicode.com/users
Auth Method: None
JSONPath: $[*]
Maps to Label: User
```

## Troubleshooting

### Application Won't Start
Expand Down
4 changes: 2 additions & 2 deletions e2e/chat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test('chat page loads and displays beta badge', async ({ page, baseURL }) => {
await page.waitForLoadState('networkidle');

// Verify page loads
await expect(page).toHaveTitle(/SciDK - Chats/i, { timeout: 10_000 });
await expect(page).toHaveTitle(/-SciDK-> Chats/i, { timeout: 10_000 });

// Check for Beta badge
const betaBadge = page.locator('.badge');
Expand Down Expand Up @@ -57,7 +57,7 @@ test('chat navigation link is visible in header', async ({ page, baseURL }) => {
// Click it and verify we navigate to chat page
await chatsLink.click();
await page.waitForLoadState('networkidle');
await expect(page).toHaveTitle(/SciDK - Chats/i);
await expect(page).toHaveTitle(/-SciDK-> Chats/i);
});

test('chat form can accept input', async ({ page, baseURL }) => {
Expand Down
2 changes: 1 addition & 1 deletion e2e/core-flows.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ test('navigation covers all 7 pages', async ({ page, baseURL }) => {
{ testId: 'nav-maps', url: '/map', titlePattern: /Map/i },
{ testId: 'nav-chats', url: '/chat', titlePattern: /Chat/i },
{ testId: 'nav-labels', url: '/labels', titlePattern: /Labels/i },
{ testId: 'nav-links', url: '/links', titlePattern: /Links/i },
{ testId: 'nav-integrate', url: '/integrate', titlePattern: /-SciDK-> Integrations/i },
{ testId: 'nav-settings', url: '/settings', titlePattern: /Settings/i },
];

Expand Down
10 changes: 10 additions & 0 deletions e2e/global-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ export default async function globalSetup(config: FullConfig) {
(process as any).env.BASE_URL = baseUrl;

await waitForReady(baseUrl);

// Clean up any leftover test data from previous runs
try {
await fetch(`${baseUrl}/api/admin/cleanup-test-scans`, { method: 'POST' });
await fetch(`${baseUrl}/api/admin/cleanup-test-labels`, { method: 'POST' });
await fetch(`${baseUrl}/api/admin/cleanup-test-endpoints`, { method: 'POST' });
console.log('[setup] Test data cleaned up');
} catch (error) {
console.error('[setup] Failed to cleanup test data:', error);
}
}

export async function teardown() {
Expand Down
11 changes: 11 additions & 0 deletions e2e/global-teardown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ export default async function globalTeardown(config: FullConfig) {
} catch (error) {
console.error('[cleanup] Failed to cleanup test labels:', error);
}

// Clean up test API endpoints
try {
const response = await fetch(`${baseUrl}/api/admin/cleanup-test-endpoints`, {
method: 'POST',
});
const result = await response.json();
console.log('[cleanup] Test API endpoints cleaned up:', result);
} catch (error) {
console.error('[cleanup] Failed to cleanup test API endpoints:', error);
}
}

// Kill the server process
Expand Down
24 changes: 12 additions & 12 deletions e2e/links-advanced.spec.ts → e2e/integrations-advanced.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { test, expect } from '@playwright/test';

test('links page api source inputs are functional', async ({ page, baseURL }) => {
const base = baseURL || process.env.BASE_URL || 'http://127.0.0.1:5000';
await page.goto(`${base}/links`);
await page.goto(`${base}/integrate`);
await page.waitForLoadState('networkidle');

// Wait for labels to load (Links page needs labels for dropdowns)
await page.waitForTimeout(2000);

// Create new link
await page.getByTestId('new-link-btn').click();
await page.getByTestId('new-integration-btn').click();

// Switch to API source type
const apiSourceButton = page.locator('button').filter({ hasText: /^API$/i });
Expand All @@ -38,14 +38,14 @@ test('links page api source inputs are functional', async ({ page, baseURL }) =>

test('links page target graph label input is functional', async ({ page, baseURL }) => {
const base = baseURL || process.env.BASE_URL || 'http://127.0.0.1:5000';
await page.goto(`${base}/links`);
await page.goto(`${base}/integrate`);
await page.waitForLoadState('networkidle');

// Wait for labels to load (Links page needs labels for dropdowns)
await page.waitForTimeout(2000);

// Create new link
await page.getByTestId('new-link-btn').click();
await page.getByTestId('new-integration-btn').click();

// Navigate to target step (wizard has: source -> target -> matching -> relationship)
const nextButton = page.locator('#btn-next');
Expand Down Expand Up @@ -78,14 +78,14 @@ test('links page target graph label input is functional', async ({ page, baseURL

test('links page cypher matching query input is functional', async ({ page, baseURL }) => {
const base = baseURL || process.env.BASE_URL || 'http://127.0.0.1:5000';
await page.goto(`${base}/links`);
await page.goto(`${base}/integrate`);
await page.waitForLoadState('networkidle');

// Wait for labels to load (Links page needs labels for dropdowns)
await page.waitForTimeout(2000);

// Create new link
await page.getByTestId('new-link-btn').click();
await page.getByTestId('new-integration-btn').click();

// Navigate through wizard to matching step (4 steps to reach matching)
const nextButton = page.locator('#btn-next');
Expand Down Expand Up @@ -118,14 +118,14 @@ test('links page cypher matching query input is functional', async ({ page, base

test('links page preview button is present', async ({ page, baseURL }) => {
const base = baseURL || process.env.BASE_URL || 'http://127.0.0.1:5000';
await page.goto(`${base}/links`);
await page.goto(`${base}/integrate`);
await page.waitForLoadState('networkidle');

// Wait for labels to load (Links page needs labels for dropdowns)
await page.waitForTimeout(2000);

// Create new link
await page.getByTestId('new-link-btn').click();
await page.getByTestId('new-integration-btn').click();

// Navigate through wizard
const nextButton = page.locator('#btn-next');
Expand Down Expand Up @@ -155,7 +155,7 @@ test('links page preview button is present', async ({ page, baseURL }) => {

test('links page execute button is present and functional', async ({ page, baseURL }) => {
const base = baseURL || process.env.BASE_URL || 'http://127.0.0.1:5000';
await page.goto(`${base}/links`);
await page.goto(`${base}/integrate`);
await page.waitForLoadState('networkidle');

// Wait for labels to load (Links page needs labels for dropdowns)
Expand All @@ -174,7 +174,7 @@ test('links page execute button is present and functional', async ({ page, baseU
await expect(executeButton).toBeVisible();

// Mock API to prevent actual execution
await page.route('**/api/links/*/execute', async (route) => {
await page.route('**/api/integrate/*/execute', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
Expand All @@ -191,10 +191,10 @@ test('links page execute button is present and functional', async ({ page, baseU
}
} else {
// Create a new link and save it first
await page.getByTestId('new-link-btn').click();
await page.getByTestId('new-integration-btn').click();

// Fill in minimal link data
await page.locator('#link-name').fill('Test Execute Link');
await page.locator('#integration-name').fill('Test Execute Link');

// Fill CSV data
const csvData = page.locator('#csv-data');
Expand Down
Loading