mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-22 15:07:41 +08:00
962d36323b
* add mock data * add helpers * page objects * updated specs * remove PENDING_REWARITE * formatting
167 lines
5.2 KiB
TypeScript
167 lines
5.2 KiB
TypeScript
/**
|
|
* Navigation tests -- CRITICAL tier.
|
|
*
|
|
* Covers sidebar (desktop) / bottombar (mobile) link set, conditional
|
|
* nav items (faces, chat, classification), settings menu navigation,
|
|
* unknown-route redirect to /, and mobile-specific nav behaviors.
|
|
*/
|
|
|
|
import { test, expect } from "../fixtures/frigate-test";
|
|
import { BasePage } from "../pages/base.page";
|
|
|
|
const PRIMARY_ROUTES = ["/review", "/explore", "/export"] as const;
|
|
|
|
test.describe("Navigation — primary links @critical", () => {
|
|
test("every primary link is visible and navigates", async ({
|
|
frigateApp,
|
|
}) => {
|
|
await frigateApp.goto("/");
|
|
for (const route of PRIMARY_ROUTES) {
|
|
await expect(
|
|
frigateApp.page.locator(`a[href="${route}"]`).first(),
|
|
).toBeVisible();
|
|
}
|
|
const base = new BasePage(frigateApp.page, !frigateApp.isMobile);
|
|
for (const route of PRIMARY_ROUTES) {
|
|
await base.navigateTo(route);
|
|
await expect(frigateApp.page).toHaveURL(new RegExp(route));
|
|
await expect(frigateApp.page.locator("#pageRoot")).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test("logo links home on desktop", async ({ frigateApp }) => {
|
|
test.skip(frigateApp.isMobile, "Sidebar logo is desktop-only");
|
|
await frigateApp.goto("/review");
|
|
await frigateApp.page.locator("aside a[href='/']").first().click();
|
|
await expect(frigateApp.page).toHaveURL(/\/$/);
|
|
});
|
|
|
|
test("unknown route redirects to /", async ({ frigateApp }) => {
|
|
await frigateApp.page.goto("/nonexistent-route");
|
|
await frigateApp.page.waitForSelector("#pageRoot", { timeout: 10_000 });
|
|
await expect(frigateApp.page).toHaveURL(/\/$/);
|
|
await expect(
|
|
frigateApp.page.locator("[data-camera='front_door']"),
|
|
).toBeVisible({ timeout: 10_000 });
|
|
});
|
|
});
|
|
|
|
test.describe("Navigation — conditional items @critical", () => {
|
|
test("/faces is hidden when face_recognition.enabled is false", async ({
|
|
frigateApp,
|
|
}) => {
|
|
await frigateApp.goto("/");
|
|
await expect(
|
|
frigateApp.page.locator('a[href="/faces"]').first(),
|
|
).toHaveCount(0);
|
|
});
|
|
|
|
test("/faces is visible when face_recognition.enabled is true (desktop)", async ({
|
|
frigateApp,
|
|
}) => {
|
|
test.skip(frigateApp.isMobile, "Desktop sidebar");
|
|
await frigateApp.installDefaults({
|
|
config: { face_recognition: { enabled: true } },
|
|
});
|
|
await frigateApp.goto("/");
|
|
await expect(
|
|
frigateApp.page.locator('a[href="/faces"]').first(),
|
|
).toBeVisible();
|
|
});
|
|
|
|
test("/chat is hidden when genai.model is none (desktop)", async ({
|
|
frigateApp,
|
|
}) => {
|
|
test.skip(frigateApp.isMobile, "Desktop sidebar");
|
|
await frigateApp.installDefaults({
|
|
config: {
|
|
genai: {
|
|
enabled: false,
|
|
provider: "ollama",
|
|
model: "none",
|
|
base_url: "",
|
|
},
|
|
},
|
|
});
|
|
await frigateApp.goto("/");
|
|
await expect(
|
|
frigateApp.page.locator('a[href="/chat"]').first(),
|
|
).toHaveCount(0);
|
|
});
|
|
|
|
test("/chat is visible when genai.model is set (desktop)", async ({
|
|
frigateApp,
|
|
}) => {
|
|
test.skip(frigateApp.isMobile, "Desktop sidebar");
|
|
await frigateApp.installDefaults({
|
|
config: { genai: { enabled: true, model: "llava" } },
|
|
});
|
|
await frigateApp.goto("/");
|
|
await expect(
|
|
frigateApp.page.locator('a[href="/chat"]').first(),
|
|
).toBeVisible();
|
|
});
|
|
|
|
test("/classification is visible for admin on desktop", async ({
|
|
frigateApp,
|
|
}) => {
|
|
test.skip(frigateApp.isMobile, "Desktop sidebar");
|
|
await frigateApp.goto("/");
|
|
await expect(
|
|
frigateApp.page.locator('a[href="/classification"]').first(),
|
|
).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe("Navigation — settings menu (desktop) @critical", () => {
|
|
test.skip(
|
|
({ frigateApp }) => frigateApp.isMobile,
|
|
"Sidebar settings menu is desktop-only",
|
|
);
|
|
|
|
const TARGETS = [
|
|
{ label: "Settings", url: /\/settings/ },
|
|
{ label: "System metrics", url: /\/system/ },
|
|
{ label: "System logs", url: /\/logs/ },
|
|
{ label: "Configuration Editor", url: /\/config/ },
|
|
];
|
|
|
|
for (const target of TARGETS) {
|
|
test(`menu → ${target.label} navigates`, async ({ frigateApp }) => {
|
|
await frigateApp.goto("/");
|
|
const gear = frigateApp.page
|
|
.locator("aside .mb-8 div[class*='cursor-pointer']")
|
|
.first();
|
|
await gear.click();
|
|
await frigateApp.page.getByLabel(target.label).click();
|
|
await expect(frigateApp.page).toHaveURL(target.url);
|
|
});
|
|
}
|
|
});
|
|
|
|
test.describe("Navigation — mobile @critical @mobile", () => {
|
|
test("mobile bottombar visible, sidebar not rendered", async ({
|
|
frigateApp,
|
|
}) => {
|
|
test.skip(!frigateApp.isMobile, "Mobile-only");
|
|
await frigateApp.goto("/");
|
|
await expect(frigateApp.page.locator("aside")).toHaveCount(0);
|
|
for (const route of PRIMARY_ROUTES) {
|
|
await expect(
|
|
frigateApp.page.locator(`a[href="${route}"]`).first(),
|
|
).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test("mobile nav survives route change", async ({ frigateApp }) => {
|
|
test.skip(!frigateApp.isMobile, "Mobile-only");
|
|
await frigateApp.goto("/");
|
|
const reviewLink = frigateApp.page.locator('a[href="/review"]').first();
|
|
await reviewLink.click();
|
|
await expect(frigateApp.page).toHaveURL(/\/review/);
|
|
await expect(
|
|
frigateApp.page.locator('a[href="/review"]').first(),
|
|
).toBeVisible();
|
|
});
|
|
});
|