mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-04 07:33:18 +00:00
Fixing a prompt after interrupting it, or retrying one after a provider error, meant scrolling up and copying it out of the chat. Up in an empty agent composer now fills the last message sent to that agent; Up walks older, Down walks newer and past the newest back to empty. History is read from the loaded timeline on key press, not kept in a separate store, so it follows rewinds, reloads and other devices and costs nothing while a turn streams. Recall only starts from an empty composer, so it never discards a half-written draft. While a recalled message is unedited the autocomplete stays hidden, otherwise a recalled `/command` would open the picker and Enter would pick an option instead of sending.
82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
import { expect, test, type Page } from "../support/fixtures";
|
|
import {
|
|
composerLocator,
|
|
expectComposerDraft,
|
|
expectComposerVisible,
|
|
submitMessage,
|
|
typeIntoFocusedComposer,
|
|
} from "../support/helpers/composer";
|
|
import { openAgentRoute, seedMockAgentWorkspace } from "../support/helpers/mock-agent";
|
|
|
|
function userMessages(page: Page) {
|
|
return page.getByTestId("user-message");
|
|
}
|
|
|
|
async function sendAndWaitForMessage(page: Page, text: string, expectedCount: number) {
|
|
await submitMessage(page, text);
|
|
await expect(userMessages(page)).toHaveCount(expectedCount, { timeout: 30_000 });
|
|
await expectComposerDraft(page, "");
|
|
}
|
|
|
|
async function pressInComposer(page: Page, key: string) {
|
|
await composerLocator(page).press(key);
|
|
}
|
|
|
|
test.describe("Composer recall", () => {
|
|
test("Up and Down walk sent messages from an empty composer", async ({ page }) => {
|
|
const session = await seedMockAgentWorkspace({
|
|
repoPrefix: "composer-recall-",
|
|
title: "Composer recall",
|
|
});
|
|
try {
|
|
await openAgentRoute(page, session);
|
|
await expectComposerVisible(page);
|
|
await sendAndWaitForMessage(page, "fix the auth bug", 1);
|
|
await sendAndWaitForMessage(page, "add tests", 2);
|
|
|
|
await pressInComposer(page, "ArrowUp");
|
|
await expectComposerDraft(page, "add tests");
|
|
await pressInComposer(page, "ArrowUp");
|
|
await expectComposerDraft(page, "fix the auth bug");
|
|
await pressInComposer(page, "ArrowDown");
|
|
await expectComposerDraft(page, "add tests");
|
|
await pressInComposer(page, "ArrowDown");
|
|
await expectComposerDraft(page, "");
|
|
|
|
await pressInComposer(page, "ArrowUp");
|
|
await typeIntoFocusedComposer(page, " for login");
|
|
await expectComposerDraft(page, "add tests for login");
|
|
await pressInComposer(page, "ArrowUp");
|
|
await expectComposerDraft(page, "add tests for login");
|
|
|
|
await pressInComposer(page, "Enter");
|
|
await expect(userMessages(page)).toHaveCount(3, { timeout: 30_000 });
|
|
await expect(userMessages(page).last()).toContainText("add tests for login");
|
|
} finally {
|
|
await session.cleanup();
|
|
}
|
|
});
|
|
|
|
test("a recalled slash message does not open the command picker", async ({ page }) => {
|
|
const session = await seedMockAgentWorkspace({
|
|
repoPrefix: "composer-recall-slash-",
|
|
title: "Composer recall slash",
|
|
});
|
|
try {
|
|
await openAgentRoute(page, session);
|
|
await expectComposerVisible(page);
|
|
await sendAndWaitForMessage(page, "/tdd", 1);
|
|
|
|
const popover = page.getByTestId("composer-autocomplete-popover").filter({ visible: true });
|
|
await pressInComposer(page, "ArrowUp");
|
|
await expectComposerDraft(page, "/tdd");
|
|
await expect(popover).toHaveCount(0);
|
|
|
|
await typeIntoFocusedComposer(page, "x");
|
|
await expect(popover.first()).toBeVisible({ timeout: 30_000 });
|
|
} finally {
|
|
await session.cleanup();
|
|
}
|
|
});
|
|
});
|