@@ -248,8 +248,7 @@ describe('ComboBox', function () {
248248 jest . spyOn ( window . HTMLElement . prototype , 'clientHeight' , 'get' ) . mockImplementation ( ( ) => 1000 ) ;
249249 window . HTMLElement . prototype . scrollIntoView = jest . fn ( ) ;
250250 jest . spyOn ( window . screen , 'width' , 'get' ) . mockImplementation ( ( ) => 1024 ) ;
251- jest . spyOn ( window , 'requestAnimationFrame' ) . mockImplementation ( cb => setTimeout ( cb , 0 ) ) ;
252- jest . useFakeTimers ( 'legacy' ) ;
251+ jest . useFakeTimers ( ) ;
253252 } ) ;
254253
255254 beforeEach ( ( ) => {
@@ -2024,23 +2023,45 @@ describe('ComboBox', function () {
20242023 ) ;
20252024
20262025 let button = getByRole ( 'button' ) ;
2026+ let combobox = getByRole ( 'combobox' ) ;
20272027
2028- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2028+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
20292029 expect ( onOpenChange ) . toHaveBeenCalledTimes ( 0 ) ;
20302030 expect ( onLoadMore ) . toHaveBeenCalledTimes ( 0 ) ;
20312031
2032+ // open menu
2033+ triggerPress ( button ) ;
2034+ // use async act to resolve initial load
20322035 await act ( async ( ) => {
2033- triggerPress ( button ) ;
2034- jest . runAllTimers ( ) ;
2036+ // advance to open state from Transition
2037+ jest . advanceTimersToNextTimer ( ) ;
20352038 } ) ;
2036-
20372039 let listbox = getByRole ( 'listbox' ) ;
20382040 expect ( listbox ) . toBeVisible ( ) ;
2041+ jest . spyOn ( listbox , 'clientHeight' , 'get' ) . mockImplementation ( ( ) => 100 ) ;
2042+ // update size, virtualizer raf kicks in
2043+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2044+ // onLoadMore queued by previous timer, run it now
2045+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
20392046
20402047 expect ( onOpenChange ) . toHaveBeenCalledTimes ( 1 ) ;
20412048 expect ( onOpenChange ) . toHaveBeenCalledWith ( true , 'manual' ) ;
20422049 expect ( onLoadMore ) . toHaveBeenCalledTimes ( 1 ) ;
2043- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2050+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
2051+
2052+ // close menu
2053+ act ( ( ) => { combobox . blur ( ) ; } ) ;
2054+ // raf from virtualizer relayout
2055+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2056+ // previous act wraps up onExiting
2057+ // raf
2058+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2059+ // raf
2060+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2061+ // exited
2062+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2063+
2064+ expect ( listbox ) . not . toBeInTheDocument ( ) ;
20442065 } ) ;
20452066
20462067 it ( 'onLoadMore is not called on when previously opened' , async ( ) => {
@@ -2052,29 +2073,46 @@ describe('ComboBox', function () {
20522073
20532074 let button = getByRole ( 'button' ) ;
20542075 let combobox = getByRole ( 'combobox' ) ;
2055- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2076+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
20562077 expect ( onOpenChange ) . toHaveBeenCalledTimes ( 0 ) ;
20572078 expect ( onLoadMore ) . toHaveBeenCalledTimes ( 0 ) ;
20582079
20592080 // this call and the one below are more correct for how the code should
2060- // behave, the inital call would have a height of zero and after that a measureable height
2081+ // behave, the initial call would have a height of zero and after that a measureable height
20612082 clientHeightSpy . mockRestore ( ) ;
20622083 clientHeightSpy = jest . spyOn ( window . HTMLElement . prototype , 'clientHeight' , 'get' ) . mockImplementationOnce ( ( ) => 0 ) . mockImplementation ( ( ) => 40 ) ;
20632084 // open menu
2085+ triggerPress ( button ) ;
2086+ // use async act to resolve initial load
20642087 await act ( async ( ) => {
2065- triggerPress ( button ) ;
2066- jest . runAllTimers ( ) ;
2088+ // advance to open state from Transition
2089+ jest . advanceTimersToNextTimer ( ) ;
20672090 } ) ;
2091+ let listbox = getByRole ( 'listbox' ) ;
2092+ expect ( listbox ) . toBeVisible ( ) ;
2093+ jest . spyOn ( listbox , 'clientHeight' , 'get' ) . mockImplementation ( ( ) => 100 ) ;
2094+ // update size, virtualizer raf kicks in
2095+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2096+ // onLoadMore queued by previous timer, run it now
2097+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
20682098
20692099 expect ( onOpenChange ) . toHaveBeenCalledTimes ( 1 ) ;
20702100 expect ( onOpenChange ) . toHaveBeenCalledWith ( true , 'manual' ) ;
20712101 expect ( onLoadMore ) . toHaveBeenCalledTimes ( 1 ) ;
20722102
20732103 // close menu
2074- act ( ( ) => {
2075- combobox . blur ( ) ;
2076- jest . runAllTimers ( ) ;
2077- } ) ;
2104+ act ( ( ) => { combobox . blur ( ) ; } ) ;
2105+ // raf from virtualizer relayout
2106+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2107+ // previous act wraps up onExiting
2108+ // raf
2109+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2110+ // raf
2111+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2112+ // exited
2113+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2114+
2115+ expect ( listbox ) . not . toBeInTheDocument ( ) ;
20782116
20792117 expect ( onOpenChange ) . toHaveBeenCalledTimes ( 2 ) ;
20802118 expect ( onOpenChange ) . toHaveBeenLastCalledWith ( false , undefined ) ;
@@ -2083,10 +2121,18 @@ describe('ComboBox', function () {
20832121 clientHeightSpy . mockRestore ( ) ;
20842122 clientHeightSpy = jest . spyOn ( window . HTMLElement . prototype , 'clientHeight' , 'get' ) . mockImplementationOnce ( ( ) => 0 ) . mockImplementation ( ( ) => 40 ) ;
20852123 // reopen menu
2124+ triggerPress ( button ) ;
20862125 await act ( async ( ) => {
2087- triggerPress ( button ) ;
2088- jest . runAllTimers ( ) ;
2126+ // advance to open state from Transition
2127+ jest . advanceTimersToNextTimer ( ) ;
20892128 } ) ;
2129+ listbox = getByRole ( 'listbox' ) ;
2130+ expect ( listbox ) . toBeVisible ( ) ;
2131+ jest . spyOn ( listbox , 'clientHeight' , 'get' ) . mockImplementation ( ( ) => 100 ) ;
2132+ // update size, virtualizer raf kicks in
2133+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
2134+ // onLoadMore queued by previous timer, run it now
2135+ act ( ( ) => { jest . advanceTimersToNextTimer ( ) ; } ) ;
20902136
20912137 expect ( onOpenChange ) . toHaveBeenCalledTimes ( 3 ) ;
20922138 expect ( onOpenChange ) . toHaveBeenLastCalledWith ( true , 'manual' ) ;
@@ -2095,7 +2141,10 @@ describe('ComboBox', function () {
20952141 // because the browser limits the popover height via calculatePosition(),
20962142 // while the test doesn't, causing virtualizer to try to load more
20972143 expect ( onLoadMore ) . toHaveBeenCalledTimes ( 2 ) ;
2098- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2144+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
2145+
2146+ // close menu
2147+ act ( ( ) => { combobox . blur ( ) ; } ) ;
20992148 } ) ;
21002149 } ) ;
21012150
0 commit comments