refactor: cleanup

This commit is contained in:
zhom
2026-08-06 14:39:53 -07:00
parent 39bbdcb547
commit f12a84e18f
49 changed files with 4555 additions and 377 deletions
+28
View File
@@ -93,6 +93,34 @@ test("profile, group, proxy, tag, metadata, clone, and bulk-delete lifecycle", a
});
assert.ok(cachedValidity === null || cachedValidity.is_valid === false);
// Donut accepts one VLESS shape (REALITY + XTLS Vision over TCP). The form
// uses this to tell the user WHICH part of their setup is unsupported
// instead of implying they mistyped, so the reason must survive the IPC hop.
const goodVless =
"vless://6d6e21a1-4829-4d2b-bc7f-1b25707b61e4@example.com:443" +
"?security=reality&flow=xtls-rprx-vision&encryption=none&type=tcp" +
"&sni=a.com&pbk=mQB9jxUDHO7g49VaNXLEdcNQ_jLhTbLolUsMUNwb6W4&sid=00&fp=chrome";
assert.equal(
await app.invoke("validate_vless_uri", { uri: goodVless }),
null,
);
for (const [uri, reason] of [
[goodVless.replace("security=reality", "security=tls"), "security"],
[goodVless.replace("type=tcp", "type=ws"), "transport"],
[goodVless.replace("flow=xtls-rprx-vision", "flow=none"), "flow"],
]) {
// invokeError returns the command's error wrapped in a message, so match
// rather than JSON.parse the whole string.
const error = await app.invokeError("validate_vless_uri", { uri });
assert.match(error, /VLESS_CONFIG_INVALID/);
assert.match(
error,
new RegExp(`"reason":"${reason}"`),
`expected reason ${reason} for ${uri}, got: ${error}`,
);
}
const exported = JSON.parse(
await app.invoke("export_proxies", { format: "json" }),
);
+27
View File
@@ -718,6 +718,33 @@ test("offline cloud, update, team-lock, trial, and synchronizer contracts are de
}),
notSignedIn,
);
// Saved site lists are cloud-backed like the schedules above, so they
// must refuse the same way rather than appearing to work offline.
assert.match(
await app.invokeError("get_cookie_bot_user_templates", {}),
notSignedIn,
);
assert.match(
await app.invokeError("create_cookie_bot_user_template", {
name: "e2e list",
sites: ["example.com"],
}),
notSignedIn,
);
assert.match(
await app.invokeError("update_cookie_bot_user_template", {
id: "00000000-0000-0000-0000-000000000000",
name: "renamed",
sites: null,
}),
notSignedIn,
);
assert.match(
await app.invokeError("delete_cookie_bot_user_template", {
id: "00000000-0000-0000-0000-000000000000",
}),
notSignedIn,
);
assert.match(
await app.invokeError("check_cookie_bot_conflicts", {
profileId: missingProfileId,
+29 -1
View File
@@ -22,6 +22,30 @@ test("fresh app renders, completes onboarding, persists settings, and never touc
true,
);
// Where the app draws its own titlebar it also owns the window controls,
// so it needs the desktop's button layout to know which side they go on.
const decorations = await app.invoke("get_window_decoration_layout");
assert.equal(typeof decorations?.client_side, "boolean");
if (decorations.client_side) {
// Only reported where decorations were actually dropped, which is
// every Linux session except KDE on Wayland.
assert.equal(process.platform, "linux");
// `layout` may be null when GtkSettings is unavailable; the frontend
// falls back to the default arrangement rather than drawing nothing,
// so asserting a string here would be stricter than the contract.
if (decorations.layout !== null) {
assert.equal(typeof decorations.layout, "string");
assert.match(
decorations.layout,
/close|minimize|maximize/,
`layout must name a drawable control, got: ${decorations.layout}`,
);
}
} else {
// The platform still draws a titlebar; the app must not draw a second.
assert.equal(decorations.layout, null);
}
const saved = await app.invoke("save_app_settings", {
settings: {
...initial,
@@ -113,8 +137,12 @@ test("keyboard command palette and major navigation surfaces are operable throug
assert.match(body, /Settings/i);
// Exercise native WebDriver element marshalling and click, not just script execution.
// Scoped to the open dialog on purpose: on Linux the app draws its own
// titlebar, whose "Close window" control appears earlier in the DOM, and
// clicking that would exercise the window lifecycle instead of the palette.
const close = await app.execute(
`return [...document.querySelectorAll("button")].find(
`const dialog = document.querySelector("[role='dialog']") ?? document;
return [...dialog.querySelectorAll("button")].find(
(button) => /close/i.test(button.getAttribute("aria-label") || button.textContent || "")
) ?? null;`,
);
+17 -1
View File
@@ -474,7 +474,7 @@ test("VLESS proxy form keeps the share URI as one clear, validated input", async
await app.clickSelector('[aria-label="New proxy"]');
await app.waitForText("Add Proxy");
await app.fillSelector("#proxy-name", "E2E VLESS");
await chooseSelectOption(app, "#proxy-type", "VLESS · Vision · REALITY");
await chooseSelectOption(app, "#proxy-type", "VLESS");
assert.equal(
await app.execute(
@@ -512,6 +512,22 @@ test("VLESS proxy form keeps the share URI as one clear, validated input", async
true,
);
// A well-formed URI for a setup Donut cannot use must say WHICH part is
// unsupported, rather than implying the user mistyped it.
await app.fillSelector(
"#proxy-vless-uri",
`${uri.replace("type=tcp", "type=ws")}&path=%2Fray`,
);
await app.waitFor(
() =>
app.execute(
`return /only|TCP|transport/i.test(
document.querySelector("#proxy-vless-uri-help")?.textContent || ""
);`,
),
{ description: "transport-specific unsupported message" },
);
await app.fillSelector("#proxy-vless-uri", uri);
await app.waitFor(
() =>