Files
documenso/packages/app-tests/e2e/templates-flow/template-autosave-fields-step.spec.ts
David Nguyen 7f09ba72f4 feat: add envelopes (#2025)
This PR is handles the changes required to support envelopes. The new
envelope editor/signing page will be hidden during release.

The core changes here is to migrate the documents and templates model to
a centralized envelopes model.

Even though Documents and Templates are removed, from the user
perspective they will still exist as we remap envelopes to documents and
templates.
2025-10-14 21:56:36 +11:00

319 lines
9.3 KiB
TypeScript

import type { Page } from '@playwright/test';
import { expect, test } from '@playwright/test';
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication';
const setupTemplateAndNavigateToFieldsStep = async (page: Page) => {
const { user, team } = await seedUser();
const template = await seedBlankTemplate(user, team.id);
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Email').fill('recipient1@documenso.com');
await page.getByPlaceholder('Name').fill('Recipient 1');
await page.getByRole('button', { name: 'Add Placeholder Recipient' }).click();
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
await page.getByRole('button', { name: 'Continue' }).click();
return { user, team, template };
};
const triggerAutosave = async (page: Page) => {
await page.locator('body').click({ position: { x: 0, y: 0 } });
await page.locator('#document-flow-form-container').blur();
await page.waitForTimeout(5000);
};
test.describe('AutoSave Fields Step', () => {
test('should autosave the fields without advanced settings', async ({ page }) => {
const { user, template, team } = await setupTemplateAndNavigateToFieldsStep(page);
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 100,
},
});
await page.getByRole('button', { name: 'Text' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 200,
},
});
await page.getByTestId('field-advanced-settings-footer').waitFor({ state: 'visible' });
await page
.getByTestId('field-advanced-settings-footer')
.getByRole('button', { name: 'Cancel' })
.click();
await triggerAutosave(page);
await page.getByRole('combobox').first().click();
await page.getByRole('option', { name: 'Recipient 2 (recipient2@documenso.com)' }).click();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 500,
},
});
await triggerAutosave(page);
await expect(async () => {
const retrievedFields = await getTemplateById({
id: {
type: 'envelopeId',
id: template.id,
},
userId: user.id,
teamId: team.id,
});
const fields = retrievedFields.fields;
expect(fields.length).toBe(3);
expect(fields[0].type).toBe('SIGNATURE');
expect(fields[1].type).toBe('TEXT');
expect(fields[2].type).toBe('SIGNATURE');
}).toPass();
});
test('should autosave the field deletion', async ({ page }) => {
const { user, template, team } = await setupTemplateAndNavigateToFieldsStep(page);
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 100,
},
});
await page.getByRole('button', { name: 'Text' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 200,
},
});
await page.getByTestId('field-advanced-settings-footer').waitFor({ state: 'visible' });
await page
.getByTestId('field-advanced-settings-footer')
.getByRole('button', { name: 'Cancel' })
.click();
await triggerAutosave(page);
await page.getByRole('combobox').first().click();
await page.getByRole('option', { name: 'Recipient 2 (recipient2@documenso.com)' }).click();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 500,
},
});
await triggerAutosave(page);
await page.getByRole('combobox').first().click();
await page.getByRole('option', { name: 'Recipient 1 (recipient1@documenso.com)' }).click();
await page.getByText('Text').nth(1).click();
await page.getByRole('button', { name: 'Remove' }).click();
await triggerAutosave(page);
await expect(async () => {
const retrievedFields = await getTemplateById({
id: {
type: 'envelopeId',
id: template.id,
},
userId: user.id,
teamId: team.id,
});
const fields = retrievedFields.fields;
expect(fields.length).toBe(2);
expect(fields[0].type).toBe('SIGNATURE');
expect(fields[1].type).toBe('SIGNATURE');
}).toPass();
});
test('should autosave the field duplication', async ({ page }) => {
const { user, template, team } = await setupTemplateAndNavigateToFieldsStep(page);
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 100,
},
});
await page.getByRole('button', { name: 'Text' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 200,
},
});
await page.getByTestId('field-advanced-settings-footer').waitFor({ state: 'visible' });
await page
.getByTestId('field-advanced-settings-footer')
.getByRole('button', { name: 'Cancel' })
.click();
await triggerAutosave(page);
await page.getByRole('combobox').first().click();
await page.getByRole('option', { name: 'Recipient 2 (recipient2@documenso.com)' }).click();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 500,
},
});
await triggerAutosave(page);
await page.getByRole('combobox').first().click();
await page.getByRole('option', { name: 'Recipient 1 (recipient1@documenso.com)' }).click();
await page.getByText('Signature').nth(1).click();
await page.getByRole('button', { name: 'Duplicate', exact: true }).click();
await triggerAutosave(page);
await expect(async () => {
const retrievedFields = await getTemplateById({
id: {
type: 'envelopeId',
id: template.id,
},
userId: user.id,
teamId: team.id,
});
const fields = retrievedFields.fields;
expect(fields.length).toBe(4);
expect(fields[0].type).toBe('SIGNATURE');
expect(fields[1].type).toBe('TEXT');
expect(fields[2].type).toBe('SIGNATURE');
expect(fields[3].type).toBe('SIGNATURE');
}).toPass();
});
test('should autosave the fields with advanced settings', async ({ page }) => {
const { user, template, team } = await setupTemplateAndNavigateToFieldsStep(page);
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
await page.getByRole('button', { name: 'Signature' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 100,
},
});
await page.getByRole('button', { name: 'Text' }).click();
await page.locator('canvas').click({
position: {
x: 100,
y: 200,
},
});
await page.getByRole('textbox', { name: 'Field label' }).fill('Test Field');
await page.getByRole('textbox', { name: 'Field placeholder' }).fill('Test Placeholder');
await page.getByRole('textbox', { name: 'Add text to the field' }).fill('Test Text');
await page.getByTestId('field-advanced-settings-footer').waitFor({ state: 'visible' });
await page
.getByTestId('field-advanced-settings-footer')
.getByRole('button', { name: 'Save' })
.click();
await page.waitForTimeout(2500);
await triggerAutosave(page);
await expect(async () => {
const retrievedTemplate = await getTemplateById({
id: {
type: 'envelopeId',
id: template.id,
},
userId: user.id,
teamId: team.id,
});
const fields = retrievedTemplate.fields;
expect(fields.length).toBe(2);
expect(fields[0].type).toBe('SIGNATURE');
expect(fields[1].type).toBe('TEXT');
const textField = fields[1];
expect(textField.fieldMeta).toBeDefined();
if (
textField.fieldMeta &&
typeof textField.fieldMeta === 'object' &&
'type' in textField.fieldMeta
) {
expect(textField.fieldMeta.type).toBe('text');
expect(textField.fieldMeta.label).toBe('Test Field');
expect(textField.fieldMeta.placeholder).toBe('Test Placeholder');
if (textField.fieldMeta.type === 'text') {
expect(textField.fieldMeta.text).toBe('Test Text');
}
} else {
throw new Error('fieldMeta should be defined and contain advanced settings');
}
}).toPass();
});
});