mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-25 16:04:41 +03:00
show validation errors in multi-camera export
Clearing part of a time field in the export time picker set the range to NaN, while the picker kept showing a valid fallback time. The multi-camera Export button then stayed disabled with no explanation, and non-admins could never start an export because a case name was required even though they can't see the case field. The picker now ignores incomplete time values. The multi-camera tab shows inline errors for an invalid range, no selected cameras, and a blank case name, only requires a case name from admins, and prefills a default case name.
This commit is contained in:
@@ -988,6 +988,58 @@ test.describe("Multi-Camera Export from History @high", () => {
|
||||
"Front gate follow-up",
|
||||
);
|
||||
});
|
||||
|
||||
test("a blank case name shows an error and disables export", async ({
|
||||
frigateApp,
|
||||
}) => {
|
||||
await frigateApp.installDefaults();
|
||||
const form = await openMultiCameraTab(frigateApp);
|
||||
|
||||
const caseName = form.getByPlaceholder(/new case name/i);
|
||||
await expect(caseName).toHaveValue(/^Multi-camera export - /, {
|
||||
timeout: 5_000,
|
||||
});
|
||||
await expect(form.getByText("Case name is required")).toBeHidden();
|
||||
|
||||
await caseName.fill("");
|
||||
|
||||
await expect(form.getByText("Case name is required")).toBeVisible();
|
||||
await expect(
|
||||
form.getByRole("button", { name: /^export \d+ cameras?$/i }),
|
||||
).toBeDisabled();
|
||||
});
|
||||
|
||||
test("clearing a time field keeps the previous valid range", async ({
|
||||
frigateApp,
|
||||
}) => {
|
||||
await frigateApp.installDefaults();
|
||||
|
||||
let capturedPayload: { items: { end_time: unknown }[] } | null = null;
|
||||
await frigateApp.page.route("**/api/exports/batch", async (route) => {
|
||||
capturedPayload = route.request().postDataJSON();
|
||||
await route.fulfill({
|
||||
status: 202,
|
||||
json: { export_case_id: null, export_ids: [], results: [] },
|
||||
});
|
||||
});
|
||||
|
||||
const form = await openMultiCameraTab(frigateApp);
|
||||
|
||||
const firstCamera = form.locator("button[aria-pressed]").first();
|
||||
await expect(firstCamera).toBeVisible({ timeout: 5_000 });
|
||||
if ((await firstCamera.getAttribute("aria-pressed")) === "false") {
|
||||
await firstCamera.click();
|
||||
}
|
||||
|
||||
await form.getByRole("button", { name: /^end time$/i }).click();
|
||||
await frigateApp.page.locator("#endTime").fill("");
|
||||
await frigateApp.page.keyboard.press("Escape");
|
||||
|
||||
await form.getByRole("button", { name: /^export \d+ cameras?$/i }).click();
|
||||
|
||||
await expect.poll(() => capturedPayload).not.toBeNull();
|
||||
expect(typeof capturedPayload!.items[0].end_time).toBe("number");
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Export Page - Active Job Progress @medium", () => {
|
||||
|
||||
Reference in New Issue
Block a user