Implement Monlet MVP stack and UI updates

This commit is contained in:
Stanislav Rossovskii
2026-05-27 10:01:59 +04:00
parent dcea096327
commit edc51e9c59
145 changed files with 15618 additions and 248 deletions

63
web/tests/smoke.spec.ts Normal file
View File

@@ -0,0 +1,63 @@
import { expect, test } from "@playwright/test";
test("overview renders tallies", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("heading", { name: "Overview" })).toBeVisible();
await expect(page.locator("body")).toContainText("Agents");
await expect(page.locator("body")).toContainText("Checks");
});
test("agents list links to detail", async ({ page }) => {
await page.goto("/agents?sort=status&dir=desc");
await expect(page).toHaveURL(/\/agents$/);
await page.goto("/agents");
await expect(page.getByRole("heading", { name: "Agents" })).toBeVisible();
await expect(page.locator("thead")).not.toContainText("hostname");
await expect(page.locator("thead")).toContainText("features");
await expect(page.locator("thead")).not.toContainText("asc");
await expect(page.locator("thead")).not.toContainText("desc");
await expect(page.locator("thead")).toContainText("↓");
await expect(page.locator("body")).toContainText("checks 2");
await expect(page.locator("body")).toContainText("warn 1");
await page.getByPlaceholder("search agent").fill("host-1");
await expect(page).toHaveURL(/\/agents$/);
await expect(page.locator("tbody")).toContainText("host-1");
await expect(page.locator("tbody")).not.toContainText("host-2");
await page.getByRole("button", { name: "host" }).click();
await expect(page).toHaveURL(/\/agents$/);
await page.getByRole("button", { name: "clear" }).click();
await page.getByRole("link", { name: "agent-1" }).first().click();
await expect(page).toHaveURL(/\/agents\/agent-1$/);
await expect(page.locator("body")).toContainText("hostname");
await expect(page.getByRole("link", { name: "Checks" }).last()).toBeVisible();
await expect(page.locator("tbody").first().locator("tr").first()).toContainText("warning");
await expect(page.locator("thead").first()).not.toContainText("incident_key");
await page.getByRole("link", { name: "check_id" }).click();
await expect(page).toHaveURL(/sort=check_id/);
await page.getByRole("link", { name: "Events" }).last().click();
await expect(page).toHaveURL(/tab=events.*sort=check_id|sort=check_id.*tab=events/);
await expect(page.locator("thead").first()).not.toContainText("exit");
await page.getByRole("link", { name: "Checks" }).last().click();
await expect(page).toHaveURL(/tab=checks.*sort=check_id|sort=check_id.*tab=checks/);
});
test("checks page lists rows", async ({ page }) => {
await page.goto("/checks");
await expect(page.locator("body")).toContainText("disk");
await expect(page.locator("body")).toContainText("load");
});
test("incidents filter renders", async ({ page }) => {
await page.goto("/incidents");
await expect(page.locator("body")).toContainText("load high");
});
test("events page", async ({ page }) => {
await page.goto("/events");
await expect(page.getByRole("heading", { name: "Events" })).toBeVisible();
});
test("outbox page", async ({ page }) => {
await page.goto("/outbox");
await expect(page.locator("body")).toContainText("debug");
});