chore: optimize tests (#2280)

This commit is contained in:
David Nguyen
2025-12-06 12:59:53 +11:00
committed by GitHub
parent 9238f759a6
commit f80aa4bf72
18 changed files with 357 additions and 176 deletions
+8 -6
View File
@@ -1,14 +1,19 @@
name: Playwright Tests name: Playwright Tests
on: on:
push: push:
branches: ['main', 'feat/rr7'] branches: ['main']
pull_request: pull_request:
branches: ['main'] branches: ['main']
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
e2e_tests: e2e_tests:
name: 'E2E Tests' name: 'E2E Tests'
timeout-minutes: 60 timeout-minutes: 60
runs-on: warp-ubuntu-2204-x64-16x runs-on: warp-ubuntu-2204-x64-8x
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -28,9 +33,6 @@ jobs:
- name: Seed the database - name: Seed the database
run: npm run prisma:seed run: npm run prisma:seed
- name: Build app
run: npm run build
- name: Install playwright browsers - name: Install playwright browsers
run: npx playwright install --with-deps run: npx playwright install --with-deps
@@ -45,7 +47,7 @@ jobs:
with: with:
name: test-results name: test-results
path: 'packages/app-tests/**/test-results/*' path: 'packages/app-tests/**/test-results/*'
retention-days: 30 retention-days: 7
env: env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }} TURBO_TEAM: ${{ vars.TURBO_TEAM }}
+16 -2
View File
@@ -46,12 +46,16 @@ export async function loader({ request }: Route.LoaderArgs) {
const { getTheme } = await themeSessionResolver(request); const { getTheme } = await themeSessionResolver(request);
let lang: SupportedLanguageCodes = await langCookie.parse(request.headers.get('cookie') ?? ''); const cookieHeader = request.headers.get('cookie') ?? '';
let lang: SupportedLanguageCodes = await langCookie.parse(cookieHeader);
if (!APP_I18N_OPTIONS.supportedLangs.includes(lang)) { if (!APP_I18N_OPTIONS.supportedLangs.includes(lang)) {
lang = extractLocaleData({ headers: request.headers }).lang; lang = extractLocaleData({ headers: request.headers }).lang;
} }
const disableAnimations = cookieHeader.includes('__disable_animations=true');
let organisations = null; let organisations = null;
if (session.isAuthenticated) { if (session.isAuthenticated) {
@@ -62,6 +66,7 @@ export async function loader({ request }: Route.LoaderArgs) {
{ {
lang, lang,
theme: getTheme(), theme: getTheme(),
disableAnimations,
session: session.isAuthenticated session: session.isAuthenticated
? { ? {
user: session.user, user: session.user,
@@ -92,7 +97,8 @@ export function Layout({ children }: { children: React.ReactNode }) {
} }
export function LayoutContent({ children }: { children: React.ReactNode }) { export function LayoutContent({ children }: { children: React.ReactNode }) {
const { publicEnv, session, lang, ...data } = useLoaderData<typeof loader>() || {}; const { publicEnv, session, lang, disableAnimations, ...data } =
useLoaderData<typeof loader>() || {};
const [theme] = useTheme(); const [theme] = useTheme();
@@ -111,6 +117,14 @@ export function LayoutContent({ children }: { children: React.ReactNode }) {
<meta name="google" content="notranslate" /> <meta name="google" content="notranslate" />
<PreventFlashOnWrongTheme ssrTheme={Boolean(data.theme)} /> <PreventFlashOnWrongTheme ssrTheme={Boolean(data.theme)} />
{disableAnimations && (
<style
dangerouslySetInnerHTML={{
__html: `*, *::before, *::after { animation: none !important; transition: none !important; }`,
}}
/>
)}
{/* Fix: https://stackoverflow.com/questions/21147149/flash-of-unstyled-content-fouc-in-firefox-only-is-ff-slow-renderer */} {/* Fix: https://stackoverflow.com/questions/21147149/flash-of-unstyled-content-fouc-in-firefox-only-is-ff-slow-renderer */}
<script>0</script> <script>0</script>
</head> </head>
@@ -28,8 +28,6 @@ export const loader = () => {
export default function TeamsSettingsPage() { export default function TeamsSettingsPage() {
const { isAiFeaturesConfigured } = useLoaderData<typeof loader>(); const { isAiFeaturesConfigured } = useLoaderData<typeof loader>();
console.log('isAiFeaturesConfigured', isAiFeaturesConfigured);
const team = useCurrentTeam(); const team = useCurrentTeam();
const { t } = useLingui(); const { t } = useLingui();
@@ -144,6 +144,9 @@ test.describe('API V2 Envelopes', () => {
externalId: 'externalId', externalId: 'externalId',
visibility: DocumentVisibility.MANAGER_AND_ABOVE, visibility: DocumentVisibility.MANAGER_AND_ABOVE,
globalAccessAuth: ['ACCOUNT'], globalAccessAuth: ['ACCOUNT'],
// Ignore this error in the test since it doesn't actually exist in the PDF:
// - Error setting value for field hello: PDFDocument has no form field with the name "hello"
// We want to check if the form value is set in the DB.
formValues: { formValues: {
hello: 'world', hello: 'world',
}, },
@@ -262,8 +265,6 @@ test.describe('API V2 Envelopes', () => {
}, },
}); });
console.log(userB.email);
expect(envelope.envelopeItems.length).toBe(2); expect(envelope.envelopeItems.length).toBe(2);
expect(envelope.envelopeItems[0].title).toBe('field-meta.pdf'); expect(envelope.envelopeItems[0].title).toBe('field-meta.pdf');
expect(envelope.envelopeItems[1].title).toBe('field-font-alignment.pdf'); expect(envelope.envelopeItems[1].title).toBe('field-font-alignment.pdf');
@@ -89,9 +89,8 @@ test.describe('AutoSave Fields Step', () => {
}); });
expect(retrievedFields.length).toBe(3); expect(retrievedFields.length).toBe(3);
expect(retrievedFields[0].type).toBe('SIGNATURE'); expect(retrievedFields.filter((field) => field.type === 'SIGNATURE')).toHaveLength(2);
expect(retrievedFields[1].type).toBe('TEXT'); expect(retrievedFields.filter((field) => field.type === 'TEXT')).toHaveLength(1);
expect(retrievedFields[2].type).toBe('SIGNATURE');
}).toPass(); }).toPass();
}); });
@@ -214,10 +213,8 @@ test.describe('AutoSave Fields Step', () => {
}); });
expect(retrievedFields.length).toBe(4); expect(retrievedFields.length).toBe(4);
expect(retrievedFields[0].type).toBe('SIGNATURE'); expect(retrievedFields.filter((field) => field.type === 'SIGNATURE')).toHaveLength(3);
expect(retrievedFields[1].type).toBe('TEXT'); expect(retrievedFields.filter((field) => field.type === 'TEXT')).toHaveLength(1);
expect(retrievedFields[2].type).toBe('SIGNATURE');
expect(retrievedFields[3].type).toBe('SIGNATURE');
}).toPass(); }).toPass();
}); });
@@ -259,10 +256,16 @@ test.describe('AutoSave Fields Step', () => {
}); });
expect(retrievedFields.length).toBe(2); expect(retrievedFields.length).toBe(2);
expect(retrievedFields[0].type).toBe('SIGNATURE'); const textField = retrievedFields.find((field) => field.type === 'TEXT');
expect(retrievedFields[1].type).toBe('TEXT'); const signatureField = retrievedFields.find((field) => field.type === 'SIGNATURE');
expect(signatureField).toBeDefined();
expect(textField).toBeDefined();
if (!signatureField || !textField) {
throw new Error('No signature or text field');
}
const textField = retrievedFields[1];
expect(textField.fieldMeta).toBeDefined(); expect(textField.fieldMeta).toBeDefined();
if ( if (
@@ -9,6 +9,7 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin, apiSignout } from '../fixtures/authentication'; import { apiSignin, apiSignout } from '../fixtures/authentication';
import { checkDocumentTabCount } from '../fixtures/documents'; import { checkDocumentTabCount } from '../fixtures/documents';
import { expectToastTextToBeVisible, openDropdownMenu } from '../fixtures/generic';
test.describe.configure({ mode: 'serial' }); test.describe.configure({ mode: 'serial' });
@@ -83,14 +84,13 @@ test('[DOCUMENTS]: deleting a completed document should not remove it from recip
}); });
// Open document action menu. // Open document action menu.
await page const documentActionBtn = page
.locator('tr', { hasText: 'Document 1 - Completed' }) .locator('tr', { hasText: 'Document 1 - Completed' })
.getByTestId('document-table-action-btn') .getByTestId('document-table-action-btn');
.click(); await openDropdownMenu(page, documentActionBtn);
await page.waitForTimeout(200);
// delete document // delete document
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete'); await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
@@ -128,14 +128,13 @@ test('[DOCUMENTS]: deleting a pending document should remove it from recipients'
}); });
// Open document action menu. // Open document action menu.
await page const documentActionBtn = page
.locator('tr', { hasText: 'Document 1 - Pending' }) .locator('tr', { hasText: 'Document 1 - Pending' })
.getByTestId('document-table-action-btn') .getByTestId('document-table-action-btn');
.click(); await openDropdownMenu(page, documentActionBtn);
await page.waitForTimeout(200);
// delete document // delete document
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete'); await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
@@ -169,19 +168,17 @@ test('[DOCUMENTS]: deleting draft documents should permanently remove it', async
}); });
// Open document action menu. // Open document action menu.
await page const documentActionBtn = page
.locator('tr', { hasText: 'Document 1 - Draft' }) .locator('tr', { hasText: 'Document 1 - Draft' })
.getByTestId('document-table-action-btn') .getByTestId('document-table-action-btn');
.click(); await openDropdownMenu(page, documentActionBtn);
await page.waitForTimeout(200); await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); // Required to reduce flakiness.
// delete document
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await expect(page.getByPlaceholder("Type 'delete' to confirm")).not.toBeVisible(); await expect(page.getByPlaceholder("Type 'delete' to confirm")).not.toBeVisible();
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
await page.waitForTimeout(2500); await expectToastTextToBeVisible(page, 'Document deleted');
await expect(page.getByRole('row', { name: /Document 1 - Draft/ })).not.toBeVisible(); await expect(page.getByRole('row', { name: /Document 1 - Draft/ })).not.toBeVisible();
@@ -203,14 +200,13 @@ test('[DOCUMENTS]: deleting pending documents should permanently remove it', asy
}); });
// Open document action menu. // Open document action menu.
await page const documentActionBtn = page
.locator('tr', { hasText: 'Document 1 - Pending' }) .locator('tr', { hasText: 'Document 1 - Pending' })
.getByTestId('document-table-action-btn') .getByTestId('document-table-action-btn');
.click(); await openDropdownMenu(page, documentActionBtn);
await page.waitForTimeout(200);
// Delete document. // Delete document.
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete'); await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
@@ -239,14 +235,13 @@ test('[DOCUMENTS]: deleting completed documents as an owner should hide it from
}); });
// Open document action menu. // Open document action menu.
await page const documentActionBtn = page
.locator('tr', { hasText: 'Document 1 - Completed' }) .locator('tr', { hasText: 'Document 1 - Completed' })
.getByTestId('document-table-action-btn') .getByTestId('document-table-action-btn');
.click(); await openDropdownMenu(page, documentActionBtn);
await page.waitForTimeout(200);
// Delete document. // Delete document.
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete'); await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
@@ -292,36 +287,24 @@ test('[DOCUMENTS]: deleting documents as a recipient should only hide it for the
}); });
// Open document action menu. // Open document action menu.
await expect(async () => { const completedDocActionBtn = page
await page .locator('tr', { hasText: 'Document 1 - Completed' })
.locator('tr', { hasText: 'Document 1 - Completed' }) .getByTestId('document-table-action-btn');
.getByTestId('document-table-action-btn') await openDropdownMenu(page, completedDocActionBtn);
.click();
await page.waitForTimeout(1000);
await expect(page.getByRole('menuitem', { name: 'Hide' })).toBeVisible();
}).toPass();
// Delete document. // Delete document.
await page.getByRole('menuitem', { name: 'Hide' }).waitFor({ state: 'visible' }); await expect(page.getByRole('menuitem', { name: 'Hide' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Hide' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Hide' }).click({ force: true });
await page.getByRole('button', { name: 'Hide' }).click({ force: true }); await page.getByRole('button', { name: 'Hide' }).click({ force: true });
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await expect(async () => { const pendingDocActionBtn = page
await page .locator('tr', { hasText: 'Document 1 - Pending' })
.locator('tr', { hasText: 'Document 1 - Pending' }) .getByTestId('document-table-action-btn');
.getByTestId('document-table-action-btn') await openDropdownMenu(page, pendingDocActionBtn);
.click();
await page.waitForTimeout(1000);
await expect(page.getByRole('menuitem', { name: 'Hide' })).toBeVisible();
}).toPass();
// Delete document. // Delete document.
await page.getByRole('menuitem', { name: 'Hide' }).waitFor({ state: 'visible' }); await expect(page.getByRole('menuitem', { name: 'Hide' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Hide' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Hide' }).click({ force: true });
await page.getByRole('button', { name: 'Hide' }).click({ force: true }); await page.getByRole('button', { name: 'Hide' }).click({ force: true });
@@ -1,3 +1,4 @@
import type { Locator } from '@playwright/test';
import { type Page, expect } from '@playwright/test'; import { type Page, expect } from '@playwright/test';
export const expectTextToBeVisible = async (page: Page, text: string) => { export const expectTextToBeVisible = async (page: Page, text: string) => {
@@ -7,3 +8,22 @@ export const expectTextToBeVisible = async (page: Page, text: string) => {
export const expectTextToNotBeVisible = async (page: Page, text: string) => { export const expectTextToNotBeVisible = async (page: Page, text: string) => {
await expect(page.getByText(text).first()).not.toBeVisible(); await expect(page.getByText(text).first()).not.toBeVisible();
}; };
export const expectToastTextToBeVisible = async (page: Page, text: string) => {
await expect(page.locator('[role="status"]').getByText(text)).toBeVisible();
};
export const openDropdownMenu = async (page: Page, dropdownButton: Locator) => {
await page.waitForTimeout(500); // Initial timeout incase table remounts which will close the dropdown.
await dropdownButton.focus();
await page.keyboard.press('Enter');
await page.waitForTimeout(500);
await page.keyboard.press('Escape');
await page.waitForTimeout(500);
await dropdownButton.focus();
await page.keyboard.press('Enter');
await expect(page.getByRole('menuitem').first()).toBeVisible();
};
@@ -9,7 +9,7 @@ import { seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates'; import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
import { expectTextToBeVisible } from '../fixtures/generic'; import { expectTextToBeVisible, openDropdownMenu } from '../fixtures/generic';
test.describe.configure({ mode: 'parallel' }); test.describe.configure({ mode: 'parallel' });
@@ -117,7 +117,9 @@ test('[TEAMS]: can pin a document folder', async ({ page }) => {
redirectPath: `/t/${team.url}/documents`, redirectPath: `/t/${team.url}/documents`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Pin' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Pin' }).click(); await page.getByRole('menuitem', { name: 'Pin' }).click();
await page.reload(); await page.reload();
@@ -142,7 +144,9 @@ test('[TEAMS]: can unpin a document folder', async ({ page }) => {
redirectPath: `/t/${team.url}/documents`, redirectPath: `/t/${team.url}/documents`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Unpin' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Unpin' }).click(); await page.getByRole('menuitem', { name: 'Unpin' }).click();
await page.reload(); await page.reload();
@@ -166,7 +170,9 @@ test('[TEAMS]: can rename a document folder', async ({ page }) => {
redirectPath: `/t/${team.url}/documents`, redirectPath: `/t/${team.url}/documents`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await page.getByLabel('Name').fill('Team Archive'); await page.getByLabel('Name').fill('Team Archive');
@@ -191,7 +197,9 @@ test('[TEAMS]: document folder visibility is visible to team member', async ({ p
redirectPath: `/t/${team.url}/documents`, redirectPath: `/t/${team.url}/documents`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await expect(page.getByRole('combobox', { name: 'Visibility' })).toBeVisible(); await expect(page.getByRole('combobox', { name: 'Visibility' })).toBeVisible();
@@ -220,7 +228,9 @@ test('[TEAMS]: document folder can be moved to another document folder', async (
redirectPath: `/t/${team.url}/documents`, redirectPath: `/t/${team.url}/documents`,
}); });
await page.getByTestId('folder-card-more-button').nth(0).click(); const folderMoreBtn = page.getByTestId('folder-card-more-button').nth(0);
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Move' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move' }).click(); await page.getByRole('menuitem', { name: 'Move' }).click();
await page.getByRole('button', { name: 'Team Clients' }).click(); await page.getByRole('button', { name: 'Team Clients' }).click();
@@ -271,7 +281,9 @@ test('[TEAMS]: document folder and its contents can be deleted', async ({ page }
redirectPath: `/t/${team.url}/documents`, redirectPath: `/t/${team.url}/documents`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('textbox').fill(`delete ${folder.name}`); await page.getByRole('textbox').fill(`delete ${folder.name}`);
@@ -280,12 +292,8 @@ test('[TEAMS]: document folder and its contents can be deleted', async ({ page }
await page.goto(`/t/${team.url}/documents`); await page.goto(`/t/${team.url}/documents`);
await expect(page.locator(`[data-folder-id="${folder.id}"]`)).not.toBeVisible(); await expect(page.locator(`[data-folder-id="${folder.id}"]`)).not.toBeVisible();
await expect(page.getByText(proposal.title)).not.toBeVisible(); await expect(page.getByText(proposal.title)).toBeVisible();
await expect(page.getByText(report.title)).toBeVisible();
await page.goto(`/t/${team.url}/documents/f/${folder.id}`);
await expect(page.getByText(report.title)).not.toBeVisible();
await expect(page.locator(`[data-folder-id="${reportsFolder.id}"]`)).not.toBeVisible();
}); });
test('[TEAMS]: create folder button is visible on templates page', async ({ page }) => { test('[TEAMS]: create folder button is visible on templates page', async ({ page }) => {
@@ -410,7 +418,9 @@ test('[TEAMS]: can pin a template folder', async ({ page }) => {
redirectPath: `/t/${team.url}/templates`, redirectPath: `/t/${team.url}/templates`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Pin' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Pin' }).click(); await page.getByRole('menuitem', { name: 'Pin' }).click();
await page.reload(); await page.reload();
@@ -436,7 +446,9 @@ test('[TEAMS]: can unpin a template folder', async ({ page }) => {
redirectPath: `/t/${team.url}/templates`, redirectPath: `/t/${team.url}/templates`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Unpin' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Unpin' }).click(); await page.getByRole('menuitem', { name: 'Unpin' }).click();
await page.reload(); await page.reload();
@@ -462,7 +474,9 @@ test('[TEAMS]: can rename a template folder', async ({ page }) => {
redirectPath: `/t/${team.url}/templates`, redirectPath: `/t/${team.url}/templates`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await page.getByLabel('Name').fill('Updated Team Template Folder'); await page.getByLabel('Name').fill('Updated Team Template Folder');
@@ -488,7 +502,9 @@ test('[TEAMS]: template folder visibility is not visible to team member', async
redirectPath: `/t/${team.url}/templates`, redirectPath: `/t/${team.url}/templates`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await expect(page.getByRole('menuitem', { name: 'Visibility' })).not.toBeVisible(); await expect(page.getByRole('menuitem', { name: 'Visibility' })).not.toBeVisible();
@@ -519,7 +535,9 @@ test('[TEAMS]: template folder can be moved to another template folder', async (
redirectPath: `/t/${team.url}/templates`, redirectPath: `/t/${team.url}/templates`,
}); });
await page.getByTestId('folder-card-more-button').nth(0).click(); const folderMoreBtn = page.getByTestId('folder-card-more-button').nth(0);
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Move' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move' }).click(); await page.getByRole('menuitem', { name: 'Move' }).click();
await page.getByRole('button', { name: 'Team Client Templates' }).click(); await page.getByRole('button', { name: 'Team Client Templates' }).click();
@@ -572,7 +590,9 @@ test('[TEAMS]: template folder can be deleted', async ({ page }) => {
redirectPath: `/t/${team.url}/templates`, redirectPath: `/t/${team.url}/templates`,
}); });
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn);
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('textbox').fill(`delete ${folder.name}`); await page.getByRole('textbox').fill(`delete ${folder.name}`);
@@ -761,7 +781,9 @@ test('[TEAMS]: folder inherits team visibility settings', async ({ page }) => {
await page.goto(`/t/${team.url}/documents/`); await page.goto(`/t/${team.url}/documents/`);
await page.getByTestId('folder-card-more-button').click(); const folderMoreBtn1 = page.getByTestId('folder-card-more-button');
await openDropdownMenu(page, folderMoreBtn1);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await expect(page.getByRole('combobox', { name: 'Visibility' })).toHaveText('Admins only'); await expect(page.getByRole('combobox', { name: 'Visibility' })).toHaveText('Admins only');
@@ -781,7 +803,9 @@ test('[TEAMS]: folder inherits team visibility settings', async ({ page }) => {
await page.goto(`/t/${team.url}/documents`); await page.goto(`/t/${team.url}/documents`);
await page.getByTestId('folder-card-more-button').nth(0).click(); const folderMoreBtn2 = page.getByTestId('folder-card-more-button').nth(0);
await openDropdownMenu(page, folderMoreBtn2);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await expect(page.getByRole('combobox', { name: 'Visibility' })).toHaveText('Managers and above'); await expect(page.getByRole('combobox', { name: 'Visibility' })).toHaveText('Managers and above');
@@ -801,7 +825,9 @@ test('[TEAMS]: folder inherits team visibility settings', async ({ page }) => {
await page.goto(`/t/${team.url}/documents/`); await page.goto(`/t/${team.url}/documents/`);
await page.getByTestId('folder-card-more-button').nth(0).click(); const folderMoreBtn3 = page.getByTestId('folder-card-more-button').nth(0);
await openDropdownMenu(page, folderMoreBtn3);
await expect(page.getByRole('menuitem', { name: 'Settings' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Settings' }).click(); await page.getByRole('menuitem', { name: 'Settings' }).click();
await expect(page.getByRole('combobox', { name: 'Visibility' })).toHaveText('Everyone'); await expect(page.getByRole('combobox', { name: 'Visibility' })).toHaveText('Everyone');
@@ -966,7 +992,9 @@ test('[TEAMS]: team member can move documents to everyone folder', async ({ page
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move' }).click(); await page.getByRole('menuitem', { name: 'Move' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1018,7 +1046,9 @@ test('[TEAMS]: team manager can move manager document to manager folder', async
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1071,7 +1101,9 @@ test('[TEAMS]: team manager can move manager document to everyone folder', async
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1124,7 +1156,9 @@ test('[TEAMS]: team manager can move everyone document to manager folder', async
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1177,7 +1211,9 @@ test('[TEAMS]: team admin can move admin document to admin folder', async ({ pag
await expect(page.getByText('[TEST] Admin Document')).toBeVisible(); await expect(page.getByText('[TEST] Admin Document')).toBeVisible();
const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ }); const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ });
await adminDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = adminDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible();
@@ -1228,7 +1264,9 @@ test('[TEAMS]: team admin can move admin document to manager folder', async ({ p
await expect(page.getByText('[TEST] Admin Document')).toBeVisible(); await expect(page.getByText('[TEST] Admin Document')).toBeVisible();
const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ }); const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ });
await adminDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = adminDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1279,7 +1317,9 @@ test('[TEAMS]: team admin can move admin document to everyone folder', async ({
await expect(page.getByText('[TEST] Admin Document')).toBeVisible(); await expect(page.getByText('[TEST] Admin Document')).toBeVisible();
const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ }); const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ });
await adminDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = adminDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1330,7 +1370,9 @@ test('[TEAMS]: team admin can move manager document to admin folder', async ({ p
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Move to Folder' }).click({ force: true });
await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible();
@@ -1381,7 +1423,9 @@ test('[TEAMS]: team admin can move manager document to manager folder', async ({
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Move to Folder' }).click({ force: true });
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1432,7 +1476,9 @@ test('[TEAMS]: team admin can move manager document to everyone folder', async (
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Move to Folder' }).click({ force: true });
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1483,7 +1529,9 @@ test('[TEAMS]: team admin can move everyone document to admin folder', async ({
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible();
@@ -1534,7 +1582,9 @@ test('[TEAMS]: team admin can move everyone document to manager folder', async (
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1585,7 +1635,9 @@ test('[TEAMS]: team admin can move everyone document to everyone folder', async
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1630,7 +1682,9 @@ test('[TEAMS]: team owner can move admin document to admin folder', async ({ pag
await expect(page.getByText('[TEST] Admin Document')).toBeVisible(); await expect(page.getByText('[TEST] Admin Document')).toBeVisible();
const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ }); const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ });
await adminDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = adminDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible();
@@ -1675,7 +1729,9 @@ test('[TEAMS]: team owner can move admin document to manager folder', async ({ p
await expect(page.getByText('[TEST] Admin Document')).toBeVisible(); await expect(page.getByText('[TEST] Admin Document')).toBeVisible();
const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ }); const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ });
await adminDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = adminDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1720,7 +1776,9 @@ test('[TEAMS]: team owner can move admin document to everyone folder', async ({
await expect(page.getByText('[TEST] Admin Document')).toBeVisible(); await expect(page.getByText('[TEST] Admin Document')).toBeVisible();
const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ }); const adminDocRow = page.getByRole('row', { name: /\[TEST\] Admin Document/ });
await adminDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = adminDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1765,7 +1823,9 @@ test('[TEAMS]: team owner can move manager document to admin folder', async ({ p
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible();
@@ -1810,7 +1870,9 @@ test('[TEAMS]: team owner can move manager document to manager folder', async ({
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1855,7 +1917,9 @@ test('[TEAMS]: team owner can move manager document to everyone folder', async (
await expect(page.getByText('[TEST] Manager Document')).toBeVisible(); await expect(page.getByText('[TEST] Manager Document')).toBeVisible();
const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ }); const managerDocRow = page.getByRole('row', { name: /\[TEST\] Manager Document/ });
await managerDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = managerDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -1900,7 +1964,9 @@ test('[TEAMS]: team owner can move everyone document to admin folder', async ({
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Admin Folder' })).toBeVisible();
@@ -1945,7 +2011,9 @@ test('[TEAMS]: team owner can move everyone document to manager folder', async (
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Manager Folder' })).toBeVisible();
@@ -1990,7 +2058,9 @@ test('[TEAMS]: team owner can move everyone document to everyone folder', async
await expect(page.getByText('[TEST] Everyone Document')).toBeVisible(); await expect(page.getByText('[TEST] Everyone Document')).toBeVisible();
const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ }); const everyoneDocRow = page.getByRole('row', { name: /\[TEST\] Everyone Document/ });
await everyoneDocRow.getByTestId('document-table-action-btn').click(); const docActionBtn = everyoneDocRow.getByTestId('document-table-action-btn');
await openDropdownMenu(page, docActionBtn);
await expect(page.getByRole('menuitem', { name: 'Move to Folder' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); await page.getByRole('menuitem', { name: 'Move to Folder' }).click();
await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Everyone Folder' })).toBeVisible();
@@ -6,7 +6,11 @@ import { seedOrganisationMembers } from '@documenso/prisma/seed/organisations';
import { seedUser } from '@documenso/prisma/seed/users'; import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin, apiSignout } from '../fixtures/authentication'; import { apiSignin, apiSignout } from '../fixtures/authentication';
import { expectTextToBeVisible, expectTextToNotBeVisible } from '../fixtures/generic'; import {
expectTextToBeVisible,
expectTextToNotBeVisible,
openDropdownMenu,
} from '../fixtures/generic';
test('[ORGANISATIONS]: create and delete organisation', async ({ page }) => { test('[ORGANISATIONS]: create and delete organisation', async ({ page }) => {
const { user, organisation } = await seedUser({ const { user, organisation } = await seedUser({
@@ -399,7 +403,9 @@ test('[ORGANISATIONS]: manage groups and members', async ({ page }) => {
await expect(page.getByText('Team members have been added').first()).toBeVisible(); await expect(page.getByText('Team members have been added').first()).toBeVisible();
// Update CUSTOM_GROUP_B // Update CUSTOM_GROUP_B
await page.getByRole('row', { name: 'CUSTOM_GROUP_B' }).getByRole('button').click(); const updateBtn = page.getByRole('row', { name: 'CUSTOM_GROUP_B' }).getByRole('button');
await openDropdownMenu(page, updateBtn);
await expect(page.getByRole('menuitem', { name: 'Update role' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Update role' }).click(); await page.getByRole('menuitem', { name: 'Update role' }).click();
await page.getByRole('combobox').click(); await page.getByRole('combobox').click();
await page.getByRole('option', { name: 'Team Admin' }).click(); await page.getByRole('option', { name: 'Team Admin' }).click();
@@ -409,7 +415,9 @@ test('[ORGANISATIONS]: manage groups and members', async ({ page }) => {
await page.reload(); await page.reload();
// Delete CUSTOM_GROUP_B // Delete CUSTOM_GROUP_B
await page.getByRole('row', { name: 'CUSTOM_GROUP_B' }).getByRole('button').click(); const deleteBtn = page.getByRole('row', { name: 'CUSTOM_GROUP_B' }).getByRole('button');
await openDropdownMenu(page, deleteBtn);
await expect(page.getByRole('menuitem', { name: 'Remove' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Remove' }).click(); await page.getByRole('menuitem', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
await expectTextToBeVisible(page, 'You have successfully removed this group from the team.'); await expectTextToBeVisible(page, 'You have successfully removed this group from the team.');
@@ -477,7 +485,9 @@ test('[ORGANISATIONS]: member invites', async ({ page }) => {
await expect(page.getByText(user2.email)).toBeVisible(); await expect(page.getByText(user2.email)).toBeVisible();
await expect(page.getByText(user3.email)).toBeVisible(); await expect(page.getByText(user3.email)).toBeVisible();
await page.getByRole('row', { name: user3.email }).getByRole('button').click(); const inviteActionBtn = page.getByRole('row', { name: user3.email }).getByRole('button');
await openDropdownMenu(page, inviteActionBtn);
await expect(page.getByRole('menuitem', { name: 'Remove' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Remove' }).click(); await page.getByRole('menuitem', { name: 'Remove' }).click();
await expect(page.getByText('Invitation has been deleted').first()).toBeVisible(); await expect(page.getByText('Invitation has been deleted').first()).toBeVisible();
await expect(page.getByText(user3.email)).not.toBeVisible(); await expect(page.getByText(user3.email)).not.toBeVisible();
@@ -508,7 +518,9 @@ test('[ORGANISATIONS]: member invites', async ({ page }) => {
await expect(page.getByText(user.email)).toBeVisible(); await expect(page.getByText(user.email)).toBeVisible();
await expect(page.getByText(user2.email)).toBeVisible(); await expect(page.getByText(user2.email)).toBeVisible();
await page.getByRole('row', { name: user2.email }).getByRole('button').click(); const memberActionBtn = page.getByRole('row', { name: user2.email }).getByRole('button');
await openDropdownMenu(page, memberActionBtn);
await expect(page.getByRole('menuitem', { name: 'Remove' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Remove' }).click(); await page.getByRole('menuitem', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'Remove' }).click(); await page.getByRole('button', { name: 'Remove' }).click();
await expect(page.getByText('You have successfully removed').first()).toBeVisible(); await expect(page.getByText('You have successfully removed').first()).toBeVisible();
@@ -522,7 +534,9 @@ test('[ORGANISATIONS]: member invites', async ({ page }) => {
await expect(page.getByText(user.email)).toBeVisible(); await expect(page.getByText(user.email)).toBeVisible();
await expect(page.getByText(user2.email)).toBeVisible(); await expect(page.getByText(user2.email)).toBeVisible();
await page.getByRole('row', { name: user2.email }).getByRole('button').click(); const orgMemberBtn = page.getByRole('row', { name: user2.email }).getByRole('button');
await openDropdownMenu(page, orgMemberBtn);
await expect(page.getByRole('menuitem', { name: 'Remove' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Remove' }).click(); await page.getByRole('menuitem', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
await expect(page.getByText('You have successfully removed this user').first()).toBeVisible(); await expect(page.getByText('You have successfully removed this user').first()).toBeVisible();
@@ -1,10 +1,12 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { prisma } from '@documenso/prisma';
import { seedDirectTemplate } from '@documenso/prisma/seed/templates'; import { seedDirectTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users'; import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
import { expectToastTextToBeVisible } from '../fixtures/generic';
test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => { test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => {
const { user, team } = await seedUser(); const { user, team } = await seedUser();
@@ -44,6 +46,9 @@ test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => {
.fill('public-direct-template-description'); .fill('public-direct-template-description');
await page.getByRole('button', { name: 'Update' }).click(); await page.getByRole('button', { name: 'Update' }).click();
// Wait for toast
await expectToastTextToBeVisible(page, 'Template has been updated');
// Check that public profile is disabled. // Check that public profile is disabled.
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`); await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
await expect(page.locator('body')).toContainText('404 Profile not found'); await expect(page.locator('body')).toContainText('404 Profile not found');
@@ -51,7 +56,21 @@ test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => {
// Go back to public profile page. // Go back to public profile page.
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/settings/public-profile`); await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/settings/public-profile`);
await page.getByRole('switch').click(); await page.getByRole('switch').click();
await page.waitForTimeout(1000);
// Expect profile to be enabled via db.
await expect
.poll(
async () => {
const profile = await prisma.teamProfile.findFirst({
where: { teamId: team.id },
});
return profile?.enabled;
},
{
timeout: 1000,
},
)
.toBeTruthy();
// Assert values. // Assert values.
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`); await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
@@ -11,7 +11,11 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin, apiSignout } from '../fixtures/authentication'; import { apiSignin, apiSignout } from '../fixtures/authentication';
import { checkDocumentTabCount } from '../fixtures/documents'; import { checkDocumentTabCount } from '../fixtures/documents';
import { expectTextToBeVisible } from '../fixtures/generic'; import {
expectTextToBeVisible,
expectToastTextToBeVisible,
openDropdownMenu,
} from '../fixtures/generic';
test('[TEAMS]: check team documents count', async ({ page }) => { test('[TEAMS]: check team documents count', async ({ page }) => {
const { team, teamOwner, teamMember2 } = await seedTeamDocuments(); const { team, teamOwner, teamMember2 } = await seedTeamDocuments();
@@ -239,21 +243,15 @@ test('[TEAMS]: resend pending team document', async ({ page }) => {
redirectPath: `/t/${team.url}/documents?status=PENDING`, redirectPath: `/t/${team.url}/documents?status=PENDING`,
}); });
await expect(async () => { const actionBtn = page.getByTestId('document-table-action-btn').first();
await page.getByTestId('document-table-action-btn').first().click(); await expect(actionBtn).toBeAttached();
await openDropdownMenu(page, actionBtn);
await page.waitForTimeout(1000); await expect(page.getByRole('menuitem', { name: 'Resend' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Resend' }).click();
await expect(page.getByRole('menuitem', { name: 'Resend' })).toBeVisible();
}).toPass();
await page.getByRole('menuitem').filter({ hasText: 'Resend' }).click();
await page.getByLabel('test.documenso.com').first().click(); await page.getByLabel('test.documenso.com').first().click();
await page.getByRole('button', { name: 'Send reminder' }).click(); await page.getByRole('button', { name: 'Send reminder' }).click();
await expect( await expectToastTextToBeVisible(page, 'Document re-sent');
page.getByRole('status').filter({ hasText: 'Document re-sent' }).first(),
).toBeVisible();
}); });
test('[TEAMS]: delete draft team document', async ({ page }) => { test('[TEAMS]: delete draft team document', async ({ page }) => {
@@ -265,14 +263,12 @@ test('[TEAMS]: delete draft team document', async ({ page }) => {
redirectPath: `/t/${team.url}/documents?status=DRAFT`, redirectPath: `/t/${team.url}/documents?status=DRAFT`,
}); });
await expect(async () => { const actionBtn = page.getByTestId('document-table-action-btn').first();
await page.getByTestId('document-table-action-btn').first().click(); await expect(actionBtn).toBeVisible({
timeout: 500,
await page.waitForTimeout(1000); });
await openDropdownMenu(page, actionBtn);
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
}).toPass();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
@@ -309,14 +305,12 @@ test('[TEAMS]: delete pending team document', async ({ page }) => {
redirectPath: `/t/${team.url}/documents?status=PENDING`, redirectPath: `/t/${team.url}/documents?status=PENDING`,
}); });
await expect(async () => { const actionBtn = page.getByTestId('document-table-action-btn').first();
await page.getByTestId('document-table-action-btn').first().click(); await expect(actionBtn).toBeVisible({
timeout: 500,
await page.waitForTimeout(1000); });
await openDropdownMenu(page, actionBtn);
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
}).toPass();
await page.getByRole('menuitem', { name: 'Delete' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Delete' }).click({ force: true });
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete'); await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
await page.getByRole('button', { name: 'Delete' }).click({ force: true }); await page.getByRole('button', { name: 'Delete' }).click({ force: true });
@@ -354,14 +348,12 @@ test('[TEAMS]: delete completed team document', async ({ page }) => {
redirectPath: `/t/${team.url}/documents?status=COMPLETED`, redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
}); });
await expect(async () => { const actionBtn = page.getByTestId('document-table-action-btn').first();
await page.getByTestId('document-table-action-btn').first().click(); await expect(actionBtn).toBeVisible({
timeout: 500,
await page.waitForTimeout(1000); });
await openDropdownMenu(page, actionBtn);
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
}).toPass();
await page.getByRole('menuitem', { name: 'Delete' }).click({ force: true }); await page.getByRole('menuitem', { name: 'Delete' }).click({ force: true });
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete'); await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
await page.getByRole('button', { name: 'Delete' }).click({ force: true }); await page.getByRole('button', { name: 'Delete' }).click({ force: true });
@@ -5,6 +5,7 @@ import { seedTeamEmailVerification } from '@documenso/prisma/seed/teams';
import { seedUser } from '@documenso/prisma/seed/users'; import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
import { openDropdownMenu } from '../fixtures/generic';
test('[TEAMS]: send team email request', async ({ page }) => { test('[TEAMS]: send team email request', async ({ page }) => {
const { user, team } = await seedUser(); const { user, team } = await seedUser();
@@ -54,8 +55,13 @@ test('[TEAMS]: delete team email', async ({ page }) => {
redirectPath: `/t/${team.url}/settings`, redirectPath: `/t/${team.url}/settings`,
}); });
await page.locator('section div').filter({ hasText: 'Team email' }).getByRole('button').click(); const settingsBtn = page
.locator('section div')
.filter({ hasText: 'Team email' })
.getByRole('button');
await openDropdownMenu(page, settingsBtn);
await expect(page.getByRole('menuitem', { name: 'Remove' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Remove' }).click(); await page.getByRole('menuitem', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'Remove' }).click(); await page.getByRole('button', { name: 'Remove' }).click();
@@ -296,7 +296,13 @@ test.describe('AutoSave Fields Step', () => {
['SIGNATURE', 'TEXT'].toSorted(), ['SIGNATURE', 'TEXT'].toSorted(),
); );
const textField = fields[1]; const textField = fields.find((field) => field.type === 'TEXT');
expect(textField).toBeDefined();
if (!textField) {
throw new Error('No text field');
}
expect(textField.fieldMeta).toBeDefined(); expect(textField.fieldMeta).toBeDefined();
if ( if (
@@ -5,6 +5,7 @@ import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedTemplate } from '@documenso/prisma/seed/templates'; import { seedTemplate } from '@documenso/prisma/seed/templates';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
import { openDropdownMenu } from '../fixtures/generic';
test('[TEMPLATES]: view templates', async ({ page }) => { test('[TEMPLATES]: view templates', async ({ page }) => {
const { team, owner, organisation } = await seedTeam({ const { team, owner, organisation } = await seedTeam({
@@ -71,13 +72,14 @@ test('[TEMPLATES]: delete template', async ({ page }) => {
}); });
for (const template of ['Team template 1', 'Team template 2']) { for (const template of ['Team template 1', 'Team template 2']) {
await page const actionBtn = page
.getByRole('row', { name: template }) .getByRole('row', { name: template })
.getByRole('cell', { name: 'Use Template' }) .getByRole('cell', { name: 'Use Template' })
.getByRole('button') .getByRole('button')
.nth(1) .nth(1);
.click(); await openDropdownMenu(page, actionBtn);
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
await expect(page.getByText('Template deleted').first()).toBeVisible(); await expect(page.getByText('Template deleted').first()).toBeVisible();
@@ -110,7 +112,9 @@ test('[TEMPLATES]: duplicate template', async ({ page }) => {
}); });
// Duplicate team template. // Duplicate team template.
await page.getByRole('cell', { name: 'Use Template' }).getByRole('button').nth(1).click(); const actionBtn = page.getByRole('cell', { name: 'Use Template' }).getByRole('button').nth(1);
await openDropdownMenu(page, actionBtn);
await expect(page.getByRole('menuitem', { name: 'Duplicate' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Duplicate' }).click(); await page.getByRole('menuitem', { name: 'Duplicate' }).click();
await page.getByRole('button', { name: 'Duplicate' }).click(); await page.getByRole('button', { name: 'Duplicate' }).click();
await expect(page.getByText('Template duplicated').first()).toBeVisible(); await expect(page.getByText('Template duplicated').first()).toBeVisible();
@@ -7,7 +7,7 @@ import { seedBlankDocument } from '@documenso/prisma/seed/documents';
import { seedUser } from '@documenso/prisma/seed/users'; import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin, apiSignout } from '../fixtures/authentication'; import { apiSignin, apiSignout } from '../fixtures/authentication';
import { expectTextToBeVisible } from '../fixtures/generic'; import { expectTextToBeVisible, openDropdownMenu } from '../fixtures/generic';
/** /**
* Helper function to seed a webhook directly in the database for testing. * Helper function to seed a webhook directly in the database for testing.
@@ -147,9 +147,11 @@ test('[WEBHOOKS]: delete webhook', async ({ page }) => {
// Find the row with the webhook and click the action dropdown // Find the row with the webhook and click the action dropdown
const webhookRow = page.locator('tr', { hasText: webhookUrl }); const webhookRow = page.locator('tr', { hasText: webhookUrl });
await webhookRow.getByTestId('webhook-table-action-btn').click(); const actionBtn = webhookRow.getByTestId('webhook-table-action-btn');
await openDropdownMenu(page, actionBtn);
// Click Delete menu item // Click Delete menu item
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click();
// Fill in confirmation field // Fill in confirmation field
@@ -196,9 +198,11 @@ test('[WEBHOOKS]: update webhook', async ({ page }) => {
// Find the row with the webhook and click the action dropdown // Find the row with the webhook and click the action dropdown
const webhookRow = page.locator('tr', { hasText: originalWebhookUrl }); const webhookRow = page.locator('tr', { hasText: originalWebhookUrl });
await webhookRow.getByTestId('webhook-table-action-btn').click(); const actionBtn = webhookRow.getByTestId('webhook-table-action-btn');
await openDropdownMenu(page, actionBtn);
// Click Edit menu item // Click Edit menu item
await expect(page.getByRole('menuitem', { name: 'Edit' })).toBeVisible();
await page.getByRole('menuitem', { name: 'Edit' }).click(); await page.getByRole('menuitem', { name: 'Edit' }).click();
// Wait for dialog to open // Wait for dialog to open
+1 -1
View File
@@ -7,7 +7,7 @@
"scripts": { "scripts": {
"test:dev": "NODE_OPTIONS=--experimental-require-module playwright test", "test:dev": "NODE_OPTIONS=--experimental-require-module playwright test",
"test-ui:dev": "NODE_OPTIONS=--experimental-require-module playwright test --ui", "test-ui:dev": "NODE_OPTIONS=--experimental-require-module playwright test --ui",
"test:e2e": "NODE_OPTIONS=--experimental-require-module NODE_ENV=test start-server-and-test \"npm run start -w @documenso/remix\" http://localhost:3000 \"playwright test $E2E_TEST_PATH\"" "test:e2e": "NODE_OPTIONS=--experimental-require-module NODE_ENV=test NEXT_PRIVATE_LOGGER_FILE_PATH=./logs.json start-server-and-test \"npm run start -w @documenso/remix\" http://localhost:3000 \"playwright test $E2E_TEST_PATH\""
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
+49 -7
View File
@@ -1,7 +1,21 @@
import { defineConfig, devices } from '@playwright/test'; import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import os from 'os';
import path from 'path'; import path from 'path';
function calculateWorkers() {
const total = os.cpus().length;
// Reserve 2 cores for the system
const usable = Math.max(total - 2, 1);
// 1 worker per 2 cores, minimum 1
const workers = Math.max(Math.floor(usable / 2), 1);
// Max 6 workers
return Math.min(workers, 6);
}
const ENV_FILES = ['.env', '.env.local', `.env.${process.env.NODE_ENV || 'development'}`]; const ENV_FILES = ['.env', '.env.local', `.env.${process.env.NODE_ENV || 'development'}`];
ENV_FILES.forEach((file) => { ENV_FILES.forEach((file) => {
@@ -15,9 +29,8 @@ ENV_FILES.forEach((file) => {
*/ */
export default defineConfig({ export default defineConfig({
testDir: './e2e', testDir: './e2e',
/* Run tests in files in parallel */ fullyParallel: true,
fullyParallel: false, workers: 10, // See Projects where 10 is utilized for API tests. We're not running 10 workers for UI tests.
workers: 2,
maxFailures: process.env.CI ? 1 : undefined, maxFailures: process.env.CI ? 1 : undefined,
/* Fail the build on CI if you accidentally left test.only in the source code. */ /* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI, forbidOnly: !!process.env.CI,
@@ -31,25 +44,54 @@ export default defineConfig({
baseURL: 'http://localhost:3000', baseURL: 'http://localhost:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on', trace: 'retain-on-failure',
video: 'retain-on-failure',
video: 'on-first-retry',
/* Add explicit timeouts for actions */ /* Add explicit timeouts for actions */
actionTimeout: 15_000, actionTimeout: 15_000,
navigationTimeout: 30_000, navigationTimeout: 30_000,
contextOptions: {
reducedMotion: 'reduce',
},
/* Disable animations via cookie for more stable tests */
storageState: {
cookies: [
{
name: '__disable_animations',
value: 'true',
domain: 'localhost',
path: '/',
expires: -1,
httpOnly: false,
secure: false,
sameSite: 'Lax' as const,
},
],
origins: [],
},
}, },
timeout: 60_000, timeout: 60_000,
/* Configure projects for major browsers */ /* Configure projects for major browsers */
projects: [ projects: [
// API Tests e2e/api/**/*.spec.ts
{ {
name: 'chromium', name: 'api',
testMatch: /e2e\/api\/.*\.spec\.ts/,
workers: 10, // Limited by DB connections before it gets flakey.
},
// Run UI Tests
{
name: 'ui',
testMatch: /e2e\/(?!api\/).*\.spec\.ts/,
use: { use: {
...devices['Desktop Chrome'], ...devices['Desktop Chrome'],
viewport: { width: 1920, height: 1200 }, viewport: { width: 1920, height: 1200 },
}, },
workers: calculateWorkers(),
}, },
// { // {
+3
View File
@@ -587,6 +587,9 @@ export const seedPendingDocumentWithFullFields = async ({
where: { where: {
envelopeId: document.id, envelopeId: document.id,
}, },
orderBy: {
signingOrder: 'asc',
},
include: { include: {
fields: true, fields: true,
}, },