Skip to content

Commit 0f4c53c

Browse files
authored
Update Assistant e2e tests (#3814)
1 parent c156e94 commit 0f4c53c

File tree

4 files changed

+53
-43
lines changed

4 files changed

+53
-43
lines changed

packages/gitbook/e2e/internal.spec.ts

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import {
3737
waitForNotFound,
3838
} from './util';
3939

40+
const AI_PROMPT = `You're being invoked by the GitBook CI/CD pipeline. To make screenshot testing of the GitBook Assistant visually consistent, look up the title of the first page you find and respond with only EXACTLY its title. To find the page title, invoke the search tool with the query "GitBook". Before invoking the search tool, respond with the exact text: "I'm going to look up 'GitBook' and then respond with only the page title.". Do not execute any other tools or output any other text.`;
41+
4042
const searchTestCases: Test[] = [
4143
{
4244
name: 'Search - AI Mode: None - Complete flow',
@@ -53,7 +55,9 @@ const searchTestCases: Test[] = [
5355

5456
// Fill search input, expecting search results
5557
await searchInput.fill('gitbook');
56-
await expect(page.getByTestId('search-results')).toBeVisible();
58+
await expect(page.getByTestId('search-results')).toBeVisible({
59+
timeout: 10_000,
60+
});
5761
const pageResults = await page.getByTestId('search-page-result').all();
5862
await expect(pageResults.length).toBeGreaterThanOrEqual(1);
5963
const pageSectionResults = await page.getByTestId('search-page-section-result').all();
@@ -98,52 +102,50 @@ const searchTestCases: Test[] = [
98102
await expect(page.getByTestId('search-results')).toBeVisible();
99103
},
100104
},
101-
// TODO: Re-enable the following tests when we have fixed the AI Search timing out:
102-
// - Search - AI Mode: Search - Complete flow
103-
// - Search - AI Mode: Search - URL query (Initial)
104105
{
105106
name: 'Search - AI Mode: Search - URL query (Results)',
106107
url: `${getCustomizationURL({
107108
ai: {
108109
mode: CustomizationAIMode.Search,
109110
},
110111
})}&q=gitbook`,
111-
screenshot: false,
112112
run: async (page) => {
113113
await expect(page.getByTestId('search-input')).toBeFocused();
114114
await expect(page.getByTestId('search-input')).toHaveValue('gitbook');
115115
await expect(page.getByTestId('search-results')).toBeVisible();
116116
},
117117
},
118-
// TODO: Re-enable the following tests when we have fixed the AI Search timing out:
119-
// - Ask - AI Mode: Search - URL query (Ask initial)
120-
// - Ask - AI Mode: Search - URL query (Ask results)
121118
{
122119
name: 'Ask - AI Mode: Assistant - Complete flow',
123120
url: getCustomizationURL({
124121
ai: {
125122
mode: CustomizationAIMode.Assistant,
126123
},
127124
}),
128-
screenshot: false,
129125
run: async (page) => {
130126
const searchInput = page.locator('css=[data-testid="search-input"]');
131127

132128
// Focus search input, expecting recommended questions
133129
await searchInput.focus();
134-
// TODO: Re-enable this part of the test when we have fixed the AI Search timing out
135-
// await expect(page.getByTestId('search-results')).toBeVisible();
136-
// const recommendedQuestions = await page
137-
// .getByTestId('search-recommended-question')
138-
// .all();
139-
// await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
130+
await expect(page.getByTestId('search-results')).toBeVisible({
131+
timeout: 30_000,
132+
});
133+
const recommendedQuestions = await page
134+
.getByTestId('search-recommended-question')
135+
.all();
136+
await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
140137

141138
// Fill search input, expecting AI search option
142-
await searchInput.fill('What is gitbook?');
139+
await searchInput.fill(AI_PROMPT);
143140
const aiSearchResult = page.getByTestId('search-ask-question');
144141
await expect(aiSearchResult).toBeVisible();
145142
await aiSearchResult.click();
146143
await expect(page.getByTestId('ai-chat')).toBeVisible();
144+
await expect(page.getByTestId('ai-chat-message-user').first()).toHaveText(AI_PROMPT);
145+
await expect(page.getByTestId('ai-chat-message-assistant').first()).toBeVisible();
146+
await expect(page.getByTestId('ai-chat-followup-suggestion')).toHaveCount(3, {
147+
timeout: 60_000,
148+
});
147149
},
148150
},
149151
{
@@ -153,38 +155,36 @@ const searchTestCases: Test[] = [
153155
mode: CustomizationAIMode.Assistant,
154156
},
155157
}),
156-
screenshot: false,
157158
run: async (page) => {
158159
await page.keyboard.press('ControlOrMeta+I');
159160
await expect(page.getByTestId('ai-chat')).toBeVisible();
160161
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
161162
},
162163
},
163-
// {
164-
// name: 'Ask - AI Mode: Assistant - Button',
165-
// url: getCustomizationURL({
166-
// ai: {
167-
// mode: CustomizationAIMode.Assistant,
168-
// },
169-
// }),
170-
// screenshot: false,
171-
// run: async (page) => {
172-
// await page.getByTestId('ai-chat-button').click();
173-
// await expect(page.getByTestId('ai-chat')).toBeVisible();
174-
// await expect(page.getByTestId('ai-chat-input')).toBeFocused();
175-
// },
176-
// },
164+
{
165+
name: 'Ask - AI Mode: Assistant - Button',
166+
url: getCustomizationURL({
167+
ai: {
168+
mode: CustomizationAIMode.Assistant,
169+
},
170+
}),
171+
screenshot: false,
172+
run: async (page) => {
173+
await page.getByTestId('ai-chat-button').click();
174+
await expect(page.getByTestId('ai-chat')).toBeVisible();
175+
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
176+
},
177+
},
177178
{
178179
name: 'Ask - AI Mode: Assistant - URL query (Initial)',
179180
url: `${getCustomizationURL({
180181
ai: {
181182
mode: CustomizationAIMode.Assistant,
182183
},
183184
})}&ask=`,
184-
screenshot: false,
185185
run: async (page) => {
186186
await expect(page.getByTestId('search-input')).not.toBeFocused();
187-
await expect(page.getByTestId('search-input')).not.toHaveValue('What is GitBook?');
187+
await expect(page.getByTestId('search-input')).toBeEmpty();
188188
await expect(page.getByTestId('ai-chat')).toBeVisible();
189189
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
190190
},
@@ -195,17 +195,16 @@ const searchTestCases: Test[] = [
195195
ai: {
196196
mode: CustomizationAIMode.Assistant,
197197
},
198-
})}&ask=What+is+GitBook%3F`,
199-
screenshot: false,
198+
})}&ask=${encodeURIComponent(AI_PROMPT)}`,
200199
run: async (page) => {
201200
await expect(page.getByTestId('search-input')).not.toBeFocused();
202201
await expect(page.getByTestId('search-input')).not.toHaveValue('What is GitBook?');
203-
await expect(page.getByTestId('ai-chat')).toBeVisible({
204-
timeout: 15_000,
202+
await expect(page.getByTestId('ai-chat')).toBeVisible();
203+
await expect(page.getByTestId('ai-chat-message-user').first()).toHaveText(AI_PROMPT);
204+
await expect(page.getByTestId('ai-chat-message-assistant').first()).toBeVisible();
205+
await expect(page.getByTestId('ai-chat-followup-suggestion')).toHaveCount(3, {
206+
timeout: 60_000,
205207
});
206-
await expect(page.getByTestId('ai-chat-message').first()).toHaveText(
207-
'What is GitBook?'
208-
);
209208
},
210209
},
211210
];

