fix(custom-widgets): address v2 merge review

This commit is contained in:
ajnart committed 2026-07-22 23:36:25 +02:00
1 parent 6aceb2fd1f
commit 48ce83806d
122 files changed
+8534 -1447

No files matched your search

+19 -14
View File
@@ -1,9 +1,12 @@
import { chromium, expect } from "@playwright/test";
import type { Browser } from "@playwright/test";
import type { StartedTestContainer } from "testcontainers";
import { describe, test } from "vitest";
import { createHomarrContainer } from "./shared/create-homarr-container";
import { createSqliteDbFileAsync } from "./shared/e2e-db";
import { startMockApiContainerAsync } from "./shared/mock-api-container";
import type { MockApiServer } from "./shared/mock-api-server";
import { startMockApiServerAsync } from "./shared/mock-api-server";
import { seedAdminUserAsync } from "./shared/seed-admin-user";
const adminCredentials = { username: "admin", password: "Comp(exP4sswOrd" };
@@ -13,18 +16,22 @@ const updatedTemplate = "<Stack><Text fw={700}>{data.status?.title}</Text><Text>
describe("Custom JSX v2 workbench", () => {
test("creates, previews, edits, and immediately adds a widget to a board", async () => {
const mockApi = await startMockApiContainerAsync({ title: "E2E Widget", status: "online", value: 42 });
const { db, localMountPath } = await createSqliteDbFileAsync();
await seedAdminUserAsync(db, adminCredentials);
const homarrContainer = await createHomarrContainer({
environment: { AUTH_PROVIDERS: "credentials" },
mounts: { "/appdata": localMountPath },
}).start();
const baseUrl = `http://${homarrContainer.getHost()}:${homarrContainer.getMappedPort(7575)}`;
const browser = await chromium.launch();
const page = await browser.newPage();
let mockApi: MockApiServer | undefined;
let homarrContainer: StartedTestContainer | undefined;
let browser: Browser | undefined;
try {
mockApi = await startMockApiServerAsync({ title: "E2E Widget", status: "online", value: 42 });
const { db, localMountPath } = await createSqliteDbFileAsync();
await seedAdminUserAsync(db, adminCredentials);
homarrContainer = await createHomarrContainer({
environment: { AUTH_PROVIDERS: "credentials" },
mounts: { "/appdata": localMountPath },
}).start();
const baseUrl = `http://${homarrContainer.getHost()}:${homarrContainer.getMappedPort(7575)}`;
browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(`${baseUrl}/auth/login`);
await page.waitForLoadState("networkidle");
await page.getByLabel("Username").fill(adminCredentials.username);
@@ -84,9 +91,7 @@ describe("Custom JSX v2 workbench", () => {
await expect(page.getByText("E2E Widget")).toBeVisible({ timeout: 15_000 });
await expect(page.getByText("42")).toBeVisible({ timeout: 15_000 });
} finally {
await browser.close();
await homarrContainer.stop();
await mockApi.stop();
await Promise.allSettled([browser?.close(), homarrContainer?.stop(), mockApi?.close()]);
}
}, 180_000);
});
-27
View File
@@ -1,27 +0,0 @@
import { GenericContainer, Wait } from "testcontainers";
import type { StartedTestContainer } from "testcontainers";
export interface MockApiContainer {
url: string;
stop: () => Promise<void>;
}
export async function startMockApiContainerAsync(responseBody: unknown): Promise<MockApiContainer> {
const body = JSON.stringify(responseBody);
const script = [
'const { createServer } = require("node:http");',
`const body = ${JSON.stringify(body)};`,
'createServer((_request, response) => { response.writeHead(200, { "content-type": "application/json" }); response.end(body); }).listen(8080, "0.0.0.0");',
].join("\n");
const container: StartedTestContainer = await new GenericContainer("node:24-alpine")
.withCommand(["node", "-e", script])
.withExposedPorts(8080)
.withWaitStrategy(Wait.forHttp("/status", 8080))
.start();
return {
url: `http://${container.getIpAddress("bridge")}:8080`,
stop: async () => void (await container.stop()),
};
}
+31
View File
@@ -0,0 +1,31 @@
import { createServer } from "node:http";
import type { Server } from "node:http";
export interface MockApiServer {
url: string;
close: () => Promise<void>;
}
export async function startMockApiServerAsync(responseBody: unknown): Promise<MockApiServer> {
const body = JSON.stringify(responseBody);
const server: Server = await new Promise((resolve) => {
const candidate = createServer((_request, response) => {
response.writeHead(200, { "content-type": "application/json" });
response.end(body);
});
candidate.listen(0, "0.0.0.0", () => resolve(candidate));
});
const address = server.address();
if (!address || typeof address === "string") {
server.close();
throw new Error("Failed to start mock API server");
}
return {
url: `http://host.docker.internal:${address.port}`,
close: () =>
new Promise((resolve, reject) => {
server.close((error) => (error ? reject(error) : resolve()));
}),
};
}