Files
Momento/memento-note/tests/collaboration.spec.ts
Sepehr Ramezani aa6a214f37 feat: rename keep-notes to memento-note, migrate to PostgreSQL, fix MCP bugs
- Rename directory keep-notes -> memento-note with all code references
- Prisma: SQLite -> PostgreSQL (both app and MCP server schemas)
- Sync MCP schema with main app (add missing fields, relations, indexes)
- Delete 17 SQLite migrations (clean slate for PostgreSQL)
- Remove SQLite dependencies (@libsql/client, better-sqlite3, etc.)
- Fix MCP server: hardcoded Windows DB paths -> DATABASE_URL env var
- Fix MCP server: .dockerignore excluded index-sse.js (SSE mode broken)
- MCP Dockerfile: node:20 -> node:22
- Docker Compose: add postgres service, remove SQLite volume
- Generate favicon.ico, icon-192.png, icon-512.png, apple-icon.png
- Update layout.tsx icons and manifest.json for PNG icons
- Update all .env files for PostgreSQL
- Rewrite README.md with updated sections
- Remove mcp-server/node_modules and prisma/client-generated from git tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-20 20:58:04 +02:00

133 lines
4.8 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Collaboration Feature', () => {
test.beforeEach(async ({ page }) => {
// Login before each test
await page.goto('http://localhost:3000/login');
await page.fill('input[name="email"]', 'test@example.com');
await page.fill('input[name="password"]', 'password123');
await page.click('button[type="submit"]');
await page.waitForURL('http://localhost:3000/');
});
test('COLLAB-2: Add collaborator to existing note', async ({ page, context }) => {
// Start from the main page
await page.goto('http://localhost:3000/');
// Find a note card (should have at least one)
const noteCard = page.locator('[data-testid="note-card"]').first();
await expect(noteCard).toBeVisible();
// Open collaborator dialog from the note menu
await noteCard.hover();
await page.click('[aria-label="More options"]');
// Click "Share with collaborators"
await page.click('text=Share with collaborators');
// Verify dialog opens
const dialog = page.locator('[role="dialog"]');
await expect(dialog).toBeVisible();
await expect(dialog.locator('text=Share with collaborators')).toBeVisible();
// Try to add a collaborator (note: user may not exist)
await page.fill('input[type="email"]', 'collaborator@example.com');
await page.click('button:has-text("Invite")');
// Wait for response (either success or error toast)
await page.waitForTimeout(2000);
// Verify either:
// 1. Success: User added to list
// 2. Error: User not found message
const collaboratorInList = page.locator('text=collaborator@example.com');
const errorMessage = page.locator('.toast:has-text("User not found")');
const collaboratorAdded = await collaboratorInList.count() > 0;
const errorShown = await errorMessage.count() > 0;
expect(collaboratorAdded || errorShown).toBeTruthy();
});
test('COLLAB-2: Remove collaborator from note', async ({ page }) => {
// This test assumes a note with collaborators exists
await page.goto('http://localhost:3000/');
// Find a note card
const noteCard = page.locator('[data-testid="note-card"]').first();
await noteCard.hover();
await page.click('[aria-label="More options"]');
await page.click('text=Share with collaborators');
const dialog = page.locator('[role="dialog"]');
await expect(dialog).toBeVisible();
// Check if there are any collaborators listed
const collaboratorItems = dialog.locator('[data-testid="collaborator-item"]');
const count = await collaboratorItems.count();
if (count > 0) {
// Get initial count
const initialCount = count;
// Remove first collaborator
await collaboratorItems.first().hover();
await collaboratorItems.first().locator('button[aria-label="Remove"]').click();
// Wait for update
await page.waitForTimeout(1000);
// Verify count decreased
const newCount = await dialog.locator('[data-testid="collaborator-item"]').count();
expect(newCount).toBeLessThan(initialCount);
} else {
// Skip test if no collaborators exist
test.skip(true, 'No collaborators to remove');
}
});
test('COLLAB-2: View collaborators list', async ({ page }) => {
await page.goto('http://localhost:3000/');
const noteCard = page.locator('[data-testid="note-card"]').first();
await noteCard.hover();
await page.click('[aria-label="More options"]');
await page.click('text=Share with collaborators');
const dialog = page.locator('[role="dialog"]');
await expect(dialog).toBeVisible();
// Verify "People with access" section exists
await expect(dialog.locator('text=People with access')).toBeVisible();
// Check for owner badge
const ownerBadge = dialog.locator('text=Owner');
await expect(ownerBadge).toBeVisible();
});
test('COLLAB-2: Non-owner cannot remove collaborators', async ({ page }) => {
// This test requires setup with a shared note where current user is not owner
// For now, we'll test the UI shows correct state
await page.goto('http://localhost:3000/');
const noteCard = page.locator('[data-testid="note-card"]').first();
await noteCard.hover();
await page.click('[aria-label="More options"]');
await page.click('text=Share with collaborators');
const dialog = page.locator('[role="dialog"]');
await expect(dialog).toBeVisible();
// Verify "Only the owner can manage collaborators" message appears if not owner
const description = dialog.locator('text=You have access to this note');
const isNotOwner = await description.count() > 0;
if (isNotOwner) {
// Verify no remove buttons are visible
const removeButtons = dialog.locator('button[aria-label="Remove"]');
expect(await removeButtons.count()).toBe(0);
}
});
});