Skip to content

Commit b1f608b

Browse files
authored
Implement basic URL scheme for Assistant & AI Search (#3503)
1 parent c799375 commit b1f608b

15 files changed

+509
-213
lines changed

.changeset/odd-candles-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gitbook": patch
3+
---
4+
5+
Implement basic URL scheme for assistant with ask

packages/gitbook/e2e/internal.spec.ts

Lines changed: 248 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
CustomizationAIMode,
23
CustomizationBackground,
34
CustomizationCorners,
45
CustomizationDefaultMonospaceFont,
@@ -19,6 +20,7 @@ import {
1920

2021
import { getSiteAPIToken } from '../tests/utils';
2122
import {
23+
type Test,
2224
type TestsCase,
2325
allDeprecatedThemePresets,
2426
allLocales,
@@ -34,6 +36,250 @@ import {
3436
waitForNotFound,
3537
} from './util';
3638

39+
const searchTestCases: Test[] = [
40+
{
41+
name: 'Search - AI Mode: None - Complete flow',
42+
url: getCustomizationURL({
43+
ai: {
44+
mode: CustomizationAIMode.None,
45+
},
46+
}),
47+
screenshot: false,
48+
run: async (page) => {
49+
const searchInput = page.getByTestId('search-input');
50+
await searchInput.focus();
51+
await expect(page.getByTestId('search-results')).toHaveCount(0); // No pop-up yet because there's no recommended questions.
52+
53+
// Fill search input, expecting search results
54+
await searchInput.fill('gitbook');
55+
await expect(page.getByTestId('search-results')).toBeVisible();
56+
const pageResults = await page.getByTestId('search-page-result').all();
57+
await expect(pageResults.length).toBeGreaterThan(2);
58+
const pageSectionResults = await page.getByTestId('search-page-section-result').all();
59+
await expect(pageSectionResults.length).toBeGreaterThan(2);
60+
await expect(page.getByTestId('search-ask-question')).toHaveCount(0); // No AI search results with aiMode=None.
61+
},
62+
},
63+
{
64+
name: 'Search - AI Mode: None - Keyboard shortcut',
65+
url: getCustomizationURL({
66+
ai: {
67+
mode: CustomizationAIMode.None,
68+
},
69+
}),
70+
screenshot: false,
71+
run: async (page) => {
72+
await page.keyboard.press('ControlOrMeta+K');
73+
await expect(page.getByTestId('search-input')).toBeFocused();
74+
},
75+
},
76+
{
77+
name: 'Search - AI Mode: None - URL query (Initial)',
78+
url: `${getCustomizationURL({
79+
ai: {
80+
mode: CustomizationAIMode.None,
81+
},
82+
})}&q=`,
83+
run: async (page) => {
84+
await expect(page.getByTestId('search-results')).toHaveCount(0); // No pop-up yet because there's no recommended questions.
85+
},
86+
},
87+
{
88+
name: 'Search - AI Mode: None - URL query (Results)',
89+
url: `${getCustomizationURL({
90+
ai: {
91+
mode: CustomizationAIMode.None,
92+
},
93+
})}&q=gitbook`,
94+
run: async (page) => {
95+
await expect(page.getByTestId('search-input')).toBeFocused();
96+
await expect(page.getByTestId('search-input')).toHaveValue('gitbook');
97+
await expect(page.getByTestId('search-results')).toBeVisible();
98+
},
99+
},
100+
{
101+
name: 'Search - AI Mode: Search - Complete flow',
102+
url: getCustomizationURL({
103+
ai: {
104+
mode: CustomizationAIMode.Search,
105+
},
106+
}),
107+
screenshot: false,
108+
run: async (page) => {
109+
const searchInput = page.getByTestId('search-input');
110+
111+
// Focus search input, expecting recommended questions
112+
await searchInput.focus();
113+
await expect(page.getByTestId('search-results')).toBeVisible();
114+
const recommendedQuestions = await page
115+
.getByTestId('search-recommended-question')
116+
.all();
117+
await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
118+
119+
// Fill search input, expecting AI search option
120+
await searchInput.fill('What is gitbook?');
121+
await expect(page.getByTestId('search-results')).toBeVisible();
122+
const aiSearchResult = page.getByTestId('search-ask-question');
123+
await expect(aiSearchResult).toBeVisible();
124+
await aiSearchResult.click();
125+
await expect(page.getByTestId('search-ask-answer')).toBeVisible({
126+
timeout: 15_000,
127+
});
128+
},
129+
},
130+
{
131+
name: 'Search - AI Mode: Search - URL query (Initial)',
132+
url: `${getCustomizationURL({
133+
ai: {
134+
mode: CustomizationAIMode.Search,
135+
},
136+
})}&q=`,
137+
screenshot: false,
138+
run: async (page) => {
139+
await expect(page.getByTestId('search-input')).toBeFocused();
140+
await expect(page.getByTestId('search-results')).toBeVisible();
141+
const recommendedQuestions = await page
142+
.getByTestId('search-recommended-question')
143+
.all();
144+
await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
145+
},
146+
},
147+
{
148+
name: 'Search - AI Mode: Search - URL query (Results)',
149+
url: `${getCustomizationURL({
150+
ai: {
151+
mode: CustomizationAIMode.Search,
152+
},
153+
})}&q=gitbook`,
154+
screenshot: false,
155+
run: async (page) => {
156+
await expect(page.getByTestId('search-input')).toBeFocused();
157+
await expect(page.getByTestId('search-input')).toHaveValue('gitbook');
158+
await expect(page.getByTestId('search-results')).toBeVisible();
159+
},
160+
},
161+
{
162+
name: 'Ask - AI Mode: Search - URL query (Ask initial)',
163+
url: `${getCustomizationURL({
164+
ai: {
165+
mode: CustomizationAIMode.Search,
166+
},
167+
})}&ask=`,
168+
screenshot: false,
169+
run: async (page) => {
170+
await expect(page.getByTestId('search-input')).toBeFocused();
171+
await expect(page.getByTestId('search-results')).toBeVisible();
172+
const recommendedQuestions = await page
173+
.getByTestId('search-recommended-question')
174+
.all();
175+
await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
176+
},
177+
},
178+
{
179+
name: 'Ask - AI Mode: Search - URL query (Ask results)',
180+
url: `${getCustomizationURL({
181+
ai: {
182+
mode: CustomizationAIMode.Search,
183+
},
184+
})}&ask=What+is+GitBook%3F`,
185+
screenshot: false,
186+
run: async (page) => {
187+
await expect(page.getByTestId('search-input')).toBeFocused();
188+
await expect(page.getByTestId('search-input')).toHaveValue('What is GitBook?');
189+
await expect(page.getByTestId('search-ask-answer')).toBeVisible();
190+
},
191+
},
192+
{
193+
name: 'Ask - AI Mode: Assistant - Complete flow',
194+
url: getCustomizationURL({
195+
ai: {
196+
mode: CustomizationAIMode.Assistant,
197+
},
198+
}),
199+
screenshot: false,
200+
run: async (page) => {
201+
const searchInput = page.locator('css=[data-testid="search-input"]');
202+
203+
// Focus search input, expecting recommended questions
204+
await searchInput.focus();
205+
await expect(page.getByTestId('search-results')).toBeVisible();
206+
const recommendedQuestions = await page
207+
.getByTestId('search-recommended-question')
208+
.all();
209+
await expect(recommendedQuestions.length).toBeGreaterThan(2); // Expect at least 3 questions
210+
211+
// Fill search input, expecting AI search option
212+
await searchInput.fill('What is gitbook?');
213+
const aiSearchResult = page.getByTestId('search-ask-question');
214+
await expect(aiSearchResult).toBeVisible();
215+
await aiSearchResult.click();
216+
await expect(page.getByTestId('ai-chat')).toBeVisible();
217+
},
218+
},
219+
{
220+
name: 'Ask - AI Mode: Assistant - Keyboard shortcut',
221+
url: getCustomizationURL({
222+
ai: {
223+
mode: CustomizationAIMode.Assistant,
224+
},
225+
}),
226+
screenshot: false,
227+
run: async (page) => {
228+
await page.keyboard.press('ControlOrMeta+J');
229+
await expect(page.getByTestId('ai-chat')).toBeVisible();
230+
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
231+
},
232+
},
233+
{
234+
name: 'Ask - AI Mode: Assistant - Button',
235+
url: getCustomizationURL({
236+
ai: {
237+
mode: CustomizationAIMode.Assistant,
238+
},
239+
}),
240+
screenshot: false,
241+
run: async (page) => {
242+
await page.getByTestId('ai-chat-button').click();
243+
await expect(page.getByTestId('ai-chat')).toBeVisible();
244+
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
245+
},
246+
},
247+
{
248+
name: 'Ask - AI Mode: Assistant - URL query (Initial)',
249+
url: `${getCustomizationURL({
250+
ai: {
251+
mode: CustomizationAIMode.Assistant,
252+
},
253+
})}&ask=`,
254+
screenshot: false,
255+
run: async (page) => {
256+
await expect(page.getByTestId('search-input')).not.toBeFocused();
257+
await expect(page.getByTestId('search-input')).not.toHaveValue('What is GitBook?');
258+
await expect(page.getByTestId('ai-chat')).toBeVisible();
259+
await expect(page.getByTestId('ai-chat-input')).toBeFocused();
260+
},
261+
},
262+
{
263+
name: 'Ask - AI Mode: Assistant - URL query (Results)',
264+
url: `${getCustomizationURL({
265+
ai: {
266+
mode: CustomizationAIMode.Assistant,
267+
},
268+
})}&ask=What+is+GitBook%3F`,
269+
screenshot: false,
270+
run: async (page) => {
271+
await expect(page.getByTestId('search-input')).not.toBeFocused();
272+
await expect(page.getByTestId('search-input')).not.toHaveValue('What is GitBook?');
273+
await expect(page.getByTestId('ai-chat')).toBeVisible({
274+
timeout: 15_000,
275+
});
276+
await expect(page.getByTestId('ai-chat-message').first()).toHaveText(
277+
'What is GitBook?'
278+
);
279+
},
280+
},
281+
];
282+
37283
const testCases: TestsCase[] = [
38284
{
39285
name: 'GitBook Site (Single Variant)',
@@ -53,34 +299,7 @@ const testCases: TestsCase[] = [
53299
);
54300
},
55301
},
56-
{
57-
name: 'Search',
58-
url: '?q=',
59-
screenshot: false,
60-
run: async (page) => {
61-
await expect(page.getByTestId('search-results')).toBeVisible();
62-
const allItems = await page.getByTestId('search-result-item').all();
63-
// Expect at least 3 questions
64-
await expect(allItems.length).toBeGreaterThan(2);
65-
},
66-
},
67-
{
68-
name: 'Search Results',
69-
url: '?q=gitbook',
70-
run: async (page) => {
71-
await expect(page.getByTestId('search-results')).toBeVisible();
72-
},
73-
},
74-
{
75-
name: 'AI Search',
76-
url: '?q=What+is+GitBook%3F&ask=true',
77-
run: async (page) => {
78-
await expect(page.getByTestId('search-ask-answer')).toBeVisible({
79-
timeout: 15_000,
80-
});
81-
},
82-
screenshot: false,
83-
},
302+
...searchTestCases,
84303
{
85304
name: 'Not found',
86305
url: 'content-not-found',
@@ -279,34 +498,7 @@ const testCases: TestsCase[] = [
279498
url: '',
280499
run: waitForCookiesDialog,
281500
},
282-
{
283-
name: 'Search',
284-
url: '?q=',
285-
screenshot: false,
286-
run: async (page) => {
287-
await expect(page.getByTestId('search-results')).toBeVisible();
288-
const allItems = await page.getByTestId('search-result-item').all();
289-
// Expect at least 3 questions
290-
await expect(allItems.length).toBeGreaterThan(2);
291-
},
292-
},
293-
{
294-
name: 'Search Results',
295-
url: '?q=gitbook',
296-
run: async (page) => {
297-
await expect(page.getByTestId('search-results')).toBeVisible();
298-
},
299-
},
300-
{
301-
name: 'AI Search',
302-
url: '?q=What+is+GitBook%3F&ask=true',
303-
run: async (page) => {
304-
await expect(page.getByTestId('search-ask-answer')).toBeVisible({
305-
timeout: 15_000,
306-
});
307-
},
308-
screenshot: false,
309-
},
501+
...searchTestCases,
310502
{
311503
name: 'Not found',
312504
url: 'content-not-found',

0 commit comments

Comments
 (0)