refactor(tests): dedupe browser and telegram tool test fixtures

This commit is contained in:
Peter Steinberger
2026-03-03 01:22:40 +00:00
parent a3b674cc98
commit c1b37f29f0
2 changed files with 112 additions and 122 deletions

View File

@@ -108,16 +108,33 @@ function mockSingleBrowserProxyNode() {
]);
}
describe("browser tool snapshot maxChars", () => {
function resetBrowserToolMocks() {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
}
function registerBrowserToolAfterEachReset() {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
resetBrowserToolMocks();
});
}
async function runSnapshotToolCall(params: {
snapshotFormat: "ai" | "aria";
refs?: "aria" | "dom";
maxChars?: number;
profile?: string;
}) {
const tool = createBrowserTool();
await tool.execute?.("call-1", { action: "snapshot", ...params });
}
describe("browser tool snapshot maxChars", () => {
registerBrowserToolAfterEachReset();
it("applies the default ai snapshot limit", async () => {
const tool = createBrowserTool();
await tool.execute?.("call-1", { action: "snapshot", snapshotFormat: "ai" });
await runSnapshotToolCall({ snapshotFormat: "ai" });
expect(browserClientMocks.browserSnapshot).toHaveBeenCalledWith(
undefined,
@@ -184,8 +201,7 @@ describe("browser tool snapshot maxChars", () => {
configMocks.loadConfig.mockReturnValue({
browser: { snapshotDefaults: { mode: "efficient" } },
});
const tool = createBrowserTool();
await tool.execute?.("call-1", { action: "snapshot", snapshotFormat: "ai" });
await runSnapshotToolCall({ snapshotFormat: "ai" });
expect(browserClientMocks.browserSnapshot).toHaveBeenCalledWith(
undefined,
@@ -263,11 +279,7 @@ describe("browser tool snapshot maxChars", () => {
});
describe("browser tool url alias support", () => {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
});
registerBrowserToolAfterEachReset();
it("accepts url alias for open", async () => {
const tool = createBrowserTool();
@@ -308,11 +320,7 @@ describe("browser tool url alias support", () => {
});
describe("browser tool act compatibility", () => {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
});
registerBrowserToolAfterEachReset();
it("accepts flattened act params for backward compatibility", async () => {
const tool = createBrowserTool();
@@ -364,10 +372,7 @@ describe("browser tool act compatibility", () => {
});
describe("browser tool snapshot labels", () => {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
});
registerBrowserToolAfterEachReset();
it("returns image + text when labels are requested", async () => {
const tool = createBrowserTool();
@@ -409,11 +414,7 @@ describe("browser tool snapshot labels", () => {
});
describe("browser tool external content wrapping", () => {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
});
registerBrowserToolAfterEachReset();
it("wraps aria snapshots as external content", async () => {
browserClientMocks.browserSnapshot.mockResolvedValueOnce({
@@ -525,11 +526,7 @@ describe("browser tool external content wrapping", () => {
});
describe("browser tool act stale target recovery", () => {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
});
registerBrowserToolAfterEachReset();
it("retries chrome act once without targetId when tab id is stale", async () => {
browserActionsMocks.browserAct

View File

@@ -51,6 +51,22 @@ describe("handleTelegramAction", () => {
} as OpenClawConfig;
}
async function sendInlineButtonsMessage(params: {
to: string;
buttons: Array<Array<{ text: string; callback_data: string; style?: string }>>;
inlineButtons: "dm" | "group" | "all";
}) {
await handleTelegramAction(
{
action: "sendMessage",
to: params.to,
content: "Choose",
buttons: params.buttons,
},
telegramConfig({ capabilities: { inlineButtons: params.inlineButtons } }),
);
}
async function expectReactionAdded(reactionLevel: "minimal" | "extensive") {
await handleTelegramAction(defaultReactionAction, reactionConfig(reactionLevel));
expect(reactMessageTelegram).toHaveBeenCalledWith(
@@ -103,9 +119,6 @@ describe("handleTelegramAction", () => {
});
it("accepts snake_case message_id for reactions", async () => {
const cfg = {
channels: { telegram: { botToken: "tok", reactionLevel: "minimal" } },
} as OpenClawConfig;
await handleTelegramAction(
{
action: "react",
@@ -113,7 +126,7 @@ describe("handleTelegramAction", () => {
message_id: "456",
emoji: "✅",
},
cfg,
reactionConfig("minimal"),
);
expect(reactMessageTelegram).toHaveBeenCalledWith(
"123",
@@ -143,9 +156,6 @@ describe("handleTelegramAction", () => {
});
it("removes reactions on empty emoji", async () => {
const cfg = {
channels: { telegram: { botToken: "tok", reactionLevel: "minimal" } },
} as OpenClawConfig;
await handleTelegramAction(
{
action: "react",
@@ -153,7 +163,7 @@ describe("handleTelegramAction", () => {
messageId: "456",
emoji: "",
},
cfg,
reactionConfig("minimal"),
);
expect(reactMessageTelegram).toHaveBeenCalledWith(
"123",
@@ -476,44 +486,29 @@ describe("handleTelegramAction", () => {
});
it("allows inline buttons in DMs with tg: prefixed targets", async () => {
const cfg = telegramConfig({ capabilities: { inlineButtons: "dm" } });
await handleTelegramAction(
{
action: "sendMessage",
to: "tg:5232990709",
content: "Choose",
buttons: [[{ text: "Ok", callback_data: "cmd:ok" }]],
},
cfg,
);
await sendInlineButtonsMessage({
to: "tg:5232990709",
buttons: [[{ text: "Ok", callback_data: "cmd:ok" }]],
inlineButtons: "dm",
});
expect(sendMessageTelegram).toHaveBeenCalled();
});
it("allows inline buttons in groups with topic targets", async () => {
const cfg = telegramConfig({ capabilities: { inlineButtons: "group" } });
await handleTelegramAction(
{
action: "sendMessage",
to: "telegram:group:-1001234567890:topic:456",
content: "Choose",
buttons: [[{ text: "Ok", callback_data: "cmd:ok" }]],
},
cfg,
);
await sendInlineButtonsMessage({
to: "telegram:group:-1001234567890:topic:456",
buttons: [[{ text: "Ok", callback_data: "cmd:ok" }]],
inlineButtons: "group",
});
expect(sendMessageTelegram).toHaveBeenCalled();
});
it("sends messages with inline keyboard buttons when enabled", async () => {
const cfg = telegramConfig({ capabilities: { inlineButtons: "all" } });
await handleTelegramAction(
{
action: "sendMessage",
to: "@testchannel",
content: "Choose",
buttons: [[{ text: " Option A ", callback_data: " cmd:a " }]],
},
cfg,
);
await sendInlineButtonsMessage({
to: "@testchannel",
buttons: [[{ text: " Option A ", callback_data: " cmd:a " }]],
inlineButtons: "all",
});
expect(sendMessageTelegram).toHaveBeenCalledWith(
"@testchannel",
"Choose",
@@ -524,24 +519,19 @@ describe("handleTelegramAction", () => {
});
it("forwards optional button style", async () => {
const cfg = telegramConfig({ capabilities: { inlineButtons: "all" } });
await handleTelegramAction(
{
action: "sendMessage",
to: "@testchannel",
content: "Choose",
buttons: [
[
{
text: "Option A",
callback_data: "cmd:a",
style: "primary",
},
],
await sendInlineButtonsMessage({
to: "@testchannel",
inlineButtons: "all",
buttons: [
[
{
text: "Option A",
callback_data: "cmd:a",
style: "primary",
},
],
},
cfg,
);
],
});
expect(sendMessageTelegram).toHaveBeenCalledWith(
"@testchannel",
"Choose",
@@ -601,6 +591,25 @@ describe("readTelegramButtons", () => {
});
describe("handleTelegramAction per-account gating", () => {
function accountTelegramConfig(params: {
accounts: Record<
string,
{ botToken: string; actions?: { sticker?: boolean; reactions?: boolean } }
>;
topLevelBotToken?: string;
topLevelActions?: { reactions?: boolean };
}): OpenClawConfig {
return {
channels: {
telegram: {
...(params.topLevelBotToken ? { botToken: params.topLevelBotToken } : {}),
...(params.topLevelActions ? { actions: params.topLevelActions } : {}),
accounts: params.accounts,
},
},
} as OpenClawConfig;
}
async function expectAccountStickerSend(cfg: OpenClawConfig, accountId = "media") {
await handleTelegramAction(
{ action: "sendSticker", to: "123", fileId: "sticker-id", accountId },
@@ -614,15 +623,11 @@ describe("handleTelegramAction per-account gating", () => {
}
it("allows sticker when account config enables it", async () => {
const cfg = {
channels: {
telegram: {
accounts: {
media: { botToken: "tok-media", actions: { sticker: true } },
},
},
const cfg = accountTelegramConfig({
accounts: {
media: { botToken: "tok-media", actions: { sticker: true } },
},
} as OpenClawConfig;
});
await expectAccountStickerSend(cfg);
});
@@ -647,30 +652,22 @@ describe("handleTelegramAction per-account gating", () => {
it("uses account-merged config, not top-level config", async () => {
// Top-level has no sticker enabled, but the account does
const cfg = {
channels: {
telegram: {
botToken: "tok-base",
accounts: {
media: { botToken: "tok-media", actions: { sticker: true } },
},
},
const cfg = accountTelegramConfig({
topLevelBotToken: "tok-base",
accounts: {
media: { botToken: "tok-media", actions: { sticker: true } },
},
} as OpenClawConfig;
});
await expectAccountStickerSend(cfg);
});
it("inherits top-level reaction gate when account overrides sticker only", async () => {
const cfg = {
channels: {
telegram: {
actions: { reactions: false },
accounts: {
media: { botToken: "tok-media", actions: { sticker: true } },
},
},
const cfg = accountTelegramConfig({
topLevelActions: { reactions: false },
accounts: {
media: { botToken: "tok-media", actions: { sticker: true } },
},
} as OpenClawConfig;
});
const result = await handleTelegramAction(
{
@@ -689,16 +686,12 @@ describe("handleTelegramAction per-account gating", () => {
});
it("allows account to explicitly re-enable top-level disabled reaction gate", async () => {
const cfg = {
channels: {
telegram: {
actions: { reactions: false },
accounts: {
media: { botToken: "tok-media", actions: { sticker: true, reactions: true } },
},
},
const cfg = accountTelegramConfig({
topLevelActions: { reactions: false },
accounts: {
media: { botToken: "tok-media", actions: { sticker: true, reactions: true } },
},
} as OpenClawConfig;
});
await handleTelegramAction(
{