| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- import {afterEach,expect,it,vi} from 'vitest'
- import {flushPromises,mount} from '@vue/test-utils'
- import Panel from '../../src/client/components/workspace/WorkspaceInspectorPanel.vue'
- import {apiRequest} from '../../src/client/api/client'
- import type {WorkspaceInspectorEntry} from '../../src/shared/workspacePanels'
- vi.mock('../../src/client/api/client',()=>({apiRequest:vi.fn()}))
- const entry=(id:string,at:number,method='message.delta',direction:WorkspaceInspectorEntry['direction']='event',agentId='agent'):WorkspaceInspectorEntry=>({id,at,method,direction,agentId,runId:'run',data:{text:id}})
- afterEach(()=>{vi.restoreAllMocks();vi.clearAllMocks()})
- function setup(entries:WorkspaceInspectorEntry[]){
- vi.spyOn(document,'hidden','get').mockReturnValue(false)
- vi.mocked(apiRequest).mockResolvedValue({entries})
- return mount(Panel,{props:{conversationId:'conversation'},global:{stubs:{AppIcon:true}}})
- }
- it('sorts by timestamp before grouping, shows newest groups first and keeps delta text in order',async()=>{
- const wrapper=setup([entry('done',400,'message.complete'),entry('B',300),entry('A',200),entry('other',100,'message.delta','event','other')])
- try{
- await flushPromises()
- const rows=wrapper.findAll('details')
- expect(rows.map(row=>row.find('.summary').text())).toEqual(['done','AB','other'])
- expect(rows[1]!.find('time').text()).toMatch(/\.300$/)
- expect(rows[1]!.find('.tag').text()).toContain('×2')
- expect(JSON.parse(rows[1]!.find('pre').text()).map((e:WorkspaceInspectorEntry)=>e.id)).toEqual(['A','B'])
- }finally{wrapper.unmount()}
- })
- it('sorts Raw responses and requests newest first, including equal-time arrival order',async()=>{
- const wrapper=setup([entry('response',300,'session.usage','response'),entry('request',100,'prompt.submit','request'),entry('same-1',200,'first','request'),entry('same-2',200,'second','response')])
- try{
- await flushPromises();await wrapper.get('.lenses button:last-child').trigger('click');await flushPromises()
- expect(wrapper.findAll('pre').map(row=>JSON.parse(row.text()).id)).toEqual(['response','same-2','same-1','request'])
- }finally{wrapper.unmount()}
- })
- it('opens at the top, follows new records at capacity, and resets a changed lens after reading older records',async()=>{
- const wrapper=setup([entry('old',100,'message.complete'),entry('new',200,'message.complete')])
- try{
- await flushPromises()
- const list=wrapper.get('.inspector-list').element as HTMLElement
- expect(list.scrollTop).toBe(0)
- list.scrollTop=150;await wrapper.get('.inspector-list').trigger('scroll')
- vi.mocked(apiRequest).mockResolvedValue({entries:[entry('new',200,'message.complete'),entry('latest',300,'message.complete')]})
- await wrapper.get('.reload').trigger('click');await flushPromises()
- expect(list.scrollTop).toBe(150)
- await wrapper.get('.lenses button:last-child').trigger('click');await flushPromises();expect(list.scrollTop).toBe(0)
- await wrapper.get('.lenses button:first-child').trigger('click');await flushPromises()
- list.scrollTop=20;await wrapper.get('.inspector-list').trigger('scroll')
- vi.mocked(apiRequest).mockResolvedValue({entries:[entry('latest',300,'message.complete'),entry('live',400,'message.complete')]})
- await wrapper.get('.reload').trigger('click');await flushPromises();expect(list.scrollTop).toBe(0)
- expect(wrapper.find('.summary').text()).toBe('live')
- }finally{wrapper.unmount()}
- })
|