import { test, expect } from '@playwright/test'; import { login, BASE_URL } from '../../helpers/auth'; import { markManual, markPartial } from '../../helpers/manual'; test.describe('core-installation', () => { test('core-installation-check-fresh_installation', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'manual' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markManual('Requires provisioning a clean VM/bare-metal host, mounting the installation ISO/OVA, and completing the setup wizard; this cannot be driven by Playwright alone'); testInfo.annotations.push({ type: 'description', description: 'Verify a complete fresh installation from scratch succeeds on each supported hypervisor' }); // Manual steps: // 1. Provision a clean VM with the minimum required specs (vCPU, RAM, Disk). // 2. Mount the installation ISO or import the OVA template. // 3. Power on and follow the installation wizard / first-boot script. // 4. Verify installation completes without errors (exit code 0 / no red messages). // 5. Verify the admin portal is accessible at the configured IP:port. // 6. Record: installation time, any warnings, hypervisor used. }); test('core-installation-check-post_install_service_status_and_port_verification', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'partial' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markPartial('Service status dashboard in admin portal can be verified by Playwright; TCP port verification requires nmap or netstat from outside/inside the host — run that step as a separate CLI check in CI'); testInfo.annotations.push({ type: 'description', description: 'Verify all required services are running and expected ports are open after a fresh installation' }); await test.step('Navigate to System → Service Status', async () => { await login(page); await page.goto(`${BASE_URL}/admin/system/status`); }); await test.step('Verify core services are shown as running', async () => { const pageText = await page.locator('body').textContent() ?? ''; expect(pageText).toMatch(/running|active|online/i); }); await test.step('Verify no service is shown as failed or stopped', async () => { const failedEl = page.locator('.status-failed, .status-stopped, [data-status="failed"]'); await expect(failedEl).toHaveCount(0); }); // TODO_MANUAL: From a network-adjacent host run: // nmap -p 443,80,5060,5061,8443 // and verify all expected ports are OPEN. }); test('core-installation-check-initial_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 the initial configuration wizard completes successfully and all mandatory settings are applied' }); await test.step('Navigate to admin portal — expect initial wizard on first run', async () => { await page.goto(BASE_URL); }); await test.step('Fill in System Name', async () => { const sysNameInput = page.locator('[name="system_name"],[name="pbxname"],[id="system-name"]').first(); if (await sysNameInput.count() > 0) { await sysNameInput.fill('PBX-Test-Instance'); } }); await test.step('Fill in Administrator email', async () => { const emailInput = page.locator('[name="admin_email"],[type="email"]').first(); if (await emailInput.count() > 0) { await emailInput.fill('admin@test.local'); } }); await test.step('Complete wizard and verify success message', async () => { const nextBtn = page.locator('button:has-text("Next"),button:has-text("Finish"),button:has-text("Save")').first(); if (await nextBtn.count() > 0) { await nextBtn.click(); await expect(page.locator('body')).not.toContainText(/error|failed/i); } }); await test.step('Verify admin portal dashboard is accessible after initial config', async () => { await login(page); await expect(page.locator('body')).not.toContainText(/wizard|setup required/i); }); }); test('core-installation-check-license_activation', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'automated' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); testInfo.annotations.push({ type: 'description', description: 'Verify license activation completes successfully and licensed features are unlocked' }); await test.step('Login to admin portal', async () => { await login(page); }); await test.step('Navigate to System → License', async () => { await page.goto(`${BASE_URL}/admin/system/license`); }); await test.step('Verify license page loads', async () => { await expect(page.locator('body')).not.toContainText(/500|not found/i); }); await test.step('Verify license status is shown', async () => { const licenseInfo = page.locator('.license-status, .license-info, [data-field="license"]').first(); await expect(licenseInfo).toBeVisible(); }); await test.step('Verify license is active (not expired or invalid)', async () => { const pageText = await page.locator('body').textContent() ?? ''; expect(pageText).not.toMatch(/expired|invalid license|not activated/i); }); }); });