Files
XC_VM/tests/e2e/playwright.config.ts
T
rootandClaude Opus 5 d0458a8eeb test(e2e): drive the admin panel the way an administrator does
The Playwright suite only checked that pages render. It now performs the
administrator's work against a live test panel and asserts the panel's own
data after each step:

- catalogue: a stream category, a bouquet and a reseller package — created,
  renamed / edited, reopened, deleted;
- subscribers: a line with a bouquet (search, edit in the modal, disable /
  enable, ban / unban, delete), a MAG and an Enigma2 device;
- bulk: two lines selected with the header checkbox, disabled and deleted;
- resellers: created with credits, topped up, edited, disabled, deleted;
- block lists: an IP (RFC 5737 address — blocking adds an iptables rule), a
  user agent and an ISP;
- streams: a live stream added with a source and a server, started, running
  with codecs and the Resources column filled in, stopped, renamed, deleted;
- sign-in: a second administrator refused with a wrong password, signing in
  and out — a separate account, because every admin login re-hashes the
  password and ends that account's other sessions.

Records are named `e2e-<run>-…`; a teardown project sweeps whatever a run
leaves behind and nothing else. tools/create-admin.php provisions the
dedicated test administrator on the panel host.

The first runs found three save paths that answered an empty page (fixed in
f7bba5cb, fd13c940, ee2f586a). Against the test panel: 82 passed, 1 skipped
(no series to select).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WDhDajBPziJwjWZcXnh6R
2026-09-16 14:39:39 +00:00

60 lines
2.1 KiB
TypeScript

import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';
import path from 'node:path';
// Load tests/e2e/.env (copy from .env.example) so `make e2e` picks up creds.
dotenv.config({ path: path.resolve(__dirname, '.env') });
/**
* Playwright config for the XC_VM admin smoke suite.
*
* Configure via env (see .env.example):
* XC_E2E_BASE_URL admin panel base incl. the access code,
* e.g. http://panel.example.com/ACCESS_CODE
* XC_E2E_USER admin username
* XC_E2E_PASS admin password
*
* A `setup` project logs in once and stores the session; the browser projects
* reuse it via storageState.
*/
// A trailing slash is required so relative gotos keep the access-code path
// segment (new URL('./login', '.../code') would otherwise drop 'code').
const rawBase = process.env.XC_E2E_BASE_URL || 'http://localhost/admin';
const baseURL = rawBase.endsWith('/') ? rawBase : rawBase + '/';
export default defineConfig({
testDir: './tests',
outputDir: './test-results',
timeout: 30_000,
expect: { timeout: 10_000 },
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
workers: 1,
reporter: [['list'], ['html', { open: 'never' }]],
use: {
baseURL,
// 'on' so the UI-mode Actions timeline + snapshot preview are always populated
// (with 'on-first-retry' a passing first run captures nothing to preview).
trace: 'on',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
ignoreHTTPSErrors: true,
},
projects: [
// Logs in once; when every dependent project has finished, `cleanup` sweeps
// the records the admin specs created (tests/admin/cleanup.teardown.ts).
{ name: 'setup', testMatch: /auth\.setup\.ts/, teardown: 'cleanup' },
{
name: 'cleanup',
testMatch: /cleanup\.teardown\.ts/,
use: { ...devices['Desktop Chrome'], storageState: '.auth/admin.json' },
},
{
name: 'chromium',
use: { ...devices['Desktop Chrome'], storageState: '.auth/admin.json' },
dependencies: ['setup'],
},
],
});