mirror of
https://github.com/documenso/documenso.git
synced 2026-06-22 04:12:06 +10:00
chore: optimize tests (#2280)
This commit is contained in:
@@ -1,14 +1,19 @@
|
||||
name: Playwright Tests
|
||||
on:
|
||||
push:
|
||||
branches: ['main', 'feat/rr7']
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
e2e_tests:
|
||||
name: 'E2E Tests'
|
||||
timeout-minutes: 60
|
||||
runs-on: warp-ubuntu-2204-x64-16x
|
||||
runs-on: warp-ubuntu-2204-x64-8x
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -28,9 +33,6 @@ jobs:
|
||||
- name: Seed the database
|
||||
run: npm run prisma:seed
|
||||
|
||||
- name: Build app
|
||||
run: npm run build
|
||||
|
||||
- name: Install playwright browsers
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
@@ -45,7 +47,7 @@ jobs:
|
||||
with:
|
||||
name: test-results
|
||||
path: 'packages/app-tests/**/test-results/*'
|
||||
retention-days: 30
|
||||
retention-days: 7
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
|
||||
+16
-2
@@ -46,12 +46,16 @@ export async function loader({ request }: Route.LoaderArgs) {
|
||||
|
||||
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)) {
|
||||
lang = extractLocaleData({ headers: request.headers }).lang;
|
||||
}
|
||||
|
||||
const disableAnimations = cookieHeader.includes('__disable_animations=true');
|
||||
|
||||
let organisations = null;
|
||||
|
||||
if (session.isAuthenticated) {
|
||||
@@ -62,6 +66,7 @@ export async function loader({ request }: Route.LoaderArgs) {
|
||||
{
|
||||
lang,
|
||||
theme: getTheme(),
|
||||
disableAnimations,
|
||||
session: session.isAuthenticated
|
||||
? {
|
||||
user: session.user,
|
||||
@@ -92,7 +97,8 @@ export function Layout({ 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();
|
||||
|
||||
@@ -111,6 +117,14 @@ export function LayoutContent({ children }: { children: React.ReactNode }) {
|
||||
<meta name="google" content="notranslate" />
|
||||
<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 */}
|
||||
<script>0</script>
|
||||
</head>
|
||||
|
||||
@@ -28,8 +28,6 @@ export const loader = () => {
|
||||
export default function TeamsSettingsPage() {
|
||||
const { isAiFeaturesConfigured } = useLoaderData<typeof loader>();
|
||||
|
||||
console.log('isAiFeaturesConfigured', isAiFeaturesConfigured);
|
||||
|
||||
const team = useCurrentTeam();
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
@@ -144,6 +144,9 @@ test.describe('API V2 Envelopes', () => {
|
||||
externalId: 'externalId',
|
||||
visibility: DocumentVisibility.MANAGER_AND_ABOVE,
|
||||
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: {
|
||||
hello: 'world',
|
||||
},
|
||||
@@ -262,8 +265,6 @@ test.describe('API V2 Envelopes', () => {
|
||||
},
|
||||
});
|
||||
|
||||
console.log(userB.email);
|
||||
|
||||
expect(envelope.envelopeItems.length).toBe(2);
|
||||
expect(envelope.envelopeItems[0].title).toBe('field-meta.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[0].type).toBe('SIGNATURE');
|
||||
expect(retrievedFields[1].type).toBe('TEXT');
|
||||
expect(retrievedFields[2].type).toBe('SIGNATURE');
|
||||
expect(retrievedFields.filter((field) => field.type === 'SIGNATURE')).toHaveLength(2);
|
||||
expect(retrievedFields.filter((field) => field.type === 'TEXT')).toHaveLength(1);
|
||||
}).toPass();
|
||||
});
|
||||
|
||||
@@ -214,10 +213,8 @@ test.describe('AutoSave Fields Step', () => {
|
||||
});
|
||||
|
||||
expect(retrievedFields.length).toBe(4);
|
||||
expect(retrievedFields[0].type).toBe('SIGNATURE');
|
||||
expect(retrievedFields[1].type).toBe('TEXT');
|
||||
expect(retrievedFields[2].type).toBe('SIGNATURE');
|
||||
expect(retrievedFields[3].type).toBe('SIGNATURE');
|
||||
expect(retrievedFields.filter((field) => field.type === 'SIGNATURE')).toHaveLength(3);
|
||||
expect(retrievedFields.filter((field) => field.type === 'TEXT')).toHaveLength(1);
|
||||
}).toPass();
|
||||
});
|
||||
|
||||
@@ -259,10 +256,16 @@ test.describe('AutoSave Fields Step', () => {
|
||||
});
|
||||
|
||||
expect(retrievedFields.length).toBe(2);
|
||||
expect(retrievedFields[0].type).toBe('SIGNATURE');
|
||||
expect(retrievedFields[1].type).toBe('TEXT');
|
||||
const textField = retrievedFields.find((field) => field.type === '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();
|
||||
|
||||
if (
|
||||
|
||||
@@ -9,6 +9,7 @@ import { seedUser } from '@documenso/prisma/seed/users';
|
||||
|
||||
import { apiSignin, apiSignout } from '../fixtures/authentication';
|
||||
import { checkDocumentTabCount } from '../fixtures/documents';
|
||||
import { expectToastTextToBeVisible, openDropdownMenu } from '../fixtures/generic';
|
||||
|
||||
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.
|
||||
await page
|
||||
const documentActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Completed' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
|
||||
await page.waitForTimeout(200);
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, documentActionBtn);
|
||||
|
||||
// delete document
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
|
||||
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.
|
||||
await page
|
||||
const documentActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Pending' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
|
||||
await page.waitForTimeout(200);
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, documentActionBtn);
|
||||
|
||||
// delete document
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
|
||||
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.
|
||||
await page
|
||||
const documentActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Draft' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, documentActionBtn);
|
||||
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
// delete document
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); // Required to reduce flakiness.
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await expect(page.getByPlaceholder("Type 'delete' to confirm")).not.toBeVisible();
|
||||
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();
|
||||
|
||||
@@ -203,14 +200,13 @@ test('[DOCUMENTS]: deleting pending documents should permanently remove it', asy
|
||||
});
|
||||
|
||||
// Open document action menu.
|
||||
await page
|
||||
const documentActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Pending' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
|
||||
await page.waitForTimeout(200);
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, documentActionBtn);
|
||||
|
||||
// Delete document.
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
|
||||
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.
|
||||
await page
|
||||
const documentActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Completed' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
|
||||
await page.waitForTimeout(200);
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, documentActionBtn);
|
||||
|
||||
// Delete document.
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
|
||||
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.
|
||||
await expect(async () => {
|
||||
await page
|
||||
.locator('tr', { hasText: 'Document 1 - Completed' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Hide' })).toBeVisible();
|
||||
}).toPass();
|
||||
const completedDocActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Completed' })
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, completedDocActionBtn);
|
||||
|
||||
// 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('button', { name: 'Hide' }).click({ force: true });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await expect(async () => {
|
||||
await page
|
||||
.locator('tr', { hasText: 'Document 1 - Pending' })
|
||||
.getByTestId('document-table-action-btn')
|
||||
.click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Hide' })).toBeVisible();
|
||||
}).toPass();
|
||||
const pendingDocActionBtn = page
|
||||
.locator('tr', { hasText: 'Document 1 - Pending' })
|
||||
.getByTestId('document-table-action-btn');
|
||||
await openDropdownMenu(page, pendingDocActionBtn);
|
||||
|
||||
// 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('button', { name: 'Hide' }).click({ force: true });
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Locator } from '@playwright/test';
|
||||
import { type Page, expect } from '@playwright/test';
|
||||
|
||||
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) => {
|
||||
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 { apiSignin } from '../fixtures/authentication';
|
||||
import { expectTextToBeVisible } from '../fixtures/generic';
|
||||
import { expectTextToBeVisible, openDropdownMenu } from '../fixtures/generic';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
@@ -117,7 +117,9 @@ test('[TEAMS]: can pin a document folder', async ({ page }) => {
|
||||
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.reload();
|
||||
@@ -142,7 +144,9 @@ test('[TEAMS]: can unpin a document folder', async ({ page }) => {
|
||||
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.reload();
|
||||
@@ -166,7 +170,9 @@ test('[TEAMS]: can rename a document folder', async ({ page }) => {
|
||||
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.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`,
|
||||
});
|
||||
|
||||
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 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`,
|
||||
});
|
||||
|
||||
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('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`,
|
||||
});
|
||||
|
||||
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('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 expect(page.locator(`[data-folder-id="${folder.id}"]`)).not.toBeVisible();
|
||||
await expect(page.getByText(proposal.title)).not.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();
|
||||
await expect(page.getByText(proposal.title)).toBeVisible();
|
||||
await expect(page.getByText(report.title)).toBeVisible();
|
||||
});
|
||||
|
||||
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`,
|
||||
});
|
||||
|
||||
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.reload();
|
||||
@@ -436,7 +446,9 @@ test('[TEAMS]: can unpin a template folder', async ({ page }) => {
|
||||
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.reload();
|
||||
@@ -462,7 +474,9 @@ test('[TEAMS]: can rename a template folder', async ({ page }) => {
|
||||
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.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`,
|
||||
});
|
||||
|
||||
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 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`,
|
||||
});
|
||||
|
||||
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('button', { name: 'Team Client Templates' }).click();
|
||||
@@ -572,7 +590,9 @@ test('[TEAMS]: template folder can be deleted', async ({ page }) => {
|
||||
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('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.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 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.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 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.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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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();
|
||||
|
||||
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 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 { 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 }) => {
|
||||
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();
|
||||
|
||||
// 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('combobox').click();
|
||||
await page.getByRole('option', { name: 'Team Admin' }).click();
|
||||
@@ -409,7 +415,9 @@ test('[ORGANISATIONS]: manage groups and members', async ({ page }) => {
|
||||
await page.reload();
|
||||
|
||||
// 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('button', { name: 'Delete' }).click();
|
||||
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(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 expect(page.getByText('Invitation has been deleted').first()).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(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('button', { name: 'Remove' }).click();
|
||||
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(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('button', { name: 'Delete' }).click();
|
||||
await expect(page.getByText('You have successfully removed this user').first()).toBeVisible();
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { seedDirectTemplate } from '@documenso/prisma/seed/templates';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
|
||||
import { apiSignin } from '../fixtures/authentication';
|
||||
import { expectToastTextToBeVisible } from '../fixtures/generic';
|
||||
|
||||
test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => {
|
||||
const { user, team } = await seedUser();
|
||||
@@ -44,6 +46,9 @@ test('[PUBLIC_PROFILE]: create team profile', async ({ page }) => {
|
||||
.fill('public-direct-template-description');
|
||||
await page.getByRole('button', { name: 'Update' }).click();
|
||||
|
||||
// Wait for toast
|
||||
await expectToastTextToBeVisible(page, 'Template has been updated');
|
||||
|
||||
// Check that public profile is disabled.
|
||||
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/p/${publicProfileUrl}`);
|
||||
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.
|
||||
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/settings/public-profile`);
|
||||
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.
|
||||
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 { checkDocumentTabCount } from '../fixtures/documents';
|
||||
import { expectTextToBeVisible } from '../fixtures/generic';
|
||||
import {
|
||||
expectTextToBeVisible,
|
||||
expectToastTextToBeVisible,
|
||||
openDropdownMenu,
|
||||
} from '../fixtures/generic';
|
||||
|
||||
test('[TEAMS]: check team documents count', async ({ page }) => {
|
||||
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`,
|
||||
});
|
||||
|
||||
await expect(async () => {
|
||||
await page.getByTestId('document-table-action-btn').first().click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Resend' })).toBeVisible();
|
||||
}).toPass();
|
||||
|
||||
await page.getByRole('menuitem').filter({ hasText: 'Resend' }).click();
|
||||
const actionBtn = page.getByTestId('document-table-action-btn').first();
|
||||
await expect(actionBtn).toBeAttached();
|
||||
await openDropdownMenu(page, actionBtn);
|
||||
await expect(page.getByRole('menuitem', { name: 'Resend' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Resend' }).click();
|
||||
await page.getByLabel('test.documenso.com').first().click();
|
||||
await page.getByRole('button', { name: 'Send reminder' }).click();
|
||||
|
||||
await expect(
|
||||
page.getByRole('status').filter({ hasText: 'Document re-sent' }).first(),
|
||||
).toBeVisible();
|
||||
await expectToastTextToBeVisible(page, 'Document re-sent');
|
||||
});
|
||||
|
||||
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`,
|
||||
});
|
||||
|
||||
await expect(async () => {
|
||||
await page.getByTestId('document-table-action-btn').first().click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
}).toPass();
|
||||
|
||||
const actionBtn = page.getByTestId('document-table-action-btn').first();
|
||||
await expect(actionBtn).toBeVisible({
|
||||
timeout: 500,
|
||||
});
|
||||
await openDropdownMenu(page, actionBtn);
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { 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`,
|
||||
});
|
||||
|
||||
await expect(async () => {
|
||||
await page.getByTestId('document-table-action-btn').first().click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
}).toPass();
|
||||
|
||||
const actionBtn = page.getByTestId('document-table-action-btn').first();
|
||||
await expect(actionBtn).toBeVisible({
|
||||
timeout: 500,
|
||||
});
|
||||
await openDropdownMenu(page, actionBtn);
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click({ force: true });
|
||||
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
|
||||
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`,
|
||||
});
|
||||
|
||||
await expect(async () => {
|
||||
await page.getByTestId('document-table-action-btn').first().click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
}).toPass();
|
||||
|
||||
const actionBtn = page.getByTestId('document-table-action-btn').first();
|
||||
await expect(actionBtn).toBeVisible({
|
||||
timeout: 500,
|
||||
});
|
||||
await openDropdownMenu(page, actionBtn);
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click({ force: true });
|
||||
await page.getByPlaceholder("Type 'delete' to confirm").fill('delete');
|
||||
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 { apiSignin } from '../fixtures/authentication';
|
||||
import { openDropdownMenu } from '../fixtures/generic';
|
||||
|
||||
test('[TEAMS]: send team email request', async ({ page }) => {
|
||||
const { user, team } = await seedUser();
|
||||
@@ -54,8 +55,13 @@ test('[TEAMS]: delete team email', async ({ page }) => {
|
||||
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('button', { name: 'Remove' }).click();
|
||||
|
||||
|
||||
@@ -296,7 +296,13 @@ test.describe('AutoSave Fields Step', () => {
|
||||
['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();
|
||||
|
||||
if (
|
||||
|
||||
@@ -5,6 +5,7 @@ import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||
import { seedTemplate } from '@documenso/prisma/seed/templates';
|
||||
|
||||
import { apiSignin } from '../fixtures/authentication';
|
||||
import { openDropdownMenu } from '../fixtures/generic';
|
||||
|
||||
test('[TEMPLATES]: view templates', async ({ page }) => {
|
||||
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']) {
|
||||
await page
|
||||
const actionBtn = page
|
||||
.getByRole('row', { name: template })
|
||||
.getByRole('cell', { name: 'Use Template' })
|
||||
.getByRole('button')
|
||||
.nth(1)
|
||||
.click();
|
||||
.nth(1);
|
||||
await openDropdownMenu(page, actionBtn);
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
await expect(page.getByText('Template deleted').first()).toBeVisible();
|
||||
@@ -110,7 +112,9 @@ test('[TEMPLATES]: duplicate template', async ({ page }) => {
|
||||
});
|
||||
|
||||
// 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('button', { name: 'Duplicate' }).click();
|
||||
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 { 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.
|
||||
@@ -147,9 +147,11 @@ test('[WEBHOOKS]: delete webhook', async ({ page }) => {
|
||||
|
||||
// Find the row with the webhook and click the action dropdown
|
||||
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
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
|
||||
// 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
|
||||
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
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' })).toBeVisible();
|
||||
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||
|
||||
// Wait for dialog to open
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"test:dev": "NODE_OPTIONS=--experimental-require-module playwright test",
|
||||
"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": [],
|
||||
"author": "",
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
import dotenv from 'dotenv';
|
||||
import os from 'os';
|
||||
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'}`];
|
||||
|
||||
ENV_FILES.forEach((file) => {
|
||||
@@ -15,9 +29,8 @@ ENV_FILES.forEach((file) => {
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './e2e',
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: false,
|
||||
workers: 2,
|
||||
fullyParallel: true,
|
||||
workers: 10, // See Projects where 10 is utilized for API tests. We're not running 10 workers for UI tests.
|
||||
maxFailures: process.env.CI ? 1 : undefined,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
@@ -31,25 +44,54 @@ export default defineConfig({
|
||||
baseURL: 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on',
|
||||
|
||||
video: 'on-first-retry',
|
||||
trace: 'retain-on-failure',
|
||||
video: 'retain-on-failure',
|
||||
|
||||
/* Add explicit timeouts for actions */
|
||||
actionTimeout: 15_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,
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
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: {
|
||||
...devices['Desktop Chrome'],
|
||||
viewport: { width: 1920, height: 1200 },
|
||||
},
|
||||
workers: calculateWorkers(),
|
||||
},
|
||||
|
||||
// {
|
||||
|
||||
@@ -587,6 +587,9 @@ export const seedPendingDocumentWithFullFields = async ({
|
||||
where: {
|
||||
envelopeId: document.id,
|
||||
},
|
||||
orderBy: {
|
||||
signingOrder: 'asc',
|
||||
},
|
||||
include: {
|
||||
fields: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user