Files
siftlode/frontend/e2e/nav.spec.ts
T
peter 24448e7c6f feat(activity): one Activity page — runs, admin actions, server log and quota under one filter bar
The audit log, the server log and the admin quota view were three pages (the quota one a Stats tab),
each with its own filters, and the background runs had no list at all. Now one page ("Napló" /
"Activity") reads all four, each still its own table on the server: a shared bar (text, a period of
1 h to 90 days defaulting to 7, an account) and each tab's own filters, the whole view in the URL.
The old page ids open their tab.

Server side: the audit log and the new run list (`/api/admin/runs`) filter and page like the server
log, through one keyset helper (`routes/_keyset`) the log now shares; an audit row keeps the request
it was made in (migration 0111), so its log lines are a pivot away, as a run's are (`lrun`). The
quota breakdown takes since/until and one account. The Scheduler rows get a history button to their
job's runs.

Also fixed on the way: re-saving the value in force on the Configuration page staged its override
without committing it (the commit sat inside the audit branch), so the save was lost.
2026-10-18 03:45:18 +02:00

53 lines
2.4 KiB
TypeScript

import { test, expect } from "@playwright/test";
import { openApp } from "./helpers";
// Locks top-level navigation: each rail item activates its page (aria-current), and browser
// Back steps through the history the app pushes. The render ternary + prop-drilled page state
// this exercises is precisely what the module-registry refactor replaces.
test.describe("page switching", () => {
// Core + admin modules (the E2E account is an admin, matching the real primary user), so this
// also exercises the admin pages. They sit behind ONE rail row ("Administration",
// `nav-admin`) that opens a panel of them — the spec still listed them as rail rows of their own,
// and it failed on every run for a while without anyone seeing it, because e2e was in no
// required gate (it is now part of `release`).
const RAIL = ["channels", "playlists", "files", "stats", "settings", "feed"];
const ADMIN = ["scheduler", "config", "users", "activity"];
test("each rail item activates its page", async ({ page }) => {
await openApp(page);
for (const id of RAIL) {
await page.getByTestId(`nav-${id}`).click();
await expect(page.getByTestId(`nav-${id}`)).toHaveAttribute("aria-current", "page");
}
});
test("each admin page opens from the Administration panel and marks it current", async ({
page,
}) => {
await openApp(page);
for (const id of ADMIN) {
await page.getByTestId("nav-admin").click();
await page.getByTestId(`nav-admin-${id}`).click();
// The panel closes on a pick; the group row carries the current page…
await expect(page.getByTestId("nav-admin")).toHaveAttribute("aria-current", "page");
// …and, reopened, the panel marks which one.
await page.getByTestId("nav-admin").click();
await expect(page.getByTestId(`nav-admin-${id}`)).toHaveAttribute("aria-current", "page");
await page.keyboard.press("Escape");
}
});
test("browser Back steps through visited pages", async ({ page }) => {
await openApp(page);
await page.getByTestId("nav-channels").click();
await expect(page.getByTestId("nav-channels")).toHaveAttribute("aria-current", "page");
await page.getByTestId("nav-playlists").click();
await expect(page.getByTestId("nav-playlists")).toHaveAttribute("aria-current", "page");
await page.goBack();
await expect(page.getByTestId("nav-channels")).toHaveAttribute("aria-current", "page");
});
});