@@ -198,6 +198,130 @@ test.describe('Search Plugin Tests', () => {
198198 await expect ( resultsHeadingElm ) . toHaveText ( 'EmptyContent' ) ;
199199 } ) ;
200200
201+ test ( 'keeps saving index when one auto path request fails with cached records' , async ( {
202+ page,
203+ } ) => {
204+ const indexKey = 'docsify.search.index' ;
205+ const expireKey = 'docsify.search.expires' ;
206+
207+ const pageErrors = [ ] ;
208+ page . on ( 'pageerror' , error => pageErrors . push ( error . message ) ) ;
209+
210+ await page . evaluate (
211+ ( { indexKey, expireKey } ) => {
212+ return new Promise ( ( resolve , reject ) => {
213+ const request = indexedDB . open ( 'docsify' , 1 ) ;
214+
215+ request . onupgradeneeded = ( ) => {
216+ const db = request . result ;
217+
218+ if ( ! db . objectStoreNames . contains ( 'search' ) ) {
219+ db . createObjectStore ( 'search' , { keyPath : 'slug' } ) ;
220+ }
221+
222+ if ( ! db . objectStoreNames . contains ( 'expires' ) ) {
223+ db . createObjectStore ( 'expires' , { keyPath : 'key' } ) ;
224+ }
225+ } ;
226+
227+ request . onerror = ( ) => reject ( request . error ) ;
228+ request . onsuccess = ( ) => {
229+ const db = request . result ;
230+ const tx = db . transaction ( [ 'search' , 'expires' ] , 'readwrite' ) ;
231+
232+ tx . objectStore ( 'search' ) . put ( {
233+ slug : '/cached' ,
234+ title : 'Cached Page' ,
235+ body : 'cached record' ,
236+ path : '/cached' ,
237+ indexKey,
238+ } ) ;
239+ tx . objectStore ( 'expires' ) . put ( {
240+ key : expireKey ,
241+ value : Date . now ( ) + 60 * 1000 ,
242+ } ) ;
243+
244+ tx . oncomplete = ( ) => {
245+ db . close ( ) ;
246+ resolve ( ) ;
247+ } ;
248+ tx . onerror = ( ) => reject ( tx . error ) ;
249+ } ;
250+ } ) ;
251+ } ,
252+ { indexKey, expireKey } ,
253+ ) ;
254+
255+ await docsifyInit ( {
256+ markdown : {
257+ homepage : '# Home' ,
258+ sidebar : `
259+ - [Cached](cached)
260+ - [Success](success)
261+ - [Fail](fail)
262+ ` ,
263+ } ,
264+ routes : {
265+ '/success.md' : '# Success\n\nregressionKeyword' ,
266+ '/fail.md' : {
267+ status : 404 ,
268+ body : 'Not Found' ,
269+ contentType : 'text/markdown' ,
270+ } ,
271+ } ,
272+ scriptURLs : [ '/dist/plugins/search.js' ] ,
273+ } ) ;
274+
275+ await expect
276+ . poll ( async ( ) => {
277+ return await page . evaluate ( indexKey => {
278+ return new Promise ( ( resolve , reject ) => {
279+ const request = indexedDB . open ( 'docsify' ) ;
280+
281+ request . onerror = ( ) => reject ( request . error ) ;
282+ request . onsuccess = ( ) => {
283+ const db = request . result ;
284+ const tx = db . transaction ( [ 'search' , 'expires' ] , 'readonly' ) ;
285+ const searchStore = tx . objectStore ( 'search' ) ;
286+ const expiresStore = tx . objectStore ( 'expires' ) ;
287+ const searchReq = searchStore . getAll ( ) ;
288+ const expiresReq = expiresStore . get ( 'docsify.search.expires' ) ;
289+
290+ tx . onerror = ( ) => reject ( tx . error ) ;
291+ tx . oncomplete = ( ) => {
292+ const records = Array . isArray ( searchReq . result )
293+ ? searchReq . result
294+ : [ ] ;
295+ const hasSuccessRecord = records . some (
296+ record =>
297+ record &&
298+ record . indexKey === indexKey &&
299+ record . path === '/success' ,
300+ ) ;
301+ const hasInvalidRecord = records . some (
302+ record => ! record || typeof record . slug !== 'string' ,
303+ ) ;
304+ const hasExpireRecord = Boolean ( expiresReq . result ?. value ) ;
305+
306+ db . close ( ) ;
307+ resolve (
308+ hasSuccessRecord && hasExpireRecord && ! hasInvalidRecord ,
309+ ) ;
310+ } ;
311+ } ;
312+ } ) ;
313+ } , indexKey ) ;
314+ } )
315+ . toBe ( true ) ;
316+
317+ const searchFieldElm = page . locator ( 'input[type=search]' ) ;
318+ const resultsHeadingElm = page . locator ( '.results-panel .title' ) ;
319+
320+ await searchFieldElm . fill ( 'regressionKeyword' ) ;
321+ await expect ( resultsHeadingElm ) . toHaveText ( 'Success' ) ;
322+ expect ( pageErrors ) . toEqual ( [ ] ) ;
323+ } ) ;
324+
201325 test ( 'handles default focusSearch binding' , async ( { page } ) => {
202326 const docsifyInitConfig = {
203327 scriptURLs : [ '/dist/plugins/search.js' ] ,
0 commit comments