@@ -1433,6 +1433,92 @@ describe("chat session controls", () => {
14331433 } ) ;
14341434 } ) ;
14351435
1436+ it ( "does not destroy picker result when blurring an initially empty search input" , async ( ) => {
1437+ const { state, request } = createChatHeaderState ( ) ;
1438+ state . sessionsIncludeGlobal = false ;
1439+ state . sessionsIncludeUnknown = false ;
1440+ const container = document . createElement ( "div" ) ;
1441+ render ( renderChatSessionSelect ( state ) , container ) ;
1442+
1443+ container . querySelector < HTMLButtonElement > ( 'button[data-chat-session-select="true"]' ) ! . click ( ) ;
1444+ await vi . waitFor ( ( ) => expect ( state . chatSessionPickerResult ) . not . toBeNull ( ) ) ;
1445+ render ( renderChatSessionSelect ( state ) , container ) ;
1446+ const pickerResultBefore = state . chatSessionPickerResult ;
1447+ const optionsBefore = container . querySelectorAll (
1448+ 'button[data-chat-session-picker-option="true"]' ,
1449+ ) ;
1450+ expect ( optionsBefore . length ) . toBeGreaterThan ( 0 ) ;
1451+
1452+ const input = container . querySelector < HTMLInputElement > (
1453+ 'input[data-chat-session-picker-search="true"]' ,
1454+ ) ;
1455+ expect ( input ! . value ) . toBe ( "" ) ;
1456+ const searchCallsBefore = request . mock . calls . filter (
1457+ ( [ method ] ) => method === "sessions.list" ,
1458+ ) . length ;
1459+
1460+ input ! . dispatchEvent ( new FocusEvent ( "blur" , { bubbles : false } ) ) ;
1461+ render ( renderChatSessionSelect ( state ) , container ) ;
1462+
1463+ expect ( state . chatSessionPickerResult ) . toBe ( pickerResultBefore ) ;
1464+ expect ( state . chatSessionPickerOpen ) . toBe ( true ) ;
1465+ const optionsAfter = container . querySelectorAll (
1466+ 'button[data-chat-session-picker-option="true"]' ,
1467+ ) ;
1468+ expect ( optionsAfter . length ) . toBe ( optionsBefore . length ) ;
1469+ const searchCallsAfter = request . mock . calls . filter (
1470+ ( [ method ] ) => method === "sessions.list" ,
1471+ ) . length ;
1472+ expect ( searchCallsAfter ) . toBe ( searchCallsBefore ) ;
1473+ } ) ;
1474+
1475+ it ( "session option click still works after blurring an empty search input" , async ( ) => {
1476+ const { state } = createChatHeaderState ( ) ;
1477+ state . sessionsIncludeGlobal = false ;
1478+ state . sessionsIncludeUnknown = false ;
1479+ state . sessionsResult = createSessionsResultFromRows ( [
1480+ { key : "main" , kind : "direct" , label : "Main" , updatedAt : 2 } ,
1481+ { key : "agent:main:work" , kind : "direct" , label : "Work" , updatedAt : 1 } ,
1482+ ] ) ;
1483+ const request = vi . fn ( ( method : string ) => {
1484+ if ( method === "sessions.list" ) {
1485+ return Promise . resolve (
1486+ createSessionsResultFromRows ( [
1487+ { key : "main" , kind : "direct" , label : "Main" , updatedAt : 2 } ,
1488+ { key : "agent:main:work" , kind : "direct" , label : "Work" , updatedAt : 1 } ,
1489+ ] ) ,
1490+ ) ;
1491+ }
1492+ throw new Error ( `Unexpected request: ${ method } ` ) ;
1493+ } ) ;
1494+ state . client = { request } as unknown as GatewayBrowserClient ;
1495+ const onSwitchSession = vi . fn ( ) ;
1496+ const container = document . createElement ( "div" ) ;
1497+ render ( renderChatSessionSelect ( state , onSwitchSession ) , container ) ;
1498+
1499+ container . querySelector < HTMLButtonElement > ( 'button[data-chat-session-select="true"]' ) ! . click ( ) ;
1500+ await vi . waitFor ( ( ) => expect ( state . chatSessionPickerResult ) . not . toBeNull ( ) ) ;
1501+ render ( renderChatSessionSelect ( state , onSwitchSession ) , container ) ;
1502+
1503+ const input = container . querySelector < HTMLInputElement > (
1504+ 'input[data-chat-session-picker-search="true"]' ,
1505+ ) ;
1506+ expect ( input ! . value ) . toBe ( "" ) ;
1507+ input ! . dispatchEvent ( new FocusEvent ( "blur" , { bubbles : false } ) ) ;
1508+ render ( renderChatSessionSelect ( state , onSwitchSession ) , container ) ;
1509+
1510+ const options = container . querySelectorAll < HTMLButtonElement > (
1511+ 'button[data-chat-session-picker-option="true"]' ,
1512+ ) ;
1513+ const target = [ ...options ] . find (
1514+ ( button ) => button . dataset . sessionKey && button . dataset . sessionKey !== state . sessionKey ,
1515+ ) ;
1516+ expect ( target ) . toBeTruthy ( ) ;
1517+ target ! . click ( ) ;
1518+
1519+ expect ( onSwitchSession ) . toHaveBeenCalledWith ( state , target ! . dataset . sessionKey ) ;
1520+ } ) ;
1521+
14361522 it ( "clears applied chat session picker search when the input is cleared" , async ( ) => {
14371523 const { state } = createChatHeaderState ( ) ;
14381524 state . sessionsIncludeGlobal = false ;
0 commit comments