mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-08 07:42:47 +03:00
share the setup wizard e2e helpers and mock users
This commit is contained in:
@@ -47,6 +47,7 @@ export interface ApiMockOverrides {
|
|||||||
recommended: string;
|
recommended: string;
|
||||||
available?: { key: string; presets: Record<string, string> }[];
|
available?: { key: string; presets: Record<string, string> }[];
|
||||||
};
|
};
|
||||||
|
users?: { username: string; role: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ApiMocker {
|
export class ApiMocker {
|
||||||
@@ -200,6 +201,16 @@ export class ApiMocker {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Users. GET lists them; POST/PUT (create, password) just succeed, so
|
||||||
|
// tests assert on the intercepted request body instead of a response.
|
||||||
|
await this.page.route("**/api/users**", (route) =>
|
||||||
|
route.request().method() === "GET"
|
||||||
|
? route.fulfill({
|
||||||
|
json: overrides?.users ?? [{ username: "admin", role: "admin" }],
|
||||||
|
})
|
||||||
|
: route.fulfill({ json: { message: "ok" } }),
|
||||||
|
);
|
||||||
|
|
||||||
// Go2RTC streams
|
// Go2RTC streams
|
||||||
await this.page.route("**/api/go2rtc/streams**", (route) =>
|
await this.page.route("**/api/go2rtc/streams**", (route) =>
|
||||||
route.fulfill({ json: {} }),
|
route.fulfill({ json: {} }),
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Shared setup-wizard e2e helpers.
|
||||||
|
*
|
||||||
|
* The wizard shows when config has no cameras, so a first run is mocked by
|
||||||
|
* serving a camera-less config until the returned callback is fired.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { Page } from "@playwright/test";
|
||||||
|
import { expect } from "../fixtures/frigate-test";
|
||||||
|
import { configFactory } from "../fixtures/mock-data/config";
|
||||||
|
import type { ApiMockOverrides } from "./api-mocker";
|
||||||
|
|
||||||
|
export async function installFirstRun(
|
||||||
|
frigateApp: { installDefaults: (o?: ApiMockOverrides) => Promise<void> },
|
||||||
|
page: Page,
|
||||||
|
overrides?: ApiMockOverrides,
|
||||||
|
): Promise<() => void> {
|
||||||
|
await frigateApp.installDefaults(overrides);
|
||||||
|
|
||||||
|
const full = configFactory(overrides?.config);
|
||||||
|
let cameras: unknown = {};
|
||||||
|
|
||||||
|
await page.route("**/api/config", (route) => {
|
||||||
|
if (route.request().method() === "GET") {
|
||||||
|
return route.fulfill({ json: { ...full, cameras } });
|
||||||
|
}
|
||||||
|
return route.fulfill({ json: { success: true } });
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cameras = full.cameras;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function gotoDetectorStep(page: Page, addCamera: () => void) {
|
||||||
|
await page.getByRole("button", { name: "Get Started" }).click();
|
||||||
|
await expect(page.getByText("Add Your First Camera")).toBeVisible();
|
||||||
|
|
||||||
|
// the camera step's Next only renders once its local addedCameras fills,
|
||||||
|
// which SetupCamera does by refetching config when the dialog closes, so
|
||||||
|
// opening and cancelling the dialog is what reveals Next
|
||||||
|
await page.getByRole("button", { name: "Add Camera" }).click();
|
||||||
|
addCamera();
|
||||||
|
await page.getByRole("button", { name: "Cancel" }).click();
|
||||||
|
|
||||||
|
await expect(page.getByRole("button", { name: "Next" })).toBeVisible({
|
||||||
|
timeout: 10_000,
|
||||||
|
});
|
||||||
|
await page.getByRole("button", { name: "Next" }).click();
|
||||||
|
await expect(page.getByText("Object Detection")).toBeVisible();
|
||||||
|
}
|
||||||
@@ -9,8 +9,7 @@
|
|||||||
|
|
||||||
import { test, expect } from "../../fixtures/frigate-test";
|
import { test, expect } from "../../fixtures/frigate-test";
|
||||||
import type { Page } from "@playwright/test";
|
import type { Page } from "@playwright/test";
|
||||||
import { configFactory } from "../../fixtures/mock-data/config";
|
import { gotoDetectorStep, installFirstRun } from "../../helpers/setup-wizard";
|
||||||
import type { ApiMockOverrides } from "../../helpers/api-mocker";
|
|
||||||
|
|
||||||
const NVIDIA_HARDWARE = [
|
const NVIDIA_HARDWARE = [
|
||||||
{
|
{
|
||||||
@@ -57,51 +56,6 @@ async function captureRestarts(page: Page): Promise<string[]> {
|
|||||||
return calls;
|
return calls;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Install mocks for a first run: the wizard shows when config has no cameras,
|
|
||||||
* so the config route starts empty and only reports cameras once the returned
|
|
||||||
* callback is fired, standing in for the camera the user adds.
|
|
||||||
*/
|
|
||||||
async function installFirstRun(
|
|
||||||
frigateApp: { installDefaults: (o?: ApiMockOverrides) => Promise<void> },
|
|
||||||
page: Page,
|
|
||||||
overrides?: ApiMockOverrides,
|
|
||||||
): Promise<() => void> {
|
|
||||||
await frigateApp.installDefaults(overrides);
|
|
||||||
|
|
||||||
const full = configFactory(overrides?.config);
|
|
||||||
let cameras: unknown = {};
|
|
||||||
|
|
||||||
await page.route("**/api/config", (route) => {
|
|
||||||
if (route.request().method() === "GET") {
|
|
||||||
return route.fulfill({ json: { ...full, cameras } });
|
|
||||||
}
|
|
||||||
return route.fulfill({ json: { success: true } });
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
cameras = full.cameras;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function gotoDetectorStep(page: Page, addCamera: () => void) {
|
|
||||||
await page.getByRole("button", { name: "Get Started" }).click();
|
|
||||||
await expect(page.getByText("Add Your First Camera")).toBeVisible();
|
|
||||||
|
|
||||||
// the camera step's Next only renders once its local addedCameras fills,
|
|
||||||
// which SetupCamera does by refetching config when the dialog closes, so
|
|
||||||
// opening and cancelling the dialog is what reveals Next
|
|
||||||
await page.getByRole("button", { name: "Add Camera" }).click();
|
|
||||||
addCamera();
|
|
||||||
await page.getByRole("button", { name: "Cancel" }).click();
|
|
||||||
|
|
||||||
await expect(page.getByRole("button", { name: "Next" })).toBeVisible({
|
|
||||||
timeout: 10_000,
|
|
||||||
});
|
|
||||||
await page.getByRole("button", { name: "Next" }).click();
|
|
||||||
await expect(page.getByText("Object Detection")).toBeVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
test.describe("setup wizard hardware @high @mobile", () => {
|
test.describe("setup wizard hardware @high @mobile", () => {
|
||||||
test("lists probed hardware and writes a models config", async ({
|
test("lists probed hardware and writes a models config", async ({
|
||||||
frigateApp,
|
frigateApp,
|
||||||
|
|||||||
Reference in New Issue
Block a user