/** * Memory View File Extension Edge Cases E2E Tests * * Tests for file extension handling in the memory view: * - Files with valid markdown extensions (.md, .markdown) * - Files without extensions (edge case for isMarkdownFile) * - Files with multiple dots in name */ import { test, expect } from '@playwright/test'; import { resetMemoryDirectory, setupProjectWithFixture, getFixturePath, navigateToMemory, waitForMemoryFile, selectMemoryFile, waitForMemoryContentToLoad, clickElement, fillInput, waitForNetworkIdle, authenticateForTests, waitForElementHidden, createMemoryFileOnDisk, } from '../utils'; // Use desktop viewport for these tests test.use({ viewport: { width: 1280, height: 720 } }); test.describe('Memory View File Extension Edge Cases', () => { test.beforeEach(async () => { resetMemoryDirectory(); }); test.afterEach(async () => { resetMemoryDirectory(); }); test('should handle file with .md extension', async ({ page }) => { const fileName = 'standard-file.md'; const content = '# Standard Markdown'; await setupProjectWithFixture(page, getFixturePath()); await authenticateForTests(page); await navigateToMemory(page); // Create file via API createMemoryFileOnDisk(fileName, content); await waitForNetworkIdle(page); // Refresh to load the file await page.reload(); await waitForMemoryFile(page, fileName); // Select and verify it opens as markdown await selectMemoryFile(page, fileName); await waitForMemoryContentToLoad(page); // Should show markdown preview const markdownPreview = page.locator('[data-testid="markdown-preview"]'); await expect(markdownPreview).toBeVisible(); // Verify content rendered const h1 = markdownPreview.locator('h1'); await expect(h1).toHaveText('Standard Markdown'); }); test('should handle file with .markdown extension', async ({ page }) => { const fileName = 'extended-extension.markdown'; const content = '# Extended Extension Test'; await setupProjectWithFixture(page, getFixturePath()); await authenticateForTests(page); await navigateToMemory(page); // Create file via API createMemoryFileOnDisk(fileName, content); await waitForNetworkIdle(page); // Refresh to load the file await page.reload(); await waitForMemoryFile(page, fileName); // Select and verify await selectMemoryFile(page, fileName); await waitForMemoryContentToLoad(page); const markdownPreview = page.locator('[data-testid="markdown-preview"]'); await expect(markdownPreview).toBeVisible(); }); test('should handle file with multiple dots in name', async ({ page }) => { const fileName = 'my.detailed.notes.md'; const content = '# Multiple Dots Test'; await setupProjectWithFixture(page, getFixturePath()); await authenticateForTests(page); await navigateToMemory(page); // Create file via API createMemoryFileOnDisk(fileName, content); await waitForNetworkIdle(page); // Refresh to load the file await page.reload(); await waitForMemoryFile(page, fileName); // Select and verify - should still recognize as markdown await selectMemoryFile(page, fileName); await waitForMemoryContentToLoad(page); const markdownPreview = page.locator('[data-testid="markdown-preview"]'); await expect(markdownPreview).toBeVisible(); }); test('should NOT show file without extension in file list', async ({ page }) => { const fileName = 'README'; const content = '# File Without Extension'; await setupProjectWithFixture(page, getFixturePath()); await authenticateForTests(page); await navigateToMemory(page); // Create file via API (without extension) createMemoryFileOnDisk(fileName, content); await waitForNetworkIdle(page); // Refresh to load the file await page.reload(); // Wait a moment for files to load await page.waitForTimeout(1000); // File should NOT appear in list because isMarkdownFile returns false for no extension const fileButton = page.locator(`[data-testid="memory-file-${fileName}"]`); await expect(fileButton).not.toBeVisible(); }); test('should NOT create file without .md extension via UI', async ({ page }) => { const fileName = 'NOTES'; const content = '# Notes without extension'; await setupProjectWithFixture(page, getFixturePath()); await authenticateForTests(page); await navigateToMemory(page); // Create file via UI without extension await clickElement(page, 'create-memory-button'); await page.waitForSelector('[data-testid="create-memory-dialog"]', { timeout: 5000 }); await fillInput(page, 'new-memory-name', fileName); await fillInput(page, 'new-memory-content', content); await clickElement(page, 'confirm-create-memory'); await waitForElementHidden(page, 'create-memory-dialog', { timeout: 5000 }); await waitForNetworkIdle(page); // File should NOT appear in list because UI enforces .md extension // (The UI may add .md automatically or show validation error) const fileButton = page.locator(`[data-testid="memory-file-${fileName}"]`); await expect(fileButton) .not.toBeVisible({ timeout: 3000 }) .catch(() => { // It's OK if it doesn't appear - that's expected behavior }); }); test('should handle uppercase extensions', async ({ page }) => { const fileName = 'uppercase.MD'; const content = '# Uppercase Extension'; await setupProjectWithFixture(page, getFixturePath()); await authenticateForTests(page); await navigateToMemory(page); // Create file via API with uppercase extension createMemoryFileOnDisk(fileName, content); await waitForNetworkIdle(page); // Refresh to load the file await page.reload(); await waitForMemoryFile(page, fileName); // Select and verify - should recognize .MD as markdown (case-insensitive) await selectMemoryFile(page, fileName); await waitForMemoryContentToLoad(page); const markdownPreview = page.locator('[data-testid="markdown-preview"]'); await expect(markdownPreview).toBeVisible(); }); });