diff --git a/docs/pr-assets/combo-strategy-selector-after.png b/docs/pr-assets/combo-strategy-selector-after.png new file mode 100644 index 0000000000..502bd0cc3a Binary files /dev/null and b/docs/pr-assets/combo-strategy-selector-after.png differ diff --git a/docs/pr-assets/combo-strategy-selector-before.png b/docs/pr-assets/combo-strategy-selector-before.png new file mode 100644 index 0000000000..77227ce9ce Binary files /dev/null and b/docs/pr-assets/combo-strategy-selector-before.png differ diff --git a/gui/src/components/combo-workspace-controls.tsx b/gui/src/components/combo-workspace-controls.tsx index 7cafea176f..8e4a8108bc 100644 --- a/gui/src/components/combo-workspace-controls.tsx +++ b/gui/src/components/combo-workspace-controls.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import type { ComboEffort, ComboStrategy, ComboTarget, ProviderQuotaStates } from "../combo-workspace-data"; import { comboImagesSupported } from "../combo-capabilities"; -import { COMBO_EFFORTS, COMBO_STRATEGY_LABEL_KEYS, newComboTarget } from "../combo-workspace-data"; +import { COMBO_EFFORTS, COMBO_STRATEGIES, COMBO_STRATEGY_LABEL_KEYS, newComboTarget } from "../combo-workspace-data"; import { IconArrowDown, IconArrowUp, IconGrip, IconPlus, IconTrash } from "../icons"; import { useT } from "../i18n/shared"; import { Switch } from "../ui"; @@ -21,10 +21,7 @@ export function StrategySeg({ const t = useT(); return (
- {([ - ["failover", "cws.strategy.failover"], - ["round-robin", "cws.strategy.roundRobin"], - ] as const).map(([id, key]) => ( + {COMBO_STRATEGIES.map((id) => ( ))} - {value !== "failover" && value !== "round-robin" ? ( - - ) : null}
); } diff --git a/gui/tests/combo-strategy-selector.test.tsx b/gui/tests/combo-strategy-selector.test.tsx new file mode 100644 index 0000000000..8bfe0c541f --- /dev/null +++ b/gui/tests/combo-strategy-selector.test.tsx @@ -0,0 +1,31 @@ +import { afterEach, beforeEach, expect, test } from "bun:test"; +import { renderToStaticMarkup } from "react-dom/server"; +import { StrategySeg } from "../src/components/combo-workspace-controls"; +import { LanguageProvider } from "../src/i18n/provider"; + +let previousLanguage: unknown; + +beforeEach(() => { + previousLanguage = (globalThis.navigator as { language?: unknown } | undefined)?.language; + Object.defineProperty(globalThis.navigator, "language", { configurable: true, value: "en-US" }); +}); + +afterEach(() => { + Object.defineProperty(globalThis.navigator, "language", { configurable: true, value: previousLanguage }); +}); + +test("combo strategy selector exposes all runtime strategies", () => { + const html = renderToStaticMarkup( + + {}} /> + , + ); + const radios = html.match(/]*role="radio"[^>]*>/g) ?? []; + expect(radios).toHaveLength(5); + expect(html).toContain("Failover"); + expect(html).toContain("Round-robin"); + expect(html).toContain("Random"); + expect(html).toContain("Least-used"); + expect(html).toContain("Reset-window"); + expect(radios.every((button) => !button.includes("disabled="))).toBe(true); +});