Files
autotest/tests/pbx/configuration.spec.ts
T
2026-05-22 11:46:43 +02:00

144 lines
7.1 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { login, BASE_URL } from '../../helpers/auth';
import * as path from 'path';
import * as fs from 'fs';
test.describe('pbx-configuration', () => {
test.beforeEach(async ({ page }) => {
await login(page);
});
test('pbx-configuration-check-initial_system_setup_and_network_settings', async ({ page }, testInfo) => {
testInfo.annotations.push({ type: 'automationStatus', description: 'automated' });
testInfo.annotations.push({ type: 'testType', description: 'check' });
testInfo.annotations.push({ type: 'description', description: 'Verify initial PBX system setup and network settings are correctly configured' });
await test.step('Navigate to Settings → Network', async () => {
await page.goto(`${BASE_URL}/admin/settings/network`);
});
await test.step('Verify network settings page loads', async () => {
await expect(page.locator('body')).not.toContainText(/500|not found/i);
});
await test.step('Verify hostname/FQDN field is populated', async () => {
const fqdnInput = page.locator('[name*="hostname"],[name*="fqdn"],[id*="hostname"],[id*="fqdn"]').first();
if (await fqdnInput.count() > 0) {
const value = await fqdnInput.inputValue();
expect(value.trim()).not.toBe('');
}
});
await test.step('Verify IP address field is populated', async () => {
const ipInput = page.locator('[name*="ip_address"],[name*="local_ip"],[id*="ip-address"]').first();
if (await ipInput.count() > 0) {
const value = await ipInput.inputValue();
expect(value).toMatch(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/);
}
});
await test.step('Verify DNS server field is populated', async () => {
const dnsInput = page.locator('[name*="dns"],[id*="dns"]').first();
if (await dnsInput.count() > 0) {
const value = await dnsInput.inputValue();
expect(value.trim()).not.toBe('');
}
});
});
test('pbx-configuration-check-dialplan_route_and_outbound_rule_creation', async ({ page }, testInfo) => {
testInfo.annotations.push({ type: 'automationStatus', description: 'automated' });
testInfo.annotations.push({ type: 'testType', description: 'check' });
testInfo.annotations.push({ type: 'description', description: 'Verify creation and validation of dial plan rules and outbound routes' });
const testRuleName = `autotest-rule-${Date.now()}`;
await test.step('Navigate to Dial Plans / Outbound Routes', async () => {
await page.goto(`${BASE_URL}/admin/dialplans/outbound`);
});
await test.step('Create a new outbound rule', async () => {
await page.locator('button:has-text("Add"),button:has-text("New"),a:has-text("Add Rule")').first().click();
await page.locator('[name*="name"],[id*="rule-name"]').first().fill(testRuleName);
await page.locator('[name*="prefix"],[name*="pattern"],[id*="pattern"]').first().fill('9.');
await page.locator('button:has-text("Save"),button[type="submit"]').first().click();
});
await test.step('Verify new rule appears in the list', async () => {
await page.goto(`${BASE_URL}/admin/dialplans/outbound`);
await expect(page.locator('table, .rule-list').filter({ hasText: testRuleName })).toBeVisible();
});
await test.step('Edit the rule and verify save succeeds', async () => {
await page.locator('tr, .rule-item').filter({ hasText: testRuleName }).locator('a:has-text("Edit"),button:has-text("Edit")').first().click();
await page.locator('button:has-text("Save"),button[type="submit"]').first().click();
await expect(page.locator('.alert-success, .success-banner, [class*="success"]').first()).toBeVisible();
});
await test.step('Delete the test rule', async () => {
await page.goto(`${BASE_URL}/admin/dialplans/outbound`);
await page.locator('tr, .rule-item').filter({ hasText: testRuleName }).locator('button:has-text("Delete"),a:has-text("Delete")').first().click();
await page.locator('button:has-text("Confirm"),button:has-text("Yes")').first().click();
await expect(page.locator('body')).not.toContainText(testRuleName);
});
});
test('pbx-configuration-check-backup_restore_full_system_configuration', async ({ page }, testInfo) => {
testInfo.annotations.push({ type: 'automationStatus', description: 'automated' });
testInfo.annotations.push({ type: 'testType', description: 'check' });
testInfo.annotations.push({ type: 'description', description: 'Verify full system configuration backup and restore operations work correctly' });
await test.step('Navigate to Backup & Restore', async () => {
await page.goto(`${BASE_URL}/admin/backup`);
});
await test.step('Trigger a backup and wait for completion', async () => {
await page.locator('button:has-text("Create Backup"),button:has-text("Backup Now")').first().click();
await expect(page.locator('.backup-status, .progress, [data-status="complete"]').first()).toBeVisible({ timeout: 60_000 });
});
await test.step('Verify backup file appears in the backup list', async () => {
const backupList = page.locator('table, .backup-list');
await expect(backupList.first()).toBeVisible();
const rows = await backupList.locator('tr, .backup-item').count();
expect(rows).toBeGreaterThan(0);
});
await test.step('Verify restore button is available for the latest backup', async () => {
const restoreBtn = page.locator('button:has-text("Restore"),a:has-text("Restore")').first();
await expect(restoreBtn).toBeVisible();
});
});
test('pbx-configuration-check-bulk_csv_import_export_of_settings', async ({ page }, testInfo) => {
testInfo.annotations.push({ type: 'automationStatus', description: 'automated' });
testInfo.annotations.push({ type: 'testType', description: 'check' });
testInfo.annotations.push({ type: 'description', description: 'Verify bulk CSV import and export of settings (extensions, contacts, etc.)' });
const csvContent = 'extension,name,email\n5001,Test User One,test1@test.local\n5002,Test User Two,test2@test.local';
const tmpCsvPath = path.join(process.cwd(), 'test-results', 'bulk-import-test.csv');
await test.step('Navigate to Bulk Import / Export section', async () => {
fs.mkdirSync(path.dirname(tmpCsvPath), { recursive: true });
fs.writeFileSync(tmpCsvPath, csvContent, 'utf-8');
await page.goto(`${BASE_URL}/admin/extensions/import`);
});
await test.step('Verify import page loads', async () => {
await expect(page.locator('input[type="file"], .dropzone, .upload-area').first()).toBeVisible();
});
await test.step('Navigate to export section', async () => {
await page.goto(`${BASE_URL}/admin/extensions/export`);
});
await test.step('Trigger CSV export and verify download is initiated', async () => {
const [download] = await Promise.all([
page.waitForEvent('download', { timeout: 20_000 }),
page.locator('button:has-text("Export"),a:has-text("Export CSV"),a:has-text("Download")').first().click(),
]);
expect(download.suggestedFilename()).toMatch(/\.csv$/i);
});
});
});