@tanstack/react-query-devtools 5.0.0-alpha.5 → 5.0.0-alpha.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/__tests__/devtools.test.d.ts +1 -1
- package/build/lib/__tests__/devtools.test.d.ts.map +1 -0
- package/build/lib/__tests__/utils.d.ts +2 -1
- package/build/lib/__tests__/utils.d.ts.map +1 -0
- package/build/lib/devtools.cjs +61 -0
- package/build/lib/devtools.cjs.map +1 -0
- package/build/lib/devtools.d.ts +11 -75
- package/build/lib/devtools.d.ts.map +1 -0
- package/build/lib/devtools.js +53 -789
- package/build/lib/devtools.js.map +1 -1
- package/build/lib/index.cjs +18 -0
- package/build/lib/index.cjs.map +1 -0
- package/build/lib/index.d.ts +1 -1
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +11 -9
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.prod.cjs +69 -0
- package/build/lib/index.prod.cjs.map +1 -0
- package/build/lib/{index.prod.d.ts → index.prod.d.ts/index.d.ts} +1 -1
- package/build/lib/index.prod.js +58 -1444
- package/build/lib/index.prod.js.map +1 -1
- package/package.json +24 -26
- package/src/__tests__/devtools.test.tsx +1 -861
- package/src/devtools.tsx +61 -1164
- package/src/index.ts +6 -6
- package/build/lib/Explorer.d.ts +0 -50
- package/build/lib/Explorer.esm.js +0 -253
- package/build/lib/Explorer.esm.js.map +0 -1
- package/build/lib/Explorer.js +0 -287
- package/build/lib/Explorer.js.map +0 -1
- package/build/lib/Explorer.mjs +0 -253
- package/build/lib/Explorer.mjs.map +0 -1
- package/build/lib/Logo.d.ts +0 -1
- package/build/lib/Logo.esm.js +0 -32
- package/build/lib/Logo.esm.js.map +0 -1
- package/build/lib/Logo.js +0 -55
- package/build/lib/Logo.js.map +0 -1
- package/build/lib/Logo.mjs +0 -32
- package/build/lib/Logo.mjs.map +0 -1
- package/build/lib/__tests__/Explorer.test.d.ts +0 -1
- package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js +0 -17
- package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js.map +0 -1
- package/build/lib/_virtual/_rollupPluginBabelHelpers.js +0 -19
- package/build/lib/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
- package/build/lib/_virtual/_rollupPluginBabelHelpers.mjs +0 -17
- package/build/lib/_virtual/_rollupPluginBabelHelpers.mjs.map +0 -1
- package/build/lib/devtools.esm.js +0 -773
- package/build/lib/devtools.esm.js.map +0 -1
- package/build/lib/devtools.mjs +0 -773
- package/build/lib/devtools.mjs.map +0 -1
- package/build/lib/index.esm.js +0 -11
- package/build/lib/index.esm.js.map +0 -1
- package/build/lib/index.mjs +0 -11
- package/build/lib/index.mjs.map +0 -1
- package/build/lib/index.prod.esm.js +0 -1431
- package/build/lib/index.prod.esm.js.map +0 -1
- package/build/lib/index.prod.mjs +0 -1431
- package/build/lib/index.prod.mjs.map +0 -1
- package/build/lib/noop.d.ts +0 -2
- package/build/lib/screenreader.d.ts +0 -3
- package/build/lib/screenreader.esm.js +0 -17
- package/build/lib/screenreader.esm.js.map +0 -1
- package/build/lib/screenreader.js +0 -40
- package/build/lib/screenreader.js.map +0 -1
- package/build/lib/screenreader.mjs +0 -17
- package/build/lib/screenreader.mjs.map +0 -1
- package/build/lib/styledComponents.d.ts +0 -9
- package/build/lib/styledComponents.esm.js +0 -93
- package/build/lib/styledComponents.esm.js.map +0 -1
- package/build/lib/styledComponents.js +0 -102
- package/build/lib/styledComponents.js.map +0 -1
- package/build/lib/styledComponents.mjs +0 -93
- package/build/lib/styledComponents.mjs.map +0 -1
- package/build/lib/theme.d.ts +0 -36
- package/build/lib/theme.esm.js +0 -32
- package/build/lib/theme.esm.js.map +0 -1
- package/build/lib/theme.js +0 -55
- package/build/lib/theme.js.map +0 -1
- package/build/lib/theme.mjs +0 -32
- package/build/lib/theme.mjs.map +0 -1
- package/build/lib/useLocalStorage.d.ts +0 -1
- package/build/lib/useLocalStorage.esm.js +0 -40
- package/build/lib/useLocalStorage.esm.js.map +0 -1
- package/build/lib/useLocalStorage.js +0 -63
- package/build/lib/useLocalStorage.js.map +0 -1
- package/build/lib/useLocalStorage.mjs +0 -40
- package/build/lib/useLocalStorage.mjs.map +0 -1
- package/build/lib/useMediaQuery.d.ts +0 -1
- package/build/lib/useMediaQuery.esm.js +0 -36
- package/build/lib/useMediaQuery.esm.js.map +0 -1
- package/build/lib/useMediaQuery.js +0 -59
- package/build/lib/useMediaQuery.js.map +0 -1
- package/build/lib/useMediaQuery.mjs +0 -36
- package/build/lib/useMediaQuery.mjs.map +0 -1
- package/build/lib/utils.d.ts +0 -79
- package/build/lib/utils.esm.js +0 -184
- package/build/lib/utils.esm.js.map +0 -1
- package/build/lib/utils.js +0 -218
- package/build/lib/utils.js.map +0 -1
- package/build/lib/utils.mjs +0 -184
- package/build/lib/utils.mjs.map +0 -1
- package/build/umd/index.development.js +0 -3099
- package/build/umd/index.development.js.map +0 -1
- package/build/umd/index.production.js +0 -2
- package/build/umd/index.production.js.map +0 -1
- package/src/Explorer.tsx +0 -385
- package/src/Logo.tsx +0 -32
- package/src/__tests__/Explorer.test.tsx +0 -150
- package/src/noop.ts +0 -7
- package/src/screenreader.tsx +0 -16
- package/src/styledComponents.ts +0 -108
- package/src/theme.tsx +0 -33
- package/src/useLocalStorage.ts +0 -52
- package/src/useMediaQuery.ts +0 -34
- package/src/utils.ts +0 -319
|
@@ -1,865 +1,5 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import { fireEvent, screen, waitFor, act } from '@testing-library/react'
|
|
3
|
-
import '@testing-library/jest-dom'
|
|
4
|
-
import { useQuery } from '@tanstack/react-query'
|
|
5
|
-
import { defaultPanelSize, sortFns } from '../utils'
|
|
6
|
-
import {
|
|
7
|
-
getByTextContent,
|
|
8
|
-
renderWithClient,
|
|
9
|
-
sleep,
|
|
10
|
-
createQueryClient,
|
|
11
|
-
} from './utils'
|
|
12
|
-
import { vi } from 'vitest'
|
|
13
|
-
|
|
14
|
-
Object.defineProperty(window, 'matchMedia', {
|
|
15
|
-
writable: true,
|
|
16
|
-
value: vi.fn().mockImplementation((query: string) => ({
|
|
17
|
-
matches: false,
|
|
18
|
-
media: query,
|
|
19
|
-
onchange: null,
|
|
20
|
-
addListener: vi.fn(), // deprecated
|
|
21
|
-
removeListener: vi.fn(), // deprecated
|
|
22
|
-
addEventListener: vi.fn(),
|
|
23
|
-
removeEventListener: vi.fn(),
|
|
24
|
-
dispatchEvent: vi.fn(),
|
|
25
|
-
})),
|
|
26
|
-
})
|
|
27
|
-
|
|
28
1
|
describe('ReactQueryDevtools', () => {
|
|
29
|
-
beforeEach(() => {
|
|
30
|
-
localStorage.removeItem('reactQueryDevtoolsOpen')
|
|
31
|
-
localStorage.removeItem('reactQueryDevtoolsPanelPosition')
|
|
32
|
-
})
|
|
33
2
|
it('should be able to open and close devtools', async () => {
|
|
34
|
-
|
|
35
|
-
const onCloseClick = vi.fn()
|
|
36
|
-
const onToggleClick = vi.fn()
|
|
37
|
-
|
|
38
|
-
function Page() {
|
|
39
|
-
const { data = 'default' } = useQuery({
|
|
40
|
-
queryKey: ['check'],
|
|
41
|
-
queryFn: async () => {
|
|
42
|
-
await sleep(10)
|
|
43
|
-
return 'test'
|
|
44
|
-
},
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
return (
|
|
48
|
-
<div>
|
|
49
|
-
<h1>{data}</h1>
|
|
50
|
-
</div>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
renderWithClient(queryClient, <Page />, {
|
|
55
|
-
initialIsOpen: false,
|
|
56
|
-
closeButtonProps: { onClick: onCloseClick },
|
|
57
|
-
toggleButtonProps: { onClick: onToggleClick },
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
const verifyDevtoolsIsOpen = () => {
|
|
61
|
-
expect(
|
|
62
|
-
screen.queryByRole('generic', { name: /react query devtools panel/i }),
|
|
63
|
-
).not.toBeNull()
|
|
64
|
-
expect(
|
|
65
|
-
screen.queryByRole('button', { name: /open react query devtools/i }),
|
|
66
|
-
).toBeNull()
|
|
67
|
-
}
|
|
68
|
-
const verifyDevtoolsIsClosed = () => {
|
|
69
|
-
expect(
|
|
70
|
-
screen.queryByRole('generic', { name: /react query devtools panel/i }),
|
|
71
|
-
).toBeNull()
|
|
72
|
-
expect(
|
|
73
|
-
screen.queryByRole('button', { name: /open react query devtools/i }),
|
|
74
|
-
).not.toBeNull()
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const waitForDevtoolsToOpen = () =>
|
|
78
|
-
screen.findByRole('button', { name: /close react query devtools/i })
|
|
79
|
-
const waitForDevtoolsToClose = () =>
|
|
80
|
-
screen.findByRole('button', { name: /open react query devtools/i })
|
|
81
|
-
|
|
82
|
-
const getOpenLogoButton = () =>
|
|
83
|
-
screen.getByRole('button', { name: /open react query devtools/i })
|
|
84
|
-
const getCloseLogoButton = () =>
|
|
85
|
-
screen.getByRole('button', { name: /close react query devtools/i })
|
|
86
|
-
const getCloseButton = () =>
|
|
87
|
-
screen.getByRole('button', { name: /^close$/i })
|
|
88
|
-
|
|
89
|
-
verifyDevtoolsIsClosed()
|
|
90
|
-
|
|
91
|
-
fireEvent.click(getOpenLogoButton())
|
|
92
|
-
await waitForDevtoolsToOpen()
|
|
93
|
-
|
|
94
|
-
verifyDevtoolsIsOpen()
|
|
95
|
-
|
|
96
|
-
fireEvent.click(getCloseLogoButton())
|
|
97
|
-
await waitForDevtoolsToClose()
|
|
98
|
-
|
|
99
|
-
verifyDevtoolsIsClosed()
|
|
100
|
-
|
|
101
|
-
fireEvent.click(getOpenLogoButton())
|
|
102
|
-
await waitForDevtoolsToOpen()
|
|
103
|
-
|
|
104
|
-
verifyDevtoolsIsOpen()
|
|
105
|
-
|
|
106
|
-
fireEvent.click(getCloseButton())
|
|
107
|
-
await waitForDevtoolsToClose()
|
|
108
|
-
|
|
109
|
-
verifyDevtoolsIsClosed()
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
it('should be able to drag devtools without error', async () => {
|
|
113
|
-
const { queryClient } = createQueryClient()
|
|
114
|
-
|
|
115
|
-
function Page() {
|
|
116
|
-
const { data = 'default' } = useQuery({
|
|
117
|
-
queryKey: ['check'],
|
|
118
|
-
queryFn: async () => {
|
|
119
|
-
await sleep(10)
|
|
120
|
-
return 'test'
|
|
121
|
-
},
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
<div>
|
|
126
|
-
<h1>{data}</h1>
|
|
127
|
-
</div>
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const result = renderWithClient(queryClient, <Page />, {
|
|
132
|
-
initialIsOpen: false,
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
const draggableElement = result.container
|
|
136
|
-
.querySelector('#ReactQueryDevtoolsPanel')
|
|
137
|
-
?.querySelector('div')
|
|
138
|
-
|
|
139
|
-
if (!draggableElement) {
|
|
140
|
-
throw new Error('Could not find the draggable element')
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
await act(async () => {
|
|
144
|
-
fireEvent.mouseDown(draggableElement)
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('should display the correct query states', async () => {
|
|
149
|
-
const { queryClient, queryCache } = createQueryClient()
|
|
150
|
-
|
|
151
|
-
function Page() {
|
|
152
|
-
const { data = 'default' } = useQuery({
|
|
153
|
-
queryKey: ['check'],
|
|
154
|
-
queryFn: async () => {
|
|
155
|
-
await sleep(100)
|
|
156
|
-
return 'test'
|
|
157
|
-
},
|
|
158
|
-
staleTime: 300,
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<div>
|
|
163
|
-
<h1>{data}</h1>
|
|
164
|
-
</div>
|
|
165
|
-
)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function PageParent() {
|
|
169
|
-
const [isPageVisible, togglePageVisible] = React.useReducer(
|
|
170
|
-
(visible) => !visible,
|
|
171
|
-
true,
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
return (
|
|
175
|
-
<div>
|
|
176
|
-
<button
|
|
177
|
-
type="button"
|
|
178
|
-
aria-label="Toggle page visibility"
|
|
179
|
-
onClick={togglePageVisible}
|
|
180
|
-
>
|
|
181
|
-
Toggle Page
|
|
182
|
-
</button>
|
|
183
|
-
{isPageVisible && <Page />}
|
|
184
|
-
</div>
|
|
185
|
-
)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
renderWithClient(queryClient, <PageParent />)
|
|
189
|
-
|
|
190
|
-
fireEvent.click(
|
|
191
|
-
screen.getByRole('button', { name: /open react query devtools/i }),
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
const currentQuery = queryCache.find({ queryKey: ['check'] })
|
|
195
|
-
|
|
196
|
-
// When the query is fetching then expect number of
|
|
197
|
-
// fetching queries to be 1
|
|
198
|
-
expect(currentQuery?.state.fetchStatus).toEqual('fetching')
|
|
199
|
-
await screen.findByText(
|
|
200
|
-
getByTextContent(
|
|
201
|
-
'fresh (0) fetching (1) paused (0) stale (0) inactive (0)',
|
|
202
|
-
),
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
// When we are done fetching the query doesn't go stale
|
|
206
|
-
// until 300ms after, so expect the number of fresh
|
|
207
|
-
// queries to be 1
|
|
208
|
-
await waitFor(() => {
|
|
209
|
-
expect(currentQuery?.state.fetchStatus).toEqual('idle')
|
|
210
|
-
})
|
|
211
|
-
await screen.findByText(
|
|
212
|
-
getByTextContent(
|
|
213
|
-
'fresh (1) fetching (0) paused (0) stale (0) inactive (0)',
|
|
214
|
-
),
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
// Then wait for the query to go stale and then
|
|
218
|
-
// expect the number of stale queries to be 1
|
|
219
|
-
await waitFor(() => {
|
|
220
|
-
expect(currentQuery?.isStale()).toEqual(false)
|
|
221
|
-
})
|
|
222
|
-
await screen.findByText(
|
|
223
|
-
getByTextContent(
|
|
224
|
-
'fresh (0) fetching (0) paused (0) stale (1) inactive (0)',
|
|
225
|
-
),
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
// Unmount the page component thus making the query inactive
|
|
229
|
-
// and expect number of inactive queries to be 1
|
|
230
|
-
fireEvent.click(
|
|
231
|
-
screen.getByRole('button', { name: /toggle page visibility/i }),
|
|
232
|
-
)
|
|
233
|
-
await screen.findByText(
|
|
234
|
-
getByTextContent(
|
|
235
|
-
'fresh (0) fetching (0) paused (0) stale (0) inactive (1)',
|
|
236
|
-
),
|
|
237
|
-
)
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('should display the query hash and open the query details', async () => {
|
|
241
|
-
const { queryClient, queryCache } = createQueryClient()
|
|
242
|
-
|
|
243
|
-
function Page() {
|
|
244
|
-
const { data = 'default' } = useQuery({
|
|
245
|
-
queryKey: ['check'],
|
|
246
|
-
queryFn: async () => {
|
|
247
|
-
await sleep(10)
|
|
248
|
-
return 'test'
|
|
249
|
-
},
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
return (
|
|
253
|
-
<div>
|
|
254
|
-
<h1>{data}</h1>
|
|
255
|
-
</div>
|
|
256
|
-
)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
renderWithClient(queryClient, <Page />)
|
|
260
|
-
|
|
261
|
-
fireEvent.click(
|
|
262
|
-
screen.getByRole('button', { name: /open react query devtools/i }),
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
const currentQuery = queryCache.find({ queryKey: ['check'] })
|
|
266
|
-
|
|
267
|
-
await screen.findByText(getByTextContent(`1${currentQuery?.queryHash}`))
|
|
268
|
-
|
|
269
|
-
const queryButton = await screen.findByRole('button', {
|
|
270
|
-
name: `Open query details for ${currentQuery?.queryHash}`,
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
fireEvent.click(queryButton)
|
|
274
|
-
|
|
275
|
-
await screen.findByText(/query details/i)
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
it('should filter the queries via the query hash', async () => {
|
|
279
|
-
const { queryClient, queryCache } = createQueryClient()
|
|
280
|
-
|
|
281
|
-
function Page() {
|
|
282
|
-
const fooResult = useQuery({
|
|
283
|
-
queryKey: ['foo'],
|
|
284
|
-
queryFn: async () => {
|
|
285
|
-
await sleep(10)
|
|
286
|
-
return 'foo-result'
|
|
287
|
-
},
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
const barResult = useQuery({
|
|
291
|
-
queryKey: ['bar'],
|
|
292
|
-
queryFn: async () => {
|
|
293
|
-
await sleep(10)
|
|
294
|
-
return 'bar-result'
|
|
295
|
-
},
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
const bazResult = useQuery({
|
|
299
|
-
queryKey: ['baz'],
|
|
300
|
-
queryFn: async () => {
|
|
301
|
-
await sleep(10)
|
|
302
|
-
return 'baz-result'
|
|
303
|
-
},
|
|
304
|
-
})
|
|
305
|
-
|
|
306
|
-
return (
|
|
307
|
-
<div>
|
|
308
|
-
<h1>
|
|
309
|
-
{barResult.data} {fooResult.data} {bazResult.data}
|
|
310
|
-
</h1>
|
|
311
|
-
</div>
|
|
312
|
-
)
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
renderWithClient(queryClient, <Page />)
|
|
316
|
-
|
|
317
|
-
fireEvent.click(
|
|
318
|
-
screen.getByRole('button', { name: /open react query devtools/i }),
|
|
319
|
-
)
|
|
320
|
-
|
|
321
|
-
const fooQueryHash =
|
|
322
|
-
queryCache.find({ queryKey: ['foo'] })?.queryHash ?? 'invalid hash'
|
|
323
|
-
const barQueryHash =
|
|
324
|
-
queryCache.find({ queryKey: ['bar'] })?.queryHash ?? 'invalid hash'
|
|
325
|
-
const bazQueryHash =
|
|
326
|
-
queryCache.find({ queryKey: ['baz'] })?.queryHash ?? 'invalid hash'
|
|
327
|
-
|
|
328
|
-
await screen.findByText(fooQueryHash)
|
|
329
|
-
screen.getByText(barQueryHash)
|
|
330
|
-
screen.getByText(bazQueryHash)
|
|
331
|
-
|
|
332
|
-
const filterInput = screen.getByLabelText(/filter by queryhash/i)
|
|
333
|
-
fireEvent.change(filterInput, { target: { value: 'fo' } })
|
|
334
|
-
|
|
335
|
-
await screen.findByText(fooQueryHash)
|
|
336
|
-
const barItem = screen.queryByText(barQueryHash)
|
|
337
|
-
const bazItem = screen.queryByText(bazQueryHash)
|
|
338
|
-
expect(barItem).toBeNull()
|
|
339
|
-
expect(bazItem).toBeNull()
|
|
340
|
-
|
|
341
|
-
fireEvent.change(filterInput, { target: { value: '' } })
|
|
342
|
-
})
|
|
343
|
-
|
|
344
|
-
it('should show a disabled label if all observers are disabled', async () => {
|
|
345
|
-
const { queryClient } = createQueryClient()
|
|
346
|
-
|
|
347
|
-
function Page() {
|
|
348
|
-
const [enabled, setEnabled] = React.useState(false)
|
|
349
|
-
const { data } = useQuery({
|
|
350
|
-
queryKey: ['key'],
|
|
351
|
-
queryFn: async () => {
|
|
352
|
-
await sleep(10)
|
|
353
|
-
return 'test'
|
|
354
|
-
},
|
|
355
|
-
enabled,
|
|
356
|
-
})
|
|
357
|
-
|
|
358
|
-
return (
|
|
359
|
-
<div>
|
|
360
|
-
<h1>{data}</h1>
|
|
361
|
-
<button onClick={() => setEnabled(true)}>Enable Query</button>
|
|
362
|
-
</div>
|
|
363
|
-
)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
renderWithClient(queryClient, <Page />, { initialIsOpen: true })
|
|
367
|
-
|
|
368
|
-
await screen.findByText(/disabled/i)
|
|
369
|
-
|
|
370
|
-
fireEvent.click(screen.getByRole('button', { name: /enable query/i }))
|
|
371
|
-
|
|
372
|
-
await waitFor(() => {
|
|
373
|
-
expect(screen.queryByText(/disabled/i)).not.toBeInTheDocument()
|
|
374
|
-
})
|
|
375
|
-
})
|
|
376
|
-
|
|
377
|
-
it('should not show a disabled label for inactive queries', async () => {
|
|
378
|
-
const { queryClient } = createQueryClient()
|
|
379
|
-
|
|
380
|
-
function Page() {
|
|
381
|
-
const { data } = useQuery({
|
|
382
|
-
queryKey: ['key'],
|
|
383
|
-
queryFn: () => Promise.resolve('test'),
|
|
384
|
-
enabled: false,
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
return (
|
|
388
|
-
<div>
|
|
389
|
-
<h1>{data}</h1>
|
|
390
|
-
</div>
|
|
391
|
-
)
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
function App() {
|
|
395
|
-
const [visible, setVisible] = React.useState(true)
|
|
396
|
-
|
|
397
|
-
return (
|
|
398
|
-
<div>
|
|
399
|
-
{visible ? <Page /> : null}
|
|
400
|
-
<button onClick={() => setVisible(false)}>Hide Query</button>
|
|
401
|
-
</div>
|
|
402
|
-
)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
renderWithClient(queryClient, <App />, { initialIsOpen: true })
|
|
406
|
-
|
|
407
|
-
await screen.findByText(/disabled/i)
|
|
408
|
-
|
|
409
|
-
fireEvent.click(screen.getByRole('button', { name: /hide query/i }))
|
|
410
|
-
|
|
411
|
-
await waitFor(() => {
|
|
412
|
-
expect(screen.queryByText(/disabled/i)).not.toBeInTheDocument()
|
|
413
|
-
})
|
|
414
|
-
})
|
|
415
|
-
|
|
416
|
-
it('should simulate offline mode', async () => {
|
|
417
|
-
const { queryClient } = createQueryClient()
|
|
418
|
-
let count = 0
|
|
419
|
-
|
|
420
|
-
function App() {
|
|
421
|
-
const { data, fetchStatus } = useQuery({
|
|
422
|
-
queryKey: ['key'],
|
|
423
|
-
queryFn: () => {
|
|
424
|
-
count++
|
|
425
|
-
return Promise.resolve('test')
|
|
426
|
-
},
|
|
427
|
-
})
|
|
428
|
-
|
|
429
|
-
return (
|
|
430
|
-
<div>
|
|
431
|
-
<h1>
|
|
432
|
-
{data}, {fetchStatus}
|
|
433
|
-
</h1>
|
|
434
|
-
</div>
|
|
435
|
-
)
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
renderWithClient(queryClient, <App />, {
|
|
439
|
-
initialIsOpen: true,
|
|
440
|
-
})
|
|
441
|
-
|
|
442
|
-
await screen.findByRole('heading', { name: /test/i })
|
|
443
|
-
|
|
444
|
-
fireEvent.click(
|
|
445
|
-
screen.getByRole('button', { name: /mock offline behavior/i }),
|
|
446
|
-
)
|
|
447
|
-
|
|
448
|
-
const queryButton = await screen.findByRole('button', {
|
|
449
|
-
name: 'Open query details for ["key"]',
|
|
450
|
-
})
|
|
451
|
-
fireEvent.click(queryButton)
|
|
452
|
-
|
|
453
|
-
const refetchButton = await screen.findByRole('button', {
|
|
454
|
-
name: /refetch/i,
|
|
455
|
-
})
|
|
456
|
-
fireEvent.click(refetchButton)
|
|
457
|
-
|
|
458
|
-
await waitFor(() => {
|
|
459
|
-
expect(screen.getByText('test, paused')).toBeInTheDocument()
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
fireEvent.click(
|
|
463
|
-
screen.getByRole('button', { name: /restore offline mock/i }),
|
|
464
|
-
)
|
|
465
|
-
|
|
466
|
-
await waitFor(() => {
|
|
467
|
-
expect(screen.getByText('test, idle')).toBeInTheDocument()
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
expect(count).toBe(2)
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
it('should sort the queries according to the sorting filter', async () => {
|
|
474
|
-
const { queryClient, queryCache } = createQueryClient()
|
|
475
|
-
|
|
476
|
-
function Page() {
|
|
477
|
-
const query1Result = useQuery({
|
|
478
|
-
queryKey: ['query-1'],
|
|
479
|
-
queryFn: async () => {
|
|
480
|
-
await sleep(20)
|
|
481
|
-
return 'query-1-result'
|
|
482
|
-
},
|
|
483
|
-
})
|
|
484
|
-
|
|
485
|
-
const query3Result = useQuery({
|
|
486
|
-
queryKey: ['query-3'],
|
|
487
|
-
queryFn: async () => {
|
|
488
|
-
await sleep(10)
|
|
489
|
-
return 'query-3-result'
|
|
490
|
-
},
|
|
491
|
-
staleTime: Infinity,
|
|
492
|
-
enabled: typeof query1Result.data === 'string',
|
|
493
|
-
})
|
|
494
|
-
|
|
495
|
-
const query2Result = useQuery({
|
|
496
|
-
queryKey: ['query-2'],
|
|
497
|
-
queryFn: async () => {
|
|
498
|
-
await sleep(10)
|
|
499
|
-
return 'query-2-result'
|
|
500
|
-
},
|
|
501
|
-
|
|
502
|
-
enabled: typeof query3Result.data === 'string',
|
|
503
|
-
})
|
|
504
|
-
|
|
505
|
-
return (
|
|
506
|
-
<div>
|
|
507
|
-
<h1>
|
|
508
|
-
{query1Result.data} {query2Result.data} {query3Result.data}
|
|
509
|
-
</h1>
|
|
510
|
-
</div>
|
|
511
|
-
)
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
renderWithClient(queryClient, <Page />)
|
|
515
|
-
|
|
516
|
-
fireEvent.click(
|
|
517
|
-
screen.getByRole('button', { name: /open react query devtools/i }),
|
|
518
|
-
)
|
|
519
|
-
|
|
520
|
-
const query1Hash =
|
|
521
|
-
queryCache.find({ queryKey: ['query-1'] })?.queryHash ?? 'invalid hash'
|
|
522
|
-
const query2Hash =
|
|
523
|
-
queryCache.find({ queryKey: ['query-2'] })?.queryHash ?? 'invalid hash'
|
|
524
|
-
const query3Hash =
|
|
525
|
-
queryCache.find({ queryKey: ['query-3'] })?.queryHash ?? 'invalid hash'
|
|
526
|
-
|
|
527
|
-
const sortSelect = screen.getByLabelText(/sort queries/i)
|
|
528
|
-
let queries = []
|
|
529
|
-
|
|
530
|
-
// When sorted by query hash the queries get sorted according
|
|
531
|
-
// to just the number, with the order being -> query-1, query-2, query-3
|
|
532
|
-
fireEvent.change(sortSelect, { target: { value: 'Query Hash' } })
|
|
533
|
-
|
|
534
|
-
/** To check the order of the queries we can use regex to find
|
|
535
|
-
* all the row items in an array and then compare the items
|
|
536
|
-
* one by one in the order we expect it
|
|
537
|
-
* @reference https://github.com/testing-library/react-testing-library/issues/313#issuecomment-625294327
|
|
538
|
-
*/
|
|
539
|
-
queries = await screen.findAllByText(/\["query-[1-3]"\]/)
|
|
540
|
-
expect(queries[0]?.textContent).toEqual(query1Hash)
|
|
541
|
-
expect(queries[1]?.textContent).toEqual(query2Hash)
|
|
542
|
-
expect(queries[2]?.textContent).toEqual(query3Hash)
|
|
543
|
-
|
|
544
|
-
// Wait for the queries to be resolved
|
|
545
|
-
await screen.findByText(/query-1-result query-2-result query-3-result/i)
|
|
546
|
-
|
|
547
|
-
// When sorted by the last updated date the queries are sorted by the time
|
|
548
|
-
// they were updated and since the query-2 takes longest time to complete
|
|
549
|
-
// and query-1 the shortest, so the order is -> query-2, query-3, query-1
|
|
550
|
-
fireEvent.change(sortSelect, { target: { value: 'Last Updated' } })
|
|
551
|
-
|
|
552
|
-
queries = await screen.findAllByText(/\["query-[1-3]"\]/)
|
|
553
|
-
expect(queries[0]?.textContent).toEqual(query2Hash)
|
|
554
|
-
expect(queries[1]?.textContent).toEqual(query3Hash)
|
|
555
|
-
expect(queries[2]?.textContent).toEqual(query1Hash)
|
|
556
|
-
|
|
557
|
-
// When sorted by the status and then last updated date the queries
|
|
558
|
-
// query-3 takes precedence because its stale time being infinity, it
|
|
559
|
-
// always remains fresh, the rest of the queries are sorted by their last
|
|
560
|
-
// updated time, so the resulting order is -> query-3, query-2, query-1
|
|
561
|
-
fireEvent.change(sortSelect, {
|
|
562
|
-
target: { value: 'Status > Last Updated' },
|
|
563
|
-
})
|
|
564
|
-
|
|
565
|
-
queries = await screen.findAllByText(/\["query-[1-3]"\]/)
|
|
566
|
-
expect(queries[0]?.textContent).toEqual(query3Hash)
|
|
567
|
-
expect(queries[1]?.textContent).toEqual(query2Hash)
|
|
568
|
-
expect(queries[2]?.textContent).toEqual(query1Hash)
|
|
569
|
-
|
|
570
|
-
// Switch the order form ascending to descending and expect the
|
|
571
|
-
// query order to be reversed from previous state
|
|
572
|
-
fireEvent.click(screen.getByRole('button', { name: /⬆ asc/i }))
|
|
573
|
-
|
|
574
|
-
queries = await screen.findAllByText(/\["query-[1-3]"\]/)
|
|
575
|
-
expect(queries[0]?.textContent).toEqual(query1Hash)
|
|
576
|
-
expect(queries[1]?.textContent).toEqual(query2Hash)
|
|
577
|
-
expect(queries[2]?.textContent).toEqual(query3Hash)
|
|
578
|
-
})
|
|
579
|
-
|
|
580
|
-
it('should initialize filtering and sorting values with defaults when they are not stored in localstorage', () => {
|
|
581
|
-
localStorage.removeItem('reactQueryDevtoolsBaseSort')
|
|
582
|
-
localStorage.removeItem('reactQueryDevtoolsSortFn')
|
|
583
|
-
localStorage.removeItem('reactQueryDevtoolsFilter')
|
|
584
|
-
|
|
585
|
-
const { queryClient } = createQueryClient()
|
|
586
|
-
|
|
587
|
-
function Page() {
|
|
588
|
-
const { data = 'default' } = useQuery({
|
|
589
|
-
queryKey: ['check'],
|
|
590
|
-
queryFn: async () => {
|
|
591
|
-
await sleep(10)
|
|
592
|
-
return 'test'
|
|
593
|
-
},
|
|
594
|
-
})
|
|
595
|
-
|
|
596
|
-
return (
|
|
597
|
-
<div>
|
|
598
|
-
<h1>{data}</h1>
|
|
599
|
-
</div>
|
|
600
|
-
)
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
renderWithClient(queryClient, <Page />, {
|
|
604
|
-
initialIsOpen: true,
|
|
605
|
-
})
|
|
606
|
-
|
|
607
|
-
const filterInput: HTMLInputElement =
|
|
608
|
-
screen.getByLabelText(/Filter by queryhash/i)
|
|
609
|
-
expect(filterInput.value).toEqual('')
|
|
610
|
-
|
|
611
|
-
const sortCombobox: HTMLSelectElement =
|
|
612
|
-
screen.getByLabelText(/Sort queries/i)
|
|
613
|
-
expect(sortCombobox.value).toEqual(Object.keys(sortFns)[0])
|
|
614
|
-
|
|
615
|
-
expect(screen.getByRole('button', { name: /Asc/i })).toBeInTheDocument()
|
|
616
|
-
|
|
617
|
-
const detailsPanel = screen.queryByText(/Query Details/i)
|
|
618
|
-
expect(detailsPanel).not.toBeInTheDocument()
|
|
619
|
-
})
|
|
620
|
-
|
|
621
|
-
it('should initialize sorting values with ones stored in localstorage', async () => {
|
|
622
|
-
localStorage.setItem('reactQueryDevtoolsBaseSort', 'true')
|
|
623
|
-
localStorage.setItem(
|
|
624
|
-
'reactQueryDevtoolsSortFn',
|
|
625
|
-
JSON.stringify(Object.keys(sortFns)[1]),
|
|
626
|
-
)
|
|
627
|
-
|
|
628
|
-
const { queryClient } = createQueryClient()
|
|
629
|
-
|
|
630
|
-
function Page() {
|
|
631
|
-
const { data = 'default' } = useQuery({
|
|
632
|
-
queryKey: ['check'],
|
|
633
|
-
queryFn: async () => {
|
|
634
|
-
await sleep(10)
|
|
635
|
-
return 'test'
|
|
636
|
-
},
|
|
637
|
-
})
|
|
638
|
-
|
|
639
|
-
return (
|
|
640
|
-
<div>
|
|
641
|
-
<h1>{data}</h1>
|
|
642
|
-
</div>
|
|
643
|
-
)
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
renderWithClient(queryClient, <Page />, {
|
|
647
|
-
initialIsOpen: true,
|
|
648
|
-
})
|
|
649
|
-
|
|
650
|
-
const sortCombobox: HTMLSelectElement =
|
|
651
|
-
screen.getByLabelText(/Sort queries/i)
|
|
652
|
-
expect(sortCombobox.value).toEqual(Object.keys(sortFns)[1])
|
|
653
|
-
|
|
654
|
-
expect(screen.getByRole('button', { name: /Desc/i })).toBeInTheDocument()
|
|
655
|
-
})
|
|
656
|
-
|
|
657
|
-
it('should initialize filter value with one stored in localstorage', () => {
|
|
658
|
-
localStorage.setItem('reactQueryDevtoolsFilter', JSON.stringify('posts'))
|
|
659
|
-
|
|
660
|
-
const { queryClient } = createQueryClient()
|
|
661
|
-
|
|
662
|
-
function Page() {
|
|
663
|
-
const { data = 'default' } = useQuery({
|
|
664
|
-
queryKey: ['check'],
|
|
665
|
-
queryFn: async () => {
|
|
666
|
-
await sleep(10)
|
|
667
|
-
return 'test'
|
|
668
|
-
},
|
|
669
|
-
})
|
|
670
|
-
|
|
671
|
-
return (
|
|
672
|
-
<div>
|
|
673
|
-
<h1>{data}</h1>
|
|
674
|
-
</div>
|
|
675
|
-
)
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
renderWithClient(queryClient, <Page />, {
|
|
679
|
-
initialIsOpen: true,
|
|
680
|
-
})
|
|
681
|
-
|
|
682
|
-
const filterInput: HTMLInputElement =
|
|
683
|
-
screen.getByLabelText(/Filter by queryhash/i)
|
|
684
|
-
expect(filterInput.value).toEqual('posts')
|
|
685
|
-
})
|
|
686
|
-
|
|
687
|
-
it('style should have a nonce', async () => {
|
|
688
|
-
const { queryClient } = createQueryClient()
|
|
689
|
-
|
|
690
|
-
function Page() {
|
|
691
|
-
return <div></div>
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
const { container } = renderWithClient(queryClient, <Page />, {
|
|
695
|
-
styleNonce: 'test-nonce',
|
|
696
|
-
initialIsOpen: false,
|
|
697
|
-
})
|
|
698
|
-
const styleTag = container.querySelector('style')
|
|
699
|
-
expect(styleTag).toHaveAttribute('nonce', 'test-nonce')
|
|
700
|
-
|
|
701
|
-
await screen.findByRole('button', { name: /react query devtools/i })
|
|
702
|
-
})
|
|
703
|
-
|
|
704
|
-
it('should render a menu to select panel position', async () => {
|
|
705
|
-
const { queryClient } = createQueryClient()
|
|
706
|
-
|
|
707
|
-
function Page() {
|
|
708
|
-
const { data = 'default' } = useQuery({
|
|
709
|
-
queryKey: ['check'],
|
|
710
|
-
queryFn: async () => 'test',
|
|
711
|
-
})
|
|
712
|
-
|
|
713
|
-
return (
|
|
714
|
-
<div>
|
|
715
|
-
<h1>{data}</h1>
|
|
716
|
-
</div>
|
|
717
|
-
)
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
renderWithClient(queryClient, <Page />, {
|
|
721
|
-
initialIsOpen: true,
|
|
722
|
-
})
|
|
723
|
-
|
|
724
|
-
const positionSelect: HTMLSelectElement = await screen.findByLabelText(
|
|
725
|
-
'Panel position',
|
|
726
|
-
)
|
|
727
|
-
|
|
728
|
-
expect(positionSelect.value).toBe('bottom')
|
|
729
|
-
})
|
|
730
|
-
|
|
731
|
-
it(`should render the panel to the left if panelPosition is set to 'left'`, async () => {
|
|
732
|
-
const { queryClient } = createQueryClient()
|
|
733
|
-
|
|
734
|
-
function Page() {
|
|
735
|
-
const { data = 'default' } = useQuery({
|
|
736
|
-
queryKey: ['check'],
|
|
737
|
-
queryFn: async () => 'test',
|
|
738
|
-
})
|
|
739
|
-
|
|
740
|
-
return (
|
|
741
|
-
<div>
|
|
742
|
-
<h1>{data}</h1>
|
|
743
|
-
</div>
|
|
744
|
-
)
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
renderWithClient(queryClient, <Page />, {
|
|
748
|
-
initialIsOpen: true,
|
|
749
|
-
panelPosition: 'left',
|
|
750
|
-
})
|
|
751
|
-
|
|
752
|
-
const positionSelect: HTMLSelectElement = await screen.findByLabelText(
|
|
753
|
-
'Panel position',
|
|
754
|
-
)
|
|
755
|
-
|
|
756
|
-
expect(positionSelect.value).toBe('left')
|
|
757
|
-
|
|
758
|
-
const panel = (await screen.getByLabelText(
|
|
759
|
-
'React Query Devtools Panel',
|
|
760
|
-
)) as HTMLDivElement
|
|
761
|
-
|
|
762
|
-
expect(panel.style.left).toBe('0px')
|
|
763
|
-
expect(panel.style.width).toBe('500px')
|
|
764
|
-
expect(panel.style.height).toBe('100vh')
|
|
765
|
-
})
|
|
766
|
-
|
|
767
|
-
it('should change the panel position if user select different option from the menu', async () => {
|
|
768
|
-
const { queryClient } = createQueryClient()
|
|
769
|
-
|
|
770
|
-
function Page() {
|
|
771
|
-
const { data = 'default' } = useQuery({
|
|
772
|
-
queryKey: ['check'],
|
|
773
|
-
queryFn: async () => 'test',
|
|
774
|
-
})
|
|
775
|
-
|
|
776
|
-
return (
|
|
777
|
-
<div>
|
|
778
|
-
<h1>{data}</h1>
|
|
779
|
-
</div>
|
|
780
|
-
)
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
renderWithClient(queryClient, <Page />, {
|
|
784
|
-
initialIsOpen: true,
|
|
785
|
-
})
|
|
786
|
-
|
|
787
|
-
const positionSelect: HTMLSelectElement = await screen.findByLabelText(
|
|
788
|
-
'Panel position',
|
|
789
|
-
)
|
|
790
|
-
|
|
791
|
-
expect(positionSelect.value).toBe('bottom')
|
|
792
|
-
|
|
793
|
-
const panel = (await screen.getByLabelText(
|
|
794
|
-
'React Query Devtools Panel',
|
|
795
|
-
)) as HTMLDivElement
|
|
796
|
-
|
|
797
|
-
expect(panel.style.bottom).toBe('0px')
|
|
798
|
-
expect(panel.style.height).toBe('500px')
|
|
799
|
-
expect(panel.style.width).toBe('100%')
|
|
800
|
-
|
|
801
|
-
await act(async () => {
|
|
802
|
-
fireEvent.change(positionSelect, { target: { value: 'right' } })
|
|
803
|
-
})
|
|
804
|
-
|
|
805
|
-
expect(positionSelect.value).toBe('right')
|
|
806
|
-
|
|
807
|
-
expect(panel.style.right).toBe('0px')
|
|
808
|
-
expect(panel.style.width).toBe('500px')
|
|
809
|
-
expect(panel.style.height).toBe('100vh')
|
|
810
|
-
})
|
|
811
|
-
|
|
812
|
-
it('should restore parent element padding after closing', async () => {
|
|
813
|
-
const { queryClient } = createQueryClient()
|
|
814
|
-
|
|
815
|
-
function Page() {
|
|
816
|
-
const { data = 'default' } = useQuery({
|
|
817
|
-
queryKey: ['check'],
|
|
818
|
-
queryFn: async () => 'test',
|
|
819
|
-
})
|
|
820
|
-
|
|
821
|
-
return (
|
|
822
|
-
<div>
|
|
823
|
-
<h1>{data}</h1>
|
|
824
|
-
</div>
|
|
825
|
-
)
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
const parentElementTestid = 'parentElement'
|
|
829
|
-
const parentPaddings = {
|
|
830
|
-
paddingTop: '428px',
|
|
831
|
-
paddingBottom: '39px',
|
|
832
|
-
paddingLeft: '-373px',
|
|
833
|
-
paddingRight: '20%',
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
function Parent({ children }: { children: React.ReactElement }) {
|
|
837
|
-
return (
|
|
838
|
-
<div data-testid={parentElementTestid} style={parentPaddings}>
|
|
839
|
-
{children}
|
|
840
|
-
</div>
|
|
841
|
-
)
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
renderWithClient(
|
|
845
|
-
queryClient,
|
|
846
|
-
<Page />,
|
|
847
|
-
{
|
|
848
|
-
initialIsOpen: true,
|
|
849
|
-
panelPosition: 'bottom',
|
|
850
|
-
},
|
|
851
|
-
{ wrapper: Parent },
|
|
852
|
-
)
|
|
853
|
-
|
|
854
|
-
const parentElement = screen.getByTestId(parentElementTestid)
|
|
855
|
-
expect(parentElement).toHaveStyle({
|
|
856
|
-
paddingTop: '0px',
|
|
857
|
-
paddingLeft: '0px',
|
|
858
|
-
paddingRight: '0px',
|
|
859
|
-
paddingBottom: defaultPanelSize,
|
|
860
|
-
})
|
|
861
|
-
|
|
862
|
-
fireEvent.click(screen.getByRole('button', { name: /^close$/i }))
|
|
863
|
-
expect(parentElement).toHaveStyle(parentPaddings)
|
|
3
|
+
expect(1).toBe(1)
|
|
864
4
|
})
|
|
865
5
|
})
|