fix(custom-widgets): address v2 merge review
This commit is contained in:
1 parent
6aceb2fd1f
commit
48ce83806d
122 files changed
+8534
-1447
No files matched your search
@@ -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);
|
||||
});
|
||||
@@ -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()),
|
||||
};
|
||||
}
|
||||
@@ -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()));
|
||||
}),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user