@@ -248,8 +248,7 @@ describe('ComboBox', function () {
248
248
jest . spyOn ( window . HTMLElement . prototype , 'clientHeight' , 'get' ) . mockImplementation ( ( ) => 1000 ) ;
249
249
window . HTMLElement . prototype . scrollIntoView = jest . fn ( ) ;
250
250
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 ( ) ;
253
252
} ) ;
254
253
255
254
beforeEach ( ( ) => {
@@ -2024,23 +2023,45 @@ describe('ComboBox', function () {
2024
2023
) ;
2025
2024
2026
2025
let button = getByRole ( 'button' ) ;
2026
+ let combobox = getByRole ( 'combobox' ) ;
2027
2027
2028
- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2028
+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
2029
2029
expect ( onOpenChange ) . toHaveBeenCalledTimes ( 0 ) ;
2030
2030
expect ( onLoadMore ) . toHaveBeenCalledTimes ( 0 ) ;
2031
2031
2032
+ // open menu
2033
+ triggerPress ( button ) ;
2034
+ // use async act to resolve initial load
2032
2035
await act ( async ( ) => {
2033
- triggerPress ( button ) ;
2034
- jest . runAllTimers ( ) ;
2036
+ // advance to open state from Transition
2037
+ jest . advanceTimersToNextTimer ( ) ;
2035
2038
} ) ;
2036
-
2037
2039
let listbox = getByRole ( 'listbox' ) ;
2038
2040
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 ( ) ; } ) ;
2039
2046
2040
2047
expect ( onOpenChange ) . toHaveBeenCalledTimes ( 1 ) ;
2041
2048
expect ( onOpenChange ) . toHaveBeenCalledWith ( true , 'manual' ) ;
2042
2049
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 ( ) ;
2044
2065
} ) ;
2045
2066
2046
2067
it ( 'onLoadMore is not called on when previously opened' , async ( ) => {
@@ -2052,29 +2073,46 @@ describe('ComboBox', function () {
2052
2073
2053
2074
let button = getByRole ( 'button' ) ;
2054
2075
let combobox = getByRole ( 'combobox' ) ;
2055
- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2076
+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
2056
2077
expect ( onOpenChange ) . toHaveBeenCalledTimes ( 0 ) ;
2057
2078
expect ( onLoadMore ) . toHaveBeenCalledTimes ( 0 ) ;
2058
2079
2059
2080
// 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
2061
2082
clientHeightSpy . mockRestore ( ) ;
2062
2083
clientHeightSpy = jest . spyOn ( window . HTMLElement . prototype , 'clientHeight' , 'get' ) . mockImplementationOnce ( ( ) => 0 ) . mockImplementation ( ( ) => 40 ) ;
2063
2084
// open menu
2085
+ triggerPress ( button ) ;
2086
+ // use async act to resolve initial load
2064
2087
await act ( async ( ) => {
2065
- triggerPress ( button ) ;
2066
- jest . runAllTimers ( ) ;
2088
+ // advance to open state from Transition
2089
+ jest . advanceTimersToNextTimer ( ) ;
2067
2090
} ) ;
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 ( ) ; } ) ;
2068
2098
2069
2099
expect ( onOpenChange ) . toHaveBeenCalledTimes ( 1 ) ;
2070
2100
expect ( onOpenChange ) . toHaveBeenCalledWith ( true , 'manual' ) ;
2071
2101
expect ( onLoadMore ) . toHaveBeenCalledTimes ( 1 ) ;
2072
2102
2073
2103
// 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 ( ) ;
2078
2116
2079
2117
expect ( onOpenChange ) . toHaveBeenCalledTimes ( 2 ) ;
2080
2118
expect ( onOpenChange ) . toHaveBeenLastCalledWith ( false , undefined ) ;
@@ -2083,10 +2121,18 @@ describe('ComboBox', function () {
2083
2121
clientHeightSpy . mockRestore ( ) ;
2084
2122
clientHeightSpy = jest . spyOn ( window . HTMLElement . prototype , 'clientHeight' , 'get' ) . mockImplementationOnce ( ( ) => 0 ) . mockImplementation ( ( ) => 40 ) ;
2085
2123
// reopen menu
2124
+ triggerPress ( button ) ;
2086
2125
await act ( async ( ) => {
2087
- triggerPress ( button ) ;
2088
- jest . runAllTimers ( ) ;
2126
+ // advance to open state from Transition
2127
+ jest . advanceTimersToNextTimer ( ) ;
2089
2128
} ) ;
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 ( ) ; } ) ;
2090
2136
2091
2137
expect ( onOpenChange ) . toHaveBeenCalledTimes ( 3 ) ;
2092
2138
expect ( onOpenChange ) . toHaveBeenLastCalledWith ( true , 'manual' ) ;
@@ -2095,7 +2141,10 @@ describe('ComboBox', function () {
2095
2141
// because the browser limits the popover height via calculatePosition(),
2096
2142
// while the test doesn't, causing virtualizer to try to load more
2097
2143
expect ( onLoadMore ) . toHaveBeenCalledTimes ( 2 ) ;
2098
- await waitFor ( ( ) => expect ( load ) . toHaveBeenCalledTimes ( 1 ) ) ;
2144
+ expect ( load ) . toHaveBeenCalledTimes ( 1 ) ;
2145
+
2146
+ // close menu
2147
+ act ( ( ) => { combobox . blur ( ) ; } ) ;
2099
2148
} ) ;
2100
2149
} ) ;
2101
2150
0 commit comments