From 7b26ecc1fd5fe3a735f7fdb8d8f1c96df9b1a065 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:13:16 -0500 Subject: [PATCH] add e2e tests for shareable hardware and Frigate+ model saves --- .../specs/settings/detection-models.spec.ts | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/web/e2e/specs/settings/detection-models.spec.ts b/web/e2e/specs/settings/detection-models.spec.ts index f764b70d7c..6631878a09 100644 --- a/web/e2e/specs/settings/detection-models.spec.ts +++ b/web/e2e/specs/settings/detection-models.spec.ts @@ -217,6 +217,23 @@ test.describe("Detection models settings @high", () => { ).toBeDisabled(); }); + test("shareable hardware another model uses can still be picked", async ({ + frigateApp, + }) => { + await installRoutes(frigateApp.page, [ + { scene: "all", devices: ["openvino:GPU.0"] }, + { scene: "outdoor", devices: ["openvino:GPU.1"] }, + ]); + await openPage(frigateApp); + + await expect( + frigateApp.page.locator("#models-0-openvino\\:GPU\\.1").first(), + ).toBeEnabled(); + await expect(frigateApp.page.locator("#pageRoot")).not.toContainText( + "used by outdoor", + ); + }); + test("adding a model appends a card with an unused scene", async ({ frigateApp, }) => { @@ -248,15 +265,13 @@ test.describe("Detection models settings @high", () => { test("a saved Frigate+ model opens on the Frigate+ tab", async ({ frigateApp, }) => { - // the backend resolves plus:// to a cache path before serving the config - // back, so the plus metadata is the only signal the model is a Plus one await installRoutes( frigateApp.page, [ { scene: "all", devices: ["openvino:GPU.0"], - path: "/config/model_cache/abc123", + path: "plus://abc123", plus: PLUS_MODEL, }, ], @@ -302,6 +317,40 @@ test.describe("Detection models settings @high", () => { expect(saves.at(-1)?.config_data?.models?.[0].path).toBe("plus://abc123"); }); + test("saving a Frigate+ model keeps its reference without the Frigate+ fields", async ({ + frigateApp, + }) => { + // the backend fills these in from the Frigate+ model info when it loads + const saves = await installRoutes( + frigateApp.page, + [ + { + scene: "all", + devices: ["openvino:GPU.0"], + path: "plus://abc123", + plus: PLUS_MODEL, + width: 320, + height: 320, + input_tensor: "nchw", + model_type: "yolo-generic", + }, + ], + true, + ); + await openPage(frigateApp); + + await frigateApp.page.locator("#models-0-openvino\\:GPU\\.1").click(); + await frigateApp.page.getByRole("button", { name: /^Save$/ }).click(); + await expect.poll(() => saves.length).toBeGreaterThan(0); + + const model = saves.at(-1)?.config_data?.models?.[0]; + expect(model?.path).toBe("plus://abc123"); + expect(model?.devices).toEqual(["openvino:GPU.0", "openvino:GPU.1"]); + expect(model).not.toHaveProperty("width"); + expect(model).not.toHaveProperty("input_tensor"); + expect(model).not.toHaveProperty("model_type"); + }); + test("a Frigate+ Hailo model is listed by the device it was built for", async ({ frigateApp, }) => {