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>
This commit is contained in:
161
memento-note/tests/recent-notes-section.spec.ts
Normal file
161
memento-note/tests/recent-notes-section.spec.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Recent Notes Section', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Navigate to home page
|
||||
await page.goto('/')
|
||||
// Wait for page to load
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('should display recent notes section when notes exist', async ({ page }) => {
|
||||
// Check if recent notes section exists
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
|
||||
// The section should be visible when there are recent notes
|
||||
// Note: This test assumes there are notes created/modified in the last 7 days
|
||||
await expect(recentSection).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show section header with clock icon and title', async ({ page }) => {
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
|
||||
// Check for header elements
|
||||
await expect(recentSection.locator('text=Recent Notes')).toBeVisible()
|
||||
await expect(recentSection.locator('text=(last 7 days)')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should be collapsible', async ({ page }) => {
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
const collapseButton = recentSection.locator('button[aria-expanded]')
|
||||
|
||||
// Check that collapse button exists
|
||||
await expect(collapseButton).toBeVisible()
|
||||
|
||||
// Click to collapse
|
||||
await collapseButton.click()
|
||||
await expect(collapseButton).toHaveAttribute('aria-expanded', 'false')
|
||||
|
||||
// Click to expand
|
||||
await collapseButton.click()
|
||||
await expect(collapseButton).toHaveAttribute('aria-expanded', 'true')
|
||||
})
|
||||
|
||||
test('should display notes in grid layout', async ({ page }) => {
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
const collapseButton = recentSection.locator('button[aria-expanded]')
|
||||
|
||||
// Ensure section is expanded
|
||||
if (await collapseButton.getAttribute('aria-expanded') === 'false') {
|
||||
await collapseButton.click()
|
||||
}
|
||||
|
||||
// Check for grid layout
|
||||
const grid = recentSection.locator('.grid')
|
||||
await expect(grid).toBeVisible()
|
||||
|
||||
// Check that grid has correct classes
|
||||
await expect(grid).toHaveClass(/grid-cols-1/)
|
||||
})
|
||||
|
||||
test('should not show pinned notes in recent section', async ({ page }) => {
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
|
||||
// Recent notes should filter out pinned notes
|
||||
// Get all note cards in recent section
|
||||
const recentNoteCards = recentSection.locator('[data-testid^="note-card-"]')
|
||||
|
||||
// If there are recent notes, none should be pinned
|
||||
const count = await recentNoteCards.count()
|
||||
if (count > 0) {
|
||||
// Check that none of the notes in recent section have pin indicator
|
||||
// This is an indirect check - pinned notes are shown in FavoritesSection
|
||||
// The implementation should filter them out
|
||||
const favoriteSection = page.locator('[data-testid="favorites-section"]')
|
||||
await expect(favoriteSection).toBeVisible()
|
||||
}
|
||||
})
|
||||
|
||||
test('should handle empty state (no recent notes)', async ({ page }) => {
|
||||
// This test would need to manipulate the database to ensure no recent notes
|
||||
// For now, we can check that the section doesn't break when empty
|
||||
|
||||
// Reload page to check stability
|
||||
await page.reload()
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Page should load without errors
|
||||
await expect(page).toHaveTitle(/Keep/)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Recent Notes - Integration', () => {
|
||||
test('new note should appear in recent section', async ({ page }) => {
|
||||
// Create a new note
|
||||
await page.goto('/')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
const noteContent = `Test note for recent section - ${Date.now()}`
|
||||
|
||||
// Type in note input
|
||||
const noteInput = page.locator('[data-testid="note-input-textarea"]')
|
||||
await noteInput.fill(noteContent)
|
||||
|
||||
// Submit note
|
||||
const submitButton = page.locator('button[type="submit"]')
|
||||
await submitButton.click()
|
||||
|
||||
// Wait for note to be created
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
// Reload page to refresh recent notes
|
||||
await page.reload()
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Check if recent notes section is visible
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
|
||||
// The section should now be visible with the new note
|
||||
await expect(recentSection).toBeVisible()
|
||||
})
|
||||
|
||||
test('editing note should update its position in recent section', async ({ page }) => {
|
||||
// This test verifies that edited notes move to top
|
||||
// It requires at least one note to exist
|
||||
|
||||
await page.goto('/')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
const recentSection = page.locator('[data-testid="recent-notes-section"]')
|
||||
|
||||
// If recent notes exist
|
||||
if (await recentSection.isVisible()) {
|
||||
// Get first note card
|
||||
const firstNote = recentSection.locator('[data-testid^="note-card-"]').first()
|
||||
|
||||
// Click to edit
|
||||
await firstNote.click()
|
||||
|
||||
// Wait for editor to open
|
||||
const editor = page.locator('[data-testid="note-editor"]')
|
||||
await expect(editor).toBeVisible()
|
||||
|
||||
// Make a small edit
|
||||
const contentArea = editor.locator('textarea').first()
|
||||
await contentArea.press('End')
|
||||
await contentArea.type(' - edited')
|
||||
|
||||
// Save changes
|
||||
const saveButton = editor.locator('button:has-text("Save")').first()
|
||||
await saveButton.click()
|
||||
|
||||
// Wait for save and reload
|
||||
await page.waitForTimeout(1000)
|
||||
await page.reload()
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// The edited note should still be in recent section
|
||||
await expect(recentSection).toBeVisible()
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user