import { test, expect, type Page } from '@playwright/test'; import { setupTest, uploadFiles, ensureDocumentsListed, waitForDocumentListHintPersist, dragAndDrop, expectDocumentListed, expectNoDocumentLink, escapeRegExp, } from './helpers'; test.describe('Document folders and hint persistence', () => { test.beforeEach(async ({ page }, testInfo) => { await setupTest(page, testInfo); }); // Utility to get the draggable tile for a given filename (by link). const rowFor = (page: Page, fileName: string) => { const link = page.getByRole('link', { name: new RegExp(escapeRegExp(fileName), 'i') }).first(); // The drag source is the tile container ancestor, marked with data-doc-tile. return link.locator('xpath=ancestor::*[@data-doc-tile][1]'); }; const folderRow = (page: Page, folderName: string) => page.getByRole('button', { name: new RegExp(`^${folderName}\\b`, 'i') }).first(); const allDocumentsRow = (page: Page) => page.getByRole('button', { name: /^All Documents\b/i }).first(); test('Folder creation via drag-and-drop with persistence', async ({ page }) => { // Upload four docs (one stays outside folder to verify filtering) await uploadFiles(page, 'sample.pdf', 'sample.epub', 'sample.txt', 'sample.md'); await ensureDocumentsListed(page, ['sample.pdf', 'sample.epub', 'sample.txt', 'sample.md']); // Drag PDF onto EPUB to create a folder const pdfRow = rowFor(page, 'sample.pdf'); const epubRow = rowFor(page, 'sample.epub'); await dragAndDrop(page, pdfRow, epubRow); // Folder name dialog appears await expect(page.getByRole('heading', { name: 'Create New Folder' })).toBeVisible(); const nameInput = page.getByPlaceholder('Enter folder name'); await nameInput.fill('My Folder'); await nameInput.press('Enter'); await expect(page.getByRole('dialog', { name: 'Create New Folder' })).toHaveCount(0); // Sidebar folder row exists and folder becomes selected (content filtered to folder docs) const myFolderRow = folderRow(page, 'My Folder'); await expect(myFolderRow).toBeVisible(); await expectDocumentListed(page, 'sample.pdf'); await expectDocumentListed(page, 'sample.epub'); await expectNoDocumentLink(page, 'sample.txt'); await expectNoDocumentLink(page, 'sample.md'); // Switch to all documents and drag TXT into sidebar folder row await allDocumentsRow(page).click(); const txtRow = rowFor(page, 'sample.txt'); await dragAndDrop(page, txtRow, myFolderRow); await expectDocumentListed(page, 'sample.txt'); await expectNoDocumentLink(page, 'sample.md'); // Reload and verify persisted folder + membership await page.reload(); await page.waitForLoadState('networkidle'); const myFolderRowAfter = folderRow(page, 'My Folder'); await expect(myFolderRowAfter).toBeVisible(); await myFolderRowAfter.click(); await expectDocumentListed(page, 'sample.pdf'); await expectDocumentListed(page, 'sample.epub'); await expectDocumentListed(page, 'sample.txt'); await expectNoDocumentLink(page, 'sample.md'); }); test('Dismiss “Drag files to make folders” hint persists after reload', async ({ page }) => { // Need at least 2 docs for the hint to appear await uploadFiles(page, 'sample.pdf', 'sample.epub'); await ensureDocumentsListed(page, ['sample.pdf', 'sample.epub']); const hint = page.getByText('Drag files onto each other to make folders. Drop into the sidebar to move.'); await expect(hint).toBeVisible(); await page.getByRole('button', { name: 'Dismiss hint' }).click(); // Hint should disappear await expect(hint).toHaveCount(0); // Ensure the dismissal has been persisted to server preferences before reloading await waitForDocumentListHintPersist(page, false); // Reload and ensure it remains dismissed await page.reload(); await page.waitForLoadState('networkidle'); await expect(page.getByText('Drag files onto each other to make folders. Drop into the sidebar to move.')).toHaveCount(0); }); });