bot-panels.spec.ts 5.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import {test,expect,type Page} from '@playwright/test'
  2. import {mkdirSync} from 'node:fs'
  3. const evidence='docs/verification/2026-09-10-bot-panels'
  4. async function create(page:Page,name:string){
  5. await page.locator('.desktop-sidebar .sidebar-create-trigger').click()
  6. await page.getByRole('menuitem',{name:'新建 Bot',exact:true}).click()
  7. const editor=page.getByRole('dialog');await editor.getByRole('textbox',{name:'名称',exact:true}).fill(name)
  8. await editor.getByRole('button',{name:'保存',exact:true}).click()
  9. await expect(page.getByRole('heading',{name,exact:true})).toBeVisible()
  10. }
  11. test('robot sidebar, source changes, requests, routines and group boundaries work on desktop and phone',async({page})=>{
  12. mkdirSync(evidence,{recursive:true})
  13. await page.goto('/conversations')
  14. await page.getByRole('textbox',{name:'账号',exact:true}).fill('fixture')
  15. await page.getByRole('textbox',{name:'密码',exact:true}).fill('fixture-pass')
  16. await page.getByRole('button',{name:'登录',exact:true}).click()
  17. await expect(page.locator('.desktop-sidebar .sidebar-create-trigger')).toBeVisible()
  18. await create(page,'侧栏验收')
  19. await page.getByRole('button',{name:'聊天设置',exact:true}).click()
  20. const editor=page.getByRole('dialog')
  21. await editor.getByLabel('基础机器人',{exact:false}).selectOption(JSON.stringify(['local','server']))
  22. await editor.getByRole('button',{name:'保存',exact:true}).click()
  23. await expect(editor).not.toBeVisible()
  24. const agents=(await(await page.request.get('/api/app/agents')).json()).agents
  25. const first=agents.find((a:any)=>a.name==='侧栏验收');expect(first.profile).toBe('server')
  26. const composer=page.getByRole('textbox',{name:'输入消息,Enter 发送,Shift + Enter 换行'})
  27. await composer.fill('侧栏真实请求验收 '+Date.now())
  28. await page.getByRole('button',{name:'发送消息',exact:true}).click()
  29. await expect(page.locator('.message--assistant')).toContainText('会话独立保存')
  30. await page.getByRole('button',{name:'电脑与定时任务',exact:true}).click()
  31. const panel=page.getByRole('complementary',{name:'机器人右侧栏'})
  32. await expect(panel.getByRole('tab',{name:'自动',exact:true})).toBeVisible()
  33. await expect(panel.getByRole('tab',{name:'云端 · Grok Bot',exact:true})).toBeVisible()
  34. await page.screenshot({path:evidence+'/desktop-computer.png'})
  35. await panel.getByRole('button',{name:'Inspector',exact:true}).click()
  36. await panel.getByRole('button',{name:'Raw',exact:true}).click()
  37. await expect(panel.locator('summary').filter({hasText:'prompt.submit'}).first()).toBeVisible()
  38. await page.screenshot({path:evidence+'/desktop-inspector.png'})
  39. await panel.getByRole('button',{name:'定时任务',exact:true}).click()
  40. await panel.getByRole('button',{name:'新建定时任务',exact:true}).click()
  41. const routineEditor=page.getByRole('dialog',{name:'新建定时任务',exact:true})
  42. await routineEditor.getByRole('textbox',{name:'名称',exact:true}).fill('每小时核对')
  43. await routineEditor.getByRole('textbox',{name:'任务内容',exact:true}).fill('核对项目状态并给出结果')
  44. await routineEditor.getByLabel('重复',{exact:true}).selectOption('interval')
  45. await routineEditor.getByRole('button',{name:'保存',exact:true}).click()
  46. await expect(panel.getByRole('heading',{name:'每小时核对',exact:true})).toBeVisible()
  47. await panel.getByRole('heading',{name:'每小时核对',exact:true}).click()
  48. await page.getByRole('dialog',{name:'编辑定时任务',exact:true}).getByRole('button',{name:'立即执行',exact:true}).click()
  49. await expect(panel.locator('.run-state')).toContainText('已完成',{timeout:15000})
  50. await page.screenshot({path:evidence+'/desktop-routine-logs.png'})
  51. await panel.getByRole('button',{name:'返回定时任务列表',exact:true}).click()
  52. await page.screenshot({path:evidence+'/desktop-routines.png'})
  53. await panel.getByRole('button',{name:'关闭机器人侧栏',exact:true}).click()
  54. await create(page,'群聊成员')
  55. const all=(await(await page.request.get('/api/app/agents')).json()).agents
  56. const second=all.find((a:any)=>a.name==='群聊成员')
  57. const capabilities=await(await page.request.get('/api/realtime/capabilities')).json()
  58. const response=await page.request.post('/api/app/conversations',{headers:{'X-CSRF-Token':capabilities.csrfToken,Origin:'http://127.0.0.1:18832'},data:{name:'群聊侧栏验收',memberIds:[first.id,second.id],administratorId:first.id}})
  59. expect(response.ok(),await response.text()).toBe(true)
  60. const group=(await response.json()).conversation
  61. await page.goto('/conversations/'+group.id)
  62. await expect(page.getByRole('button',{name:'电脑与定时任务',exact:true})).toHaveCount(0)
  63. await page.getByRole('button',{name:'Inspector',exact:true}).click()
  64. await expect(panel.getByRole('button',{name:'电脑',exact:true})).toHaveCount(0)
  65. await expect(panel.getByRole('button',{name:'定时任务',exact:true})).toHaveCount(0)
  66. await page.setViewportSize({width:375,height:812});await page.emulateMedia({colorScheme:'dark',reducedMotion:'reduce'})
  67. await page.screenshot({path:evidence+'/phone-group-inspector.png'})
  68. const box=await panel.boundingBox();expect(box!.width).toBeLessThanOrEqual(375)
  69. await expect(panel.getByRole('button',{name:'关闭机器人侧栏',exact:true})).toBeVisible()
  70. })