mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-08 01:14:52 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa7ade90fd |
@@ -485,6 +485,43 @@ describe("toAgentPayload", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildStoredAgentPayload features", () => {
|
||||
it.each([null, "2026-11-01T00:00:00.000Z"])(
|
||||
"preserves saved feature definitions like live snapshots (archivedAt=%s)",
|
||||
(archivedAt) => {
|
||||
const features: AgentFeature[] = [
|
||||
createFeature({ value: false }),
|
||||
{
|
||||
type: "select",
|
||||
id: "service_tier",
|
||||
label: "Service tier",
|
||||
value: "default",
|
||||
options: [
|
||||
{ id: "default", label: "Normal" },
|
||||
{ id: "fast", label: "Fast" },
|
||||
],
|
||||
},
|
||||
];
|
||||
const agent = createManagedAgent({ features });
|
||||
const record = { ...toStoredAgentRecord(agent), archivedAt };
|
||||
|
||||
const payload = buildStoredAgentPayload(record, [agent.provider]);
|
||||
|
||||
expect(payload.features).toEqual(features);
|
||||
expect(payload.features).toEqual(toAgentPayload(agent).features);
|
||||
expect(payload.features).not.toBe(record.features);
|
||||
expect(payload.features?.[0]).not.toBe(record.features?.[0]);
|
||||
},
|
||||
);
|
||||
|
||||
it("uses an empty feature list for older records without saved definitions", () => {
|
||||
const record = toStoredAgentRecord(createManagedAgent());
|
||||
delete record.features;
|
||||
|
||||
expect(buildStoredAgentPayload(record, [record.provider]).features).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toRecentProviderSessionDescriptorPayload", () => {
|
||||
it("projects provider import rows to provider-opaque public recent sessions", () => {
|
||||
const session: ImportableProviderSession & { provider: string } = {
|
||||
|
||||
@@ -263,6 +263,7 @@ export function buildStoredAgentPayload(
|
||||
capabilities: defaultCapabilities,
|
||||
currentModeId: record.lastModeId ?? null,
|
||||
availableModes: [],
|
||||
features: normalizeFeatures(record.features),
|
||||
pendingPermissions: [],
|
||||
persistence,
|
||||
title: record.title ?? null,
|
||||
|
||||
@@ -9,23 +9,6 @@ async function chooseLanguage(page: Page, language: string) {
|
||||
await page.getByRole("menuitemradio", { name: language }).click();
|
||||
}
|
||||
|
||||
async function withPageScriptsHeld(page: Page, run: (release: () => void) => Promise<void>) {
|
||||
let releaseScripts!: () => void;
|
||||
const scriptsReleased = new Promise<void>((resolve) => {
|
||||
releaseScripts = resolve;
|
||||
});
|
||||
await page.route("**/*.js", async (route) => {
|
||||
await scriptsReleased;
|
||||
await route.continue();
|
||||
});
|
||||
try {
|
||||
await run(releaseScripts);
|
||||
} finally {
|
||||
releaseScripts();
|
||||
await page.unrouteAll({ behavior: "wait" });
|
||||
}
|
||||
}
|
||||
|
||||
function describeAlternates(links: Element[]): string[] {
|
||||
return links.map((link) => `${link.getAttribute("hreflang")} ${link.getAttribute("href")}`);
|
||||
}
|
||||
@@ -131,7 +114,6 @@ test("shows the language as an abbreviation and lists every language by name", a
|
||||
|
||||
test("switches language from the keyboard", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await expect(languageButton(page)).toBeEnabled();
|
||||
await languageButton(page).focus();
|
||||
await page.keyboard.press("Enter");
|
||||
await expect(page.getByRole("menuitemradio", { name: "English" })).toBeFocused();
|
||||
@@ -201,15 +183,3 @@ test("shows the changelog in Chinese", async ({ page }) => {
|
||||
await expect(page.getByRole("heading", { name: "新增" }).first()).toBeVisible();
|
||||
await expect(page.getByRole("note")).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("waits for scripts before enabling the language menu", async ({ page }) => {
|
||||
await withPageScriptsHeld(page, async (releaseScripts) => {
|
||||
await page.goto("/docs/cli#running-agents", { waitUntil: "commit" });
|
||||
await expect(languageButton(page)).toBeVisible();
|
||||
await expect(languageButton(page)).toBeDisabled();
|
||||
|
||||
releaseScripts();
|
||||
await languageButton(page).click();
|
||||
await expect(page.getByRole("menuitemradio", { name: "English" })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -181,23 +181,6 @@ test("keeps the directory's ranking window when searching", async ({ page }) =>
|
||||
);
|
||||
});
|
||||
|
||||
test("submits the visible search term when its input event was missed", async ({ page }) => {
|
||||
await page.goto("/plugins?window=month");
|
||||
await expect(page.getByRole("button", { name: "Language: English" }).first()).toBeEnabled();
|
||||
await fillSearchWithMissedInputEvent(page, "graphite");
|
||||
|
||||
await page.keyboard.press("Enter");
|
||||
|
||||
await expect(page).toHaveURL(/\/plugins\/all\?q=graphite&window=month$/);
|
||||
await expect(
|
||||
page.getByRole("heading", { level: 1, name: /^Results for “graphite”/ }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "This month" })).toHaveAttribute(
|
||||
"aria-current",
|
||||
"true",
|
||||
);
|
||||
});
|
||||
|
||||
test("searches for a term typed before the page finished loading", async ({ page }) => {
|
||||
const loadScripts = await holdScripts(page);
|
||||
await page.goto("/plugins?window=month", { waitUntil: "domcontentloaded" });
|
||||
@@ -436,21 +419,6 @@ async function searchPlugins(page: Page, term: string) {
|
||||
await page.getByRole("searchbox", { name: "Search plugins" }).fill(term);
|
||||
}
|
||||
|
||||
/** Reproduce text entered before hydration's input listener can observe it, without a clock race. */
|
||||
async function fillSearchWithMissedInputEvent(page: Page, term: string) {
|
||||
const search = page.getByRole("searchbox", { name: "Search plugins" });
|
||||
await search.evaluate(() => {
|
||||
for (const eventType of ["input", "change"]) {
|
||||
document.addEventListener(eventType, (event) => event.stopImmediatePropagation(), {
|
||||
capture: true,
|
||||
once: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
await search.fill(term);
|
||||
await expect(search).toHaveValue(term);
|
||||
}
|
||||
|
||||
async function submitSearch(page: Page, term: string) {
|
||||
await searchPlugins(page, term);
|
||||
await page.keyboard.press("Enter");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useHydrated, useLocation, useNavigate } from "@tanstack/react-router";
|
||||
import { useLocation, useNavigate } from "@tanstack/react-router";
|
||||
import { AnimatePresence, motion, type Transition } from "framer-motion";
|
||||
import { Check, ChevronDown, Languages } from "lucide-react";
|
||||
import { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
||||
@@ -33,7 +33,6 @@ type OpenFocus = "current" | "first" | "last";
|
||||
* the menu button pattern: arrows move between languages, Escape and outside presses close it.
|
||||
*/
|
||||
export function LanguageSelector() {
|
||||
const hydrated = useHydrated();
|
||||
const { t } = useTranslation();
|
||||
const locale = useLocale();
|
||||
const location = useLocation();
|
||||
@@ -126,7 +125,6 @@ export function LanguageSelector() {
|
||||
<button
|
||||
ref={triggerRef}
|
||||
type="button"
|
||||
disabled={!hydrated}
|
||||
aria-label={t("languageSelector.current", { language: LANGUAGE_NAMES[locale] })}
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={open}
|
||||
|
||||
@@ -68,16 +68,12 @@ export function PluginSearch({
|
||||
input.current?.focus();
|
||||
}, [edit]);
|
||||
const handleSubmit = useCallback(
|
||||
(event: FormEvent<HTMLFormElement>) => {
|
||||
(event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
// Live results already show the term.
|
||||
if (!live) {
|
||||
// Hydration can attach this handler before state adopts text already in the input.
|
||||
const submittedTerm = String(new FormData(event.currentTarget).get("q") ?? "");
|
||||
show(submittedTerm, { replace: false });
|
||||
}
|
||||
if (!live) show(term, { replace: false });
|
||||
},
|
||||
[live, show],
|
||||
[live, show, term],
|
||||
);
|
||||
return (
|
||||
<form
|
||||
|
||||
Reference in New Issue
Block a user