| 1 | // Unit coverage for trajectory redaction: every text-entry argument, including |
| 2 | // run_actions steps and the merged clipboard tool, is replaced before writing. |
| 3 | import { test } from "node:test"; |
| 4 | import assert from "node:assert/strict"; |
| 5 | import { redactCall, REDACTED } from "../src/trajectory.mjs"; |
| 6 | |
| 7 | test("redactCall removes entered text from every text-entry tool", () => { |
| 8 | for (const [tool, args, field] of [ |
| 9 | ["type", { text: "pw", press_enter: true }, "text"], |
| 10 | ["set_value", { value: "pw", target: { type: "element", index: 1 } }, "value"], |
| 11 | ["browser_type", { text: "pw", selector: "#p" }, "text"], |
| 12 | ["clipboard", { action: "write", text: "pw" }, "text"], |
| 13 | ["write_clipboard", { text: "pw" }, "text"], |
| 14 | ]) { |
| 15 | const r = redactCall(tool, args); |
| 16 | assert.equal(r.redacted, true, tool); |
| 17 | assert.equal(r.args[field], REDACTED, tool); |
| 18 | assert.equal(args[field], "pw", "the live call's arguments are not mutated"); |
| 19 | } |
| 20 | const steps = redactCall("run_actions", { steps: [{ tool: "left_click", arguments: { target: { type: "element", index: 2 } } }, { tool: "type", arguments: { text: "pw" } }] }); |
| 21 | assert.equal(steps.redacted, true); |
| 22 | assert.equal(steps.args.steps[1].arguments.text, REDACTED); |
| 23 | assert.deepEqual(steps.args.steps[0].arguments, { target: { type: "element", index: 2 } }); |
| 24 | const plain = redactCall("left_click", { target: { type: "coordinate", x: 1, y: 2 } }); |
| 25 | assert.equal(plain.redacted, false); |
| 26 | assert.equal(redactCall("key", { text: "return" }).redacted, false, "key names are not entered text"); |
| 27 | }); |
| 28 |