chore: increase wait times for tests (#1778)

This commit is contained in:
Ephraim Duncan
2025-06-11 03:25:21 +00:00
committed by GitHub
parent d11ec8fa2a
commit fd2b413ed9
14 changed files with 113 additions and 49 deletions

View File

@ -197,7 +197,7 @@ test.describe('Template Field Prefill API v1', () => {
id: numberField.id, id: numberField.id,
type: 'number', type: 'number',
label: 'Prefilled Number', label: 'Prefilled Number',
value: '42', value: '98765',
}, },
{ {
id: radioField.id, id: radioField.id,
@ -256,7 +256,7 @@ test.describe('Template Field Prefill API v1', () => {
expect(documentNumberField?.fieldMeta).toMatchObject({ expect(documentNumberField?.fieldMeta).toMatchObject({
type: 'number', type: 'number',
label: 'Prefilled Number', label: 'Prefilled Number',
value: '42', value: '98765',
}); });
const documentRadioField = document?.fields.find( const documentRadioField = document?.fields.find(
@ -329,7 +329,7 @@ test.describe('Template Field Prefill API v1', () => {
await expect(page.getByText('This is prefilled')).toBeVisible(); await expect(page.getByText('This is prefilled')).toBeVisible();
// Number field // Number field
await expect(page.getByText('42')).toBeVisible(); await expect(page.getByText('98765', { exact: true })).toBeVisible();
// Radio field // Radio field
await expect(page.getByText('Option A')).toBeVisible(); await expect(page.getByText('Option A')).toBeVisible();
@ -383,7 +383,7 @@ test.describe('Template Field Prefill API v1', () => {
// 5. Add fields to the template // 5. Add fields to the template
// Add TEXT field // Add TEXT field
const textField = await prisma.field.create({ await prisma.field.create({
data: { data: {
templateId: template.id, templateId: template.id,
recipientId: recipient.id, recipientId: recipient.id,
@ -403,7 +403,7 @@ test.describe('Template Field Prefill API v1', () => {
}); });
// Add NUMBER field // Add NUMBER field
const numberField = await prisma.field.create({ await prisma.field.create({
data: { data: {
templateId: template.id, templateId: template.id,
recipientId: recipient.id, recipientId: recipient.id,

View File

@ -194,7 +194,7 @@ test.describe('Template Field Prefill API v2', () => {
id: numberField.id, id: numberField.id,
type: 'number', type: 'number',
label: 'Prefilled Number', label: 'Prefilled Number',
value: '42', value: '98765',
}, },
{ {
id: radioField.id, id: radioField.id,
@ -253,7 +253,7 @@ test.describe('Template Field Prefill API v2', () => {
expect(documentNumberField?.fieldMeta).toMatchObject({ expect(documentNumberField?.fieldMeta).toMatchObject({
type: 'number', type: 'number',
label: 'Prefilled Number', label: 'Prefilled Number',
value: '42', value: '98765',
}); });
const documentRadioField = document?.fields.find( const documentRadioField = document?.fields.find(
@ -326,7 +326,7 @@ test.describe('Template Field Prefill API v2', () => {
await expect(page.getByText('This is prefilled')).toBeVisible(); await expect(page.getByText('This is prefilled')).toBeVisible();
// Number field // Number field
await expect(page.getByText('42')).toBeVisible(); await expect(page.getByText('98765', { exact: true })).toBeVisible();
// Radio field // Radio field
await expect(page.getByText('Option A')).toBeVisible(); await expect(page.getByText('Option A')).toBeVisible();
@ -380,7 +380,7 @@ test.describe('Template Field Prefill API v2', () => {
// 5. Add fields to the template // 5. Add fields to the template
// Add TEXT field // Add TEXT field
const textField = await prisma.field.create({ await prisma.field.create({
data: { data: {
templateId: template.id, templateId: template.id,
recipientId: recipient.id, recipientId: recipient.id,
@ -400,7 +400,7 @@ test.describe('Template Field Prefill API v2', () => {
}); });
// Add NUMBER field // Add NUMBER field
const numberField = await prisma.field.create({ await prisma.field.create({
data: { data: {
templateId: template.id, templateId: template.id,
recipientId: recipient.id, recipientId: recipient.id,

View File

@ -633,7 +633,7 @@ test('[DOCUMENT_FLOW]: should be able to create and sign a document with 3 recip
} }
// Wait for the document to be signed. // Wait for the document to be signed.
await page.waitForTimeout(5000); await page.waitForTimeout(10000);
const finalDocument = await prisma.document.findFirst({ const finalDocument = await prisma.document.findFirst({
where: { id: createdDocument?.id }, where: { id: createdDocument?.id },

View File

@ -283,10 +283,10 @@ test('[DOCUMENTS]: deleting documents as a recipient should only hide it for the
}).toPass(); }).toPass();
// Delete document. // Delete document.
await page.getByRole('menuitem', { name: 'Hide' }).click(); await page.getByRole('menuitem', { name: 'Hide' }).waitFor({ state: 'visible' });
await page.getByRole('button', { name: 'Hide' }).click(); await page.getByRole('menuitem', { name: 'Hide' }).click({ force: true });
await page.getByRole('button', { name: 'Hide' }).click({ force: true });
await page.waitForTimeout(1000); await page.waitForTimeout(2000);
await expect(async () => { await expect(async () => {
await page await page
@ -300,8 +300,10 @@ test('[DOCUMENTS]: deleting documents as a recipient should only hide it for the
}).toPass(); }).toPass();
// Delete document. // Delete document.
await page.getByRole('menuitem', { name: 'Hide' }).click(); await page.getByRole('menuitem', { name: 'Hide' }).waitFor({ state: 'visible' });
await page.getByRole('button', { name: 'Hide' }).click(); await page.getByRole('menuitem', { name: 'Hide' }).click({ force: true });
await page.getByRole('button', { name: 'Hide' }).click({ force: true });
await page.waitForTimeout(2000);
// Check document counts. // Check document counts.
await expect(page.getByRole('row', { name: /Document 1 - Completed/ })).not.toBeVisible(); await expect(page.getByRole('row', { name: /Document 1 - Completed/ })).not.toBeVisible();

View File

@ -49,9 +49,11 @@ test.describe('Signing Certificate Tests', () => {
} }
await page.getByRole('button', { name: 'Complete' }).click(); await page.getByRole('button', { name: 'Complete' }).click();
await page.getByRole('button', { name: 'Sign' }).click(); await page.getByRole('button', { name: 'Sign' }).click({ force: true });
await page.waitForURL(`/sign/${recipient.token}/complete`); await page.waitForURL(`/sign/${recipient.token}/complete`);
await page.waitForTimeout(10000);
await expect(async () => { await expect(async () => {
const { status } = await getDocumentByToken({ const { status } = await getDocumentByToken({
token: recipient.token, token: recipient.token,

View File

@ -3,8 +3,7 @@ import path from 'node:path';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { DocumentVisibility, FolderType, TeamMemberRole } from '@documenso/prisma/client'; import { DocumentVisibility, FolderType, TeamMemberRole } from '@documenso/prisma/client';
import { seedTeamDocuments } from '@documenso/prisma/seed/documents'; import { seedBlankDocument, seedTeamDocuments } from '@documenso/prisma/seed/documents';
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
import { seedBlankFolder } from '@documenso/prisma/seed/folders'; import { seedBlankFolder } from '@documenso/prisma/seed/folders';
import { seedTeamMember } from '@documenso/prisma/seed/teams'; import { seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates'; import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
@ -1328,7 +1327,7 @@ test('[TEAMS]: team admin can move manager document to admin folder', async ({ p
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(); await managerDocRow.getByTestId('document-table-action-btn').click();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); 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();
await page.getByRole('button', { name: 'Admin Folder' }).click(); await page.getByRole('button', { name: 'Admin Folder' }).click();
@ -1379,7 +1378,7 @@ test('[TEAMS]: team admin can move manager document to manager folder', async ({
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(); await managerDocRow.getByTestId('document-table-action-btn').click();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); 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();
await page.getByRole('button', { name: 'Manager Folder' }).click(); await page.getByRole('button', { name: 'Manager Folder' }).click();
@ -1430,7 +1429,7 @@ test('[TEAMS]: team admin can move manager document to everyone folder', async (
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(); await managerDocRow.getByTestId('document-table-action-btn').click();
await page.getByRole('menuitem', { name: 'Move to Folder' }).click(); 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();
await page.getByRole('button', { name: 'Everyone Folder' }).click(); await page.getByRole('button', { name: 'Everyone Folder' }).click();

View File

@ -31,7 +31,7 @@ test('[ORGANISATIONS]: create and delete organisation', async ({ page }) => {
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
await page.waitForURL(`/settings/organisations`); await page.waitForURL(`/settings/organisations`);
await expect(page.getByText('No results found')).toBeVisible(); await expectTextToBeVisible(page, 'No results found');
await page.getByRole('button', { name: 'Create organisation' }).click(); await page.getByRole('button', { name: 'Create organisation' }).click();
await page.getByLabel('Organisation Name*').fill('test'); await page.getByLabel('Organisation Name*').fill('test');

View File

@ -1,8 +1,11 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@prisma/client'; import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@prisma/client';
import { seedBlankDocument } from '@documenso/prisma/seed/documents'; import {
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents'; seedBlankDocument,
seedDocuments,
seedTeamDocuments,
} from '@documenso/prisma/seed/documents';
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams'; import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedUser } from '@documenso/prisma/seed/users'; import { seedUser } from '@documenso/prisma/seed/users';
@ -314,9 +317,9 @@ test('[TEAMS]: delete pending team document', async ({ page }) => {
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
}).toPass(); }).toPass();
await page.getByRole('menuitem', { name: 'Delete' }).click(); 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(); await page.getByRole('button', { name: 'Delete' }).click({ force: true });
await checkDocumentTabCount(page, 'Pending', 1); await checkDocumentTabCount(page, 'Pending', 1);
@ -359,9 +362,9 @@ test('[TEAMS]: delete completed team document', async ({ page }) => {
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
}).toPass(); }).toPass();
await page.getByRole('menuitem', { name: 'Delete' }).click(); 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(); await page.getByRole('button', { name: 'Delete' }).click({ force: true });
await checkDocumentTabCount(page, 'Completed', 0); await checkDocumentTabCount(page, 'Completed', 0);

View File

@ -80,18 +80,27 @@ test('[TEAMS]: check signature modes can be disabled', async ({ page }) => {
await page.getByRole('button', { name: 'Update' }).first().click(); await page.getByRole('button', { name: 'Update' }).first().click();
// Wait for the update to complete
const toast = page.locator('li[role="status"][data-state="open"]').first();
await expect(toast).toBeVisible();
await expect(toast.getByText('Document preferences updated', { exact: true })).toBeVisible();
const document = await seedTeamDocumentWithMeta(team); const document = await seedTeamDocumentWithMeta(team);
// Go to document and check that the signatured tabs are correct. // Go to document and check that the signature tabs are correct.
await page.goto(`/sign/${document.recipients[0].token}`); await page.goto(`/sign/${document.recipients[0].token}`);
await page.getByTestId('signature-pad-dialog-button').click(); await page.getByTestId('signature-pad-dialog-button').click();
// Wait for signature dialog to fully load
await page.waitForSelector('[role="dialog"]');
// Check the tab values // Check the tab values
for (const tab of allTabs) { for (const tab of allTabs) {
if (tabs.includes(tab)) { if (tabs.includes(tab)) {
await expect(page.getByRole('tab', { name: tab })).toBeVisible(); await expect(page.getByRole('tab', { name: tab })).toBeVisible();
} else { } else {
await expect(page.getByRole('tab', { name: tab })).not.toBeVisible(); // await expect(page.getByRole('tab', { name: tab })).not.toBeVisible();
await expect(page.getByRole('tab', { name: tab })).toHaveCount(0);
} }
} }
} }

View File

@ -297,10 +297,22 @@ test('[TEMPLATE]: should create a document from a template with custom document'
}, },
}); });
const expectedDocumentDataType =
process.env.NEXT_PUBLIC_UPLOAD_TRANSPORT === 's3'
? DocumentDataType.S3_PATH
: DocumentDataType.BYTES_64;
expect(document.title).toEqual('TEMPLATE_WITH_CUSTOM_DOC'); expect(document.title).toEqual('TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(DocumentDataType.BYTES_64); expect(document.documentData.type).toEqual(expectedDocumentDataType);
if (expectedDocumentDataType === DocumentDataType.BYTES_64) {
expect(document.documentData.data).toEqual(pdfContent); expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent); expect(document.documentData.initialData).toEqual(pdfContent);
} else {
// For S3, we expect the data/initialData to be the S3 path (non-empty string)
expect(document.documentData.data).toBeTruthy();
expect(document.documentData.initialData).toBeTruthy();
}
}); });
/** /**
@ -378,11 +390,23 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
}, },
}); });
const expectedDocumentDataType =
process.env.NEXT_PUBLIC_UPLOAD_TRANSPORT === 's3'
? DocumentDataType.S3_PATH
: DocumentDataType.BYTES_64;
expect(document.teamId).toEqual(team.id); expect(document.teamId).toEqual(team.id);
expect(document.title).toEqual('TEAM_TEMPLATE_WITH_CUSTOM_DOC'); expect(document.title).toEqual('TEAM_TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(DocumentDataType.BYTES_64); expect(document.documentData.type).toEqual(expectedDocumentDataType);
if (expectedDocumentDataType === DocumentDataType.BYTES_64) {
expect(document.documentData.data).toEqual(pdfContent); expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent); expect(document.documentData.initialData).toEqual(pdfContent);
} else {
// For S3, we expect the data/initialData to be the S3 path (non-empty string)
expect(document.documentData.data).toBeTruthy();
expect(document.documentData.initialData).toBeTruthy();
}
}); });
/** /**

View File

@ -178,4 +178,7 @@ test('[DIRECT_TEMPLATES]: use direct template link with 1 recipient', async ({ p
await page.getByRole('button', { name: 'Sign' }).click(); await page.getByRole('button', { name: 'Sign' }).click();
await page.waitForURL(/\/sign/); await page.waitForURL(/\/sign/);
await expect(page.getByRole('heading', { name: 'Document Signed' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Document Signed' })).toBeVisible();
// Add a longer waiting period to ensure document status is updated
await page.waitForTimeout(3000);
}); });

View File

@ -27,6 +27,9 @@ test('[USER] can sign up with email and password', async ({ page }: { page: Page
await page.waitForURL('/unverified-account'); await page.waitForURL('/unverified-account');
// Wait to ensure token is created in the database
await page.waitForTimeout(2000);
const { token } = await extractUserVerificationToken(email); const { token } = await extractUserVerificationToken(email);
const team = await prisma.team.findFirstOrThrow({ const team = await prisma.team.findFirstOrThrow({

View File

@ -17,9 +17,14 @@ test('[USER] can reset password via forgot password', async ({ page }: { page: P
await page.goto('http://localhost:3000/signin'); await page.goto('http://localhost:3000/signin');
await page.getByRole('link', { name: 'Forgot your password?' }).click(); await page.getByRole('link', { name: 'Forgot your password?' }).click();
await page.getByRole('textbox', { name: 'Email' }).click();
await page.getByRole('textbox', { name: 'Email' }).fill(user.email); await page.getByRole('textbox', { name: 'Email' }).fill(user.email);
await expect(page.getByRole('button', { name: 'Reset Password' })).toBeEnabled();
await page.getByRole('button', { name: 'Reset Password' }).click(); await page.getByRole('button', { name: 'Reset Password' }).click();
await expect(page.locator('body')).toContainText('Reset email sent');
await expect(page.locator('body')).toContainText('Reset email sent', { timeout: 10000 });
const foundToken = await prisma.passwordResetToken.findFirstOrThrow({ const foundToken = await prisma.passwordResetToken.findFirstOrThrow({
where: { where: {
@ -33,16 +38,26 @@ test('[USER] can reset password via forgot password', async ({ page }: { page: P
await page.goto(`http://localhost:3000/reset-password/${foundToken.token}`); await page.goto(`http://localhost:3000/reset-password/${foundToken.token}`);
// Assert that password cannot be same as old password. // Assert that password cannot be same as old password.
await page.getByRole('textbox', { name: 'Password', exact: true }).fill(oldPassword); await page.getByLabel('Password', { exact: true }).fill(oldPassword);
await page.getByRole('textbox', { name: 'Repeat Password' }).fill(oldPassword); await page.getByLabel('Repeat Password').fill(oldPassword);
// Ensure both fields are filled before clicking
await expect(page.getByLabel('Password', { exact: true })).toHaveValue(oldPassword);
await expect(page.getByLabel('Repeat Password')).toHaveValue(oldPassword);
await page.getByRole('button', { name: 'Reset Password' }).click(); await page.getByRole('button', { name: 'Reset Password' }).click();
await expect(page.locator('body')).toContainText( await expect(page.locator('body')).toContainText(
'Your new password cannot be the same as your old password.', 'Your new password cannot be the same as your old password.',
); );
// Assert password reset. // Assert password reset.
await page.getByRole('textbox', { name: 'Password', exact: true }).fill(newPassword); await page.getByLabel('Password', { exact: true }).fill(newPassword);
await page.getByRole('textbox', { name: 'Repeat Password' }).fill(newPassword); await page.getByLabel('Repeat Password').fill(newPassword);
// Ensure both fields are filled before clicking
await expect(page.getByLabel('Password', { exact: true })).toHaveValue(newPassword);
await expect(page.getByLabel('Repeat Password')).toHaveValue(newPassword);
await page.getByRole('button', { name: 'Reset Password' }).click(); await page.getByRole('button', { name: 'Reset Password' }).click();
await expect(page.locator('body')).toContainText('Your password has been updated successfully.'); await expect(page.locator('body')).toContainText('Your password has been updated successfully.');
@ -73,9 +88,9 @@ test('[USER] can reset password via user settings', async ({ page }: { page: Pag
redirectPath: '/settings/security', redirectPath: '/settings/security',
}); });
await page.getByRole('textbox', { name: 'Current password' }).fill(oldPassword); await page.getByLabel('Current password').fill(oldPassword);
await page.getByRole('textbox', { name: 'New password' }).fill(newPassword); await page.getByLabel('New password').fill(newPassword);
await page.getByRole('textbox', { name: 'Repeat password' }).fill(newPassword); await page.getByLabel('Repeat password').fill(newPassword);
await page.getByRole('button', { name: 'Update password' }).click(); await page.getByRole('button', { name: 'Update password' }).click();
await expect(page.locator('body')).toContainText('Password updated'); await expect(page.locator('body')).toContainText('Password updated');

View File

@ -24,19 +24,23 @@ export default defineConfig({
/* Retry on CI only */ /* Retry on CI only */
retries: process.env.CI ? 4 : 1, retries: process.env.CI ? 4 : 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html', reporter: [['html'], ['list']],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: { use: {
/* Base URL to use in actions like `await page.goto('/')`. */ /* Base URL to use in actions like `await page.goto('/')`. */
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-first-retry', trace: 'on',
video: 'retain-on-failure', video: 'retain-on-failure',
/* Add explicit timeouts for actions */
actionTimeout: 15_000,
navigationTimeout: 30_000,
}, },
timeout: 30_000, timeout: 60_000,
/* Configure projects for major browsers */ /* Configure projects for major browsers */
projects: [ projects: [