feca-mailshots-plugin/tests/e2e/specs/download-pdf-renewal.spec.mjs

144 lines
5.6 KiB
JavaScript

import { test, expect } from '@playwright/test';
import fs from 'node:fs';
import { adminPath, apiList, ensureDataSource, ensureMailshot, cleanupByNames } from './helpers.mjs';
const mailshotPurpose = process.env.E2E_RENEWAL_MAILSHOT_PURPOSE || 'Renewals (pending accounts and contacts)';
const allowCreate = process.env.E2E_RENEWAL_ALLOW_CREATE !== '0';
const runEnabled = process.env.E2E_RENEWAL_ENABLE === '1';
const fallbackPdfTemplate = '<div>Download PDF test</div>';
test.describe('renewal dataset: download pdf e2e', () => {
test.skip(!runEnabled, 'Enable with E2E_RENEWAL_ENABLE=1');
const safeDownloadBaseName = (name) => String(name || '')
.trim()
.replace(/[^A-Za-z0-9._-]+/g, '_')
.replace(/_+/g, '_')
.replace(/^[._-]+|[._-]+$/g, '') || 'mailshot';
const clickAndExpectDownload = async (page, buttonName, expectedFilename) => {
page.once('dialog', async (dialog) => {
await dialog.accept();
});
let downloaded;
try {
const out = await Promise.all([
page.waitForEvent('download', { timeout: 90000 }),
page.getByRole('button', { name: buttonName }).click()
]);
downloaded = out[0] || null;
} catch {
const critical = page.getByText('There has been a critical error on this website.');
if (await critical.count()) {
throw new Error(`Download action "${buttonName}" reached a WordPress critical error page.`);
}
const failBanner = page.locator('strong', { hasText: 'PDF generation failed.' });
if (await failBanner.count()) {
const msg = (await page.locator('.wrap').innerText()).replace(/\s+/g, ' ').trim();
throw new Error(`Download action "${buttonName}" failed in UI: ${msg}`);
}
throw new Error(`Download action "${buttonName}" timed out waiting for file download.`);
}
if (!downloaded) {
const critical = page.getByText('There has been a critical error on this website.');
if (await critical.count()) {
throw new Error(`Download action "${buttonName}" reached a WordPress critical error page.`);
}
const failBanner = page.locator('strong', { hasText: 'PDF generation failed.' });
if (await failBanner.count()) {
const msg = (await page.locator('.wrap').innerText()).replace(/\s+/g, ' ').trim();
throw new Error(`Download action "${buttonName}" failed in UI: ${msg}`);
}
throw new Error(`Download action "${buttonName}" timed out waiting for file download.`);
}
expect(downloaded.suggestedFilename()).toBe(expectedFilename);
const outPath = await downloaded.path();
expect(outPath).toBeTruthy();
const outSize = fs.statSync(outPath).size;
expect(outSize).toBeGreaterThan(1000);
};
const resolveMailshot = async (request) => {
const uniq = `${Date.now()}_${Math.floor(Math.random() * 100000)}`;
const purpose = `e2e_renewal_download_${uniq}`;
const dsCreatedName = `e2e_renewal_ds_${uniq}`;
if (!allowCreate) {
const mailshotList = await apiList(request, 'feca_mailshots_mailshots_api');
expect(mailshotList.ok).toBeTruthy();
const existing = (mailshotList.items || []).find(
(row) => String(row.Purpose || '') === mailshotPurpose
);
if (!existing) {
throw new Error(`Required mailshot not found: ${mailshotPurpose}`);
}
const existingId = String(existing.id || '');
expect(existingId).not.toBe('');
return { mailshotId: existingId, purpose: String(existing.Purpose || ''), cleanup: async () => {} };
}
await ensureDataSource(request, dsCreatedName, 'contacts');
const saved = await ensureMailshot(request, {
Purpose: purpose,
DataSource: dsCreatedName,
CC: '',
BCC: '',
Subject: 'Renewal PDF e2e',
Message: '',
PDFAttachment: fallbackPdfTemplate,
AttachmentNames: '[]',
PDFFilenameDerivedFrom: '',
RecipientEmailField: '',
ReplyTo: ''
});
let mailshotId = String(saved.id || '');
expect(mailshotId).not.toBe('');
return {
mailshotId,
purpose,
cleanup: async () => {
await cleanupByNames(request, {
dataSourceNames: [dsCreatedName],
mailshotPurposes: [purpose]
});
}
};
};
test('downloads merged PDF for renewal_accounts_with_contacts', async ({ page, request }) => {
const resolved = await resolveMailshot(request);
try {
await page.goto(`${adminPath('feca-mailshots-download-pdf')}&mailshot_id=${encodeURIComponent(resolved.mailshotId)}`);
await expect(page.getByRole('heading', { name: 'Download PDF' })).toBeVisible();
await page.locator('#dp_mailshot_id').selectOption(resolved.mailshotId);
await clickAndExpectDownload(page, 'Download Merged PDF', `${safeDownloadBaseName(resolved.purpose)}_merged.pdf`);
} finally {
try {
await resolved.cleanup();
} catch {
// best effort cleanup
}
}
});
test('downloads ZIP of PDFs for renewal_accounts_with_contacts', async ({ page, request }) => {
const resolved = await resolveMailshot(request);
try {
await page.goto(`${adminPath('feca-mailshots-download-pdf')}&mailshot_id=${encodeURIComponent(resolved.mailshotId)}`);
await expect(page.getByRole('heading', { name: 'Download PDF' })).toBeVisible();
await page.locator('#dp_mailshot_id').selectOption(resolved.mailshotId);
await clickAndExpectDownload(page, 'Download ZIP of PDFs', `${safeDownloadBaseName(resolved.purpose)}_pdfs.zip`);
} finally {
try {
await resolved.cleanup();
} catch {
// best effort cleanup
}
}
});
});