feat: 支持自定义订阅节点并兼容现有数据库
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { test, expect } from "./e2e-fixtures";
|
||||
import { parse } from "yaml";
|
||||
|
||||
test("custom YAML nodes use compact forms, persist edits and integrate with subscription groups", async ({
|
||||
page,
|
||||
}) => {
|
||||
const errors: string[] = [];
|
||||
page.on("pageerror", (e) => errors.push(e.message));
|
||||
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: "节点管理" }).click();
|
||||
const create = page
|
||||
.locator(".compact-create-panel details")
|
||||
.filter({ has: page.getByRole("heading", { name: "新增自定义订阅节点" }) });
|
||||
await create.locator(":scope > summary").click();
|
||||
await create.getByLabel("Slug", { exact: true }).fill("custom-browser");
|
||||
await create.getByLabel("显示名", { exact: true }).fill("香港自定义节点");
|
||||
await create.getByRole("textbox", { name: "节点 YAML", exact: true }).fill("name: [invalid");
|
||||
await create.getByRole("button", { name: "创建自定义节点" }).click();
|
||||
await expect(create.getByRole("alert")).toContainText("YAML 格式错误");
|
||||
await expect(create.getByRole("textbox", { name: "节点 YAML", exact: true })).toHaveValue(
|
||||
"name: [invalid",
|
||||
);
|
||||
const source =
|
||||
'# keep this comment\nproxies:\n - name: \'HK "AnyTLS": #1\'\n type: anytls\n server: hk.example.com\n port: 443\n password: "test-only:password"\n udp: true\n';
|
||||
await create.getByRole("textbox", { name: "节点 YAML", exact: true }).fill(source);
|
||||
await create.getByRole("button", { name: "创建自定义节点" }).click();
|
||||
const row = page
|
||||
.locator(".entity-table__item")
|
||||
.filter({ hasText: "custom-browser" });
|
||||
await expect(row).toBeVisible();
|
||||
await expect(row).toContainText("不轮询");
|
||||
await row.locator(":scope > summary").click();
|
||||
await expect(row.getByRole("textbox", { name: "节点 YAML", exact: true })).toHaveValue(
|
||||
source,
|
||||
);
|
||||
await expect(row.getByLabel("客户端地址", { exact: true })).toHaveCount(0);
|
||||
const updated = source.replace('HK "AnyTLS": #1', 'HK "AnyTLS": #2');
|
||||
await row.getByRole("textbox", { name: "节点 YAML", exact: true }).fill(updated);
|
||||
await row.getByRole("button", { name: "保存自定义节点" }).click();
|
||||
await expect(row.locator("p[role=status]")).toHaveText("已保存");
|
||||
await page.reload();
|
||||
await row.locator(":scope > summary").click();
|
||||
await expect(
|
||||
row.getByRole("textbox", { name: "节点 YAML", exact: true }),
|
||||
).toHaveValue(updated);
|
||||
await page.screenshot({
|
||||
path: "test-results/custom-node-desktop.png",
|
||||
fullPage: true,
|
||||
});
|
||||
const config = await page.request.get(
|
||||
"/api/admin/nodes/custom-browser/config",
|
||||
);
|
||||
expect(config.status()).toBe(409);
|
||||
const auth = await page.request.post("/api/hy2/nodes/custom-browser/auth", {
|
||||
data: { auth: "test:test" },
|
||||
});
|
||||
expect(await auth.json()).toMatchObject({ ok: false });
|
||||
|
||||
await page.getByRole("link", { name: "订阅配置" }).click();
|
||||
const main = page.locator(".proxy-group-card").first();
|
||||
await expect(main.locator(".proxy-sort-item")).toContainText(
|
||||
'HK "AnyTLS": #2',
|
||||
);
|
||||
const createGroup = page
|
||||
.locator("details")
|
||||
.filter({ has: page.locator("summary", { hasText: "新建分组" }) });
|
||||
await createGroup.locator(":scope > summary").click();
|
||||
await createGroup.getByLabel("新建分组名").fill("Custom Work");
|
||||
await createGroup.getByRole("button", { name: /HK.*添加/ }).click();
|
||||
await createGroup
|
||||
.getByRole("button", { name: "新建分组", exact: true })
|
||||
.click();
|
||||
await expect(
|
||||
page.locator("summary strong", { hasText: "Custom Work" }),
|
||||
).toBeVisible();
|
||||
const url = await page.locator(".copy-line code").first().textContent();
|
||||
const response = await page.request.get(url!);
|
||||
expect(response.status()).toBe(200);
|
||||
const subscription = parse(await response.text());
|
||||
const proxy = subscription.proxies.find(
|
||||
(p: { type: string }) => p.type === "anytls",
|
||||
);
|
||||
expect(proxy).toMatchObject({
|
||||
name: 'HK "AnyTLS": #2',
|
||||
server: "hk.example.com",
|
||||
password: "test-only:password",
|
||||
udp: true,
|
||||
});
|
||||
expect(
|
||||
subscription["proxy-groups"].find(
|
||||
(g: { name: string }) => g.name === "Custom Work",
|
||||
).proxies,
|
||||
).toEqual([proxy.name]);
|
||||
const group = page
|
||||
.locator("details")
|
||||
.filter({
|
||||
has: page.locator("summary strong", { hasText: "Custom Work" }),
|
||||
});
|
||||
await group.locator(":scope > summary").click();
|
||||
await group.getByRole("button", { name: "删除分组" }).click();
|
||||
await page.getByRole("button", { name: "确认删除分组" }).click();
|
||||
await expect(group).toHaveCount(0);
|
||||
|
||||
await page.getByRole("link", { name: "节点管理" }).click();
|
||||
await page.getByRole("searchbox").fill("custom");
|
||||
await expect(page.locator(".entity-table__item:visible")).toHaveCount(1);
|
||||
await row.locator(":scope > summary").click();
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await expect
|
||||
.poll(() =>
|
||||
page.evaluate(() => document.documentElement.scrollWidth <= innerWidth),
|
||||
)
|
||||
.toBe(true);
|
||||
await page.screenshot({
|
||||
path: "test-results/custom-node-mobile.png",
|
||||
fullPage: true,
|
||||
});
|
||||
await row.getByLabel("启用节点", { exact: true }).uncheck();
|
||||
await row.getByRole("button", { name: "保存自定义节点" }).click();
|
||||
await expect(row.locator("p[role=status]")).toHaveText("已保存");
|
||||
const disabled = parse(await (await page.request.get(url!)).text());
|
||||
expect(
|
||||
disabled.proxies.some((p: { type: string }) => p.type === "anytls"),
|
||||
).toBe(false);
|
||||
await row.getByRole("button", { name: "删除节点" }).click();
|
||||
await page.getByRole("button", { name: "确认删除节点" }).click();
|
||||
await expect(row).toHaveCount(0);
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
Reference in New Issue
Block a user