test(web): media settings E2E with the media-settings screenshot
The Media settings section (added in the previous web commit) lets the deployment owner point media at their own servers: ComfyUI URL and optional key, with the image model and custom image/video workflows folded under Advanced, and a transcription URL with optional model and key. Saved keys are never shown again; the key field says one is saved and offers to remove it. Members who do not own the deployment do not see the section. The spec fills both servers, captures `media-settings`, saves and checks the exact update the server receives, then removes the saved key and the transcription server; a second spec checks a member has no Media section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
parent
4e88a9dfe6
commit
f407829524
122
apps/web/e2e/media-settings.spec.ts
Normal file
122
apps/web/e2e/media-settings.spec.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { captureScreenshot, completeOnboarding, openUserSettings, signup } from "./helpers";
|
||||
|
||||
type Draft = {
|
||||
comfyui: {
|
||||
baseUrl: string;
|
||||
apiKey?: string;
|
||||
imageModel?: string;
|
||||
imageWorkflow?: string;
|
||||
videoWorkflow?: string;
|
||||
} | null;
|
||||
transcription: { baseUrl: string; model?: string; apiKey?: string } | null;
|
||||
};
|
||||
|
||||
/** The server keeps keys; the settings screen only learns whether one is saved. */
|
||||
function view(draft: Draft, previous: { comfyui: boolean; transcription: boolean }) {
|
||||
const hasKey = (key: string | undefined, had: boolean) => (key === undefined ? had : key !== "");
|
||||
const text = (value: string | undefined) => (value ? value : undefined);
|
||||
return {
|
||||
comfyui: draft.comfyui
|
||||
? {
|
||||
baseUrl: draft.comfyui.baseUrl,
|
||||
hasApiKey: hasKey(draft.comfyui.apiKey, previous.comfyui),
|
||||
imageModel: text(draft.comfyui.imageModel),
|
||||
imageWorkflow: text(draft.comfyui.imageWorkflow),
|
||||
videoWorkflow: text(draft.comfyui.videoWorkflow),
|
||||
}
|
||||
: null,
|
||||
transcription: draft.transcription
|
||||
? {
|
||||
baseUrl: draft.transcription.baseUrl,
|
||||
model: text(draft.transcription.model),
|
||||
hasApiKey: hasKey(draft.transcription.apiKey, previous.transcription),
|
||||
}
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
async function asDeploymentOwner(page: Page, isDeploymentOwner: boolean) {
|
||||
await page.route("**/rpc/bootstrap", async (route) => {
|
||||
const response = await route.fetch();
|
||||
const body = await response.json();
|
||||
await route.fulfill({
|
||||
response,
|
||||
json: { json: { ...body.json, me: { ...body.json.me, isDeploymentOwner } } },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test("the deployment owner points media at their own servers", async ({ page }, testInfo) => {
|
||||
await asDeploymentOwner(page, true);
|
||||
let current: ReturnType<typeof view> = { comfyui: null, transcription: null };
|
||||
const saved: Draft[] = [];
|
||||
await page.route("**/rpc/media/settings/get", (route) =>
|
||||
route.fulfill({ json: { json: current } }),
|
||||
);
|
||||
await page.route("**/rpc/media/settings/update", (route) => {
|
||||
const draft = (route.request().postDataJSON() as { json: Draft }).json;
|
||||
saved.push(draft);
|
||||
current = view(draft, {
|
||||
comfyui: Boolean(current.comfyui?.hasApiKey),
|
||||
transcription: Boolean(current.transcription?.hasApiKey),
|
||||
});
|
||||
return route.fulfill({ json: { json: current } });
|
||||
});
|
||||
|
||||
await signup(page, `media-settings-${Date.now()}@rakazo.test`, "password12", "Media Owner");
|
||||
await completeOnboarding(page);
|
||||
const settings = await openUserSettings(page);
|
||||
await settings.getByTestId("settings-nav-media").click();
|
||||
const panel = settings.getByTestId("media-settings");
|
||||
await expect(panel).toBeVisible();
|
||||
|
||||
const comfy = panel.locator("section").filter({ hasText: "ComfyUI" });
|
||||
const transcription = panel.locator("section").filter({ hasText: "Transcription" });
|
||||
await comfy.getByLabel("Server URL", { exact: true }).fill("http://127.0.0.1:8188");
|
||||
await comfy.getByLabel("API key", { exact: true }).fill("fake-comfy-key");
|
||||
await transcription.getByLabel("Server URL", { exact: true }).fill("http://127.0.0.1:8080/v1");
|
||||
await transcription.getByLabel("Model", { exact: true }).fill("whisper-1");
|
||||
// The ComfyUI model and workflows stay folded away until asked for.
|
||||
await expect(comfy.getByLabel("Image model", { exact: true })).toBeHidden();
|
||||
await comfy.scrollIntoViewIfNeeded();
|
||||
await captureScreenshot(page, testInfo, "media-settings");
|
||||
await comfy.getByText("Advanced", { exact: true }).click();
|
||||
await comfy.getByLabel("Image model", { exact: true }).fill("sd_xl_base_1.0.safetensors");
|
||||
|
||||
await panel.getByRole("button", { name: "Save", exact: true }).click();
|
||||
await expect(panel.getByText("Saved", { exact: true })).toBeVisible();
|
||||
expect(saved).toEqual([
|
||||
{
|
||||
comfyui: {
|
||||
baseUrl: "http://127.0.0.1:8188",
|
||||
apiKey: "fake-comfy-key",
|
||||
imageModel: "sd_xl_base_1.0.safetensors",
|
||||
imageWorkflow: "",
|
||||
videoWorkflow: "",
|
||||
},
|
||||
transcription: { baseUrl: "http://127.0.0.1:8080/v1", model: "whisper-1" },
|
||||
},
|
||||
]);
|
||||
// The key never comes back; the field shows that one is saved and offers to remove it.
|
||||
const comfyKey = comfy.getByLabel("API key", { exact: true });
|
||||
await expect(comfyKey).toHaveValue("");
|
||||
await expect(comfyKey).toHaveAttribute("placeholder", "Saved");
|
||||
|
||||
await comfy.getByRole("button", { name: "Remove", exact: true }).click();
|
||||
await transcription.getByLabel("Server URL", { exact: true }).fill("");
|
||||
await panel.getByRole("button", { name: "Save", exact: true }).click();
|
||||
await expect.poll(() => saved.length).toBe(2);
|
||||
expect(saved[1]).toMatchObject({ comfyui: { apiKey: "" }, transcription: null });
|
||||
await expect(comfyKey).toHaveAttribute("placeholder", "Optional");
|
||||
});
|
||||
|
||||
test("members who do not own the deployment have no media settings", async ({ page }) => {
|
||||
await asDeploymentOwner(page, false);
|
||||
await signup(page, `media-member-${Date.now()}@rakazo.test`, "password12", "Media Member");
|
||||
await completeOnboarding(page);
|
||||
const settings = await openUserSettings(page);
|
||||
await expect(settings.getByTestId("settings-nav-voice")).toBeVisible();
|
||||
await expect(settings.getByTestId("settings-nav-media")).toHaveCount(0);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user