Files
frigate/web/e2e/specs/settings/camera-detect-scene.spec.ts
T
2026-09-29 15:56:42 -06:00

136 lines
4.1 KiB
TypeScript

/**
* Camera detect scene tests -- MEDIUM tier.
*
* Scenes are free-form names declared by the configured models, so a camera
* only needs to pick one when there is a choice to make. The choices are the
* scenes of the configured models, plus a saved scene that no model uses.
*/
import { readFileSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { test, expect } from "../../fixtures/frigate-test";
import type { Page } from "@playwright/test";
import { configFactory } from "../../fixtures/mock-data/config";
const __dirname = dirname(fileURLToPath(import.meta.url));
const CONFIG_SCHEMA = JSON.parse(
readFileSync(
resolve(__dirname, "../../fixtures/mock-data/config-schema.json"),
"utf-8",
),
);
const SETTINGS_URL = "/settings?page=cameraDetect&camera=front_door";
async function installRoutes(
page: Page,
models: { scene: string; devices: string[] }[],
cameraScene?: string,
) {
const config = configFactory({
models,
...(cameraScene
? { cameras: { front_door: { detect: { scene: cameraScene } } } }
: {}),
} as never);
await page.route("**/api/config/schema.json", (route) =>
route.fulfill({ json: CONFIG_SCHEMA }),
);
await page.route("**/api/config", (route) =>
route.request().method() === "GET"
? route.fulfill({ json: config })
: route.fulfill({ json: { success: true } }),
);
await page.route("**/api/config/raw_paths", (route) =>
route.fulfill({ json: {} }),
);
}
test.describe("camera detect scene @medium", () => {
test("is hidden when there is only one model", async ({ frigateApp }) => {
await installRoutes(frigateApp.page, [
{ scene: "default", devices: ["cpu"] },
]);
await frigateApp.goto(SETTINGS_URL);
const root = frigateApp.page.locator("#pageRoot");
await expect(root).toContainText("Detect FPS");
await expect(root).not.toContainText("Detect scene");
});
test("offers the default and configured model scenes", async ({
frigateApp,
}) => {
await installRoutes(frigateApp.page, [
{ scene: "default", devices: ["cpu"] },
{ scene: "thermal", devices: ["openvino:GPU.0"] },
]);
await frigateApp.goto(SETTINGS_URL);
const root = frigateApp.page.locator("#pageRoot");
await expect(root).toContainText("Detect scene");
await frigateApp.page.locator("#root_scene").click();
const options = frigateApp.page.getByRole("option");
await expect(options).toHaveText(["Default", "thermal"]);
});
test("a saved scene no model uses stays editable", async ({ frigateApp }) => {
// the camera falls back to the default model, but its saved scene would
// silently take effect if a model for it were added later
await installRoutes(
frigateApp.page,
[{ scene: "default", devices: ["cpu"] }],
"garage",
);
await frigateApp.goto(SETTINGS_URL);
await expect(frigateApp.page.locator("#pageRoot")).toContainText(
"Detect scene",
);
await frigateApp.page.locator("#root_scene").click();
await expect(frigateApp.page.getByRole("option")).toHaveText([
"Default",
"garage",
]);
});
test("default is only offered when a default model exists", async ({
frigateApp,
}) => {
await installRoutes(
frigateApp.page,
[
{ scene: "thermal", devices: ["cpu"] },
{ scene: "visible", devices: ["openvino:GPU.0"] },
],
"thermal",
);
await frigateApp.goto(SETTINGS_URL);
await frigateApp.page.locator("#root_scene").click();
await expect(frigateApp.page.getByRole("option")).toHaveText([
"thermal",
"visible",
]);
});
test("one model every camera selects needs no choice", async ({
frigateApp,
}) => {
await installRoutes(
frigateApp.page,
[{ scene: "thermal", devices: ["cpu"] }],
"thermal",
);
await frigateApp.goto(SETTINGS_URL);
const root = frigateApp.page.locator("#pageRoot");
await expect(root).toContainText("Detect FPS");
await expect(root).not.toContainText("Detect scene");
});
});