bump rjsf to 6.10.0 and add e2e test (#24332)
CI / AMD64 Build (push) Canceled after 0s
CI / AMD64 Smoke Test (push) Canceled after 0s
CI / ARM Build (push) Canceled after 0s
CI / Jetson Jetpack 6 (push) Canceled after 0s
CI / AMD64 Extra Build (push) Canceled after 0s
CI / ARM Extra Build (push) Canceled after 0s
CI / Synaptics Build (push) Canceled after 0s
CI / Assemble and push default build (push) Canceled after 0s

This commit is contained in:
Josh Hawkins
2026-09-14 13:36:27 -05:00
committed by GitHub
parent 7821ecbb43
commit eecc43ccef
3 changed files with 212 additions and 86 deletions
@@ -0,0 +1,141 @@
/**
* Object filters settings tests -- MEDIUM tier.
*
* `objects.filters` is an additionalProperties map, so each label's filter is
* an entry RJSF adds at runtime. RJSF has changed how a cleared field nested
* inside such an entry is stored (`""` before 6.9, omitted after). These tests
* pin what Frigate does with it: the save payload deletes only the cleared
* key, and restoring the value leaves the section clean.
*/
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=cameraObjects&camera=front_door";
const UNSAVED = "You have unsaved changes";
// A non-default value can only come from the YAML, so deleting it is safe
const MIN_AREA = 5000;
async function installRoutes(page: Page) {
const config = configFactory({
cameras: {
front_door: {
objects: {
filters: {
person: {
min_area: MIN_AREA,
max_area: 24000000,
min_ratio: 0,
max_ratio: 24000000,
threshold: 0.7,
min_score: 0.5,
},
},
},
},
},
});
let lastSavedConfig: unknown = null;
await page.route("**/api/config/schema.json", (route) =>
route.fulfill({ json: CONFIG_SCHEMA }),
);
await page.route("**/api/config", (route) => {
if (route.request().method() === "GET") {
return route.fulfill({ json: config });
}
return route.fulfill({ json: { success: true } });
});
await page.route("**/api/config/raw_paths", (route) =>
route.fulfill({ json: {} }),
);
await page.route("**/api/config/set", async (route) => {
lastSavedConfig = route.request().postDataJSON();
await route.fulfill({ json: { success: true, require_restart: false } });
});
return { capturedConfig: () => lastSavedConfig };
}
async function openPersonMinArea(page: Page) {
await page.getByText("Object filters", { exact: true }).click();
await page.locator('[aria-expanded="false"]', { hasText: /^Person/ }).click();
const minArea = page.getByRole("textbox", { name: "Minimum object area" });
await expect(minArea).toHaveValue(String(MIN_AREA));
return minArea;
}
test.describe("object filters additionalProperties entries @medium", () => {
test("clearing a nested filter field deletes only that key on save", async ({
frigateApp,
}) => {
const capture = await installRoutes(frigateApp.page);
await frigateApp.goto(SETTINGS_URL);
const minArea = await openPersonMinArea(frigateApp.page);
await minArea.fill("");
await expect(frigateApp.page.getByText(UNSAVED)).toBeVisible();
await frigateApp.page
.getByRole("button", { name: "Save", exact: true })
.click();
// Empty string is the backend's remove sentinel. Sibling filter fields
// must not appear, or the save would rewrite values the user didn't touch.
await expect
.poll(() => capture.capturedConfig(), { timeout: 5_000 })
.toMatchObject({
config_data: {
cameras: {
front_door: { objects: { filters: { person: { min_area: "" } } } },
},
},
});
const saved = capture.capturedConfig() as {
config_data: {
cameras: {
front_door: { objects: { filters: { person: object } } };
};
};
};
expect(saved.config_data.cameras.front_door.objects.filters.person).toEqual(
{ min_area: "" },
);
});
test("restoring a cleared nested filter field leaves the section clean", async ({
frigateApp,
}) => {
await installRoutes(frigateApp.page);
await frigateApp.goto(SETTINGS_URL);
const minArea = await openPersonMinArea(frigateApp.page);
const save = frigateApp.page.getByRole("button", {
name: "Save",
exact: true,
});
await minArea.fill("");
await expect(frigateApp.page.getByText(UNSAVED)).toBeVisible();
await expect(save).toBeEnabled();
await minArea.fill(String(MIN_AREA));
await expect(frigateApp.page.getByText(UNSAVED)).toBeHidden();
await expect(save).toBeDisabled();
});
});
+67 -82
View File
@@ -34,10 +34,10 @@
"@radix-ui/react-toggle": "^1.1.2", "@radix-ui/react-toggle": "^1.1.2",
"@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-toggle-group": "^1.1.2",
"@radix-ui/react-tooltip": "^1.2.8", "@radix-ui/react-tooltip": "^1.2.8",
"@rjsf/core": "^6.4.1", "@rjsf/core": "^6.10.0",
"@rjsf/shadcn": "^6.5.2", "@rjsf/shadcn": "^6.10.0",
"@rjsf/utils": "^6.4.1", "@rjsf/utils": "^6.10.0",
"@rjsf/validator-ajv8": "^6.4.1", "@rjsf/validator-ajv8": "^6.10.0",
"apexcharts": "^7.3.0", "apexcharts": "^7.3.0",
"axios": "^1.18.0", "axios": "^1.18.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
@@ -5168,15 +5168,6 @@
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@react-icons/all-files": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz",
"integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
"node_modules/@remix-run/router": { "node_modules/@remix-run/router": {
"version": "1.23.4", "version": "1.23.4",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.4.tgz", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.4.tgz",
@@ -5187,73 +5178,63 @@
} }
}, },
"node_modules/@rjsf/core": { "node_modules/@rjsf/core": {
"version": "6.5.2", "version": "6.10.0",
"resolved": "https://registry.npmjs.org/@rjsf/core/-/core-6.5.2.tgz", "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-6.10.0.tgz",
"integrity": "sha512-Fx+aVNQRYQyoY0vM8zYDZkuOiNe+5PLsxUySUdHfjljlT23mJnTCpPKMkxWJwh4UEWeSN0xjmknW9LfIwuQmOg==", "integrity": "sha512-fdyaPnhIe+NzTFZcYcYcp/QqVcAJhhloIsU6vN+hp/IhiGJrzgB9REMVVUlKYNzP37xZ/BsEq7u7RC24KKdLAQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"lodash": "^4.18.1", "markdown-to-jsx": "^9.8.2"
"lodash-es": "^4.18.1",
"markdown-to-jsx": "^8.0.0",
"prop-types": "^15.8.1"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">=20"
}, },
"peerDependencies": { "peerDependencies": {
"@rjsf/utils": "^6.5.x", "@rjsf/utils": "^6.10.0",
"react": ">=18" "react": ">=18"
} }
}, },
"node_modules/@rjsf/shadcn": { "node_modules/@rjsf/shadcn": {
"version": "6.5.2", "version": "6.10.0",
"resolved": "https://registry.npmjs.org/@rjsf/shadcn/-/shadcn-6.5.2.tgz", "resolved": "https://registry.npmjs.org/@rjsf/shadcn/-/shadcn-6.10.0.tgz",
"integrity": "sha512-h3FsGRy07Gw4MrORlxNTuSb7icuyiUM0KXimg1jgtlYLhYvMKaHzJgdL/SrAyBWiUtXIsxuBhPU3rFxnA9Ml6Q==", "integrity": "sha512-rEUvRannFGWrdH0Mdl4E9NPv9htnUv8hZhMXR+hzO3wpCOlKGmMvThvzqLnkIFtolLu296OW+cTWK6x/POHqOQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-label": "^2.1.8", "@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-radio-group": "^1.3.8", "@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slider": "^1.3.6", "@radix-ui/react-slider": "^1.3.6",
"@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-slot": "^1.2.0",
"@react-icons/all-files": "^4.1.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
"lodash": "^4.18.1", "lucide-react": "^1.16.0",
"lodash-es": "^4.18.1", "tailwind-merge": "^3.6.0"
"lucide-react": "^0.548.0",
"tailwind-merge": "^3.5.0",
"tailwindcss-animate": "^1.0.7",
"uuid": "^14.0.0"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">=20"
}, },
"peerDependencies": { "peerDependencies": {
"@rjsf/core": "^6.5.x", "@rjsf/core": "^6.10.0",
"@rjsf/utils": "^6.5.x", "@rjsf/utils": "^6.10.0",
"react": ">=18" "react": ">=18"
} }
}, },
"node_modules/@rjsf/shadcn/node_modules/lucide-react": { "node_modules/@rjsf/shadcn/node_modules/lucide-react": {
"version": "0.548.0", "version": "1.46.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.548.0.tgz", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.46.0.tgz",
"integrity": "sha512-63b16z63jM9yc1MwxajHeuu0FRZFsDtljtDjYm26Kd86UQ5HQzu9ksEtoUUw4RBuewodw/tGFmvipePvRsKeDA==", "integrity": "sha512-Bv+FZXgZPrxc/NCl1e7JJVQFLdiCxYgxNVhqoV7X0p6I8ADJo8DxBnK1auH0fZz4AmqOJ3jgneL4f1i8LJQRAA==",
"license": "ISC", "license": "ISC",
"peerDependencies": { "peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
} }
}, },
"node_modules/@rjsf/shadcn/node_modules/tailwind-merge": { "node_modules/@rjsf/shadcn/node_modules/tailwind-merge": {
"version": "3.5.0", "version": "3.7.0",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.7.0.tgz",
"integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", "integrity": "sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "github", "type": "github",
@@ -5261,17 +5242,15 @@
} }
}, },
"node_modules/@rjsf/utils": { "node_modules/@rjsf/utils": {
"version": "6.5.2", "version": "6.10.0",
"resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-6.5.2.tgz", "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-6.10.0.tgz",
"integrity": "sha512-qBVQ5qf9BKMOQy/DjMl/IjD5s6akRDx18cgiSYunKt/CYc+kPzHyCVA2TU0rXCsigNlhgnfM8piC3LEHye6vpA==", "integrity": "sha512-GQa+dr28FgGOaRRhIOX3QEv1GkzoklrZYf4f1bTEDNuAWWWyO1oznw62ryZBj4FI/XKPaE/VyJQlssOSbD5KiQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@x0k/json-schema-merge": "^1.0.3", "@x0k/json-schema-merge": "^1.0.3",
"fast-equals": "^6.0.0", "fast-equals": "^6.0.0",
"fast-uri": "^3.1.0", "fast-uri": "^4.1.4",
"jsonpointer": "^5.0.1", "jsonpointer": "^5.0.1",
"lodash": "^4.18.1",
"lodash-es": "^4.18.1",
"react-is": "^18.3.1" "react-is": "^18.3.1"
}, },
"engines": { "engines": {
@@ -5290,28 +5269,42 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@rjsf/utils/node_modules/fast-uri": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.4.tgz",
"integrity": "sha512-dODXrIxlS9JSdgAnhIUKOosKV1oMtU2VtVw87QRaHzyl5jxO290Ii5tEZfCfzfWNHi3jKWwBSdQj0qIyshdZdQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
},
"node_modules/@rjsf/validator-ajv8": { "node_modules/@rjsf/validator-ajv8": {
"version": "6.4.1", "version": "6.10.0",
"resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-6.4.1.tgz", "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-6.10.0.tgz",
"integrity": "sha512-Gx28sRIV7E4CYs2c7BxOGLX44p5IlJE+IaD7GbVk1S+6TxDATqFBSYYZukLB+/vNk3urpndQMreQLKW3W7POHQ==", "integrity": "sha512-B/cNuPIQNBiJo4ByoJUXwGylu51JA5Jhkj4gsZ794dl85xxfcQ43HKfR1Lg55SoCUOzHc0Sf7zI/0q3R3sKEEQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"ajv": "^8.17.1", "ajv": "^8.20.0",
"ajv-formats": "^2.1.1", "ajv-formats": "^2.1.1"
"lodash": "^4.17.23",
"lodash-es": "^4.17.23"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">=20"
}, },
"peerDependencies": { "peerDependencies": {
"@rjsf/utils": "^6.4.x" "@rjsf/utils": "^6.10.0"
} }
}, },
"node_modules/@rjsf/validator-ajv8/node_modules/ajv": { "node_modules/@rjsf/validator-ajv8/node_modules/ajv": {
"version": "8.18.0", "version": "8.20.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
@@ -10043,12 +10036,6 @@
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash-es": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
"license": "MIT"
},
"node_modules/log-symbols": { "node_modules/log-symbols": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz",
@@ -10155,19 +10142,30 @@
} }
}, },
"node_modules/markdown-to-jsx": { "node_modules/markdown-to-jsx": {
"version": "8.0.0", "version": "9.10.2",
"resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-8.0.0.tgz", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-9.10.2.tgz",
"integrity": "sha512-hWEaRxeCDjes1CVUQqU+Ov0mCqBqkGhLKjL98KdbwHSgEWZZSJQeGlJQatVfeZ3RaxrfTrZZ3eczl2dhp5c/pA==", "integrity": "sha512-iR9GadlIox0q1uXnpqdxpF02Vb1WDmZ/QIXWjBR5htzjUEEhyIWbM65LuVKavdwJaVo4q95C/F2OOyNjWe91ig==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 10" "node": ">= 18"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">= 0.14.0" "react": ">= 16.0.0",
"solid-js": ">=1.0.0",
"vue": ">=3.0.0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"react": { "react": {
"optional": true "optional": true
},
"react-native": {
"optional": true
},
"solid-js": {
"optional": true
},
"vue": {
"optional": true
} }
} }
}, },
@@ -13841,19 +13839,6 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"node_modules/uuid": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/vaul": { "node_modules/vaul": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz",
+4 -4
View File
@@ -48,10 +48,10 @@
"@radix-ui/react-toggle": "^1.1.2", "@radix-ui/react-toggle": "^1.1.2",
"@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-toggle-group": "^1.1.2",
"@radix-ui/react-tooltip": "^1.2.8", "@radix-ui/react-tooltip": "^1.2.8",
"@rjsf/core": "^6.4.1", "@rjsf/core": "^6.10.0",
"@rjsf/shadcn": "^6.5.2", "@rjsf/shadcn": "^6.10.0",
"@rjsf/utils": "^6.4.1", "@rjsf/utils": "^6.10.0",
"@rjsf/validator-ajv8": "^6.4.1", "@rjsf/validator-ajv8": "^6.10.0",
"apexcharts": "^7.3.0", "apexcharts": "^7.3.0",
"axios": "^1.18.0", "axios": "^1.18.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",