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.
53 lines
2.4 KiB
TypeScript
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");
|
|
});
|
|
});
|