@@ -211,28 +211,43 @@ test('the pointer is always on a tick while it travels down the rail', async ({
211211 await expect
212212 . poll ( async ( ) => {
213213 const travel = await page . evaluate ( ( ) => {
214- const ticks = [ ...document . querySelectorAll ( '.maka-prompt-rail-tick' ) ] ;
214+ const ticks = [ ...document . querySelectorAll < HTMLElement > ( '.maka-prompt-rail-tick' ) ] ;
215215 if ( ticks . length < 2 ) throw new Error ( 'the prompt rail needs at least two ticks' ) ;
216- const first = ticks [ 0 ] ! . getBoundingClientRect ( ) ;
217- const last = ticks [ ticks . length - 1 ] ! . getBoundingClientRect ( ) ;
218- const x = Math . round ( first . left + first . width / 2 ) ;
216+ const boxes = ticks . map ( ( tick ) => tick . getBoundingClientRect ( ) ) ;
217+ const first = boxes [ 0 ] ! ;
218+ const last = boxes [ boxes . length - 1 ] ! ;
219219 const describe = ( found : Element | null ) =>
220220 found instanceof Element
221221 ? `${ found . tagName . toLowerCase ( ) } .${ found . className . toString ( ) . trim ( ) . replace ( / \s + / g, '.' ) } `
222222 : 'null' ;
223- const startY = Math . round ( first . top + first . height / 2 ) ;
224- const endY = Math . round ( last . top + last . height / 2 ) ;
225- const misses : Array < { y : number ; hit : string } > = [ ] ;
226- for ( let y = startY ; y <= endY ; y += 1 ) {
227- const found = document . elementFromPoint ( x , y ) ;
228- if ( ! found ?. closest ( '.maka-prompt-rail-tick' ) ) {
229- misses . push ( { y, hit : describe ( found ) } ) ;
223+ const misses : Array < { index : number ; kind : 'center' | 'seam' ; hit : string } > = [ ] ;
224+ for ( const [ index , box ] of boxes . entries ( ) ) {
225+ const found = document . elementFromPoint (
226+ box . left + box . width / 2 ,
227+ box . top + box . height / 2 ,
228+ ) ;
229+ if ( found ?. closest ( '.maka-prompt-rail-tick' ) !== ticks [ index ] ) {
230+ misses . push ( { index, kind : 'center' , hit : describe ( found ) } ) ;
231+ }
232+ }
233+ const gaps = boxes . slice ( 1 ) . map ( ( box , index ) => box . top - boxes [ index ] ! . bottom ) ;
234+ for ( let index = 0 ; index < boxes . length - 1 ; index += 1 ) {
235+ const before = boxes [ index ] ! ;
236+ const after = boxes [ index + 1 ] ! ;
237+ const found = document . elementFromPoint (
238+ before . left + before . width / 2 ,
239+ ( before . bottom + after . top ) / 2 ,
240+ ) ;
241+ const landed = found ?. closest ( '.maka-prompt-rail-tick' ) ;
242+ if ( landed !== ticks [ index ] && landed !== ticks [ index + 1 ] ) {
243+ misses . push ( { index, kind : 'seam' , hit : describe ( found ) } ) ;
230244 }
231245 }
232246 return {
233- insideViewport : startY >= 0 && endY < window . innerHeight ,
247+ insideViewport : first . top >= 0 && last . bottom <= window . innerHeight ,
234248 misses : misses . length ,
235- hasSpan : endY > startY ,
249+ hasSpan : last . bottom > first . top ,
250+ continuousBoxes : Math . max ( ...gaps ) <= 0.25 ,
236251 sample : misses . slice ( 0 , 3 ) ,
237252 } ;
238253 } ) ;
@@ -242,6 +257,7 @@ test('the pointer is always on a tick while it travels down the rail', async ({
242257 insideViewport : true ,
243258 misses : 0 ,
244259 hasSpan : true ,
260+ continuousBoxes : true ,
245261 } ) ;
246262} ) ;
247263
0 commit comments