@@ -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+
4042const 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,59 @@ 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+ } ) ;
149+ // Override text content for visual consistency in screenshots
150+ await page . evaluate ( ( ) => {
151+ const suggestions = document . querySelectorAll (
152+ '[data-testid="ai-chat-followup-suggestion"]'
153+ ) ;
154+ suggestions . forEach ( ( suggestion ) => {
155+ suggestion . textContent = 'Follow-up suggestion' ;
156+ } ) ;
157+ } ) ;
147158 } ,
148159 } ,
149160 {
@@ -153,40 +164,59 @@ const searchTestCases: Test[] = [
153164 mode : CustomizationAIMode . Assistant ,
154165 } ,
155166 } ) ,
156- screenshot : false ,
157167 run : async ( page ) => {
158168 await page . keyboard . press ( 'ControlOrMeta+I' ) ;
159169 await expect ( page . getByTestId ( 'ai-chat' ) ) . toBeVisible ( ) ;
160170 await expect ( page . getByTestId ( 'ai-chat-input' ) ) . toBeFocused ( ) ;
171+ // Override text content for visual consistency in screenshots
172+ await page . evaluate ( ( ) => {
173+ const greeting = document . querySelector ( '[data-testid="ai-chat-time-greeting"]' ) ;
174+ if ( greeting ) {
175+ greeting . textContent = 'Good morning' ;
176+ }
177+ } ) ;
178+ } ,
179+ } ,
180+ {
181+ name : 'Ask - AI Mode: Assistant - Button' ,
182+ url : getCustomizationURL ( {
183+ ai : {
184+ mode : CustomizationAIMode . Assistant ,
185+ } ,
186+ } ) ,
187+ screenshot : false ,
188+ run : async ( page ) => {
189+ await page . getByTestId ( 'ai-chat-button' ) . click ( ) ;
190+ await expect ( page . getByTestId ( 'ai-chat' ) ) . toBeVisible ( ) ;
191+ await expect ( page . getByTestId ( 'ai-chat-input' ) ) . toBeFocused ( ) ;
192+ // Override text content for visual consistency in screenshots
193+ await page . evaluate ( ( ) => {
194+ const greeting = document . querySelector ( '[data-testid="ai-chat-time-greeting"]' ) ;
195+ if ( greeting ) {
196+ greeting . textContent = 'Good morning' ;
197+ }
198+ } ) ;
161199 } ,
162200 } ,
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- // },
177201 {
178202 name : 'Ask - AI Mode: Assistant - URL query (Initial)' ,
179203 url : `${ getCustomizationURL ( {
180204 ai : {
181205 mode : CustomizationAIMode . Assistant ,
182206 } ,
183207 } ) } &ask=`,
184- screenshot : false ,
185208 run : async ( page ) => {
186209 await expect ( page . getByTestId ( 'search-input' ) ) . not . toBeFocused ( ) ;
187- await expect ( page . getByTestId ( 'search-input' ) ) . not . toHaveValue ( 'What is GitBook?' ) ;
210+ await expect ( page . getByTestId ( 'search-input' ) ) . toBeEmpty ( ) ;
188211 await expect ( page . getByTestId ( 'ai-chat' ) ) . toBeVisible ( ) ;
189212 await expect ( page . getByTestId ( 'ai-chat-input' ) ) . toBeFocused ( ) ;
213+ // Override text content for visual consistency in screenshots
214+ await page . evaluate ( ( ) => {
215+ const greeting = document . querySelector ( '[data-testid="ai-chat-time-greeting"]' ) ;
216+ if ( greeting ) {
217+ greeting . textContent = 'Good morning' ;
218+ }
219+ } ) ;
190220 } ,
191221 } ,
192222 {
@@ -195,17 +225,25 @@ const searchTestCases: Test[] = [
195225 ai : {
196226 mode : CustomizationAIMode . Assistant ,
197227 } ,
198- } ) } &ask=What+is+GitBook%3F`,
199- screenshot : false ,
228+ } ) } &ask=${ encodeURIComponent ( AI_PROMPT ) } `,
200229 run : async ( page ) => {
201230 await expect ( page . getByTestId ( 'search-input' ) ) . not . toBeFocused ( ) ;
202231 await expect ( page . getByTestId ( 'search-input' ) ) . not . toHaveValue ( 'What is GitBook?' ) ;
203- await expect ( page . getByTestId ( 'ai-chat' ) ) . toBeVisible ( {
204- timeout : 15_000 ,
232+ await expect ( page . getByTestId ( 'ai-chat' ) ) . toBeVisible ( ) ;
233+ await expect ( page . getByTestId ( 'ai-chat-message-user' ) . first ( ) ) . toHaveText ( AI_PROMPT ) ;
234+ await expect ( page . getByTestId ( 'ai-chat-message-assistant' ) . first ( ) ) . toBeVisible ( ) ;
235+ await expect ( page . getByTestId ( 'ai-chat-followup-suggestion' ) ) . toHaveCount ( 3 , {
236+ timeout : 60_000 ,
237+ } ) ;
238+ // Override text content for visual consistency in screenshots
239+ await page . evaluate ( ( ) => {
240+ const suggestions = document . querySelectorAll (
241+ '[data-testid="ai-chat-followup-suggestion"]'
242+ ) ;
243+ suggestions . forEach ( ( suggestion ) => {
244+ suggestion . textContent = 'Follow-up suggestion' ;
245+ } ) ;
205246 } ) ;
206- await expect ( page . getByTestId ( 'ai-chat-message' ) . first ( ) ) . toHaveText (
207- 'What is GitBook?'
208- ) ;
209247 } ,
210248 } ,
211249] ;
@@ -880,6 +918,11 @@ const testCases: TestsCase[] = [
880918 url : 'blocks/cards' ,
881919 fullPage : true ,
882920 } ,
921+ {
922+ name : 'Updates' ,
923+ url : 'blocks/updates' ,
924+ fullPage : true ,
925+ } ,
883926 {
884927 name : 'Math' ,
885928 url : 'blocks/math' ,
0 commit comments