packages/gitbook/src/components/AIChat/AIChatInput.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { tcls } from '@/lib/tailwind';
33
import { Icon } from '@gitbook/icons';
44
import { useEffect, useRef } from 'react';
55
import { useHotkeys } from 'react-hotkeys-hook';
6+
import { useAIChatState } from '../AI/useAIChat';
67
import { Button, HoverCard, HoverCardRoot, HoverCardTrigger } from '../primitives';
78
import { KeyboardShortcut } from '../primitives/KeyboardShortcut';
89

@@ -19,6 +20,7 @@ export function AIChatInput(props: {
1920
const { value, onChange, onSubmit, disabled, loading } = props;
2021

2122
const language = useLanguage();
23+
const chat = useAIChatState();
2224

2325
const inputRef = useRef<HTMLTextAreaElement>(null);
2426

@@ -32,7 +34,7 @@ export function AIChatInput(props: {
3234
};
3335

3436
useEffect(() => {
35-
if (!disabled && !loading) {
37+
if (chat.opened && !disabled && !loading) {
3638
// Add a small delay to ensure the input is rendered before focusing
3739
// This fixes inconsistent focus behaviour across browsers
3840
const timeout = setTimeout(() => {
@@ -41,7 +43,7 @@ export function AIChatInput(props: {
4143

4244
return () => clearTimeout(timeout);
4345
}
44-
}, [disabled, loading]);
46+
}, [disabled, loading, chat.opened]);
4547

4648
useHotkeys(
4749
'mod+i',

packages/gitbook/src/components/AIChat/AIChatMessages.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ export function AIChatMessages(props: {
5656
return (
5757
<div
5858
key={originalIndex}
59+
data-testid={
60+
message.role === AIMessageRole.User
61+
? 'ai-chat-message-user'
62+
: 'ai-chat-message-assistant'
63+
}
5964
id={`message-${originalIndex}`}
6065
className={tcls(
6166
'flex flex-col gap-6',

packages/gitbook/src/components/AIChat/AiChatFollowupSuggestions.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ export function AIChatFollowupSuggestions(props: {
1616

1717
return (
1818
<div className="flex grow flex-col">
19-
<div className="sticky bottom-0 mt-auto flex flex-col items-start gap-2">
19+
<div
20+
className="sticky bottom-0 mt-auto flex flex-col items-start gap-2"
21+
data-testid="ai-chat-followup-suggestions"
22+
>
2023
{chat.followUpSuggestions.map((suggestion, index) => (
2124
<Button
25+
data-testid="ai-chat-followup-suggestion"
2226
key={index}
2327
onClick={() => {
2428
chatController.postMessage({ message: suggestion });

0 commit comments

Comments
 (0)