Files
Momento/memento-note/tests/undo-redo.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

168 lines
5.1 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Note Input - Undo/Redo', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
// Expand the note input
await page.click('input[placeholder="Take a note..."]');
await expect(page.locator('input[placeholder="Title"]')).toBeVisible();
});
test('should save history after 1 second of inactivity', async ({ page }) => {
const contentArea = page.locator('textarea[placeholder="Take a note..."]');
// Type "Hello"
await contentArea.fill('Hello');
// Wait for debounce to save
await page.waitForTimeout(1100);
// Type " World"
await contentArea.fill('Hello World');
// Wait for debounce
await page.waitForTimeout(1100);
// Click Undo button
const undoButton = page.locator('button:has(svg.lucide-undo-2)');
await expect(undoButton).toBeEnabled();
await undoButton.click();
// Should show "Hello" only
await expect(contentArea).toHaveValue('Hello');
// Undo should now be disabled (back to initial state)
// Actually not disabled, there's the initial empty state
await undoButton.click();
await expect(contentArea).toHaveValue('');
// Undo should be disabled now
await expect(undoButton).toBeDisabled();
// Click Redo
const redoButton = page.locator('button:has(svg.lucide-redo-2)');
await expect(redoButton).toBeEnabled();
await redoButton.click();
// Should show "Hello"
await expect(contentArea).toHaveValue('Hello');
// Redo again
await redoButton.click();
await expect(contentArea).toHaveValue('Hello World');
// Redo should be disabled now
await expect(redoButton).toBeDisabled();
});
test('should undo/redo with keyboard shortcuts', async ({ page }) => {
const contentArea = page.locator('textarea[placeholder="Take a note..."]');
// Type and wait
await contentArea.fill('First');
await page.waitForTimeout(1100);
await contentArea.fill('Second');
await page.waitForTimeout(1100);
// Ctrl+Z to undo
await page.keyboard.press('Control+z');
await expect(contentArea).toHaveValue('First');
// Ctrl+Z again
await page.keyboard.press('Control+z');
await expect(contentArea).toHaveValue('');
// Ctrl+Y to redo
await page.keyboard.press('Control+y');
await expect(contentArea).toHaveValue('First');
// Ctrl+Shift+Z also works for redo
await page.keyboard.press('Control+Shift+z');
await expect(contentArea).toHaveValue('Second');
});
test('should work with title and content', async ({ page }) => {
const titleInput = page.locator('input[placeholder="Title"]');
const contentArea = page.locator('textarea[placeholder="Take a note..."]');
// Type title
await titleInput.fill('My Title');
await page.waitForTimeout(1100);
// Type content
await contentArea.fill('My Content');
await page.waitForTimeout(1100);
// Undo
await page.keyboard.press('Control+z');
await expect(titleInput).toHaveValue('My Title');
await expect(contentArea).toHaveValue('');
// Undo again
await page.keyboard.press('Control+z');
await expect(titleInput).toHaveValue('');
await expect(contentArea).toHaveValue('');
});
test('should reset history after creating note', async ({ page }) => {
const contentArea = page.locator('textarea[placeholder="Take a note..."]');
const undoButton = page.locator('button:has(svg.lucide-undo-2)');
// Type something
await contentArea.fill('Test note');
await page.waitForTimeout(1100);
// Undo should be enabled
await expect(undoButton).toBeEnabled();
// Submit note
await page.click('button:has-text("Add")');
// Wait for note to be created and form to reset
await page.waitForTimeout(500);
// Expand again
await page.click('input[placeholder="Take a note..."]');
// Undo should be disabled (fresh start)
await expect(undoButton).toBeDisabled();
});
test('should not create history during undo/redo', async ({ page }) => {
const contentArea = page.locator('textarea[placeholder="Take a note..."]');
// Type "A"
await contentArea.fill('A');
await page.waitForTimeout(1100);
// Type "B"
await contentArea.fill('B');
await page.waitForTimeout(1100);
// Type "C"
await contentArea.fill('C');
await page.waitForTimeout(1100);
// Undo to B
await page.keyboard.press('Control+z');
await expect(contentArea).toHaveValue('B');
// Undo to A
await page.keyboard.press('Control+z');
await expect(contentArea).toHaveValue('A');
// Redo to B
await page.keyboard.press('Control+y');
await expect(contentArea).toHaveValue('B');
// Redo to C
await page.keyboard.press('Control+y');
await expect(contentArea).toHaveValue('C');
// Should not be able to redo further
const redoButton = page.locator('button:has(svg.lucide-redo-2)');
await expect(redoButton).toBeDisabled();
});
});