From feb7e082afd78609b27aff297f460efbb82183c8 Mon Sep 17 00:00:00 2001 From: Jessica Rynkar <67977755+jessrynkar@users.noreply.github.com> Date: Tue, 27 May 2025 18:00:56 +0100 Subject: [PATCH] chore(ui): finish adding folders e2e tests (#12524) --- test/folders/e2e.spec.ts | 355 ++++++++++++++++++++++++++++++++++----- 1 file changed, 314 insertions(+), 41 deletions(-) diff --git a/test/folders/e2e.spec.ts b/test/folders/e2e.spec.ts index 3df90d6d51..11ee4aa7d7 100644 --- a/test/folders/e2e.spec.ts +++ b/test/folders/e2e.spec.ts @@ -30,7 +30,9 @@ test.describe('Folders', () => { page = await context.newPage() initPageConsoleErrorCatch(page) await ensureCompilationIsDone({ page, serverURL }) + }) + test.beforeEach(async () => { await reInitializeDB({ serverURL, snapshotKey: 'foldersTest', @@ -59,27 +61,22 @@ test.describe('Folders', () => { await createFolder('New Folder From Root') }) + /* eslint-disable playwright/expect-expect */ + test('should create new folder from collection view', async () => { + await page.goto(postURL.byFolder) + await createFolder('New Folder From Collection', true) + }) + test('should create new folder from document view', async () => { await page.goto(postURL.create) - const folderButton = page.getByRole('button', { name: 'No Folder' }) - await folderButton.click() - const addFolderButton = page.locator('button.move-folder-drawer__add-folder-button', { - hasText: 'Add Folder', - }) - await addFolderButton.click() - const folderNameInput = page.locator('input[id="field-name"]') - await folderNameInput.fill('New Folder From Doc') - const createButton = page - .locator('dialog#move-folder-drawer-new-folder button[aria-label="Apply Changes"]') - .filter({ hasText: 'Create' }) - await createButton.click() - await expect(page.locator('.payload-toast-container')).toContainText('successfully') - const folderCard = page.locator('.folder-file-card__name', { hasText: 'New Folder From Doc' }) - await expect(folderCard).toBeVisible() + await createPostWithNoFolder() + const folderPill = page.locator('.doc-controls .move-doc-to-folder', { hasText: 'No Folder' }) + await folderPill.click() + await createFolderFromDoc('New Folder From Doc') }) }) - test.describe('Folder View Actions', () => { + test.describe('Folder view actions', () => { test('should show Browse by Folder button', async () => { await page.goto(`${serverURL}/admin`) const folderButton = page.locator('text=Browse by folder') @@ -126,6 +123,33 @@ test.describe('Folders', () => { await expect(deletedFolderCard).toBeHidden() }) + test('should delete folder but not delete documents', async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Folder With Documents') + await createPostWithExistingFolder('Document 1', 'Folder With Documents') + await createPostWithExistingFolder('Document 2', 'Folder With Documents') + + await page.goto(`${serverURL}/admin/browse-by-folder`) + await clickFolderCard('Folder With Documents') + const deleteButton = page.locator('.list-selection__actions button', { + hasText: 'Delete', + }) + await deleteButton.click() + const confirmButton = page.getByRole('button', { name: 'Confirm' }) + await confirmButton.click() + await expect(page.locator('.payload-toast-container')).toContainText('successfully') + const deletedFolderCard = page.locator('.folder-file-card__name', { + hasText: 'Folder With Documents', + }) + await expect(deletedFolderCard).toBeHidden() + + await page.goto(postURL.list) + const firstDoc = page.locator('tbody .row-1') + const secondDoc = page.locator('tbody .row-2') + await expect(firstDoc).toContainText('Document 2') + await expect(secondDoc).toContainText('Document 1') + }) + test('should move folder', async () => { await page.goto(`${serverURL}/admin/browse-by-folder`) await createFolder('Move Into This Folder') @@ -221,16 +245,122 @@ test.describe('Folders', () => { await expect(page.locator('.payload-toast-container')).toContainText('successfully') await expect(page.locator('dialog#create-folder--no-results-new-folder-drawer')).toBeHidden() }) + + test('should toggle between grid and list view', async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Test Folder') + const listViewButton = page.locator('.folder-view-toggle-button').nth(1) + await listViewButton.click() + const listView = page.locator('.simple-table') + await expect(listView).toBeVisible() + + const gridViewButton = page.locator('.folder-view-toggle-button').nth(0) + await gridViewButton.click() + const gridView = page.locator('.item-card-grid') + await expect(gridView).toBeVisible() + }) + + test('should sort folders', async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('A Folder') + await createFolder('B Folder') + await createFolder('C Folder') + + const firstFolderCard = page.locator('.folder-file-card__name').first() + await expect(firstFolderCard).toHaveText('A Folder') + + const sortButton = page.locator('.sort-by-pill', { hasText: 'Name' }) + await sortButton.click() + const decendingSortButton = page.locator('.sort-by-pill__order-option', { + hasText: 'Descending', + }) + await decendingSortButton.click() + + const sortedFirstFolderCard = page.locator('.folder-file-card__name').first() + await expect(sortedFirstFolderCard).toHaveText('C Folder') + }) + + test('should allow filtering within folders', async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Filtering Folder') + await clickFolderCard('Filtering Folder', true) + + const createNewDropdown = page.locator('.create-new-doc-in-folder__popup-button', { + hasText: 'Create New', + }) + await createNewDropdown.click() + const createFolderButton = page.locator('.popup-button-list__button').first() + await createFolderButton.click() + const folderNameInput = page.locator('input[id="field-name"]') + await folderNameInput.fill('Nested Folder') + const createButton = page + .locator('.drawerHeader button[aria-label="Apply Changes"]') + .filter({ hasText: 'Create' }) + await createButton.click() + await expect(page.locator('.folder-file-card__name')).toHaveText('Nested Folder') + + await createNewDropdown.click() + const createPostButton = page.locator('.popup-button-list__button', { hasText: 'Post' }) + await createPostButton.click() + + const postTitleInput = page.locator('input[id="field-title"]') + await postTitleInput.fill('Test Post') + const saveButton = page.locator('#action-save') + await saveButton.click() + await expect(page.locator('.payload-toast-container')).toContainText('successfully') + + const typeButton = page.locator('.popup-button', { hasText: 'Type' }) + await typeButton.click() + const folderCheckbox = page.locator('.checkbox-popup__options .checkbox-input__input').first() + await folderCheckbox.click() + const folderGroup = page.locator('.item-card-grid__title', { hasText: 'Folders' }) + const postGroup = page.locator('.item-card-grid__title', { hasText: 'Documents' }) + await expect(folderGroup).toBeHidden() + await expect(postGroup).toBeVisible() + + await folderCheckbox.click() + const postCheckbox = page.locator('.checkbox-popup__options .checkbox-input__input').nth(1) + await postCheckbox.click() + + await expect(folderGroup).toBeVisible() + await expect(postGroup).toBeHidden() + }) + + test('should allow searching within folders', async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Test') + await createFolder('Search Me') + + const testFolderCard = page.locator('.folder-file-card__name', { + hasText: 'Test', + }) + const searchFolderCard = page.locator('.folder-file-card__name', { + hasText: 'Search Me', + }) + + await expect(testFolderCard).toBeVisible() + await expect(searchFolderCard).toBeVisible() + + const searchInput = page.locator('input[placeholder="Search by Name in Folders"]') + await searchInput.fill('Search Me') + await expect(testFolderCard).toBeHidden() + await expect(searchFolderCard).toBeVisible() + }) }) test.describe('Collection view actions', () => { - test('should show By Folder button', async () => { + test.beforeEach(async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Move Into This Folder') + await createPostWithNoFolder() await page.goto(postURL.list) + }) + + test('should show By Folder button', async () => { const folderButton = page.locator('.list-folder-pills__button', { hasText: 'By Folder' }) await expect(folderButton).toBeVisible() }) test('should navigate to By Folder view', async () => { - await page.goto(postURL.list) const folderButton = page.locator('.list-folder-pills__button', { hasText: 'By Folder' }) await folderButton.click() await expect(page).toHaveURL(`${serverURL}/admin/collections/posts/payload-folders`) @@ -238,7 +368,6 @@ test.describe('Folders', () => { await expect(foldersTitle).toBeVisible() }) test('should show folder pill in doc row', async () => { - await createPostWithNoFolder() await page.goto(postURL.list) const firstListItem = page.locator('tbody .row-1') const folderPill = firstListItem.locator('.move-doc-to-folder') @@ -246,8 +375,6 @@ test.describe('Folders', () => { }) test('should update folder from doc folder pill', async () => { - await createPostWithNoFolder() - await page.goto(postURL.list) await selectFolderAndConfirmMoveFromList('Move Into This Folder') await expect(page.locator('.payload-toast-container')).toContainText( 'Test Post has been moved', @@ -255,24 +382,18 @@ test.describe('Folders', () => { }) test('should resolve folder pills and not get stuck as Loading...', async () => { - await createPostWithNoFolder() - await page.goto(postURL.list) await selectFolderAndConfirmMoveFromList('Move Into This Folder') const folderPill = page.locator('tbody .row-1 .move-doc-to-folder') await page.reload() await expect(folderPill).not.toHaveText('Loading...') }) test('should show updated folder pill after folder change', async () => { - await createPostWithNoFolder() - await page.goto(postURL.list) const folderPill = page.locator('tbody .row-1 .move-doc-to-folder') await selectFolderAndConfirmMoveFromList('Move Into This Folder') await expect(folderPill).toHaveText('Move Into This Folder') }) test('should show updated folder pill after removing doc folder', async () => { - await createPostWithNoFolder() - await page.goto(postURL.list) const folderPill = page.locator('tbody .row-1 .move-doc-to-folder') await selectFolderAndConfirmMoveFromList('Move Into This Folder') await expect(folderPill).toHaveText('Move Into This Folder') @@ -304,6 +425,121 @@ test.describe('Folders', () => { }) }) + test.describe('Document view actions', () => { + test.beforeEach(async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Test Folder') + await createPostWithNoFolder() + }) + + test('should show folder pill in doc controls', async () => { + const folderPill = page.locator('.doc-controls .move-doc-to-folder', { hasText: 'No Folder' }) + await expect(folderPill).toBeVisible() + }) + + test('should update folder from folder pill in doc controls', async () => { + const folderPill = page.locator('.doc-controls .move-doc-to-folder', { hasText: 'No Folder' }) + await folderPill.click() + await clickFolderCard('Test Folder', true) + const selectButton = page + .locator('button[aria-label="Apply Changes"]') + .filter({ hasText: 'Select' }) + await selectButton.click() + await expect(page.locator('.payload-toast-container')).toContainText( + 'Test Post has been moved', + ) + }) + + test('should show updated folder pill after folder change', async () => { + const folderPill = page.locator('.doc-controls .move-doc-to-folder', { hasText: 'No Folder' }) + await folderPill.click() + await clickFolderCard('Test Folder', true) + const selectButton = page + .locator('button[aria-label="Apply Changes"]') + .filter({ hasText: 'Select' }) + await selectButton.click() + const updatedFolderPill = page.locator('.doc-controls .move-doc-to-folder', { + hasText: 'Test Folder', + }) + await expect(updatedFolderPill).toBeVisible() + }) + }) + + test.describe('Multiple select options', () => { + test.beforeEach(async () => { + await page.goto(`${serverURL}/admin/browse-by-folder`) + await createFolder('Test Folder 1') + await createFolder('Test Folder 2') + await createFolder('Test Folder 3') + }) + + test('should show how many folders are selected', async () => { + const firstFolderCard = page.locator('.folder-file-card', { + hasText: 'Test Folder 1', + }) + const thirdFolderCard = page.locator('.folder-file-card', { + hasText: 'Test Folder 3', + }) + + await page.keyboard.up('Shift') + await firstFolderCard.click() + await page.keyboard.down('Shift') + await thirdFolderCard.click() + + const selectedCount = page.locator('.list-selection') + await expect(selectedCount).toContainText('3 selected') + }) + + test('should allow multiple folder delete', async () => { + const firstFolderCard = page.locator('.folder-file-card', { + hasText: 'Test Folder 1', + }) + const thirdFolderCard = page.locator('.folder-file-card', { + hasText: 'Test Folder 3', + }) + + await page.keyboard.up('Shift') + await firstFolderCard.click() + await page.keyboard.down('Shift') + await thirdFolderCard.click() + + const deleteButton = page.locator('.list-selection__actions button', { + hasText: 'Delete', + }) + await deleteButton.click() + const confirmButton = page.getByRole('button', { name: 'Confirm' }) + await confirmButton.click() + await expect(page.locator('.payload-toast-container')).toContainText('successfully') + await expect(firstFolderCard).toBeHidden() + }) + test('should move multiple folders', async () => { + await createFolder('Move into here') + const firstFolderCard = page.locator('.folder-file-card', { + hasText: 'Test Folder 1', + }) + const thirdFolderCard = page.locator('.folder-file-card', { + hasText: 'Test Folder 3', + }) + + await page.keyboard.up('Shift') + await firstFolderCard.click() + await page.keyboard.down('Shift') + await thirdFolderCard.click() + + const moveButton = page.locator('.list-selection__actions button', { + hasText: 'Move', + }) + await moveButton.click() + const destinationFolder = page.locator('dialog#move-to-folder--list .folder-file-card', { + hasText: 'Move into here', + }) + await destinationFolder.click() + await selectFolderAndConfirmMove() + await expect(page.locator('.payload-toast-container')).toContainText('moved') + await expect(firstFolderCard).toBeHidden() + }) + }) + async function expectNoResultsAndCreateFolderButton() { const noResultsDiv = page.locator('div.no-results') await expect(noResultsDiv).toBeVisible() @@ -311,11 +547,22 @@ test.describe('Folders', () => { await expect(createFolderButton).toBeVisible() } - async function createFolder(folderName: string) { - const createFolderButton = page.locator( - '.create-new-doc-in-folder__button:has-text("Create New")', - ) - await createFolderButton.click() + async function createFolder(folderName: string, fromDropdown: boolean = false) { + if (fromDropdown) { + const folderDropdown = page.locator('.create-new-doc-in-folder__popup-button', { + hasText: 'Create', + }) + await folderDropdown.click() + const createFolderButton = page.locator('.popup-button-list__button', { + hasText: 'Folder', + }) + await createFolderButton.click() + } else { + const createFolderButton = page.locator( + '.create-new-doc-in-folder__button:has-text("Create New")', + ) + await createFolderButton.click() + } const folderNameInput = page.locator( 'dialog#create-document--header-pill-new-folder-drawer div.drawer-content-container input#field-name', @@ -332,6 +579,27 @@ test.describe('Folders', () => { await expect(folderCard).toBeVisible() } + async function createFolderFromDoc(folderName: string) { + const addFolderButton = page.locator('.create-new-doc-in-folder__button', { + hasText: 'Create folder', + }) + await addFolderButton.click() + + const folderNameInput = page.locator('div.drawer-content-container input#field-name') + + await folderNameInput.fill(folderName) + + const createButton = page + .locator('button[aria-label="Apply Changes"]') + .filter({ hasText: 'Create' }) + await createButton.click() + + await expect(page.locator('.payload-toast-container')).toContainText('successfully') + + const folderCard = page.locator('.folder-file-card__name', { hasText: folderName }).first() + await expect(folderCard).toBeVisible() + } + async function clickFolderCard(folderName: string, doubleClick: boolean = false) { const folderCard = page .locator('.folder-file-card') @@ -388,18 +656,23 @@ test.describe('Folders', () => { await titleInput.fill('Test Post') await saveDocAndAssert(page) } + + async function createPostWithExistingFolder(postTitle: string, folderName: string) { + await page.goto(postURL.create) + const titleInput = page.locator('input[name="title"]') + await titleInput.fill(postTitle) + await saveDocAndAssert(page) + const folderPill = page.locator('.doc-controls .move-doc-to-folder', { hasText: 'No Folder' }) + await folderPill.click() + await clickFolderCard(folderName) + const selectButton = page + .locator('button[aria-label="Apply Changes"]') + .filter({ hasText: 'Select' }) + await selectButton.click() + } }) // tests to write -// ---------- TODO ----------- -// - actions from document view -// - check multiple select actions (2 or more folders or docs) are selected -// - should show how many are selected -// - should allow multiple delete -// - should allow multiple move -// - toggle grid/list view from folder view -// - test sort and filter in folder view -// - test search in folder view // ------ NICE TO HAVE ------- // - check copy is correct in the confirm modal and toast notifications when moving docs / folders // - when moving from no folder to folder