mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-08 15:51:06 +00:00
test: stabilize gateway wizard e2e flow
This commit is contained in:
@@ -103,6 +103,7 @@ describe("gateway e2e", () => {
|
||||
"OPENCLAW_SKIP_CRON",
|
||||
"OPENCLAW_SKIP_CANVAS_HOST",
|
||||
"OPENCLAW_SKIP_BROWSER_CONTROL_SERVER",
|
||||
"OPENCLAW_TEST_MINIMAL_GATEWAY",
|
||||
]);
|
||||
|
||||
const { baseUrl: openaiBaseUrl, restore } = installOpenAiResponsesMock();
|
||||
@@ -116,6 +117,7 @@ describe("gateway e2e", () => {
|
||||
process.env.OPENCLAW_SKIP_CRON = "1";
|
||||
process.env.OPENCLAW_SKIP_CANVAS_HOST = "1";
|
||||
process.env.OPENCLAW_SKIP_BROWSER_CONTROL_SERVER = "1";
|
||||
process.env.OPENCLAW_TEST_MINIMAL_GATEWAY = "1";
|
||||
|
||||
const token = nextGatewayId("test-token");
|
||||
process.env.OPENCLAW_GATEWAY_TOKEN = token;
|
||||
@@ -309,6 +311,7 @@ module.exports = {
|
||||
"OPENCLAW_SKIP_CRON",
|
||||
"OPENCLAW_SKIP_CANVAS_HOST",
|
||||
"OPENCLAW_SKIP_BROWSER_CONTROL_SERVER",
|
||||
"OPENCLAW_TEST_MINIMAL_GATEWAY",
|
||||
]);
|
||||
|
||||
process.env.OPENCLAW_SKIP_CHANNELS = "1";
|
||||
@@ -316,6 +319,7 @@ module.exports = {
|
||||
process.env.OPENCLAW_SKIP_CRON = "1";
|
||||
process.env.OPENCLAW_SKIP_CANVAS_HOST = "1";
|
||||
process.env.OPENCLAW_SKIP_BROWSER_CONTROL_SERVER = "1";
|
||||
process.env.OPENCLAW_TEST_MINIMAL_GATEWAY = "1";
|
||||
delete process.env.OPENCLAW_GATEWAY_TOKEN;
|
||||
|
||||
const tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-wizard-home-"));
|
||||
@@ -362,22 +366,30 @@ module.exports = {
|
||||
|
||||
let next = start;
|
||||
let didSendToken = false;
|
||||
const seenSteps: string[] = [];
|
||||
while (!next.done) {
|
||||
const step = next.step;
|
||||
if (!step) {
|
||||
throw new Error("wizard missing step");
|
||||
}
|
||||
seenSteps.push(`${step.type}:${step.id}`);
|
||||
const value = step.type === "text" ? wizardToken : null;
|
||||
if (step.type === "text") {
|
||||
didSendToken = true;
|
||||
}
|
||||
next = await client.request("wizard.next", {
|
||||
sessionId,
|
||||
answer: { stepId: step.id, value },
|
||||
});
|
||||
next = await client.request(
|
||||
"wizard.next",
|
||||
{
|
||||
sessionId,
|
||||
answer: { stepId: step.id, value },
|
||||
},
|
||||
{ timeoutMs: 60_000 },
|
||||
);
|
||||
}
|
||||
|
||||
expect(didSendToken).toBe(true);
|
||||
expect(didSendToken, `seenSteps=${seenSteps.join(",")} final=${JSON.stringify(next)}`).toBe(
|
||||
true,
|
||||
);
|
||||
expect(next.status).toBe("done");
|
||||
|
||||
const parsed = JSON.parse(await fs.readFile(resolveConfigPath(), "utf8"));
|
||||
|
||||
@@ -71,4 +71,23 @@ describe("WizardSession", () => {
|
||||
expect(done.done).toBe(true);
|
||||
expect(done.status).toBe("cancelled");
|
||||
});
|
||||
|
||||
test("does not lose terminal completion when the last answer finishes the runner immediately", async () => {
|
||||
const session = new WizardSession(async (prompter) => {
|
||||
await prompter.text({ message: "Token" });
|
||||
});
|
||||
|
||||
const first = await session.next();
|
||||
expect(first.step?.type).toBe("text");
|
||||
if (!first.step) {
|
||||
throw new Error("expected first step");
|
||||
}
|
||||
|
||||
await session.answer(first.step.id, "ok");
|
||||
await Promise.resolve();
|
||||
|
||||
const done = await session.next();
|
||||
expect(done.done).toBe(true);
|
||||
expect(done.status).toBe("done");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -163,6 +163,7 @@ class WizardSessionPrompter implements WizardPrompter {
|
||||
export class WizardSession {
|
||||
private currentStep: WizardStep | null = null;
|
||||
private stepDeferred: Deferred<WizardStep | null> | null = null;
|
||||
private pendingTerminalResolution = false;
|
||||
private answerDeferred = new Map<string, Deferred<unknown>>();
|
||||
private status: WizardSessionStatus = "running";
|
||||
private error: string | undefined;
|
||||
@@ -176,6 +177,10 @@ export class WizardSession {
|
||||
if (this.currentStep) {
|
||||
return { done: false, step: this.currentStep, status: this.status };
|
||||
}
|
||||
if (this.pendingTerminalResolution) {
|
||||
this.pendingTerminalResolution = false;
|
||||
return { done: true, status: this.status, error: this.error };
|
||||
}
|
||||
if (this.status !== "running") {
|
||||
return { done: true, status: this.status, error: this.error };
|
||||
}
|
||||
@@ -247,6 +252,9 @@ export class WizardSession {
|
||||
|
||||
private resolveStep(step: WizardStep | null) {
|
||||
if (!this.stepDeferred) {
|
||||
if (step === null) {
|
||||
this.pendingTerminalResolution = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const deferred = this.stepDeferred;
|
||||
|
||||
Reference in New Issue
Block a user