mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-10-19 14:07:19 +02:00
refactor: better logs
This commit is contained in:
1 parent
2604994507
commit
bf625fac2c
91 files changed
+4353
-3239
No files matched your search
Generated
+1
-1
@@ -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",
|
||||
|
||||
@@ -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;`,
|
||||
|
||||
@@ -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
@@ -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"]`,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user