@@ -34,19 +34,6 @@ describe('Devtools', () => {
3434 beforeEach ( ( ) => {
3535 vi . useFakeTimers ( )
3636 previousRootFontSize = document . documentElement . style . fontSize
37- // jsdom doesn't implement `PointerEvent`; the DropdownMenu trigger checks
38- // `e.pointerType !== 'touch'` on pointerdown to decide whether to open,
39- // so we polyfill it as a thin wrapper around `MouseEvent`.
40- if ( typeof window . PointerEvent === 'undefined' ) {
41- class FakePointerEvent extends MouseEvent {
42- pointerType : string
43- constructor ( type : string , init : PointerEventInit = { } ) {
44- super ( type , init )
45- this . pointerType = init . pointerType ?? 'mouse'
46- }
47- }
48- vi . stubGlobal ( 'PointerEvent' , FakePointerEvent )
49- }
5037 vi . stubGlobal ( 'localStorage' , {
5138 getItem : ( key : string ) =>
5239 Object . prototype . hasOwnProperty . call ( storage , key )
@@ -804,4 +791,152 @@ describe('Devtools', () => {
804791 expect ( afterSecondToggle ) . toBe ( afterFirstToggle === '1' ? '-1' : '1' )
805792 } )
806793 } )
794+
795+ describe ( 'settings menu' , ( ) => {
796+ it ( 'should show "Position" sub-trigger when the settings menu is opened' , ( ) => {
797+ const rendered = renderDevtools ( { initialIsOpen : true } )
798+
799+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
800+ key : 'Enter' ,
801+ } )
802+
803+ // The menu is rendered through a Portal mounted on `document.body`,
804+ // outside `rendered.container`, so look it up via `document` directly.
805+ expect (
806+ document . querySelector ( '.tsqd-settings-menu-sub-trigger-position' ) ,
807+ ) . not . toBeNull ( )
808+ } )
809+
810+ it ( 'should open "Position" sub-menu when the sub-trigger is activated' , ( ) => {
811+ const rendered = renderDevtools ( { initialIsOpen : true } )
812+
813+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
814+ key : 'Enter' ,
815+ } )
816+
817+ const subTrigger = document . querySelector < HTMLElement > (
818+ '.tsqd-settings-menu-sub-trigger-position' ,
819+ )
820+ expect ( subTrigger ) . not . toBeNull ( )
821+ fireEvent . keyDown ( subTrigger ! , { key : 'ArrowRight' } )
822+
823+ expect (
824+ document . querySelector ( '[aria-label="Position settings"]' ) ,
825+ ) . not . toBeNull ( )
826+ } )
827+
828+ it ( 'should persist "position" when a position radio item is selected' , ( ) => {
829+ const rendered = renderDevtools ( { initialIsOpen : true } )
830+
831+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
832+ key : 'Enter' ,
833+ } )
834+
835+ const subTrigger = document . querySelector < HTMLElement > (
836+ '.tsqd-settings-menu-sub-trigger-position' ,
837+ )
838+ expect ( subTrigger ) . not . toBeNull ( )
839+ fireEvent . keyDown ( subTrigger ! , { key : 'ArrowRight' } )
840+
841+ const topItem = document . querySelector < HTMLElement > (
842+ '.tsqd-settings-menu-position-btn-top' ,
843+ )
844+ expect ( topItem ) . not . toBeNull ( )
845+ fireEvent . keyDown ( topItem ! , { key : 'Enter' } )
846+
847+ expect ( localStorage . getItem ( 'TanstackQueryDevtools.position' ) ) . toBe ( 'top' )
848+ } )
849+
850+ it ( 'should open "Theme" sub-menu when the sub-trigger is activated' , ( ) => {
851+ const rendered = renderDevtools ( { initialIsOpen : true } )
852+
853+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
854+ key : 'Enter' ,
855+ } )
856+
857+ const themeTrigger = Array . from (
858+ document . querySelectorAll < HTMLElement > (
859+ '.tsqd-settings-menu-sub-trigger' ,
860+ ) ,
861+ ) . find ( ( el ) => String ( el . textContent ) . includes ( 'Theme' ) )
862+ expect ( themeTrigger ) . not . toBeUndefined ( )
863+ fireEvent . keyDown ( themeTrigger ! , { key : 'ArrowRight' } )
864+
865+ expect (
866+ document . querySelector ( '[aria-label="Theme preference"]' ) ,
867+ ) . not . toBeNull ( )
868+ } )
869+
870+ it ( 'should persist "theme_preference" when a theme radio item is selected' , ( ) => {
871+ const rendered = renderDevtools ( { initialIsOpen : true } )
872+
873+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
874+ key : 'Enter' ,
875+ } )
876+
877+ const themeTrigger = Array . from (
878+ document . querySelectorAll < HTMLElement > (
879+ '.tsqd-settings-menu-sub-trigger' ,
880+ ) ,
881+ ) . find ( ( el ) => String ( el . textContent ) . includes ( 'Theme' ) )
882+ expect ( themeTrigger ) . not . toBeUndefined ( )
883+ fireEvent . keyDown ( themeTrigger ! , { key : 'ArrowRight' } )
884+
885+ const themeMenu = document . querySelector (
886+ '[aria-label="Theme preference"]' ,
887+ )
888+ const lightItem = Array . from (
889+ themeMenu ?. querySelectorAll < HTMLElement > ( '[role="menuitemradio"]' ) ??
890+ [ ] ,
891+ ) . find ( ( el ) => String ( el . textContent ) . includes ( 'Light' ) )
892+ expect ( lightItem ) . not . toBeUndefined ( )
893+ fireEvent . keyDown ( lightItem ! , { key : 'Enter' } )
894+
895+ expect (
896+ localStorage . getItem ( 'TanstackQueryDevtools.theme_preference' ) ,
897+ ) . toBe ( 'light' )
898+ } )
899+
900+ it ( 'should open "Hide disabled queries" sub-menu when the sub-trigger is activated' , ( ) => {
901+ const rendered = renderDevtools ( { initialIsOpen : true } )
902+
903+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
904+ key : 'Enter' ,
905+ } )
906+
907+ const hideTrigger = document . querySelector < HTMLElement > (
908+ '.tsqd-settings-menu-sub-trigger-disabled-queries' ,
909+ )
910+ expect ( hideTrigger ) . not . toBeNull ( )
911+ fireEvent . keyDown ( hideTrigger ! , { key : 'ArrowRight' } )
912+
913+ expect (
914+ document . querySelector ( '[aria-label="Hide disabled queries setting"]' ) ,
915+ ) . not . toBeNull ( )
916+ } )
917+
918+ it ( 'should persist "hideDisabledQueries" when a hide-disabled radio item is selected' , ( ) => {
919+ const rendered = renderDevtools ( { initialIsOpen : true } )
920+
921+ fireEvent . keyDown ( rendered . getByLabelText ( 'Open settings menu' ) , {
922+ key : 'Enter' ,
923+ } )
924+
925+ const hideTrigger = document . querySelector < HTMLElement > (
926+ '.tsqd-settings-menu-sub-trigger-disabled-queries' ,
927+ )
928+ expect ( hideTrigger ) . not . toBeNull ( )
929+ fireEvent . keyDown ( hideTrigger ! , { key : 'ArrowRight' } )
930+
931+ const hideItem = document . querySelector < HTMLElement > (
932+ '.tsqd-settings-menu-position-btn-hide' ,
933+ )
934+ expect ( hideItem ) . not . toBeNull ( )
935+ fireEvent . keyDown ( hideItem ! , { key : 'Enter' } )
936+
937+ expect (
938+ localStorage . getItem ( 'TanstackQueryDevtools.hideDisabledQueries' ) ,
939+ ) . toBe ( 'true' )
940+ } )
941+ } )
807942} )
0 commit comments