boot-page.client.spec.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // @vitest-environment jsdom
  2. import { afterEach, describe, expect, it } from 'vitest'
  3. import { BootPage } from '../src/boot-page.ts'
  4. afterEach(() => { document.body.innerHTML = '' })
  5. function mount() {
  6. const el = document.createElement('div')
  7. document.body.append(el)
  8. return { el, page: new BootPage(el) }
  9. }
  10. describe('BootPage', () => {
  11. it('draws the loading skeleton before any plugin state arrives', () => {
  12. const { el } = mount()
  13. expect(el.firstElementChild?.getAttribute('data-dsh-boot')).toBe('')
  14. expect(el.textContent).toContain('HARNESS')
  15. expect(el.textContent).toContain('Loading plugins…')
  16. })
  17. it('keeps loading while entries are active or loading', () => {
  18. const { el, page } = mount()
  19. page.setTotal(2)
  20. const spinner = el.querySelector<HTMLElement>('[data-dsh-boot-spinner]')
  21. expect(spinner?.style.getPropertyValue('--dsh-boot-arc')).toBe('72deg')
  22. page.setState('a', 'active')
  23. expect(spinner?.style.getPropertyValue('--dsh-boot-arc')).toBe('180deg')
  24. page.setState('b', 'loading')
  25. expect(el.querySelector('[data-dsh-boot-spinner]')).toBe(spinner)
  26. page.setState('b', 'active')
  27. expect(spinner?.style.getPropertyValue('--dsh-boot-arc')).toBe('288deg')
  28. expect(el.textContent).toContain('Loading plugins…')
  29. expect(el.textContent).not.toContain('Failed to load plugins')
  30. })
  31. it('lists failed entries', () => {
  32. const { el, page } = mount()
  33. page.setState('@deepseek-ai/dsh-client-ui-layout', 'failed')
  34. page.setState('ok', 'active')
  35. page.setState('@deepseek-ai/dsh-client-ui-tool', 'failed')
  36. expect(el.textContent).toContain('@deepseek-ai/dsh-client-ui-layout')
  37. expect(el.textContent).toContain('@deepseek-ai/dsh-client-ui-tool')
  38. expect(el.textContent).not.toContain('ok')
  39. expect(el.textContent).not.toContain('Loading plugins…')
  40. })
  41. it('shows the complete sweep report', () => {
  42. const { el, page } = mount()
  43. const report = 'web boot: 1 entry did not activate\nx: pending (waiting for service: y)'
  44. page.fail(report)
  45. page.setState('a', 'active')
  46. expect(el.textContent).toContain(report)
  47. expect(el.textContent).not.toContain('Loading plugins…')
  48. })
  49. it('detaches on disposal', () => {
  50. const { el, page } = mount()
  51. page.dispose()
  52. expect(el.childNodes).toHaveLength(0)
  53. })
  54. })