refactor(custom-widgets): extract domain package
This commit is contained in:
167 files changed
+12282
-10033
No files matched your search
@@ -3,7 +3,7 @@ import { describe, test } from "vitest";
|
||||
|
||||
import { createHomarrContainer } from "./shared/create-homarr-container";
|
||||
import { createSqliteDbFileAsync } from "./shared/e2e-db";
|
||||
import { startMockApiServerAsync } from "./shared/mock-api-server";
|
||||
import { startMockApiContainerAsync } from "./shared/mock-api-container";
|
||||
import { seedAdminUserAsync } from "./shared/seed-admin-user";
|
||||
|
||||
const adminCredentials = {
|
||||
@@ -18,7 +18,7 @@ const updatedTemplate = '<Stack gap="xs"><Text>{data.title}</Text><Badge color="
|
||||
|
||||
describe("Custom JSX custom widgets", () => {
|
||||
test("creates, previews, and edits a customJsx widget", async () => {
|
||||
const mockApi = await startMockApiServerAsync({
|
||||
const mockApi = await startMockApiContainerAsync({
|
||||
title: "E2E Widget",
|
||||
status: "online",
|
||||
value: 42,
|
||||
@@ -52,12 +52,13 @@ describe("Custom JSX custom widgets", () => {
|
||||
await page.waitForURL("**/manage/custom-widgets/new", { timeout: 15_000 });
|
||||
await page.getByRole("textbox", { name: "Name" }).fill("E2E Custom JSX");
|
||||
await page.getByRole("textbox", { name: "URL", exact: true }).fill(`${mockApi.url}/status`);
|
||||
await page.getByRole("combobox", { name: "Display Type" }).click();
|
||||
await page.getByRole("option", { name: "Custom JSX" }).click();
|
||||
await page.getByRole("button", { name: /Custom JSX/u }).click();
|
||||
await page.getByRole("combobox", { name: "Network scope" }).click();
|
||||
await page.getByRole("option", { name: "Private networks" }).click();
|
||||
await page.getByLabel("JSX Template").fill(initialTemplate);
|
||||
|
||||
await page.getByRole("button", { name: "Test" }).first().click();
|
||||
const previewPanel = page.locator(".mantine-Card-root").filter({ hasText: "Preview" });
|
||||
const previewPanel = page.getByRole("complementary", { name: "Preview" });
|
||||
await previewPanel.getByRole("button", { name: "Test" }).click();
|
||||
await expect(previewPanel.getByRole("heading", { name: "E2E Widget" }).first()).toBeVisible({
|
||||
timeout: 15_000,
|
||||
});
|
||||
@@ -65,18 +66,18 @@ describe("Custom JSX custom widgets", () => {
|
||||
await page.getByRole("button", { name: "Create" }).first().click();
|
||||
await expect(page.getByText('Widget "E2E Custom JSX" created successfully.')).toBeVisible({ timeout: 15_000 });
|
||||
await page.waitForURL("**/manage/custom-widgets/edit/**", { timeout: 15_000 });
|
||||
await expect(page.getByLabel("JSX Template")).toHaveValue(initialTemplate);
|
||||
await expect(page.getByLabel("JSX Template")).toHaveText(initialTemplate);
|
||||
|
||||
await page.getByLabel("JSX Template").fill(updatedTemplate);
|
||||
await expect(page.getByLabel("JSX Template")).toHaveValue(updatedTemplate);
|
||||
await expect(page.getByLabel("JSX Template")).toHaveText(updatedTemplate);
|
||||
|
||||
await page.getByRole("button", { name: "Save" }).first().click();
|
||||
await expect(page.getByText('Widget "E2E Custom JSX" updated successfully.')).toBeVisible({ timeout: 15_000 });
|
||||
await expect(page.getByLabel("JSX Template")).toHaveValue(updatedTemplate);
|
||||
await expect(page.getByLabel("JSX Template")).toHaveText(updatedTemplate);
|
||||
} finally {
|
||||
await browser.close();
|
||||
await homarrContainer.stop();
|
||||
await mockApi.close();
|
||||
await mockApi.stop();
|
||||
}
|
||||
}, 120_000);
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
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()),
|
||||
};
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import { createServer } from "node:http";
|
||||
|
||||
import type { Server } from "node:http";
|
||||
|
||||
export interface MockApiServer {
|
||||
url: string;
|
||||
port: number;
|
||||
close: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const startMockApiServerAsync = async (responseBody: unknown): Promise<MockApiServer> => {
|
||||
const body = JSON.stringify(responseBody);
|
||||
|
||||
const server: Server = await new Promise((resolve) => {
|
||||
const s = createServer((_req, res) => {
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(body);
|
||||
});
|
||||
s.listen(0, "0.0.0.0", () => resolve(s));
|
||||
});
|
||||
|
||||
const address = server.address();
|
||||
if (!address || typeof address === "string") {
|
||||
throw new Error("Failed to start mock API server");
|
||||
}
|
||||
|
||||
return {
|
||||
port: address.port,
|
||||
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