mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(ui): satisfy picker lint gates
Use explicit model option mapping, remove stale E2E locals, and keep the Cron behavior suite within its enforced line budget.
This commit is contained in:
@@ -130,22 +130,13 @@ suite.define(() => {
|
||||
await page.goto(`${suite.server.baseUrl}chat`);
|
||||
|
||||
const main = page.getByRole("main");
|
||||
const openModelSelect = async () => {
|
||||
const trigger = main.locator(
|
||||
'openclaw-chat-pane[aria-hidden="false"] wa-select.chat-controls__model-picker',
|
||||
);
|
||||
await trigger.waitFor({ state: "visible", timeout: 10_000 });
|
||||
return trigger;
|
||||
};
|
||||
const activePane = () => main.locator('openclaw-chat-pane[aria-hidden="false"]');
|
||||
const selectModel = async (value: string) => {
|
||||
const activePane = main.locator('openclaw-chat-pane[aria-hidden="false"]');
|
||||
await selectChatModel(activePane, value);
|
||||
await selectChatModel(activePane(), value);
|
||||
};
|
||||
|
||||
let modelSelect = await openModelSelect();
|
||||
expect(await chatModelValue(main.locator('openclaw-chat-pane[aria-hidden="false"]'))).toBe(
|
||||
"",
|
||||
);
|
||||
await chatModelPicker(activePane()).waitFor({ state: "visible", timeout: 10_000 });
|
||||
expect(await chatModelValue(activePane())).toBe("");
|
||||
|
||||
await selectModel("bedrock/claude-opus-4.5");
|
||||
const patchRequest = await gateway.waitForRequest("sessions.patch");
|
||||
@@ -153,9 +144,7 @@ suite.define(() => {
|
||||
key: "agent:main:session-a",
|
||||
model: "bedrock/claude-opus-4.5",
|
||||
});
|
||||
expect(await chatModelValue(main.locator('openclaw-chat-pane[aria-hidden="false"]'))).toBe(
|
||||
"bedrock/claude-opus-4.5",
|
||||
);
|
||||
expect(await chatModelValue(activePane())).toBe("bedrock/claude-opus-4.5");
|
||||
|
||||
await page
|
||||
.locator(
|
||||
@@ -165,10 +154,8 @@ suite.define(() => {
|
||||
await page.locator(".sidebar-recent-session--active").getByText("Session B").waitFor({
|
||||
timeout: 10_000,
|
||||
});
|
||||
modelSelect = await openModelSelect();
|
||||
expect(await chatModelValue(main.locator('openclaw-chat-pane[aria-hidden="false"]'))).toBe(
|
||||
"",
|
||||
);
|
||||
await chatModelPicker(activePane()).waitFor({ state: "visible", timeout: 10_000 });
|
||||
expect(await chatModelValue(activePane())).toBe("");
|
||||
|
||||
await page
|
||||
.locator(
|
||||
@@ -179,10 +166,8 @@ suite.define(() => {
|
||||
timeout: 10_000,
|
||||
});
|
||||
|
||||
modelSelect = await openModelSelect();
|
||||
expect(await chatModelValue(main.locator('openclaw-chat-pane[aria-hidden="false"]'))).toBe(
|
||||
"bedrock/claude-opus-4.5",
|
||||
);
|
||||
await chatModelPicker(activePane()).waitFor({ state: "visible", timeout: 10_000 });
|
||||
expect(await chatModelValue(activePane())).toBe("bedrock/claude-opus-4.5");
|
||||
} finally {
|
||||
await suite.closeBrowserContext(context);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,6 @@ suite.define(() => {
|
||||
});
|
||||
await expect.poll(() => effortSelect.getAttribute("data-chat-thinking-value")).toBe("xhigh");
|
||||
|
||||
const modelSelect = newSessionModelPicker(page);
|
||||
await selectNewSessionModel(page, "openai/gpt-5.6-sol");
|
||||
await effortSelect.click();
|
||||
|
||||
@@ -366,7 +365,6 @@ suite.define(() => {
|
||||
await page.getByRole("button", { name: "Worktree" }).click();
|
||||
await page.keyboard.press("Escape");
|
||||
|
||||
const modelSelect = newSessionModelPicker(page);
|
||||
await selectNewSessionModel(page, "anthropic/claude-sonnet-4-6");
|
||||
const effortSelect = page.locator('[data-chat-thinking-select="true"]');
|
||||
await effortSelect.click();
|
||||
@@ -582,7 +580,6 @@ suite.define(() => {
|
||||
.toBe(1);
|
||||
|
||||
await gateway.deferNext("users.prefs.set");
|
||||
const modelSelect = newSessionModelPicker(page);
|
||||
await selectNewSessionModel(page, "");
|
||||
await expect
|
||||
.poll(async () => (await gateway.getRequests("users.prefs.set")).length)
|
||||
@@ -665,7 +662,6 @@ suite.define(() => {
|
||||
await placeTrigger.click();
|
||||
await page.getByRole("button", { name: "Worktree" }).click();
|
||||
await page.keyboard.press("Escape");
|
||||
const modelSelect = newSessionModelPicker(page);
|
||||
await selectNewSessionModel(page, "anthropic/claude-sonnet-4-6");
|
||||
|
||||
await navigateInApp(page, "chat");
|
||||
@@ -747,7 +743,6 @@ suite.define(() => {
|
||||
"openclaw-next",
|
||||
);
|
||||
|
||||
const modelSelect = newSessionModelPicker(page);
|
||||
await selectNewSessionModel(page, "anthropic/claude-sonnet-4-6");
|
||||
const storedPreference = await readMainPreference(page);
|
||||
expect(storedPreference).toMatchObject({
|
||||
|
||||
@@ -378,7 +378,7 @@ function renderField(props: DreamingSettingsProps, spec: DreamingFieldSpec) {
|
||||
placeholder: spec.placeholderKey ? t(spec.placeholderKey) : "",
|
||||
commit: "change",
|
||||
},
|
||||
onChange: (value) => props.onPatch(spec.path, value.trim() || undefined),
|
||||
onChange: (model) => props.onPatch(spec.path, model.trim() || undefined),
|
||||
})}
|
||||
`,
|
||||
});
|
||||
|
||||
@@ -117,7 +117,12 @@ export function renderSessionObserverSettings(props: {
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...options.map((option) => ({ ...option, disabled: props.modelsUnavailable })),
|
||||
...options.map(({ value, label, provider }) => ({
|
||||
value,
|
||||
label,
|
||||
provider,
|
||||
disabled: props.modelsUnavailable,
|
||||
})),
|
||||
],
|
||||
disabled: props.disabled,
|
||||
onChange: (value) =>
|
||||
|
||||
@@ -249,7 +249,7 @@ function renderModelRow(props: TalkViewProps) {
|
||||
control: renderModelPicker({
|
||||
label: t("talkPage.model.title"),
|
||||
value: model ?? TALK_PICKER_UNSET,
|
||||
options: options.map((option) => ({ ...option, provider: provider.id })),
|
||||
options: options.map(({ value, label }) => ({ value, label, provider: provider.id })),
|
||||
disabled: props.configBusy,
|
||||
onChange: (value) => props.onModelChange(value || null),
|
||||
}),
|
||||
|
||||
@@ -534,7 +534,7 @@ describe("cron view editor", () => {
|
||||
prompt.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
expect(onFormChange).toHaveBeenCalledWith({ payloadText: "do the thing" });
|
||||
|
||||
for (const field of ["name", "sessionKey", "deliveryAccountId"] as const) {
|
||||
for (const field of ["name", "sessionKey", "deliveryAccountId", "payloadModel"] as const) {
|
||||
const id = `cron-${field.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}`;
|
||||
const input = getElement(container, `#${id}`, HTMLInputElement);
|
||||
if (field === "sessionKey" || field === "deliveryAccountId") {
|
||||
@@ -545,26 +545,6 @@ describe("cron view editor", () => {
|
||||
expect(onFormChange).toHaveBeenLastCalledWith({ [field]: field });
|
||||
}
|
||||
|
||||
const modelPicker = getElement(
|
||||
container,
|
||||
"#cron-payload-model-picker",
|
||||
HTMLElement,
|
||||
) as HTMLElement & { value: string };
|
||||
const customModel = Array.from(modelPicker.querySelectorAll("wa-option")).find(
|
||||
(option) => option.textContent?.trim() === "Custom model…",
|
||||
);
|
||||
Object.defineProperty(modelPicker, "value", {
|
||||
configurable: true,
|
||||
value: customModel?.getAttribute("value"),
|
||||
});
|
||||
modelPicker.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
Reflect.deleteProperty(modelPicker, "value");
|
||||
const modelInput = getElement(container, "#cron-payload-model", HTMLInputElement);
|
||||
expect(modelInput.hidden).toBe(false);
|
||||
modelInput.value = "vendor/model with spaces";
|
||||
modelInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
expect(onFormChange).toHaveBeenLastCalledWith({ payloadModel: "vendor/model with spaces" });
|
||||
|
||||
const channel = getElement(
|
||||
container,
|
||||
"#cron-failure-alert-channel",
|
||||
@@ -575,7 +555,6 @@ describe("cron view editor", () => {
|
||||
expect(
|
||||
Array.from(channel.querySelectorAll("wa-option"), (option) => option.getAttribute("value")),
|
||||
).toContain("retired-channel");
|
||||
expect(channel.localName).toBe("wa-select");
|
||||
expect(channel.querySelector('wa-option[value="telegram"] img')).not.toBeNull();
|
||||
expect(
|
||||
(channel.querySelector('wa-option[value="telegram"]') as HTMLElement & { label?: string })
|
||||
|
||||
@@ -1242,7 +1242,7 @@ function renderPromptSection(
|
||||
const modelError = props.fieldErrors.payloadModel;
|
||||
const modelOptions = uniqueStrings(props.modelSuggestions).map((value) => {
|
||||
const provider = providerIdFromModelRef(value);
|
||||
return { value, label: value, ...(provider ? { provider } : {}) };
|
||||
return { value, label: value, provider: provider ?? undefined };
|
||||
});
|
||||
const agentTurnRows = ctx.isAgentTurn
|
||||
? html`
|
||||
|
||||
Reference in New Issue
Block a user