Align dictation controls with settings dropdowns and show setup guidance
This commit is contained in:
@@ -110,7 +110,9 @@ test("an initial load failure is visible and opening the menu again can retry",
|
||||
test("the real picker searches by language, chooses with Arrow/Enter, and restores focus", async () => {
|
||||
const f = await fixture();
|
||||
assert.match(trigger().textContent!, /English/);
|
||||
assert.equal(trigger().getAttribute("data-variant"), "outline");
|
||||
for (const token of ["h-7", "rounded-sm", "border-border", "bg-background", "font-ui", "text-xs"]) {
|
||||
assert.ok(trigger().className.split(" ").includes(token), `shared settings trigger: ${token}`);
|
||||
}
|
||||
await click(trigger());
|
||||
assert.match(input().className, /lh-input/);
|
||||
assert.equal(document.activeElement, input());
|
||||
@@ -226,9 +228,15 @@ for (const source of ["none", "file", "env"] as const) test(`Language is below t
|
||||
const rows = group.lastElementChild!.children;
|
||||
assert.equal(rows[0]!.getAttribute("data-testid"), "key-deepgram_api_key");
|
||||
assert.equal(rows[1]!.getAttribute("data-testid"), "row-dictation-language");
|
||||
assert.equal(rows[2]!.getAttribute("data-testid"), "dictation-setup-hint");
|
||||
assert.equal(byTest("dictation-setup-hint").textContent, "Create a Deepgram key with the Member role or higher, then add it above.");
|
||||
assert.match(byTest("dictation-setup-hint").className, /text-muted-foreground/);
|
||||
assert.equal(byTest("dictation-setup-hint").querySelector("a")!.href, "https://developers.deepgram.com/reference/auth/tokens/grant");
|
||||
assert.match(rows[1]!.querySelector("span")!.className, /font-ui text-xs/);
|
||||
assert.equal(trigger().disabled, false, "language is independent of key ownership");
|
||||
await click(byTest("key-deepgram_api_key-row"));
|
||||
if (source !== "env") assert.ok(byTest("key-deepgram_api_key-editor"));
|
||||
assert.ok(byTest("dictation-setup-hint"), "guidance remains visible while the key is edited");
|
||||
await click(trigger());
|
||||
assert(menu());
|
||||
await key(input(), "Escape");
|
||||
|
||||
@@ -19,6 +19,8 @@ import { KeyboardSection } from "../components/settings/keyboard-section.tsx";
|
||||
import type { GraphSettings } from "../src/core/index.ts";
|
||||
import { SettingsDialogBody, SettingsDialogProvider } from "../components/settings/settings-dialog.tsx";
|
||||
import { KEYBOARD_ACTIONS } from "../src/core/index.ts";
|
||||
import { DictationLanguageSetting } from "../components/dictation-language.tsx";
|
||||
import { SettingsMenuTrigger } from "../components/settings/controls.tsx";
|
||||
|
||||
/** The full opening tag of the element carrying a testid — attribute
|
||||
* order in React output is not contractual, so assertions run on the
|
||||
@@ -60,6 +62,33 @@ describe("SettingsDialog (the designed surface, SSR)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("the shared settings dropdown trigger", () => {
|
||||
it("Agent, Appearance and dictation use the same compact dark mono trigger", () => {
|
||||
const surfaces = [
|
||||
[renderToStaticMarkup(<AgentSection agent={undefined} models={undefined} graph={undefined} onSectionChange={() => {}} onModelsChange={() => {}} />), "slot-model-strong"],
|
||||
[renderToStaticMarkup(<AppearanceSection appearance={undefined} onSectionChange={() => {}} />), "font-trigger"],
|
||||
[renderToStaticMarkup(<DictationLanguageSetting />), "dictation-language"],
|
||||
] as const;
|
||||
for (const [html, id] of surfaces) {
|
||||
const tag = tagOf(html, id);
|
||||
const classes = tag.match(/class="([^"]+)"/)![1]!.split(" ");
|
||||
for (const token of ["h-7", "rounded-sm", "border", "border-border", "bg-background", "px-1.5", "font-ui", "text-xs", "hover:border-muted-foreground/50"]) {
|
||||
assert.ok(classes.includes(token), `${id}: ${token}`);
|
||||
}
|
||||
assert.ok(html.includes("▾"), `${id}: shared dropdown indicator`);
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves native disabling separately from callers' existing click-gated unavailable state", () => {
|
||||
const disabled = tagOf(renderToStaticMarkup(<SettingsMenuTrigger value="English" disabled data-testid="disabled-trigger" />), "disabled-trigger");
|
||||
const unavailable = tagOf(renderToStaticMarkup(<SettingsMenuTrigger value="Automatic" unavailable data-testid="unavailable-trigger" />), "unavailable-trigger");
|
||||
assert.ok(disabled.includes('disabled=""'));
|
||||
assert.ok(!unavailable.includes('disabled=""'));
|
||||
assert.ok(unavailable.includes("cursor-not-allowed"));
|
||||
assert.ok(!unavailable.includes("hover:border-muted-foreground/50"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("AgentSection (thin SSR)", () => {
|
||||
it("renders the three model SLOT rows (slots-only, fix wave: unpicked reads —, no Default option)", () => {
|
||||
const html = renderToStaticMarkup(<AgentSection agent={undefined} models={undefined} graph={undefined} onSectionChange={() => {}} onModelsChange={() => {}} />);
|
||||
|
||||
Reference in New Issue
Block a user