Files
documenso/packages/app-tests/e2e/signing-branding.spec.ts
T
2026-06-09 15:51:25 +10:00

145 lines
4.8 KiB
TypeScript

import fs from 'node:fs/promises';
import path from 'node:path';
import { formatDirectTemplatePath } from '@documenso/lib/utils/templates';
import { prisma } from '@documenso/prisma';
import { seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
import { seedDirectTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users';
import { expect, type Page, test } from '@playwright/test';
import { DocumentDataType, FieldType } from '@prisma/client';
const BRANDING_URL = 'https://brand.example/signing?source=documenso';
const PDF_PAGE_SELECTOR = 'img[data-page-number]';
const readBrandingLogo = async () => {
const logo = await fs.readFile(path.join(__dirname, '../../assets/logo.png'));
return JSON.stringify({
type: DocumentDataType.BYTES_64,
data: logo.toString('base64'),
});
};
const enableOrganisationBranding = async ({
organisationGlobalSettingsId,
brandingUrl = BRANDING_URL,
}: {
organisationGlobalSettingsId: string;
brandingUrl?: string;
}) => {
await prisma.organisationGlobalSettings.update({
where: { id: organisationGlobalSettingsId },
data: {
brandingEnabled: true,
brandingLogo: await readBrandingLogo(),
brandingUrl,
},
});
};
/**
* On signing surfaces the custom branding logo must render as a plain image.
* It must not be wrapped in any link, and the Brand Website must never appear
* as a link on these pages.
*/
const expectPlainBrandingLogo = async (page: Page, logoName: string) => {
const logo = page.getByRole('img', { name: logoName });
await expect(logo).toBeVisible();
// The custom logo must not be wrapped in a link.
await expect(page.getByRole('link', { name: logoName })).toHaveCount(0);
// The Brand Website must never be rendered as a link on signing pages.
await expect(page.locator(`a[href="${BRANDING_URL}"]`)).toHaveCount(0);
};
test('[SIGNING_BRANDING]: V1 normal signing renders custom logo as a plain image', async ({ page }) => {
const { user, team, organisation } = await seedUser();
await enableOrganisationBranding({
organisationGlobalSettingsId: organisation.organisationGlobalSettingsId,
});
const { recipients } = await seedPendingDocumentWithFullFields({
owner: user,
teamId: team.id,
recipients: ['v1-branding-signer@test.documenso.com'],
fields: [FieldType.SIGNATURE],
});
await page.goto(`/sign/${recipients[0].token}`);
await expectPlainBrandingLogo(page, `${team.name}'s Logo`);
});
test('[SIGNING_BRANDING]: V2 signing renders custom logo as a plain image', async ({ page }) => {
const { user, team, organisation } = await seedUser();
await enableOrganisationBranding({
organisationGlobalSettingsId: organisation.organisationGlobalSettingsId,
});
const { recipients } = await seedPendingDocumentWithFullFields({
owner: user,
teamId: team.id,
recipients: ['v2-branding-signer@test.documenso.com'],
fields: [FieldType.SIGNATURE],
updateDocumentOptions: { internalVersion: 2 },
});
const directTemplate = await seedDirectTemplate({
title: 'V2 Branding Direct Template',
userId: user.id,
teamId: team.id,
internalVersion: 2,
});
await page.goto(`/sign/${recipients[0].token}`);
await expectPlainBrandingLogo(page, `${team.name}'s Logo`);
await page.goto(formatDirectTemplatePath(directTemplate.directLink?.token || ''));
await expectPlainBrandingLogo(page, `${team.name}'s Logo`);
});
test('[SIGNING_BRANDING]: V2 signing keeps internal link for the Documenso fallback logo', async ({ page }) => {
const { user, team } = await seedUser();
const { recipients } = await seedPendingDocumentWithFullFields({
owner: user,
teamId: team.id,
recipients: ['v2-fallback-signer@test.documenso.com'],
fields: [FieldType.SIGNATURE],
updateDocumentOptions: { internalVersion: 2 },
});
await page.goto(`/sign/${recipients[0].token}`);
const fallbackLogoLink = page.locator('a[href="/"]').first();
await expect(fallbackLogoLink).toBeVisible();
});
test('[SIGNING_BRANDING]: embedded signing does not render custom logo Brand Website links', async ({ page }) => {
const { user, team, organisation } = await seedUser();
await enableOrganisationBranding({
organisationGlobalSettingsId: organisation.organisationGlobalSettingsId,
});
const { recipients } = await seedPendingDocumentWithFullFields({
owner: user,
teamId: team.id,
recipients: ['embed-branding-signer@test.documenso.com'],
fields: [FieldType.SIGNATURE],
updateDocumentOptions: { internalVersion: 2 },
});
await page.goto(`/embed/sign/${recipients[0].token}`);
await expect(page.locator(PDF_PAGE_SELECTOR).first()).toBeVisible({ timeout: 30_000 });
await expect(page.locator(`a[href="${BRANDING_URL}"]`)).toHaveCount(0);
await expect(page.getByRole('link', { name: `${team.name}'s Logo` })).toHaveCount(0);
});