Skip to content

feat(devtools): enable setting loading/error via devtools #4352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 41 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
698a114
feat(devtools): enable setting loading/error via devtools
paul-sachs Oct 21, 2022
aed37a6
Some cleanup
paul-sachs Oct 21, 2022
246b236
Merge remote-tracking branch 'origin/main' into pr/4352
TkDodo Jan 23, 2023
5683bf8
Merge branch 'main' into error--and-loading-devtools
TkDodo Jan 23, 2023
ad1c3e6
refactor: use flex-gap to align buttons
TkDodo Jan 23, 2023
9297f4b
refactor: fix linter and dropdown reset
TkDodo Jan 23, 2023
ccdfa59
refactor: operate directly on activeQuery
TkDodo Jan 23, 2023
3b104cc
Change buttons to toggle states
paul-sachs Jan 23, 2023
3d40ba2
Sneak some queryState into meta
paul-sachs Jan 23, 2023
9d688e2
Added test for error and loading
paul-sachs Jan 23, 2023
0b1b92b
Merge branch 'main' into error--and-loading-devtools
TkDodo Jan 25, 2023
f43ac38
Merge branch 'main' into error--and-loading-devtools
TkDodo Jan 26, 2023
5fdd840
Fix lint
paul-sachs Feb 1, 2023
c78d1ec
Fix prettier formatting
paul-sachs Feb 1, 2023
356e26e
Merge branch 'main' into error--and-loading-devtools
TkDodo Feb 12, 2023
7063de9
Merge branch 'main' into error--and-loading-devtools
TkDodo Feb 25, 2023
bef1f52
chore: releases should run on alpha/beta as well
TkDodo Feb 26, 2023
7d3e61d
chore: extract package validation to an extra script (#5039)
TkDodo Feb 26, 2023
30ba660
docs: update link for v2 docs (#5044)
cseas Feb 27, 2023
590dba2
release: v4.24.12
tannerlinsley Feb 27, 2023
f38b567
fix(react-query-devtools): do not stretch query status label (#5063)
janinegygax Mar 3, 2023
82a6377
release: v4.24.13
tannerlinsley Mar 3, 2023
8db407f
fix(react-query-devtools): add 'use client' directive to disable SSR …
yousoumar Mar 4, 2023
9561549
release: v4.24.14
tannerlinsley Mar 4, 2023
5abe521
feat(core): re-export matchQuery from utils (#5070)
remolueoend Mar 5, 2023
a2c0c05
release: v4.25.0
tannerlinsley Mar 5, 2023
f57e25c
feat(query-core): Add global onSettled callbacks for QueryCache and M…
TkDodo Mar 5, 2023
761e312
release: v4.26.0
tannerlinsley Mar 5, 2023
93ecbc8
fix(core): make sure mutations get updated options (#5085)
TkDodo Mar 6, 2023
fca67f6
release: v4.26.1
tannerlinsley Mar 6, 2023
7a8654f
fix(eslint-plugin): improve object property checks (#5079)
Newbie012 Mar 6, 2023
1be904a
release: v4.26.2
tannerlinsley Mar 6, 2023
c28f64c
docs: add adapter dropdown to issue template (#5108)
DamianOsipiuk Mar 10, 2023
9ac386b
docs(queries): rename `success` (#5110)
leon-fong Mar 11, 2023
c372c2e
chore: `test:lib` task-caching w/ Nx (#5116)
ZackDeRose Mar 14, 2023
dae70a8
chore: fix missing dependencies (#5127)
TkDodo Mar 14, 2023
7d9878f
chore: turning off Nx daemon in CI (#5128)
ZackDeRose Mar 14, 2023
e9c61f1
chore: downgrade chalk to v4 because v5 is ESM only (#5130)
TkDodo Mar 14, 2023
9f043a0
fix(eslint-plugin): ignore internal properties (#5119)
Newbie012 Mar 15, 2023
3ad2ba3
chore: resolve merge conflicts
TkDodo Mar 15, 2023
a4ff17e
Merge branch 'main' into error--and-loading-devtools
TkDodo Mar 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/react/devtools.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ function App() {
- The position of the React Query devtools panel
- `context?: React.Context<QueryClient | undefined>`
- Use this to use a custom React Query context. Otherwise, `defaultContext` will be used.
- `errorTypes?: { name: string; initializer: (query: Query) => { toString(): string }}`
- Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an item that can be stringified so we can check for it's presence on any given query.

## Embedded Mode

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@testing-library/react": "^13.0.0",
"@testing-library/react-17": "npm:@testing-library/react@12.1.4",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "14.4.3",
"@types/jest": "^26.0.4",
"@types/luxon": "^2.3.1",
"@types/node": "^17.0.25",
Expand Down
4 changes: 2 additions & 2 deletions packages/query-core/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ interface ContinueAction {

interface SetStateAction<TData, TError> {
type: 'setState'
state: QueryState<TData, TError>
state: Partial<QueryState<TData, TError>>
setStateOptions?: SetStateOptions
}

Expand Down Expand Up @@ -212,7 +212,7 @@ export class Query<
}

setState(
state: QueryState<TData, TError>,
state: Partial<QueryState<TData, TError>>,
setStateOptions?: SetStateOptions,
): void {
this.dispatch({ type: 'setState', state, setStateOptions })
Expand Down
139 changes: 139 additions & 0 deletions packages/react-query-devtools/src/__tests__/devtools.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
sleep,
createQueryClient,
} from './utils'
import UserEvent from '@testing-library/user-event'

// TODO: This should be removed with the types for react-error-boundary get updated.
declare module 'react-error-boundary' {
Expand All @@ -19,6 +20,13 @@ declare module 'react-error-boundary' {
}
}

class CustomError extends Error {
constructor(message: string) {
super(message)
this.name = 'CustomError'
}
}

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query: string) => ({
Expand Down Expand Up @@ -915,4 +923,135 @@ describe('ReactQueryDevtools', () => {
fireEvent.click(screen.getByRole('button', { name: /^close$/i }))
expect(parentElement).toHaveStyle(parentPaddings)
})

it('should simulate loading state', async () => {
const { queryClient } = createQueryClient()
let count = 0
function App() {
const { data, fetchStatus } = useQuery(['key'], () => {
count++
return Promise.resolve('test')
})

return (
<div>
<h1>
{data ?? 'No data'}, {fetchStatus}
</h1>
</div>
)
}

renderWithClient(queryClient, <App />, {
initialIsOpen: true,
})

await screen.findByRole('heading', { name: /test/i })

const loadingButton = await screen.findByRole('button', {
name: 'Trigger loading',
})
fireEvent.click(loadingButton)

await waitFor(() => {
expect(screen.getByText('Restore loading')).toBeInTheDocument()
})

await waitFor(() => {
expect(screen.getByText('No data, fetching')).toBeInTheDocument()
})

fireEvent.click(screen.getByRole('button', { name: /restore loading/i }))

await waitFor(() => {
expect(screen.getByText('test, idle')).toBeInTheDocument()
})

expect(count).toBe(2)
})

it('should simulate error state', async () => {
const { queryClient } = createQueryClient()
function App() {
const { status, error } = useQuery(['key'], () => {
return Promise.resolve('test')
})

return (
<div>
<h1>
{!!error ? 'Some error' : 'No error'}, {status}
</h1>
</div>
)
}

renderWithClient(queryClient, <App />, {
initialIsOpen: true,
})

const errorButton = await screen.findByRole('button', {
name: 'Trigger error',
})
fireEvent.click(errorButton)

await waitFor(() => {
expect(screen.getByText('Restore error')).toBeInTheDocument()
})

await waitFor(() => {
expect(screen.getByText('Some error, error')).toBeInTheDocument()
})

fireEvent.click(screen.getByRole('button', { name: /Restore error/i }))

await waitFor(() => {
expect(screen.getByText('No error, success')).toBeInTheDocument()
})
})

it('should can simulate a specific error', async () => {
const { queryClient } = createQueryClient()

function App() {
const { status, error } = useQuery(['key'], () => {
return Promise.resolve('test')
})

return (
<div data-testid="test">
<h1>
{error instanceof CustomError
? error.message.toString()
: 'No error'}
, {status}
</h1>
</div>
)
}

renderWithClient(queryClient, <App />, {
initialIsOpen: true,
errorTypes: [
{
name: 'error1',
initializer: () => new CustomError('error1'),
},
],
})

const errorOption = await screen.findByLabelText('Trigger error:')

UserEvent.selectOptions(errorOption, 'error1')

await waitFor(() => {
expect(screen.getByText('error1, error')).toBeInTheDocument()
})

fireEvent.click(screen.getByRole('button', { name: /Restore error/i }))

await waitFor(() => {
expect(screen.getByText('No error, success')).toBeInTheDocument()
})
})
})
Loading