refactor: better logs

This commit is contained in:
zhom committed 2026-10-10 01:11:04 +04:00
1 parent 2604994507
commit bf625fac2c
91 files changed
+4353 -3239

No files matched your search

+1 -1
View File
@@ -1706,7 +1706,7 @@ dependencies = [
[[package]]
name = "donutbrowser"
version = "0.31.3"
version = "0.32.0"
dependencies = [
"aes 0.9.3",
"aes-gcm 0.11.1",
+5 -1
View File
@@ -345,9 +345,13 @@ test("real Wayfern fingerprinting, terms, API automation, CDP, cookies, and proc
// The new-profile form (which needs a downloaded browser and its release
// types, so it renders here and not in the UI suite): session restore is
// on by default and the checkbox is a live control.
// on by default and the checkbox is a live control. It sits under the
// collapsed advanced options.
await app.clickSelector('[aria-label="Profiles"]');
await app.clickText("New");
await app.clickText(en.createProfile.advancedOptions, {
roles: ["button"],
});
const restoreChecked = () =>
app.execute(
`return document.querySelector("#restore-session")?.getAttribute("aria-checked") ?? null;`,
+23 -1
View File
@@ -1,5 +1,5 @@
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { readdir, readFile } from "node:fs/promises";
import path from "node:path";
import test from "node:test";
import { appFromEnvironment, withApp } from "../lib/app.mjs";
@@ -351,6 +351,28 @@ test("tray labels, hide-to-tray, and confirmed quit follow the native lifecycle"
);
app.session = null;
await exitingSession.close().catch(() => {});
// Agents read this file: each session opens with its facts, closes with
// what outlives it, and no line repeats the crate name.
const logDir = path.join(app.dataRoot, "logs");
const logText = (
await Promise.all(
(
await readdir(logDir)
)
.filter((name) => name.endsWith(".log"))
.map((name) => readFile(path.join(logDir, name), "utf8")),
)
).join("\n");
assert.match(
logText,
/\[app\]\[INFO\] Donut started version=\S+ os="[^"]+" arch=\S+ pid=\d+ /,
);
assert.match(
logText,
/\[app\]\[INFO\] Donut exiting browsers=\[\] proxy_workers=\[\] vpn_workers=\[\] xray_workers=\[\]/,
);
assert.doesNotMatch(logText, /donutbrowser_lib::/);
} catch (error) {
await app.capture("failure");
throw error;
+37 -1
View File
@@ -60,6 +60,25 @@ async function tableRows(app, tableId) {
);
}
/** Selection checkboxes, and the browser icons that stand in for them, that sit
* more than half a pixel off the center of their cell. */
async function offCenterSelectionControls(app, tableSelector) {
return app.execute(
`return [...document.querySelectorAll(arguments[0] + ' :is(th, td) :is([role="checkbox"], [role="checkbox"] + [aria-hidden="true"] > svg)')]
.map((node) => {
const cell = node.closest("th, td").getBoundingClientRect();
const rect = node.getBoundingClientRect();
return {
control: node.getAttribute("aria-label") ?? "icon",
x: rect.left + rect.width / 2 - (cell.left + cell.width / 2),
y: rect.top + rect.height / 2 - (cell.top + cell.height / 2),
};
})
.filter(({ x, y }) => Math.abs(x) > 0.5 || Math.abs(y) > 0.5);`,
[tableSelector],
);
}
async function tableShiftClick(app, selector) {
// tauri-wd 0.2.1 omits modifiers from pointer events. Send the click with
// Shift through the native WebView; the real checkbox handler selects rows.
@@ -479,6 +498,10 @@ test("profile table filters, range selection, view settings, and keyboard edits
);
assert.deepEqual(chrome.controls, ["0px", "0px", "0px"]);
assert.equal(chrome.rowRules, 0, "rows are not divided by rules");
assert.deepEqual(
await offCenterSelectionControls(app, '[data-table-id="profiles"]'),
[],
);
const row = (index) => `tr[data-table-row="${profiles[index].id}"]`;
await app.clickSelector(`${row(0)} [role="checkbox"]`);
await tableShiftClick(app, `${row(3)} [role="checkbox"]`);
@@ -502,7 +525,9 @@ test("profile table filters, range selection, view settings, and keyboard edits
/4/,
);
const searchSelector = `input[placeholder="${en.header.searchPlaceholder}"]`;
await app.fillSelector(searchSelector, "Table 02");
// Quoted: an unquoted "02" is its own term, which also prefix-matches
// any profile whose random id starts with 02.
await app.fillSelector(searchSelector, '"Table 02"');
await app.waitFor(
async () =>
JSON.stringify(await tableRows(app, "profiles")) ===
@@ -746,6 +771,10 @@ test("management tables share search, filters, selection, and saved views", asyn
async () => (await tableRows(app, "proxies")).length === 3,
{ description: "proxy table" },
);
assert.deepEqual(
await offCenterSelectionControls(app, '[data-table-id="proxies"]'),
[],
);
const proxyRowHeight = () =>
app.execute(
`return document.querySelector('[data-table-id="proxies"] tr[data-table-row]')?.getBoundingClientRect().height;`,
@@ -2919,6 +2948,13 @@ test("the agent page guides setup, then shows agents, requests, notes, take-over
const row = await waitPainted(`agent-profile-${profile.id}`);
assert.match(row, /Agent UI Profile/);
assert.match(row, /LOCATOR_NO_MATCH/);
assert.deepEqual(
await offCenterSelectionControls(
app,
'[data-testid="agent-profiles"]',
),
[],
);
await app.clickSelector(
`[data-testid="agent-profile-${profile.id}"] [data-testid="agent-take-over"]`,
);