refactor: update auto scroll mechanism (#970)

This commit is contained in:
Jeremy 2025-05-01 02:28:24 -07:00 committed by GitHub
parent 1fd2302914
commit 45978c27a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 250 additions and 52 deletions

View file

@ -150,4 +150,21 @@ test.describe('Chat activity', () => {
const assistantMessage = await chatPage.getRecentAssistantMessage();
expect(assistantMessage.content).toContain("It's just blue duh!");
});
test('auto-scrolls to bottom after submitting new messages', async () => {
await chatPage.sendMultipleMessages(5, (i) => `filling message #${i}`);
await chatPage.waitForScrollToBottom();
});
test('scroll button appears when user scrolls up, hides on click', async () => {
await chatPage.sendMultipleMessages(5, (i) => `filling message #${i}`);
await expect(chatPage.scrollToBottomButton).not.toBeVisible();
await chatPage.scrollToTop();
await expect(chatPage.scrollToBottomButton).toBeVisible();
await chatPage.scrollToBottomButton.click();
await chatPage.waitForScrollToBottom();
await expect(chatPage.scrollToBottomButton).not.toBeVisible();
});
});

View file

@ -8,7 +8,7 @@ interface Fixtures {
curieContext: UserContext;
}
export const test = baseTest.extend<any, Fixtures>({
export const test = baseTest.extend<{}, Fixtures>({
adaContext: [
async ({ browser }, use, workerInfo) => {
const ada = await createAuthenticatedContext({

View file

@ -18,6 +18,14 @@ export class ChatPage {
return this.page.getByTestId('multimodal-input');
}
public get scrollContainer() {
return this.page.locator('.overflow-y-scroll');
}
public get scrollToBottomButton() {
return this.page.getByTestId('scroll-to-bottom-button');
}
async createNewChat() {
await this.page.goto('/');
}
@ -195,4 +203,37 @@ export class ChatPage {
const sidebarToggleButton = this.page.getByTestId('sidebar-toggle-button');
await sidebarToggleButton.click();
}
public async isScrolledToBottom(): Promise<boolean> {
return this.scrollContainer.evaluate(
(el) => Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) < 1,
);
}
public async waitForScrollToBottom(timeout = 5_000): Promise<void> {
const start = Date.now();
while (Date.now() - start < timeout) {
if (await this.isScrolledToBottom()) return;
await this.page.waitForTimeout(100);
}
throw new Error(`Timed out waiting for scroll bottom after ${timeout}ms`);
}
public async sendMultipleMessages(
count: number,
makeMessage: (i: number) => string,
) {
for (let i = 0; i < count; i++) {
await this.sendUserMessage(makeMessage(i));
await this.isGenerationComplete();
}
}
public async scrollToTop(): Promise<void> {
await this.scrollContainer.evaluate((element) => {
element.scrollTop = 0;
});
}
}