This commit is contained in:
@@ -2,7 +2,6 @@ import { test, expect, type Page } from '@playwright/test';
|
||||
import { createRequire } from 'node:module';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, resolve, join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
|
||||
// ── Local-auth ADMIN USER MANAGEMENT E2E ──────────────────────────────────────
|
||||
//
|
||||
@@ -29,7 +28,8 @@ const require = createRequire(import.meta.url);
|
||||
const repoRoot = resolve(__dirname, '..', '..');
|
||||
|
||||
// Same deterministic DB the webServer opens (see playwright.auth.config.ts).
|
||||
const e2eTmp = join(tmpdir(), 'maestro-e2e-auth');
|
||||
const e2eTmp = process.env.E2E_AUTH_TMP;
|
||||
if (!e2eTmp) throw new Error('E2E_AUTH_TMP must be set by playwright.auth.config.ts');
|
||||
const DB_PATH = join(e2eTmp, 'e2e-auth.db');
|
||||
|
||||
// The bootstrap admin from config.e2e-auth.yaml.
|
||||
@@ -167,10 +167,50 @@ test('admin can list users, promote a member to admin, and approve a pending use
|
||||
expect(fatalErrors, `fatal errors:\n${fatalErrors.join('\n')}`).toEqual([]);
|
||||
});
|
||||
|
||||
test('system admin opens the event log and filters its results', async ({ page }) => {
|
||||
const fatalErrors = trackFatalErrors(page);
|
||||
const resourceId = `e2e-event-log-${Date.now()}`;
|
||||
const { Repository } = require(resolve(repoRoot, 'dist/db/repository.js')) as {
|
||||
Repository: new (dbPath: string) => {
|
||||
recordEvent: (input: Record<string, unknown>) => { id: number };
|
||||
close?: () => void;
|
||||
};
|
||||
};
|
||||
const repo = new Repository(DB_PATH);
|
||||
try {
|
||||
repo.recordEvent({
|
||||
eventType: 'task.failed', resourceType: 'task', resourceId, result: 'failed',
|
||||
dedupeKey: crypto.randomUUID(), correlationId: crypto.randomUUID(),
|
||||
});
|
||||
} finally {
|
||||
repo.close?.();
|
||||
}
|
||||
|
||||
await login(page, ADMIN.email, ADMIN.password);
|
||||
await page.goto('/ui?page=users');
|
||||
await page.getByRole('tab', { name: /イベントログ|Event log/ }).click();
|
||||
await expect(page.getByRole('heading', { name: /イベントログ|Event log/ })).toBeVisible();
|
||||
|
||||
// 絞り込みはイベントログの領域の中だけを見る。上の帯にも「検索」という名前の
|
||||
// ボタン(shell-search)があり、ページ全体から探すと 2 つ当たって落ちる。
|
||||
// AdminEventLogPage の <section aria-labelledby="admin-event-log-title"> が
|
||||
// この領域(role=region)。
|
||||
const eventLog = page.getByRole('region', { name: /イベントログ|Event log/ });
|
||||
await eventLog.getByLabel(/種別|Type/).selectOption('task.failed');
|
||||
await eventLog.getByLabel(/リソースID|Resource ID/).fill(resourceId);
|
||||
await eventLog.getByRole('button', { name: /検索|Search/ }).click();
|
||||
|
||||
const row = page.getByRole('row').filter({ hasText: resourceId });
|
||||
await expect(row).toBeVisible();
|
||||
await expect(row).toContainText('task.failed');
|
||||
await expect(row).toContainText('failed');
|
||||
expect(fatalErrors, `fatal errors:\n${fatalErrors.join('\n')}`).toEqual([]);
|
||||
});
|
||||
|
||||
// Negative/visibility: a regular member gets NO Users tab and is denied the
|
||||
// admin API. The 403/401 is fetched via page.request (NOT navigation), so the
|
||||
// navigation-scoped fatal tracker never observes the expected denial.
|
||||
test('a non-admin member sees no Users tab and is denied /api/admin/users', async ({ page }) => {
|
||||
test('a non-admin member sees no admin tabs and is denied admin APIs', async ({ page }) => {
|
||||
const fatalErrors = trackFatalErrors(page);
|
||||
|
||||
// OUTSIDER is a plain 'user' that no test promotes, so the non-admin denial
|
||||
@@ -180,10 +220,13 @@ test('a non-admin member sees no Users tab and is denied /api/admin/users', asyn
|
||||
|
||||
// The Users tab is admin+auth gated; a regular user never sees it.
|
||||
await expect(page.getByTestId('nav-users')).toHaveCount(0);
|
||||
await expect(page.getByRole('tab', { name: /イベントログ|Event log/ })).toHaveCount(0);
|
||||
|
||||
// Admin-only API is denied for a regular user (401 or 403 depending on guard).
|
||||
const denied = await page.request.get('/api/admin/users');
|
||||
expect([401, 403]).toContain(denied.status());
|
||||
const eventLogDenied = await page.request.get('/api/admin/event-log');
|
||||
expect(eventLogDenied.status()).toBe(403);
|
||||
|
||||
expect(fatalErrors, `fatal errors (DOM navigation only):\n${fatalErrors.join('\n')}`).toEqual([]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user