diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index 5696d927..65e00df0 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -97,24 +97,22 @@ export const goToGridDoc = async ( const header = page.locator('header').first(); await header.locator('h2').getByText('Docs').click(); - const datagrid = page.getByLabel('Datagrid of the documents page 1'); - const datagridTable = datagrid.getByRole('table'); + const docsGrid = page.getByTestId('docs-grid'); + await expect(docsGrid).toBeVisible(); + await expect(page.getByTestId('docs-grid-loader')).toBeHidden(); - await expect(datagrid.getByLabel('Loading data')).toBeHidden({ - timeout: 10000, - }); - - const rows = datagridTable.getByRole('row'); + const rows = docsGrid.getByRole('row'); + expect(await rows.count()).toEqual(20); const row = title ? rows.filter({ hasText: title, }) : rows.nth(nthRow); - const docTitleCell = row.getByRole('cell').nth(1); - - const docTitle = await docTitleCell.textContent(); + await expect(row).toBeVisible(); + const docTitleContent = row.locator('[aria-describedby="doc-title"]').first(); + const docTitle = await docTitleContent.textContent(); expect(docTitle).toBeDefined(); await row.getByRole('link').first().click(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts index 024acf65..602d6be5 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts @@ -18,15 +18,12 @@ test.describe('Doc Create', () => { const header = page.locator('header').first(); await header.locator('h2').getByText('Docs').click(); - const datagrid = page.getByLabel('Datagrid of the documents page 1'); - const datagridTable = datagrid.getByRole('table'); + await expect(page.getByTestId('docs-grid-loader')).toBeVisible(); - await expect(datagrid.getByLabel('Loading data')).toBeHidden({ - timeout: 10000, - }); - await expect(datagridTable.getByText(docTitle)).toBeVisible({ - timeout: 5000, - }); + const docsGrid = page.getByTestId('docs-grid'); + await expect(docsGrid).toBeVisible(); + await expect(page.getByTestId('docs-grid-loader')).toBeHidden(); + await expect(docsGrid.getByText(docTitle)).toBeVisible(); }); }); 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 54febf83..efabfc2f 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,264 +1,14 @@ import { expect, test } from '@playwright/test'; +type SmallDoc = { + id: string; + title: string; +}; + test.beforeEach(async ({ page }) => { await page.goto('/'); }); -test.describe('Documents Grid', () => { - test('checks all the elements are visible', async ({ page }) => { - await expect(page.locator('h2').getByText('Documents')).toBeVisible(); - - const datagrid = page - .getByLabel('Datagrid of the documents page 1') - .getByRole('table'); - - const thead = datagrid.locator('thead'); - await expect(thead.getByText(/Document name/i)).toBeVisible(); - await expect(thead.getByText(/Created at/i)).toBeVisible(); - await expect(thead.getByText(/Updated at/i)).toBeVisible(); - await expect(thead.getByText(/Your role/i)).toBeVisible(); - await expect(thead.getByText(/Members/i)).toBeVisible(); - - const row1 = datagrid.getByRole('row').nth(1).getByRole('cell'); - const docName = await row1.nth(1).textContent(); - expect(docName).toBeDefined(); - - const docCreatedAt = await row1.nth(2).textContent(); - expect(docCreatedAt).toBeDefined(); - - const docUpdatedAt = await row1.nth(3).textContent(); - expect(docUpdatedAt).toBeDefined(); - - const docRole = await row1.nth(4).textContent(); - expect( - docRole && - ['Administrator', 'Owner', 'Reader', 'Editor'].includes(docRole), - ).toBeTruthy(); - - const docUserNumber = await row1.nth(5).textContent(); - expect(docUserNumber).toBeDefined(); - - // Open the document - await row1.nth(1).click(); - - await expect(page.locator('h2').getByText(docName!)).toBeVisible(); - }); - - [ - { - nameColumn: 'Document name', - ordering: 'title', - cellNumber: 1, - orderDefault: '', - orderDesc: '&ordering=-title', - orderAsc: '&ordering=title', - defaultColumn: false, - }, - { - nameColumn: 'Created at', - ordering: 'created_at', - cellNumber: 2, - orderDefault: '', - orderDesc: '&ordering=-created_at', - orderAsc: '&ordering=created_at', - defaultColumn: false, - }, - { - nameColumn: 'Updated at', - ordering: 'updated_at', - cellNumber: 3, - orderDefault: '&ordering=-updated_at', - orderDesc: '&ordering=updated_at', - orderAsc: '', - defaultColumn: true, - }, - ].forEach( - ({ - nameColumn, - ordering, - cellNumber, - orderDefault, - orderDesc, - orderAsc, - defaultColumn, - }) => { - test(`checks datagrid ordering ${ordering}`, async ({ page }) => { - const responsePromise = page.waitForResponse( - (response) => - response.url().includes(`/documents/?page=1${orderDefault}`) && - response.status() === 200, - ); - - const responsePromiseOrderingDesc = page.waitForResponse( - (response) => - response.url().includes(`/documents/?page=1${orderDesc}`) && - response.status() === 200, - ); - - const responsePromiseOrderingAsc = page.waitForResponse( - (response) => - response.url().includes(`/documents/?page=1${orderAsc}`) && - response.status() === 200, - ); - - // Checks the initial state - const datagrid = page.getByLabel('Datagrid of the documents page 1'); - const datagridTable = datagrid.getByRole('table'); - const thead = datagridTable.locator('thead'); - - const response = await responsePromise; - expect(response.ok()).toBeTruthy(); - - const docNameRow1 = datagridTable - .getByRole('row') - .nth(1) - .getByRole('cell') - .nth(cellNumber); - const docNameRow2 = datagridTable - .getByRole('row') - .nth(2) - .getByRole('cell') - .nth(cellNumber); - - await expect(datagrid.getByLabel('Loading data')).toBeHidden({ - timeout: 10000, - }); - - // Initial state - await expect(docNameRow1).toHaveText(/.*/); - await expect(docNameRow2).toHaveText(/.*/); - const initialDocNameRow1 = await docNameRow1.textContent(); - const initialDocNameRow2 = await docNameRow2.textContent(); - - expect(initialDocNameRow1).toBeDefined(); - expect(initialDocNameRow2).toBeDefined(); - - // Ordering ASC - await thead.getByText(nameColumn).click(); - - const responseOrderingAsc = await responsePromiseOrderingAsc; - expect(responseOrderingAsc.ok()).toBeTruthy(); - - await expect(datagrid.getByLabel('Loading data')).toBeHidden({ - timeout: 10000, - }); - - await expect(docNameRow1).toHaveText(/.*/); - await expect(docNameRow2).toHaveText(/.*/); - const textDocNameRow1Asc = await docNameRow1.textContent(); - const textDocNameRow2Asc = await docNameRow2.textContent(); - - const compare = (comp1: string, comp2: string) => { - const comparisonResult = comp1.localeCompare(comp2, 'en', { - caseFirst: 'false', - ignorePunctuation: true, - }); - - // eslint-disable-next-line playwright/no-conditional-in-test - return defaultColumn ? comparisonResult >= 0 : comparisonResult <= 0; - }; - - expect( - textDocNameRow1Asc && - textDocNameRow2Asc && - compare(textDocNameRow1Asc, textDocNameRow2Asc), - ).toBeTruthy(); - - // Ordering Desc - await thead.getByText(nameColumn).click(); - - const responseOrderingDesc = await responsePromiseOrderingDesc; - expect(responseOrderingDesc.ok()).toBeTruthy(); - - await expect(datagrid.getByLabel('Loading data')).toBeHidden({ - timeout: 10000, - }); - - await expect(docNameRow1).toHaveText(/.*/); - await expect(docNameRow2).toHaveText(/.*/); - const textDocNameRow1Desc = await docNameRow1.textContent(); - const textDocNameRow2Desc = await docNameRow2.textContent(); - - expect( - textDocNameRow1Desc && - textDocNameRow2Desc && - compare(textDocNameRow2Desc, textDocNameRow1Desc), - ).toBeTruthy(); - }); - }, - ); - - test('checks the pagination', async ({ page }) => { - const responsePromisePage1 = page.waitForResponse( - (response) => - response.url().includes(`/documents/?page=1`) && - response.status() === 200, - ); - - const responsePromisePage2 = page.waitForResponse( - (response) => - response.url().includes(`/documents/?page=2`) && - response.status() === 200, - ); - - const datagridPage1 = page - .getByLabel('Datagrid of the documents page 1') - .getByRole('table'); - - const responsePage1 = await responsePromisePage1; - expect(responsePage1.ok()).toBeTruthy(); - - await expect( - datagridPage1.getByRole('row').nth(1).getByRole('cell').nth(1), - ).toHaveText(/.*/); - - await page.getByLabel('Go to page 2').click(); - - const datagridPage2 = page - .getByLabel('Datagrid of the documents page 2') - .getByRole('table'); - - const responsePage2 = await responsePromisePage2; - expect(responsePage2.ok()).toBeTruthy(); - - await expect( - datagridPage2.getByRole('row').nth(1).getByRole('cell').nth(1), - ).toHaveText(/.*/); - }); - - test('it deletes the document', async ({ page }) => { - const datagrid = page - .getByLabel('Datagrid of the documents page 1') - .getByRole('table'); - - const docRow = datagrid.getByRole('row').nth(1).getByRole('cell'); - - const docName = await docRow.nth(1).textContent(); - - await docRow - .getByRole('button', { - name: 'Delete the document', - }) - .click(); - - await expect( - page.locator('h2').getByText(`Deleting the document "${docName}"`), - ).toBeVisible(); - - await page - .getByRole('button', { - name: 'Confirm deletion', - }) - .click(); - - await expect( - page.getByText('The document has been deleted.'), - ).toBeVisible(); - - await expect(datagrid.getByText(docName!)).toBeHidden(); - }); -}); - test.describe('Documents Grid mobile', () => { test.use({ viewport: { width: 500, height: 1200 } }); @@ -326,19 +76,122 @@ test.describe('Documents Grid mobile', () => { await page.goto('/'); - const datagrid = page.getByLabel('Datagrid of the documents page 1'); - const tableDatagrid = datagrid.getByRole('table'); + const docsGrid = page.getByTestId('docs-grid'); + await expect(docsGrid).toBeVisible(); + await expect(page.getByTestId('docs-grid-loader')).toBeHidden(); - await expect(datagrid.getByLabel('Loading data')).toBeHidden({ - timeout: 10000, - }); - - const rows = tableDatagrid.getByRole('row'); + const rows = docsGrid.getByRole('row'); const row = rows.filter({ hasText: 'My mocked document', }); - await expect(row.getByRole('cell').nth(0)).toHaveText('My mocked document'); - await expect(row.getByRole('cell').nth(1)).toHaveText('Public'); + await expect( + row.locator('[aria-describedby="doc-title"]').nth(0), + ).toHaveText('My mocked document'); + }); +}); + +test.describe('Documents Grid', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/'); + }); + + test('checks all the elements are visible', async ({ page }) => { + let docs: SmallDoc[] = []; + await expect(page.getByTestId('docs-grid-loader')).toBeVisible(); + + const response = await page.waitForResponse( + (response) => + response.url().includes('documents/?page=1') && + response.status() === 200, + ); + const result = await response.json(); + docs = result.results as SmallDoc[]; + + await expect(page.getByTestId('docs-grid-loader')).toBeHidden(); + await expect(page.locator('h4').getByText('All docs')).toBeVisible(); + + const thead = page.getByTestId('docs-grid-header'); + await expect(thead.getByText(/Name/i)).toBeVisible(); + await expect(thead.getByText(/Updated at/i)).toBeVisible(); + + await Promise.all( + docs.map(async (doc) => { + await expect( + page.getByTestId(`docs-grid-name-${doc.id}`), + ).toBeVisible(); + }), + ); + }); + + test('checks the infinite scroll', async ({ page }) => { + let docs: SmallDoc[] = []; + const responsePromisePage1 = page.waitForResponse( + (response) => + response.url().includes(`/documents/?page=1`) && + response.status() === 200, + ); + + const responsePromisePage2 = page.waitForResponse( + (response) => + response.url().includes(`/documents/?page=2`) && + response.status() === 200, + ); + + const responsePage1 = await responsePromisePage1; + expect(responsePage1.ok()).toBeTruthy(); + let result = await responsePage1.json(); + docs = result.results as SmallDoc[]; + await Promise.all( + docs.map(async (doc) => { + await expect( + page.getByTestId(`docs-grid-name-${doc.id}`), + ).toBeVisible(); + }), + ); + + await page.getByTestId('infinite-scroll-trigger').scrollIntoViewIfNeeded(); + + const responsePage2 = await responsePromisePage2; + result = await responsePage2.json(); + docs = result.results as SmallDoc[]; + await Promise.all( + docs.map(async (doc) => { + await expect( + page.getByTestId(`docs-grid-name-${doc.id}`), + ).toBeVisible(); + }), + ); + }); + + test('it deletes the document', async ({ page }) => { + let docs: SmallDoc[] = []; + const response = await page.waitForResponse( + (response) => + response.url().includes('documents/?page=1') && + response.status() === 200, + ); + const result = await response.json(); + docs = result.results as SmallDoc[]; + + const button = page.getByTestId(`docs-grid-delete-button-${docs[0].id}`); + + await expect(button).toBeVisible(); + await button.click(); + + await expect( + page.locator('h2').getByText(`Deleting the document "${docs[0].title}"`), + ).toBeVisible(); + + await page + .getByRole('button', { + name: 'Confirm deletion', + }) + .click(); + + await expect( + page.getByText('The document has been deleted.'), + ).toBeVisible(); + await expect(button).toBeHidden(); }); }); diff --git a/src/frontend/apps/impress/src/__tests__/pages.test.tsx b/src/frontend/apps/impress/src/__tests__/pages.test.tsx deleted file mode 100644 index 81f837aa..00000000 --- a/src/frontend/apps/impress/src/__tests__/pages.test.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import '@testing-library/jest-dom'; -import { render, screen } from '@testing-library/react'; - -import { AppWrapper } from '@/tests/utils'; - -import Page from '../pages'; - -jest.mock('next/router', () => ({ - useRouter() { - return { - push: jest.fn(), - }; - }, -})); - -jest.mock('@sentry/nextjs', () => ({ - captureException: jest.fn(), - captureMessage: jest.fn(), - setUser: jest.fn(), -})); - -describe('Page', () => { - it('checks Page rendering', () => { - render(, { wrapper: AppWrapper }); - - expect( - screen.getByRole('button', { - name: /Create a new document/i, - }), - ).toBeInTheDocument(); - }); -});