From a7749fc1bbcd69760dc495a2073c4f9bba7c8d9b Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Mon, 11 May 2026 09:59:34 +0900 Subject: [PATCH 1/3] test(query-devtools/Devtools): add tests for resize handle --- .../src/__tests__/Devtools.test.tsx | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/packages/query-devtools/src/__tests__/Devtools.test.tsx b/packages/query-devtools/src/__tests__/Devtools.test.tsx index 1ea120c459..6e6b07c7ba 100644 --- a/packages/query-devtools/src/__tests__/Devtools.test.tsx +++ b/packages/query-devtools/src/__tests__/Devtools.test.tsx @@ -939,4 +939,140 @@ describe('Devtools', () => { ).toBe('true') }) }) + + describe('resize handle', () => { + it('should increase height when "ArrowUp" is pressed on the resize handle in "bottom" position', () => { + const rendered = renderDevtools( + { position: 'bottom', initialIsOpen: true }, + { 'TanstackQueryDevtools.height': '500' }, + ) + + const handle = rendered.getByLabelText('Resize devtools panel') + fireEvent.keyDown(handle, { key: 'ArrowUp' }) + + expect( + Number(localStorage.getItem('TanstackQueryDevtools.height')), + ).toBeGreaterThan(500) + }) + + it('should decrease height when "ArrowDown" is pressed on the resize handle in "bottom" position', () => { + const rendered = renderDevtools( + { position: 'bottom', initialIsOpen: true }, + { 'TanstackQueryDevtools.height': '500' }, + ) + + const handle = rendered.getByLabelText('Resize devtools panel') + fireEvent.keyDown(handle, { key: 'ArrowDown' }) + + expect( + Number(localStorage.getItem('TanstackQueryDevtools.height')), + ).toBeLessThan(500) + }) + + it('should increase width when "ArrowLeft" is pressed on the resize handle in "right" position', () => { + const rendered = renderDevtools( + { position: 'right', initialIsOpen: true }, + { 'TanstackQueryDevtools.width': '500' }, + ) + + const handle = rendered.getByLabelText('Resize devtools panel') + fireEvent.keyDown(handle, { key: 'ArrowLeft' }) + + expect( + Number(localStorage.getItem('TanstackQueryDevtools.width')), + ).toBeGreaterThan(500) + }) + + it('should decrease width when "ArrowRight" is pressed on the resize handle in "right" position', () => { + const rendered = renderDevtools( + { position: 'right', initialIsOpen: true }, + { 'TanstackQueryDevtools.width': '500' }, + ) + + const handle = rendered.getByLabelText('Resize devtools panel') + fireEvent.keyDown(handle, { key: 'ArrowRight' }) + + expect( + Number(localStorage.getItem('TanstackQueryDevtools.width')), + ).toBeLessThan(500) + }) + + it('should increase height while dragging up in "bottom" position', () => { + const initialHeight = 500 + const rendered = renderDevtools( + { position: 'bottom', initialIsOpen: true }, + { 'TanstackQueryDevtools.height': String(initialHeight) }, + ) + + const handle = rendered.getByLabelText('Resize devtools panel') + // jsdom returns zeros for `getBoundingClientRect`; stub the panel size so + // that drag math starts from `initialHeight` instead of 0. + // Only `height` is read by the production code; other fields are unused. + const panel = handle.parentElement + expect(panel).not.toBeNull() + vi.spyOn(panel!, 'getBoundingClientRect').mockReturnValue({ + height: initialHeight, + width: 0, + x: 0, + y: 0, + top: 0, + right: 0, + bottom: 0, + left: 0, + toJSON: () => ({}), + }) + + // Move the cursor up by 50px (`clientY` 100 → 50), which adds 50px to the + // drag base of `initialHeight`. + fireEvent.mouseDown(handle, { clientX: 0, clientY: 100 }) + fireEvent( + document, + new MouseEvent('mousemove', { clientX: 0, clientY: 50 }), + ) + fireEvent(document, new MouseEvent('mouseup')) + + expect( + Number(localStorage.getItem('TanstackQueryDevtools.height')), + ).toBeGreaterThan(initialHeight) + }) + + it('should increase width while dragging left in "right" position', () => { + const initialWidth = 500 + const rendered = renderDevtools( + { position: 'right', initialIsOpen: true }, + { 'TanstackQueryDevtools.width': String(initialWidth) }, + ) + + const handle = rendered.getByLabelText('Resize devtools panel') + // `width` is read twice during drag: once as the base size, and again to + // detect when the panel hits its minimum. Returning the same value both + // times keeps the "minimum reached" branch from firing. + const panel = handle.parentElement + expect(panel).not.toBeNull() + vi.spyOn(panel!, 'getBoundingClientRect').mockReturnValue({ + height: 0, + width: initialWidth, + x: 0, + y: 0, + top: 0, + right: 0, + bottom: 0, + left: 0, + toJSON: () => ({}), + }) + + // Move the cursor left by 50px (`clientX` 100 → 50); in `right` position, + // moving left grows the panel by 50px from the drag base of `initialWidth`. + fireEvent.mouseDown(handle, { clientX: 100, clientY: 0 }) + fireEvent( + document, + new MouseEvent('mousemove', { clientX: 50, clientY: 0 }), + ) + fireEvent(document, new MouseEvent('mouseup')) + + expect( + Number(localStorage.getItem('TanstackQueryDevtools.width')), + ).toBeGreaterThan(initialWidth) + }) + }) }) From c2e5c0ab2801e50c36f3dc7ed34027cfc4b8da05 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Mon, 11 May 2026 10:03:01 +0900 Subject: [PATCH 2/3] test(query-devtools/Devtools): assert 'panel' is 'HTMLElement' instead of 'not.toBeNull' for stronger 'getBoundingClientRect' guarantee --- packages/query-devtools/src/__tests__/Devtools.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/query-devtools/src/__tests__/Devtools.test.tsx b/packages/query-devtools/src/__tests__/Devtools.test.tsx index 6e6b07c7ba..79f74863a3 100644 --- a/packages/query-devtools/src/__tests__/Devtools.test.tsx +++ b/packages/query-devtools/src/__tests__/Devtools.test.tsx @@ -1009,7 +1009,7 @@ describe('Devtools', () => { // that drag math starts from `initialHeight` instead of 0. // Only `height` is read by the production code; other fields are unused. const panel = handle.parentElement - expect(panel).not.toBeNull() + expect(panel).toBeInstanceOf(HTMLElement) vi.spyOn(panel!, 'getBoundingClientRect').mockReturnValue({ height: initialHeight, width: 0, @@ -1048,7 +1048,7 @@ describe('Devtools', () => { // detect when the panel hits its minimum. Returning the same value both // times keeps the "minimum reached" branch from firing. const panel = handle.parentElement - expect(panel).not.toBeNull() + expect(panel).toBeInstanceOf(HTMLElement) vi.spyOn(panel!, 'getBoundingClientRect').mockReturnValue({ height: 0, width: initialWidth, From 012b51614dbe6156b652bdf19fc9410c94a6700d Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Mon, 11 May 2026 10:04:03 +0900 Subject: [PATCH 3/3] test(query-devtools/Devtools): assert non-null before parsing 'localStorage' value to prevent 'Number(null) === 0' false positive in decrease assertions --- .../query-devtools/src/__tests__/Devtools.test.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/query-devtools/src/__tests__/Devtools.test.tsx b/packages/query-devtools/src/__tests__/Devtools.test.tsx index 79f74863a3..0ff1dd4d0c 100644 --- a/packages/query-devtools/src/__tests__/Devtools.test.tsx +++ b/packages/query-devtools/src/__tests__/Devtools.test.tsx @@ -964,9 +964,11 @@ describe('Devtools', () => { const handle = rendered.getByLabelText('Resize devtools panel') fireEvent.keyDown(handle, { key: 'ArrowDown' }) - expect( - Number(localStorage.getItem('TanstackQueryDevtools.height')), - ).toBeLessThan(500) + // Assert the value exists before parsing — `Number(null)` is `0`, + // which would falsely satisfy `toBeLessThan(500)` if the write was missing. + const nextHeight = localStorage.getItem('TanstackQueryDevtools.height') + expect(nextHeight).not.toBeNull() + expect(Number(nextHeight)).toBeLessThan(500) }) it('should increase width when "ArrowLeft" is pressed on the resize handle in "right" position', () => { @@ -992,9 +994,9 @@ describe('Devtools', () => { const handle = rendered.getByLabelText('Resize devtools panel') fireEvent.keyDown(handle, { key: 'ArrowRight' }) - expect( - Number(localStorage.getItem('TanstackQueryDevtools.width')), - ).toBeLessThan(500) + const nextWidth = localStorage.getItem('TanstackQueryDevtools.width') + expect(nextWidth).not.toBeNull() + expect(Number(nextWidth)).toBeLessThan(500) }) it('should increase height while dragging up in "bottom" position', () => {