124 lines
4.1 KiB
TypeScript
124 lines
4.1 KiB
TypeScript
/**
|
|
* Configuration module tests for cPad.
|
|
*
|
|
* Routes:
|
|
* /cp/configuration — main configuration overview (alias)
|
|
* /cp/config — canonical config route
|
|
*
|
|
* Coverage:
|
|
* • Both config URLs load without errors
|
|
* • No console/server errors
|
|
* • Configuration form is present and contains input elements
|
|
* • Smart form filler can fill the form without crashing
|
|
* • Tab-based navigation within config (if applicable) works
|
|
*
|
|
* Run:
|
|
* npx playwright test tests/cpad/modules/configuration.spec.ts --project=cpad
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
import { CP_PATH, attachErrorListeners } from '../../helpers/auth';
|
|
import { fillForm, hasForm } from '../../helpers/formFiller';
|
|
|
|
const CONFIG_URLS = [
|
|
`${CP_PATH}/configuration`,
|
|
`${CP_PATH}/config`,
|
|
] as const;
|
|
|
|
test.describe('cPad Configuration Module', () => {
|
|
for (const configUrl of CONFIG_URLS) {
|
|
test(`config page (${configUrl}) loads without errors`, async ({ page }) => {
|
|
const { consoleErrors, networkErrors } = attachErrorListeners(page);
|
|
|
|
await page.goto(configUrl);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
expect(page.url()).not.toContain('/login');
|
|
await expect(page.locator('body')).toBeVisible();
|
|
|
|
const bodyText = await page.locator('body').textContent() ?? '';
|
|
const hasError = /Whoops|Server Error|SQLSTATE|Call to undefined/.test(bodyText);
|
|
expect(hasError, `Server error at ${configUrl}`).toBe(false);
|
|
|
|
expect(consoleErrors.length, `Console errors: ${consoleErrors.join(' | ')}`).toBe(0);
|
|
expect(networkErrors.length, `HTTP 5xx: ${networkErrors.join(' | ')}`).toBe(0);
|
|
});
|
|
}
|
|
|
|
test('configuration page (/cp/config) contains a form or settings inputs', async ({ page }) => {
|
|
await page.goto(`${CP_PATH}/config`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
if (page.url().includes('/login')) {
|
|
test.skip(true, 'Not authenticated');
|
|
return;
|
|
}
|
|
|
|
const pageHasForm = await hasForm(page);
|
|
expect(pageHasForm, '/cp/config should contain a form or input fields').toBe(true);
|
|
});
|
|
|
|
test('smart form filler can fill configuration form without errors', async ({ page }) => {
|
|
const { networkErrors } = attachErrorListeners(page);
|
|
|
|
await page.goto(`${CP_PATH}/config`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
if (page.url().includes('/login')) {
|
|
test.skip(true, 'Not authenticated');
|
|
return;
|
|
}
|
|
|
|
// Fill the form — should not throw
|
|
await fillForm(page);
|
|
|
|
// No 5xx errors triggered by the fill operations
|
|
expect(networkErrors.length, `HTTP 5xx during form fill: ${networkErrors.join(' | ')}`).toBe(0);
|
|
});
|
|
|
|
test('configuration tab navigation works (if tabs present)', async ({ page }) => {
|
|
const { consoleErrors, networkErrors } = attachErrorListeners(page);
|
|
|
|
await page.goto(`${CP_PATH}/config`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
if (page.url().includes('/login')) {
|
|
test.skip(true, 'Not authenticated');
|
|
return;
|
|
}
|
|
|
|
// Look for tab buttons (Bootstrap / AdminLTE tabs)
|
|
const tabSelectors = [
|
|
'[role="tab"]',
|
|
'.nav-tabs .nav-link',
|
|
'.nav-pills .nav-link',
|
|
'a[data-toggle="tab"]',
|
|
'a[data-bs-toggle="tab"]',
|
|
];
|
|
|
|
for (const sel of tabSelectors) {
|
|
const tabs = page.locator(sel);
|
|
const count = await tabs.count();
|
|
|
|
if (count > 1) {
|
|
// Click each tab and verify no server errors
|
|
for (let i = 0; i < Math.min(count, 8); i++) {
|
|
const tab = tabs.nth(i);
|
|
if (await tab.isVisible()) {
|
|
await tab.click();
|
|
await page.waitForLoadState('domcontentloaded').catch(() => null);
|
|
|
|
const bodyText = await page.locator('body').textContent() ?? '';
|
|
const hasError = /Whoops|Server Error|SQLSTATE/.test(bodyText);
|
|
expect(hasError, `Error after clicking tab ${i} at ${sel}`).toBe(false);
|
|
}
|
|
}
|
|
break; // found tabs, done
|
|
}
|
|
}
|
|
|
|
expect(consoleErrors.length, `Console errors: ${consoleErrors.join(' | ')}`).toBe(0);
|
|
expect(networkErrors.length, `HTTP 5xx: ${networkErrors.join(' | ')}`).toBe(0);
|
|
});
|
|
});
|