diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index e067bc7a..6e65dc65 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -26,7 +26,7 @@ export const createDoc = async ( page: Page, docName: string, browserName: string, - length: number, + length: number = 1, ) => { const randomDocs = randomName(docName, browserName, length); @@ -40,7 +40,8 @@ export const createDoc = async ( }) .click(); - const input = page.getByRole('textbox', { name: 'doc title input' }); + const input = page.getByLabel('doc title input'); + await expect(input).toHaveText(''); await input.click(); await input.fill(randomDocs[i]); await input.blur(); @@ -91,6 +92,22 @@ export const addNewMember = async ( return users[index].email; }; +export const getGridRow = async (page: Page, title: string) => { + const docsGrid = page.getByRole('grid'); + await expect(docsGrid).toBeVisible(); + await expect(page.getByTestId('grid-loader')).toBeHidden(); + + const rows = docsGrid.getByRole('row'); + + const row = rows.filter({ + hasText: title, + }); + + await expect(row).toBeVisible(); + + return row; +}; + interface GoToGridDocOptions { nthRow?: number; title?: string; @@ -104,7 +121,7 @@ export const goToGridDoc = async ( const docsGrid = page.getByTestId('docs-grid'); await expect(docsGrid).toBeVisible(); - await expect(docsGrid.getByTestId('grid-loader')).toBeHidden(); + await expect(page.getByTestId('grid-loader')).toBeHidden(); const rows = docsGrid.getByRole('row'); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 8dba8dab..476510e1 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -220,7 +220,7 @@ test.describe('Doc Editor', () => { browserName, }) => { // Check the first doc - const [doc] = await createDoc(page, 'doc-saves-change', browserName, 1); + const [doc] = await createDoc(page, 'doc-saves-change', browserName); await verifyDocName(page, doc); const editor = page.locator('.ProseMirror'); @@ -228,9 +228,11 @@ test.describe('Doc Editor', () => { await editor.fill('Hello World Doc persisted 1'); await expect(editor.getByText('Hello World Doc persisted 1')).toBeVisible(); - const secondDoc = await goToGridDoc(page, { - nthRow: 2, - }); + const [secondDoc] = await createDoc( + page, + 'doc-saves-change-other', + browserName, + ); await verifyDocName(page, secondDoc); @@ -238,6 +240,7 @@ test.describe('Doc Editor', () => { title: doc, }); + await verifyDocName(page, doc); await expect(editor.getByText('Hello World Doc persisted 1')).toBeVisible(); }); @@ -246,8 +249,7 @@ test.describe('Doc Editor', () => { test.skip(browserName === 'webkit', 'This test is very flaky with webkit'); // Check the first doc - const doc = await goToGridDoc(page); - + const [doc] = await createDoc(page, 'doc-quit-1', browserName, 1); await verifyDocName(page, doc); const editor = page.locator('.ProseMirror'); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-favorite.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-favorite.spec.ts deleted file mode 100644 index f1fe950f..00000000 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-favorite.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { expect, test } from '@playwright/test'; - -import { createDoc, verifyDocName } from './common'; - -type SmallDoc = { - id: string; - title: string; -}; - -test.describe('Document favorite', () => { - test('it check the favorite workflow', async ({ page, browserName }) => { - const id = Math.random().toString(7); - await page.goto('/'); - - // Create document - const createdDoc = await createDoc(page, `Doc ${id}`, browserName, 1); - await verifyDocName(page, createdDoc[0]); - - // Reload page - await page.reload(); - await page.goto('/'); - - // Get all documents - let docs: SmallDoc[] = []; - const response = await page.waitForResponse( - (response) => - response.url().endsWith('documents/?page=1') && - response.status() === 200, - ); - const result = await response.json(); - docs = result.results as SmallDoc[]; - const docsGrid = page.getByTestId('docs-grid'); - await docsGrid.getByRole('heading', { name: 'All docs' }).click(); - await expect(docsGrid.getByText(`Doc ${id}`)).toBeVisible(); - const doc = docs.find((doc) => doc.title === createdDoc[0]) as SmallDoc; - - // Check document - expect(doc).not.toBeUndefined(); - expect(doc?.title).toBe(createdDoc[0]); - - // Open document actions - const button = docsGrid.getByTestId(`docs-grid-actions-button-${doc.id}`); - await expect(button).toBeVisible(); - await button.click(); - - // Pin document - const pinButton = page.getByTestId(`docs-grid-actions-pin-${docs[0].id}`); - await expect(pinButton).toBeVisible(); - await pinButton.click(); - - // Check response - const responsePin = await page.waitForResponse( - (response) => - response.url().includes(`documents/${doc.id}/favorite/`) && - response.status() === 201, - ); - expect(responsePin.ok()).toBeTruthy(); - - // Check left panel favorites - const leftPanelFavorites = page.getByTestId('left-panel-favorites'); - await expect(leftPanelFavorites).toBeVisible(); - await expect(leftPanelFavorites.getByText(`Doc ${id}`)).toBeVisible(); - - // - await button.click(); - const unpinButton = page.getByTestId( - `docs-grid-actions-unpin-${docs[0].id}`, - ); - await expect(unpinButton).toBeVisible(); - await unpinButton.click(); - - // Check left panel favorites - await expect(leftPanelFavorites.getByText(`Doc ${id}`)).toBeHidden(); - }); -}); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts index 1963bf1c..772ec104 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts @@ -1,5 +1,7 @@ import { expect, test } from '@playwright/test'; +import { createDoc, getGridRow } from './common'; + type SmallDoc = { id: string; title: string; @@ -92,6 +94,31 @@ test.describe('Documents Grid mobile', () => { }); test.describe('Document grid item options', () => { + test('it pins a document', async ({ page, browserName }) => { + const [docTitle] = await createDoc(page, `Favorite doc`, browserName); + + await page.goto('/'); + + const row = await getGridRow(page, docTitle); + + // Pin + await row.getByText(`more_horiz`).click(); + await page.getByText('push_pin').click(); + + // Check is pinned + await expect(row.getByLabel('Pin document icon')).toBeVisible(); + const leftPanelFavorites = page.getByTestId('left-panel-favorites'); + await expect(leftPanelFavorites.getByText(docTitle)).toBeVisible(); + + // Unpin + await row.getByText(`more_horiz`).click(); + await page.getByText('Unpin').click(); + + // Check is unpinned + await expect(row.getByLabel('Pin document icon')).toBeHidden(); + await expect(leftPanelFavorites.getByText(docTitle)).toBeHidden(); + }); + test('it deletes the document', async ({ page }) => { let docs: SmallDoc[] = []; const response = await page.waitForResponse( diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts index 04015e9e..ec2a3953 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts @@ -26,7 +26,7 @@ test.describe('Document create member', () => { const response = await responsePromise; const users = (await response.json()).results as { email: string; - full_name: string; + full_name?: string | null; }[]; const list = page.getByTestId('doc-share-add-member-list'); @@ -40,7 +40,9 @@ test.describe('Document create member', () => { await expect( list.getByTestId(`doc-share-add-member-${users[0].email}`), ).toBeVisible(); - await expect(list.getByText(`${users[0].full_name}`)).toBeVisible(); + await expect( + list.getByText(`${users[0].full_name || users[0].email}`), + ).toBeVisible(); // Select user 2 and verify tag await inputSearch.fill('user'); @@ -51,7 +53,9 @@ test.describe('Document create member', () => { await expect( list.getByTestId(`doc-share-add-member-${users[1].email}`), ).toBeVisible(); - await expect(list.getByText(`${users[1].full_name}`)).toBeVisible(); + await expect( + list.getByText(`${users[1].full_name || users[1].email}`), + ).toBeVisible(); // Select email and verify tag const email = randomName('test@test.fr', browserName, 1)[0]; @@ -81,7 +85,9 @@ test.describe('Document create member', () => { // Check user added await expect(page.getByText('Share with 3 users')).toBeVisible(); await expect( - quickSearchContent.getByText(users[0].full_name).first(), + quickSearchContent + .getByText(users[0].full_name || users[0].email) + .first(), ).toBeVisible(); await expect( quickSearchContent.getByText(users[0].email).first(), @@ -90,7 +96,9 @@ test.describe('Document create member', () => { quickSearchContent.getByText(users[1].email).first(), ).toBeVisible(); await expect( - quickSearchContent.getByText(users[1].full_name).first(), + quickSearchContent + .getByText(users[1].full_name || users[1].email) + .first(), ).toBeVisible(); }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts index 89540f93..143e383e 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-search.spec.ts @@ -1,21 +1,32 @@ import { expect, test } from '@playwright/test'; -import { DateTime } from 'luxon'; import { createDoc, verifyDocName } from './common'; -type SmallDoc = { - id: string; - title: string; - updated_at: string; -}; - test.beforeEach(async ({ page }) => { await page.goto('/'); }); test.describe('Document search', () => { - test('it checks all elements are visible', async ({ page }) => { + test('it searches documents', async ({ page, browserName }) => { + const [doc1Title] = await createDoc( + page, + 'My doc search super', + browserName, + 1, + ); + await verifyDocName(page, doc1Title); + await page.goto('/'); + + const [doc2Title] = await createDoc( + page, + 'My doc search doc', + browserName, + 1, + ); + await verifyDocName(page, doc2Title); + await page.goto('/'); await page.getByRole('button', { name: 'search' }).click(); + await expect( page.getByRole('img', { name: 'No active search' }), ).toBeVisible(); @@ -24,91 +35,32 @@ test.describe('Document search', () => { page.getByLabel('Search modal').getByText('search'), ).toBeVisible(); - await expect( - page.getByPlaceholder('Type the name of a document'), - ).toBeVisible(); - }); + const inputSearch = page.getByPlaceholder('Type the name of a document'); - test('it checks search for a document', async ({ page, browserName }) => { - const id = Math.random().toString(36).substring(7); + await inputSearch.click(); + await inputSearch.fill('My doc search'); + await inputSearch.press('ArrowDown'); - const doc1 = await createDoc(page, `My super ${id} doc`, browserName, 1); - await verifyDocName(page, doc1[0]); - await page.goto('/'); - const doc2 = await createDoc( - page, - `My super ${id} very doc`, - browserName, - 1, - ); - await verifyDocName(page, doc2[0]); - await page.goto('/'); - await page.getByRole('button', { name: 'search' }).click(); - await page.getByPlaceholder('Type the name of a document').click(); - await page - .getByPlaceholder('Type the name of a document') - .fill(`My super ${id}`); - - let responsePromisePage = page.waitForResponse( - (response) => - response.url().includes(`/documents/?page=1&title=My+super+${id}`) && - response.status() === 200, - ); - let response = await responsePromisePage; - let result = (await response.json()) as { results: SmallDoc[] }; - let docs = result.results; - expect(docs.length).toEqual(2); - - await Promise.all( - docs.map(async (doc: SmallDoc) => { - await expect( - page.getByTestId(`doc-search-item-${doc.id}`), - ).toBeVisible(); - const updatedAt = DateTime.fromISO(doc.updated_at ?? DateTime.now()) - .setLocale('en') - .toRelative(); - await expect( - page.getByTestId(`doc-search-item-${doc.id}`).getByText(updatedAt!), - ).toBeVisible(); - }), - ); - - const firstDoc = docs[0]; + const listSearch = page.getByRole('listbox').getByRole('group'); + const rowdoc = listSearch.getByRole('option').first(); + await expect(rowdoc.getByText('keyboard_return')).toBeVisible(); + await expect(rowdoc.getByText(/seconds? ago/)).toBeVisible(); await expect( - page - .getByTestId(`doc-search-item-${firstDoc.id}`) - .getByText('keyboard_return'), + listSearch.getByRole('option').getByText(doc1Title), ).toBeVisible(); - - await page - .getByPlaceholder('Type the name of a document') - .press('ArrowDown'); - - const secondDoc = docs[1]; await expect( - page - .getByTestId(`doc-search-item-${secondDoc.id}`) - .getByText('keyboard_return'), + listSearch.getByRole('option').getByText(doc2Title), ).toBeVisible(); - await page.getByPlaceholder('Type the name of a document').click(); - await page - .getByPlaceholder('Type the name of a document') - .fill(`My super ${id} doc`); + await inputSearch.fill('My doc search super'); - responsePromisePage = page.waitForResponse( - (response) => - response - .url() - .includes(`/documents/?page=1&title=My+super+${id}+doc`) && - response.status() === 200, - ); + await expect( + listSearch.getByRole('option').getByText(doc1Title), + ).toBeVisible(); - response = await responsePromisePage; - result = (await response.json()) as { results: SmallDoc[] }; - docs = result.results; - - expect(docs.length).toEqual(1); + await expect( + listSearch.getByRole('option').getByText(doc2Title), + ).toBeHidden(); }); }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts index 8414b0c7..dc7fb7eb 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts @@ -171,6 +171,9 @@ test.describe('Doc Visibility: Restricted', () => { await page.goto(urlDoc); + // eslint-disable-next-line playwright/no-wait-for-timeout + await page.waitForTimeout(1000); + await verifyDocName(page, docTitle); await expect(page.getByLabel('Share button')).toBeVisible(); }); @@ -209,6 +212,7 @@ test.describe('Doc Visibility: Public', () => { page.getByText('The document visibility has been updated.'), ).toBeVisible(); + await expect(page.getByLabel('Visibility mode')).toBeVisible(); await page.getByLabel('Visibility mode').click(); await page .getByRole('button', { diff --git a/src/frontend/apps/e2e/package.json b/src/frontend/apps/e2e/package.json index b9dcad2d..aa041400 100644 --- a/src/frontend/apps/e2e/package.json +++ b/src/frontend/apps/e2e/package.json @@ -13,11 +13,9 @@ }, "devDependencies": { "@playwright/test": "1.49.1", - "@types/luxon": "3.4.2", "@types/node": "*", "@types/pdf-parse": "1.1.4", "eslint-config-impress": "*", - "luxon": "3.5.0", "typescript": "*" }, "dependencies": { diff --git a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx index c4ed0638..b9519e41 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx @@ -30,12 +30,9 @@ import { DocShareModalFooter } from './DocShareModalFooter'; import { DocShareModalInviteUserRow } from './DocShareModalInviteUserByEmail'; const ShareModalStyle = createGlobalStyle` - .c__modal__title { padding-bottom: 0 !important; - -} - + } `; type Props = { diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx index 5c125bdb..f511abb2 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx @@ -70,6 +70,7 @@ export const DocsGrid = ({ > { + const { t } = useTranslation(); const { spacingsTokens } = useCunninghamTheme(); const { isDesktop } = useResponsiveStore(); const spacings = spacingsTokens(); @@ -44,7 +46,11 @@ export const SimpleDocItem = ({ filter: drop-shadow(0px 2px 2px rgba(0, 0, 0, 0.05)); `} > - {isPinned ? : } + {isPinned ? ( + + ) : ( + + )}