Files
caddy-proxy-manager/tests/e2e/proxy-hosts.spec.ts
akanealw 99819b70ff
Some checks failed
Build and Push Docker Images (Trusted) / build-and-push (., docker/caddy/Dockerfile, caddy) (push) Has been cancelled
Build and Push Docker Images (Trusted) / build-and-push (., docker/l4-port-manager/Dockerfile, l4-port-manager) (push) Has been cancelled
Build and Push Docker Images (Trusted) / build-and-push (., docker/web/Dockerfile, web) (push) Has been cancelled
Tests / test (push) Has been cancelled
added caddy-proxy-manager for testing
2026-04-21 22:49:08 +00:00

83 lines
3.4 KiB
TypeScript
Executable File

import { test, expect } from '@playwright/test';
test.describe('Proxy Hosts', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/proxy-hosts');
});
test('page loads with Create Host button visible', async ({ page }) => {
await expect(page.getByRole('button', { name: /create host/i })).toBeVisible();
});
test('clicking Create Host opens a dialog with form fields', async ({ page }) => {
await page.getByRole('button', { name: /create host/i }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await expect(page.getByLabel(/domains/i)).toBeVisible();
});
test('create a proxy host — appears in the table', async ({ page }) => {
await page.getByRole('button', { name: /create host/i }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await page.getByLabel('Name').fill('E2E Test Host');
await page.getByLabel(/domains/i).fill('e2etest.local');
// Upstream field uses placeholder text, not a label
await page.getByPlaceholder('10.0.0.5:8080').fill('localhost:9999');
await page.getByRole('button', { name: /^create$/i }).click();
// Dialog should close and host appear in table
await expect(page.getByRole('dialog')).not.toBeVisible({ timeout: 10000 });
await expect(page.getByRole('table').getByText('E2E Test Host')).toBeVisible({ timeout: 10000 });
});
test('clicking Name / Domain header sorts the table', async ({ page }) => {
const sortBtn = page.getByRole('button', { name: 'Name / Domain' });
await expect(sortBtn).toBeVisible({ timeout: 10_000 });
// Click to sort ascending
await sortBtn.click();
await expect(page).toHaveURL(/sortBy=name/);
await expect(page).toHaveURL(/sortDir=asc/);
// Click again to toggle to descending
await sortBtn.click();
await expect(page).toHaveURL(/sortDir=desc/);
});
test('clicking Status header sorts by enabled state', async ({ page }) => {
const sortBtn = page.getByRole('button', { name: 'Status' });
await expect(sortBtn).toBeVisible();
await sortBtn.click();
await expect(page).toHaveURL(/sortBy=enabled/);
});
test('delete proxy host removes it from table', async ({ page }) => {
// Create one to delete
await page.getByRole('button', { name: /create host/i }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await page.getByLabel('Name').fill('Host To Delete');
await page.getByLabel(/domains/i).fill('delete-me.local');
await page.getByPlaceholder('10.0.0.5:8080').fill('localhost:7777');
await page.getByRole('button', { name: /^create$/i }).click();
await expect(page.getByRole('dialog')).not.toBeVisible({ timeout: 10000 });
await expect(page.getByRole('table').getByText('Host To Delete')).toBeVisible({ timeout: 10000 });
// Open the dropdown menu for that row and click Delete
const row = page.locator('tr', { hasText: 'Host To Delete' });
await row.getByRole('button').first().click();
await page.getByRole('menuitem', { name: /delete/i }).click();
// Confirm dialog
await expect(page.getByRole('dialog')).toBeVisible();
await page.getByRole('button', { name: /^delete$/i }).click();
// Wait for dialog to close, then verify the row is gone from the table
await expect(page.getByRole('dialog')).not.toBeVisible({ timeout: 10000 });
await expect(page.locator('tbody').getByText('Host To Delete')).not.toBeVisible({ timeout: 5000 });
});
});