Files
cloudflare_temp_email/e2e/tests/browser/webhook-presets.spec.ts

111 lines
4.0 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { FRONTEND_URL, createTestAddress, deleteAddress } from '../../fixtures/test-helpers';
import { request as apiRequest } from '@playwright/test';
test.describe('Webhook Presets', () => {
test('selecting each preset fills valid settings', async ({ page, context }) => {
test.setTimeout(60_000);
const api = await apiRequest.newContext();
let jwt: string | undefined;
// Block popups (presets open doc URLs in new tabs)
context.on('page', (p) => p.close());
try {
const created = await createTestAddress(api, 'webhook-preset');
jwt = created.jwt;
// Login via JWT
await page.goto(`${FRONTEND_URL}/en/?jwt=${jwt}`);
// Click "Webhook Settings" in the sidebar menu
const webhookMenu = page.getByText('Webhook Settings');
await expect(webhookMenu).toBeVisible({ timeout: 10_000 });
await webhookMenu.click();
// Verify presets button is visible
const presetsBtn = page.getByRole('button', { name: 'Presets' });
await expect(presetsBtn).toBeVisible({ timeout: 5000 });
// Helper to get form field value by label text
const getFieldValue = async (label: string): Promise<string> => {
// Find the label, then get the sibling textbox in the same form row
const row = page.locator('div', { hasText: new RegExp(`^${label}$`) }).locator('..');
const textbox = row.getByRole('textbox');
return textbox.inputValue();
};
// Define expected presets and their key fields
const expectedPresets = [
{
name: 'Message Pusher',
urlPattern: 'msgpusher.com',
bodyKeys: ['token', 'title', 'description', 'content'],
},
{
name: 'Bark',
urlPattern: 'api.day.app',
bodyKeys: ['title', 'body', 'group'],
},
{
name: 'ntfy',
urlPattern: 'ntfy.sh',
bodyKeys: ['topic', 'title', 'message', 'tags'],
},
];
for (const preset of expectedPresets) {
// Open dropdown and select preset
await presetsBtn.click();
const option = page.locator('.n-dropdown-option', { hasText: preset.name });
await expect(option).toBeVisible({ timeout: 5_000 });
await option.click();
// Wait for dropdown to close, then for URL field to contain preset pattern
await expect(option).toBeHidden({ timeout: 5_000 });
await page.waitForTimeout(500);
const allTextboxes = page.getByRole('textbox');
const count = await allTextboxes.count();
// Find URL, HEADERS, BODY values by reading all textboxes
let urlValue = '';
let headersValue = '';
let bodyValue = '';
for (let i = 0; i < count; i++) {
const val = await allTextboxes.nth(i).inputValue();
if (val.includes(preset.urlPattern)) {
urlValue = val;
} else if (val.includes('Content-Type')) {
headersValue = val;
} else if (val.includes('${subject}')) {
bodyValue = val;
}
}
// Verify URL
expect(urlValue, `${preset.name}: URL should contain ${preset.urlPattern}`).toContain(preset.urlPattern);
// Verify HEADERS is valid JSON with Content-Type
expect(headersValue, `${preset.name}: HEADERS should not be empty`).toBeTruthy();
const headers = JSON.parse(headersValue);
expect(headers, `${preset.name}: headers should have Content-Type`).toHaveProperty('Content-Type', 'application/json');
// Verify BODY is valid JSON with expected keys
expect(bodyValue, `${preset.name}: BODY should not be empty`).toBeTruthy();
const body = JSON.parse(bodyValue);
for (const key of preset.bodyKeys) {
expect(body, `${preset.name}: body should have key "${key}"`).toHaveProperty(key);
}
}
} finally {
try {
if (jwt) await deleteAddress(api, jwt);
} finally {
await api.dispose();
}
}
});
});