mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 01:32:40 +00:00
* fix(app): let Escape close an open popover before it interrupts the agent The agent.interrupt shortcut listens on the window in the capture phase, so it sees Escape before anything else. Registered overlays get first refusal through dispatchTopWebOverlayKeyDown, but plugins cannot register, and draw their floating panels with the Popover API instead. With such a panel open and the composer focused while an agent runs, Escape closed the panel and interrupted the agent in the same press. While a popover is open, Escape is left to it and no app shortcut runs. A second Escape, with nothing open, interrupts as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: RoundRedDot <roundreddot@gmail.com> * test(app): cover Escape with a popover open through the shortcut path The first test only checked hasOpenDomPopover and would still pass with the guard removed from useKeyboardShortcuts. The check is now keyBelongsToDomPopover, called by the hook, and a browser test drives it the way the app does: a window capture listener for shortcuts, a popover closed by its own document Escape listener, focus in a textarea. The first Escape closes the popover with no interrupt; the second interrupts. Both new tests fail with the guard removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: RoundRedDot <roundreddot@gmail.com> * test(app): exercise plugin Escape through the real composer Keep the contributor fix and replace the substitute shortcut-listener test with an installed-plugin browser regression. The first Escape must close the preview without cancelling the turn; the second must cancel it. Co-authored-by: luke <luopeihuan@gmail.com> Co-authored-by: RoundRedDot <roundreddot@gmail.com> * test(app): check dismissed model pickers leave the viewport --------- Co-authored-by: luke <luopeihuan@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: RoundRedDot <roundreddot@gmail.com> Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
48 lines
2.0 KiB
TypeScript
48 lines
2.0 KiB
TypeScript
import { expect, test, type Page } from "../support/fixtures";
|
|
import { composerLocator, submitMessageWithButton } from "../support/helpers/composer";
|
|
import { seedMockAgentWorkspace, openAgentRoute } from "../support/helpers/mock-agent";
|
|
import { withPopoverTimelinePlugin } from "../support/helpers/plugin-timeline";
|
|
|
|
async function openPreviewWhileTyping(page: Page): Promise<void> {
|
|
await composerLocator(page).focus();
|
|
await page.getByRole("button", { name: "Hover plugin preview", exact: true }).hover();
|
|
await expect(page.getByRole("dialog", { name: "Plugin preview" })).toBeVisible();
|
|
await expect(composerLocator(page)).toBeFocused();
|
|
}
|
|
|
|
async function dismissPreview(page: Page): Promise<void> {
|
|
await page.keyboard.press("Escape");
|
|
await expect(page.getByRole("dialog", { name: "Plugin preview" })).not.toBeVisible();
|
|
}
|
|
|
|
test("Escape dismisses a plugin preview before interrupting the agent", async ({ page }) => {
|
|
test.setTimeout(120_000);
|
|
const agent = await seedMockAgentWorkspace({
|
|
repoPrefix: "plugin-popover-",
|
|
title: "Plugin preview keyboard regression",
|
|
model: "e2e-fast-stream",
|
|
});
|
|
try {
|
|
await withPopoverTimelinePlugin(async () => {
|
|
await openAgentRoute(page, agent);
|
|
await submitMessageWithButton(page, "Show the plugin preview.");
|
|
await agent.client.waitForFinish(agent.agentId, 30_000);
|
|
await expect(page.getByRole("button", { name: "Hover plugin preview" })).toBeVisible();
|
|
await submitMessageWithButton(page, "withhold synthetic user message until interrupted");
|
|
const stop = page.getByRole("button", { name: "Stop agent", exact: true });
|
|
await expect(stop).toBeVisible();
|
|
|
|
await openPreviewWhileTyping(page);
|
|
await dismissPreview(page);
|
|
await expect(stop).toBeVisible();
|
|
await expect(composerLocator(page)).toBeFocused();
|
|
|
|
await page.keyboard.press("Escape");
|
|
await expect(stop).not.toBeVisible();
|
|
await agent.client.waitForFinish(agent.agentId, 15_000);
|
|
});
|
|
} finally {
|
|
await agent.cleanup();
|
|
}
|
|
});
|