feat: 支持托管中转主机和节点接入线路
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { test, expect } from "./e2e-fixtures";
|
||||
import Database from "better-sqlite3";
|
||||
import { createHash } from "node:crypto";
|
||||
test("managed relay UI, authenticated script, deployment state and subscription membership", async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
await page.goto("/login");
|
||||
await page.getByLabel("用户名", { exact: true }).fill("ui-review");
|
||||
await page.getByLabel("密码", { exact: true }).fill("ui-review-local-2026");
|
||||
await page.getByRole("button", { name: "登录", exact: true }).click();
|
||||
await expect(page).toHaveURL(/dashboard/);
|
||||
await page.getByRole("link", { name: "节点管理", exact: true }).click();
|
||||
const node = page
|
||||
.locator("details")
|
||||
.filter({
|
||||
has: page.getByRole("heading", { name: "新增 HY2 节点", exact: true }),
|
||||
});
|
||||
await node.locator("summary").click();
|
||||
await node.getByLabel("Slug", { exact: true }).fill("jp2");
|
||||
await node.getByLabel("显示名", { exact: true }).fill("JP2 direct");
|
||||
await node
|
||||
.getByLabel("客户端地址", { exact: true })
|
||||
.fill("jp2.p.xn--876a.net");
|
||||
await node.getByRole("button", { name: "创建节点" }).click();
|
||||
await expect(
|
||||
page.getByText("JP2 direct", { exact: true }).first(),
|
||||
).toBeVisible();
|
||||
await page.getByRole("link", { name: "中转线路", exact: true }).click();
|
||||
const host = page
|
||||
.locator("details")
|
||||
.filter({ has: page.getByRole("heading", { name: "新增中转主机" }) });
|
||||
await host.getByLabel("主机名称").fill("HK2");
|
||||
await host.getByLabel("公网域名 / IP").fill("hk2.p.xn--876a.net");
|
||||
await host.getByRole("button", { name: "创建主机" }).click();
|
||||
await expect(page.getByText("等待安装", { exact: true })).toBeVisible();
|
||||
const row = page
|
||||
.locator("details")
|
||||
.filter({ has: page.locator("summary strong", { hasText: /^HK2$/ }) });
|
||||
await row.locator("summary").click();
|
||||
const href = await row
|
||||
.getByRole("link", { name: "下载安装 SH" })
|
||||
.getAttribute("href");
|
||||
expect((await request.get(href!, { maxRedirects: 0 })).status()).toBe(307);
|
||||
const script = await page.request.get(href!);
|
||||
expect(script.status()).toBe(200);
|
||||
expect(await script.text()).toContain("realm");
|
||||
const create = page
|
||||
.locator("details")
|
||||
.filter({ has: page.getByRole("heading", { name: "新增中转线路" }) });
|
||||
await create.getByLabel("线路名称").fill("JP2 via HK2");
|
||||
await create
|
||||
.getByLabel("中转主机", { exact: true })
|
||||
.selectOption({ label: "HK2" });
|
||||
await create
|
||||
.getByLabel("目标节点")
|
||||
.selectOption({ label: "JP2 direct · UDP" });
|
||||
await create.getByLabel("公网端口").fill("51044");
|
||||
await create.getByLabel("本机监听端口").fill("51044");
|
||||
await create.getByRole("button", { name: "创建线路" }).click();
|
||||
await expect(
|
||||
page.locator("summary strong", { hasText: "JP2 via HK2" }),
|
||||
).toBeVisible();
|
||||
const db = new Database(process.env.HY2_E2E_DATABASE!);
|
||||
const token = "a".repeat(64);
|
||||
const id = (db.prepare("SELECT id FROM relay_hosts").get() as { id: string })
|
||||
.id;
|
||||
db.prepare("UPDATE relay_hosts SET token_hash=? WHERE id=?").run(
|
||||
createHash("sha256").update(token).digest("hex"),
|
||||
id,
|
||||
);
|
||||
db.close();
|
||||
expect(
|
||||
(
|
||||
await request.post(`/api/relay/${id}/sync`, {
|
||||
data: { appliedHash: "", active: false, error: "" },
|
||||
})
|
||||
).status(),
|
||||
).toBe(403);
|
||||
expect(
|
||||
(
|
||||
await request.post(`/api/relay/${id}/sync`, { data: "x".repeat(17000) })
|
||||
).status(),
|
||||
).toBe(413);
|
||||
const sync = await request.post(`/api/relay/${id}/sync`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
data: { appliedHash: "", active: false, error: "" },
|
||||
});
|
||||
expect(sync.status()).toBe(200);
|
||||
const desired = await sync.json();
|
||||
expect(desired.config.endpoints[0].network.use_udp).toBe(true);
|
||||
await request.post(`/api/relay/${id}/sync`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
data: { appliedHash: desired.hash, active: true, error: "" },
|
||||
});
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByText("配置已应用", { exact: true }).first(),
|
||||
).toBeVisible();
|
||||
await page.screenshot({
|
||||
path: "test-results/relays-desktop.png",
|
||||
fullPage: true,
|
||||
});
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await page.screenshot({
|
||||
path: "test-results/relays-mobile.png",
|
||||
fullPage: true,
|
||||
});
|
||||
expect(
|
||||
await page.evaluate(
|
||||
() => document.documentElement.scrollWidth <= innerWidth + 1,
|
||||
),
|
||||
).toBe(true);
|
||||
await page.getByRole("link", { name: "订阅配置", exact: true }).click();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "拖拽排序 JP2 via HK2" }),
|
||||
).toBeVisible();
|
||||
});
|
||||
Reference in New Issue
Block a user