test(e2e): stabilize suite

This commit is contained in:
Peter Steinberger
2026-02-14 20:54:31 +01:00
parent 2a3da21333
commit c06a962bb6
15 changed files with 238 additions and 84 deletions

View File

@@ -56,6 +56,23 @@ describe("models-config", () => {
const previousSynthetic = process.env.SYNTHETIC_API_KEY;
const previousVenice = process.env.VENICE_API_KEY;
const previousXiaomi = process.env.XIAOMI_API_KEY;
const previousOllama = process.env.OLLAMA_API_KEY;
const previousVllm = process.env.VLLM_API_KEY;
const previousTogether = process.env.TOGETHER_API_KEY;
const previousHuggingfaceHub = process.env.HUGGINGFACE_HUB_TOKEN;
const previousHuggingfaceHf = process.env.HF_TOKEN;
const previousQianfan = process.env.QIANFAN_API_KEY;
const previousNvidia = process.env.NVIDIA_API_KEY;
const previousAwsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
const previousAwsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
const previousAwsSessionToken = process.env.AWS_SESSION_TOKEN;
const previousAwsProfile = process.env.AWS_PROFILE;
const previousAwsRegion = process.env.AWS_REGION;
const previousAwsDefaultRegion = process.env.AWS_DEFAULT_REGION;
const previousAwsSharedCredentials = process.env.AWS_SHARED_CREDENTIALS_FILE;
const previousAwsConfigFile = process.env.AWS_CONFIG_FILE;
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
delete process.env.COPILOT_GITHUB_TOKEN;
delete process.env.GH_TOKEN;
delete process.env.GITHUB_TOKEN;
@@ -65,9 +82,29 @@ describe("models-config", () => {
delete process.env.SYNTHETIC_API_KEY;
delete process.env.VENICE_API_KEY;
delete process.env.XIAOMI_API_KEY;
delete process.env.OLLAMA_API_KEY;
delete process.env.VLLM_API_KEY;
delete process.env.TOGETHER_API_KEY;
delete process.env.HUGGINGFACE_HUB_TOKEN;
delete process.env.HF_TOKEN;
delete process.env.QIANFAN_API_KEY;
delete process.env.NVIDIA_API_KEY;
delete process.env.AWS_ACCESS_KEY_ID;
delete process.env.AWS_SECRET_ACCESS_KEY;
delete process.env.AWS_SESSION_TOKEN;
delete process.env.AWS_PROFILE;
delete process.env.AWS_REGION;
delete process.env.AWS_DEFAULT_REGION;
delete process.env.AWS_SHARED_CREDENTIALS_FILE;
delete process.env.AWS_CONFIG_FILE;
delete process.env.OPENCLAW_AGENT_DIR;
delete process.env.PI_CODING_AGENT_DIR;
try {
const agentDir = path.join(home, "agent-empty");
// Avoid merging in the user's real main auth store via OPENCLAW_AGENT_DIR.
process.env.OPENCLAW_AGENT_DIR = agentDir;
process.env.PI_CODING_AGENT_DIR = agentDir;
const result = await ensureOpenClawModelsJson(
{
models: { providers: {} },
@@ -123,6 +160,91 @@ describe("models-config", () => {
} else {
process.env.XIAOMI_API_KEY = previousXiaomi;
}
if (previousOllama === undefined) {
delete process.env.OLLAMA_API_KEY;
} else {
process.env.OLLAMA_API_KEY = previousOllama;
}
if (previousVllm === undefined) {
delete process.env.VLLM_API_KEY;
} else {
process.env.VLLM_API_KEY = previousVllm;
}
if (previousTogether === undefined) {
delete process.env.TOGETHER_API_KEY;
} else {
process.env.TOGETHER_API_KEY = previousTogether;
}
if (previousHuggingfaceHub === undefined) {
delete process.env.HUGGINGFACE_HUB_TOKEN;
} else {
process.env.HUGGINGFACE_HUB_TOKEN = previousHuggingfaceHub;
}
if (previousHuggingfaceHf === undefined) {
delete process.env.HF_TOKEN;
} else {
process.env.HF_TOKEN = previousHuggingfaceHf;
}
if (previousQianfan === undefined) {
delete process.env.QIANFAN_API_KEY;
} else {
process.env.QIANFAN_API_KEY = previousQianfan;
}
if (previousNvidia === undefined) {
delete process.env.NVIDIA_API_KEY;
} else {
process.env.NVIDIA_API_KEY = previousNvidia;
}
if (previousAwsAccessKeyId === undefined) {
delete process.env.AWS_ACCESS_KEY_ID;
} else {
process.env.AWS_ACCESS_KEY_ID = previousAwsAccessKeyId;
}
if (previousAwsSecretAccessKey === undefined) {
delete process.env.AWS_SECRET_ACCESS_KEY;
} else {
process.env.AWS_SECRET_ACCESS_KEY = previousAwsSecretAccessKey;
}
if (previousAwsSessionToken === undefined) {
delete process.env.AWS_SESSION_TOKEN;
} else {
process.env.AWS_SESSION_TOKEN = previousAwsSessionToken;
}
if (previousAwsProfile === undefined) {
delete process.env.AWS_PROFILE;
} else {
process.env.AWS_PROFILE = previousAwsProfile;
}
if (previousAwsRegion === undefined) {
delete process.env.AWS_REGION;
} else {
process.env.AWS_REGION = previousAwsRegion;
}
if (previousAwsDefaultRegion === undefined) {
delete process.env.AWS_DEFAULT_REGION;
} else {
process.env.AWS_DEFAULT_REGION = previousAwsDefaultRegion;
}
if (previousAwsSharedCredentials === undefined) {
delete process.env.AWS_SHARED_CREDENTIALS_FILE;
} else {
process.env.AWS_SHARED_CREDENTIALS_FILE = previousAwsSharedCredentials;
}
if (previousAwsConfigFile === undefined) {
delete process.env.AWS_CONFIG_FILE;
} else {
process.env.AWS_CONFIG_FILE = previousAwsConfigFile;
}
if (previousAgentDir === undefined) {
delete process.env.OPENCLAW_AGENT_DIR;
} else {
process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
}
if (previousPiAgentDir === undefined) {
delete process.env.PI_CODING_AGENT_DIR;
} else {
process.env.PI_CODING_AGENT_DIR = previousPiAgentDir;
}
}
});
});
@@ -158,7 +280,7 @@ describe("models-config", () => {
}
>;
};
expect(parsed.providers.minimax?.baseUrl).toBe("https://api.minimax.chat/v1");
expect(parsed.providers.minimax?.baseUrl).toBe("https://api.minimax.io/anthropic");
expect(parsed.providers.minimax?.apiKey).toBe("MINIMAX_API_KEY");
const ids = parsed.providers.minimax?.models?.map((model) => model.id);
expect(ids).toContain("MiniMax-M2.1");

View File

@@ -116,6 +116,7 @@ vi.mock("./logger.js", () => ({
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
isEnabled: vi.fn(() => false),
},
}));

View File

@@ -586,7 +586,7 @@ describe("Agent-specific tool filtering", () => {
const helperResult = await helperExecTool!.execute("call-helper", {
command: "echo done",
host: "sandbox",
yieldMs: 10,
yieldMs: 1000,
});
expect(helperResult?.details.status).toBe("completed");
});

View File

@@ -60,6 +60,7 @@ describe("loadWorkspaceSkillEntries", () => {
),
"utf-8",
);
await fs.writeFile(path.join(pluginRoot, "index.ts"), "export {};\n", "utf-8");
await fs.writeFile(
path.join(pluginRoot, "skills", "prose", "SKILL.md"),
`---\nname: prose\ndescription: test\n---\n`,
@@ -99,6 +100,7 @@ describe("loadWorkspaceSkillEntries", () => {
),
"utf-8",
);
await fs.writeFile(path.join(pluginRoot, "index.ts"), "export {};\n", "utf-8");
await fs.writeFile(
path.join(pluginRoot, "skills", "prose", "SKILL.md"),
`---\nname: prose\ndescription: test\n---\n`,

View File

@@ -44,6 +44,18 @@ type AnnounceQueueState = {
const ANNOUNCE_QUEUES = new Map<string, AnnounceQueueState>();
export function resetAnnounceQueuesForTests() {
// Test isolation: other suites may leave a draining queue behind in the worker.
// Clearing the map alone isn't enough because drain loops capture `queue` by reference.
for (const queue of ANNOUNCE_QUEUES.values()) {
queue.items.length = 0;
queue.summaryLines.length = 0;
queue.droppedCount = 0;
queue.lastEnqueuedAt = 0;
}
ANNOUNCE_QUEUES.clear();
}
function getAnnounceQueue(
key: string,
settings: AnnounceQueueSettings,

View File

@@ -2,6 +2,7 @@ import { loadConfig } from "../config/config.js";
import { callGateway } from "../gateway/call.js";
import { onAgentEvent } from "../infra/agent-events.js";
import { type DeliveryContext, normalizeDeliveryContext } from "../utils/delivery-context.js";
import { resetAnnounceQueuesForTests } from "./subagent-announce-queue.js";
import { runSubagentAnnounceFlow, type SubagentRunOutcome } from "./subagent-announce.js";
import {
loadSubagentRegistryFromDisk,
@@ -398,6 +399,7 @@ async function waitForSubagentCompletion(runId: string, waitTimeoutMs: number) {
export function resetSubagentRegistryForTests(opts?: { persist?: boolean }) {
subagentRuns.clear();
resumedRuns.clear();
resetAnnounceQueuesForTests();
stopSweeper();
restoreAttempted = false;
if (listenerStop) {

View File

@@ -299,7 +299,7 @@ describe("image tool MiniMax VLM routing", () => {
expect(fetch).toHaveBeenCalledTimes(1);
const [url, init] = fetch.mock.calls[0];
expect(String(url)).toBe("https://api.minimax.chat/v1/coding_plan/vlm");
expect(String(url)).toBe("https://api.minimax.io/v1/coding_plan/vlm");
expect(init?.method).toBe("POST");
expect(String((init?.headers as Record<string, string>)?.Authorization)).toBe(
"Bearer minimax-test",