@happyvertical/smrt-svelte 0.53.1 → 0.53.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/package.json +15 -15
  2. package/dist/__tests__/app-state.test.js +0 -156
  3. package/dist/__tests__/data-surface-bridge.test.js +0 -351
  4. package/dist/__tests__/provider-mode-harness.svelte +0 -14
  5. package/dist/__tests__/provider-mode-harness.svelte.d.ts +0 -11
  6. package/dist/__tests__/provider-mode-harness.svelte.d.ts.map +0 -1
  7. package/dist/__tests__/provider-mode-probe.svelte +0 -13
  8. package/dist/__tests__/provider-mode-probe.svelte.d.ts +0 -8
  9. package/dist/__tests__/provider-mode-probe.svelte.d.ts.map +0 -1
  10. package/dist/__tests__/provider-webmcp-harness.svelte +0 -14
  11. package/dist/__tests__/provider-webmcp-harness.svelte.d.ts +0 -8
  12. package/dist/__tests__/provider-webmcp-harness.svelte.d.ts.map +0 -1
  13. package/dist/__tests__/success-never-text.test.js +0 -100
  14. package/dist/__tests__/warm-clients.test.js +0 -186
  15. package/dist/browser-ai/adapters/llm/bitgpu-inference-backend.test.js +0 -464
  16. package/dist/browser-ai/adapters/llm/webllm-inference-backend.test.js +0 -646
  17. package/dist/browser-ai/adapters/stt/browser-speech.test.js +0 -113
  18. package/dist/browser-ai/adapters/stt/dictation-source.test.js +0 -52
  19. package/dist/browser-ai/svelte/components/__tests__/ModelStatusControl.test.js +0 -172
  20. package/dist/components/board/__tests__/Board.test.js +0 -498
  21. package/dist/components/board/__tests__/BoardSsrHarness.svelte +0 -30
  22. package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts +0 -19
  23. package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts.map +0 -1
  24. package/dist/components/forms/__tests__/AddressInput.behavior.test.js +0 -216
  25. package/dist/components/forms/__tests__/CheckboxInput.test.js +0 -92
  26. package/dist/components/forms/__tests__/DateRangeInput.behavior.test.js +0 -135
  27. package/dist/components/forms/__tests__/DateTimeInput.behavior.test.js +0 -113
  28. package/dist/components/forms/__tests__/FileUpload.error-alert.test.js +0 -37
  29. package/dist/components/forms/__tests__/FileUpload.native-form.test.js +0 -249
  30. package/dist/components/forms/__tests__/FileUpload.test.js +0 -90
  31. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte +0 -24
  32. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts +0 -10
  33. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts.map +0 -1
  34. package/dist/components/forms/__tests__/Form.behavior.test.js +0 -137
  35. package/dist/components/forms/__tests__/Form.extraction.test.js +0 -68
  36. package/dist/components/forms/__tests__/Form.stt-error.test.js +0 -57
  37. package/dist/components/forms/__tests__/Form.test.js +0 -86
  38. package/dist/components/forms/__tests__/Form.ui-controls.test.js +0 -119
  39. package/dist/components/forms/__tests__/Form.webmcp.test.js +0 -2336
  40. package/dist/components/forms/__tests__/FormMicButton.test.js +0 -92
  41. package/dist/components/forms/__tests__/FormScope.test.js +0 -39
  42. package/dist/components/forms/__tests__/MeasurementInput.behavior.test.js +0 -129
  43. package/dist/components/forms/__tests__/MoneyInput.behavior.test.js +0 -124
  44. package/dist/components/forms/__tests__/NumberInput.behavior.test.js +0 -151
  45. package/dist/components/forms/__tests__/PhoneInput.behavior.test.js +0 -96
  46. package/dist/components/forms/__tests__/SearchInput.test.js +0 -79
  47. package/dist/components/forms/__tests__/SelectInput.behavior.test.js +0 -132
  48. package/dist/components/forms/__tests__/TextInput.behavior.test.js +0 -131
  49. package/dist/components/forms/__tests__/TextareaInput.behavior.test.js +0 -96
  50. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte +0 -30
  51. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts +0 -7
  52. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts.map +0 -1
  53. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte +0 -19
  54. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts +0 -9
  55. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts.map +0 -1
  56. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte +0 -21
  57. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts +0 -8
  58. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts.map +0 -1
  59. package/dist/components/forms/__tests__/composite-inputs-a11y.test.js +0 -69
  60. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte +0 -27
  61. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts +0 -9
  62. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts.map +0 -1
  63. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte +0 -48
  64. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts +0 -10
  65. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts.map +0 -1
  66. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte +0 -26
  67. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts +0 -13
  68. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts.map +0 -1
  69. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte +0 -52
  70. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts +0 -16
  71. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts.map +0 -1
  72. package/dist/components/forms/__tests__/form-scope.fixture.svelte +0 -30
  73. package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts +0 -10
  74. package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts.map +0 -1
  75. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte +0 -158
  76. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts +0 -51
  77. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts.map +0 -1
  78. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte +0 -24
  79. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts +0 -11
  80. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts.map +0 -1
  81. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte +0 -105
  82. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts +0 -42
  83. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts.map +0 -1
  84. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte +0 -84
  85. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts +0 -14
  86. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts.map +0 -1
  87. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte +0 -44
  88. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts +0 -9
  89. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts.map +0 -1
  90. package/dist/components/forms/__tests__/mic-keyboard-a11y.test.js +0 -74
  91. package/dist/components/forms/__tests__/policy-field.fixture.svelte +0 -35
  92. package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts +0 -8
  93. package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts.map +0 -1
  94. package/dist/components/forms/__tests__/rich-inputs-a11y.test.js +0 -87
  95. package/dist/components/settings/__tests__/SettingsCatalog.test.js +0 -69
  96. package/dist/components/settings/__tests__/catalog.test.js +0 -46
  97. package/dist/components/workspace/__tests__/AdminShell.responsive.test.js +0 -597
  98. package/dist/components/workspace/__tests__/AdminShell.test.js +0 -572
  99. package/dist/components/workspace/__tests__/RoleShell.test.js +0 -772
  100. package/dist/components/workspace/__tests__/TenantNav.test.js +0 -208
  101. package/dist/components/workspace/__tests__/WorkspaceAccountMenu.test.js +0 -79
  102. package/dist/components/workspace/__tests__/WorkspaceShell.test.js +0 -630
  103. package/dist/components/workspace/__tests__/admin-shell-header-overflow.test.js +0 -25
  104. package/dist/components/workspace/__tests__/admin-shell-hotkeys.test.js +0 -34
  105. package/dist/components/workspace/__tests__/admin-shell-mobile.test.js +0 -217
  106. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte +0 -52
  107. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts +0 -23
  108. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts.map +0 -1
  109. package/dist/components/workspace/__tests__/admin-shell-page-contracts.test.js +0 -30
  110. package/dist/components/workspace/__tests__/admin-shell-responsive-state.test.js +0 -184
  111. package/dist/components/workspace/__tests__/admin-shell-settings.test.js +0 -25
  112. package/dist/components/workspace/__tests__/admin-shell-state.test.js +0 -286
  113. package/dist/components/workspace/__tests__/admin-shell-theme-hooks.test.js +0 -36
  114. package/dist/components/workspace/__tests__/breadcrumbs-helpers.test.js +0 -141
  115. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte +0 -45
  116. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts +0 -21
  117. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts.map +0 -1
  118. package/dist/components/workspace/__tests__/define-tools-dock.test.js +0 -1188
  119. package/dist/components/workspace/__tests__/harness.svelte +0 -25
  120. package/dist/components/workspace/__tests__/harness.svelte.d.ts +0 -14
  121. package/dist/components/workspace/__tests__/harness.svelte.d.ts.map +0 -1
  122. package/dist/components/workspace/__tests__/index.test.js +0 -28
  123. package/dist/components/workspace/__tests__/legacy-index.test.js +0 -9
  124. package/dist/components/workspace/__tests__/manifest-nav-helpers.test.js +0 -24
  125. package/dist/components/workspace/__tests__/manifest-nav.test.js +0 -599
  126. package/dist/components/workspace/__tests__/nav-helpers.test.js +0 -95
  127. package/dist/components/workspace/__tests__/render-harness.svelte +0 -66
  128. package/dist/components/workspace/__tests__/render-harness.svelte.d.ts +0 -32
  129. package/dist/components/workspace/__tests__/render-harness.svelte.d.ts.map +0 -1
  130. package/dist/components/workspace/__tests__/render-tools-dock.test.js +0 -260
  131. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte +0 -58
  132. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts +0 -16
  133. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts.map +0 -1
  134. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte +0 -41
  135. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts +0 -13
  136. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts.map +0 -1
  137. package/dist/components/workspace/__tests__/shell-chrome-components.test.js +0 -108
  138. package/dist/components/workspace/__tests__/system-feed.test.js +0 -327
  139. package/dist/components/workspace/__tests__/test-icon.svelte +0 -17
  140. package/dist/components/workspace/__tests__/test-icon.svelte.d.ts +0 -19
  141. package/dist/components/workspace/__tests__/test-icon.svelte.d.ts.map +0 -1
  142. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte +0 -38
  143. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts +0 -22
  144. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts.map +0 -1
  145. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts +0 -66
  146. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts.map +0 -1
  147. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.js +0 -115
  148. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts +0 -15
  149. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts.map +0 -1
  150. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.js +0 -7
  151. package/dist/components/workspace/__tests__/typed-tool-fixture.test.js +0 -115
  152. package/dist/components/workspace/__tests__/use-harness-orphan.svelte +0 -9
  153. package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts +0 -19
  154. package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts.map +0 -1
  155. package/dist/components/workspace/__tests__/use-harness.svelte +0 -23
  156. package/dist/components/workspace/__tests__/use-harness.svelte.d.ts +0 -8
  157. package/dist/components/workspace/__tests__/use-harness.svelte.d.ts.map +0 -1
  158. package/dist/components/workspace/__tests__/use-tools-dock.test.js +0 -33
  159. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte +0 -43
  160. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts +0 -11
  161. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts.map +0 -1
  162. package/dist/components/workspace/server/__tests__/compose-availability.test.js +0 -383
  163. package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts +0 -78
  164. package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts.map +0 -1
  165. package/dist/components/workspace/server/__tests__/typed-context-fixture.js +0 -104
  166. package/dist/hooks/__tests__/stt-consumer.fixture.svelte +0 -25
  167. package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts +0 -15
  168. package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts.map +0 -1
  169. package/dist/hooks/__tests__/stt-ownership-harness.svelte +0 -42
  170. package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts +0 -20
  171. package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts.map +0 -1
  172. package/dist/hooks/__tests__/useSTT-ownership.test.js +0 -102
  173. package/dist/i18n/__tests__/server.spec.js +0 -57
  174. package/dist/internal/logger.test.js +0 -54
  175. package/dist/provider-mode.test.js +0 -86
  176. package/dist/provider-webmcp.test.js +0 -244
  177. package/dist/state/__tests__/app-state-ai-lifecycle.test.js +0 -240
  178. package/dist/state/__tests__/warm-clients.test.js +0 -40
  179. package/dist/web/__tests__/activity-feed-harness.svelte +0 -32
  180. package/dist/web/__tests__/activity-feed-harness.svelte.d.ts +0 -18
  181. package/dist/web/__tests__/activity-feed-harness.svelte.d.ts.map +0 -1
  182. package/dist/web/__tests__/activity-feed.integration.svelte.test.js +0 -190
  183. package/dist/web/__tests__/activity-feed.svelte.test.js +0 -235
  184. package/dist/web/__tests__/assistant-dock.integration.svelte.test.js +0 -204
  185. package/dist/web/__tests__/data-surface-conformance.integration.svelte.test.js +0 -1392
  186. package/dist/web/__tests__/harness.svelte +0 -25
  187. package/dist/web/__tests__/harness.svelte.d.ts +0 -15
  188. package/dist/web/__tests__/harness.svelte.d.ts.map +0 -1
  189. package/dist/web/__tests__/list-data-surface.fixture.svelte +0 -59
  190. package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts +0 -14
  191. package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts.map +0 -1
  192. package/dist/web/__tests__/list-data-surface.svelte.test.js +0 -106
  193. package/dist/web/__tests__/list-data-surface.test.js +0 -651
  194. package/dist/web/__tests__/list-sort-surface.fixture.svelte +0 -41
  195. package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts +0 -15
  196. package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts.map +0 -1
  197. package/dist/web/__tests__/list-sort-surface.svelte.test.js +0 -59
  198. package/dist/web/__tests__/live-collection.svelte.test.js +0 -185
  199. package/dist/web/__tests__/provider-ui-registry.fixture.svelte +0 -43
  200. package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts +0 -13
  201. package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts.map +0 -1
  202. package/dist/web/__tests__/provider-ui-registry.test.js +0 -235
  203. package/dist/web/__tests__/remote-query-harness.svelte +0 -27
  204. package/dist/web/__tests__/remote-query-harness.svelte.d.ts +0 -11
  205. package/dist/web/__tests__/remote-query-harness.svelte.d.ts.map +0 -1
  206. package/dist/web/__tests__/remote-query.svelte.test.js +0 -101
  207. package/dist/web/__tests__/surfaces.child.fixture.svelte +0 -69
  208. package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts +0 -16
  209. package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts.map +0 -1
  210. package/dist/web/__tests__/surfaces.fixture.svelte +0 -26
  211. package/dist/web/__tests__/surfaces.fixture.svelte.d.ts +0 -18
  212. package/dist/web/__tests__/surfaces.fixture.svelte.d.ts.map +0 -1
  213. package/dist/web/__tests__/surfaces.svelte.test.js +0 -140
  214. package/dist/web/__tests__/update-available-harness.svelte +0 -46
  215. package/dist/web/__tests__/update-available-harness.svelte.d.ts +0 -22
  216. package/dist/web/__tests__/update-available-harness.svelte.d.ts.map +0 -1
  217. package/dist/web/__tests__/update-available.svelte.test.js +0 -137
  218. package/dist/web/__tests__/view-intent-provider.fixture.svelte +0 -28
  219. package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts +0 -13
  220. package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts.map +0 -1
  221. package/dist/web/__tests__/view-intent.fixture.svelte +0 -33
  222. package/dist/web/__tests__/view-intent.fixture.svelte.d.ts +0 -15
  223. package/dist/web/__tests__/view-intent.fixture.svelte.d.ts.map +0 -1
  224. package/dist/web/__tests__/view-intent.intents.d.ts +0 -14
  225. package/dist/web/__tests__/view-intent.intents.d.ts.map +0 -1
  226. package/dist/web/__tests__/view-intent.intents.js +0 -38
  227. package/dist/web/__tests__/view-intent.svelte.test.js +0 -244
  228. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte +0 -73
  229. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts +0 -8
  230. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts.map +0 -1
  231. package/dist/web/__tests__/webmcp-composed.fixture.svelte +0 -52
  232. package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts +0 -12
  233. package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts.map +0 -1
  234. package/dist/web/__tests__/webmcp-composed.integration.svelte.test.js +0 -251
  235. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte +0 -16
  236. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts +0 -19
  237. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts.map +0 -1
  238. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte +0 -11
  239. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts +0 -8
  240. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts.map +0 -1
  241. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte +0 -20
  242. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts +0 -7
  243. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts.map +0 -1
  244. package/dist/web/__tests__/webmcp-harness-unannotated.svelte +0 -14
  245. package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts +0 -19
  246. package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts.map +0 -1
  247. package/dist/web/__tests__/webmcp-harness.svelte +0 -18
  248. package/dist/web/__tests__/webmcp-harness.svelte.d.ts +0 -7
  249. package/dist/web/__tests__/webmcp-harness.svelte.d.ts.map +0 -1
  250. package/dist/web/__tests__/webmcp-ssr.fixture.svelte +0 -13
  251. package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts +0 -19
  252. package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts.map +0 -1
  253. package/dist/web/__tests__/webmcp-ui.test.js +0 -723
  254. package/dist/web/__tests__/webmcp.test.js +0 -234
@@ -1,597 +0,0 @@
1
- /**
2
- * AdminShell's responsive chrome: header row, viewport defaults, phone top
3
- * and bottom bars, form action bars, scrim, navigation, phone presentations
4
- * of the right edge, and resizable side edges.
5
- */
6
- import { fireEvent, render, screen, waitFor } from '@testing-library/svelte';
7
- import { createRawSnippet, flushSync, tick } from 'svelte';
8
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
9
- import AdminShell from '../admin-shell/AdminShell.svelte';
10
- import { createShellState } from '../admin-shell/state.svelte.js';
11
- import { ADMIN_SHELL_REGION_IDS } from '../admin-shell/types.js';
12
- function html(markup) {
13
- return createRawSnippet(() => ({ render: () => markup }));
14
- }
15
- const listeners = new Set();
16
- let width = 1280;
17
- const originalMatchMedia = window.matchMedia;
18
- function setWidth(next) {
19
- width = next;
20
- for (const listener of listeners)
21
- listener();
22
- }
23
- beforeEach(() => {
24
- width = 1280;
25
- window.matchMedia = ((query) => {
26
- const max = /max-width:\s*([\d.]+)rem/.exec(query);
27
- const min = /min-width:\s*([\d.]+)rem/.exec(query);
28
- return {
29
- get matches() {
30
- if (query.includes('prefers-reduced-motion'))
31
- return false;
32
- return ((!max || width <= Number(max[1]) * 16) &&
33
- (!min || width >= Number(min[1]) * 16));
34
- },
35
- media: query,
36
- addEventListener: (_, listener) => listeners.add(listener),
37
- removeEventListener: (_, listener) => listeners.delete(listener),
38
- };
39
- });
40
- });
41
- afterEach(() => {
42
- listeners.clear();
43
- window.matchMedia = originalMatchMedia;
44
- });
45
- const config = {
46
- top: false,
47
- left: {
48
- label: 'Navigation',
49
- initial: 'expanded',
50
- hotkey: null,
51
- viewportDefaults: {
52
- phone: 'collapsed',
53
- tablet: 'collapsed',
54
- desktop: 'expanded',
55
- },
56
- },
57
- right: { label: 'Assistant', initial: 'collapsed', hotkey: null },
58
- bottom: false,
59
- };
60
- async function settle() {
61
- flushSync();
62
- await tick();
63
- flushSync();
64
- }
65
- function shellRoot() {
66
- return document.querySelector('.smrt-admin-shell');
67
- }
68
- describe('AdminShell header and viewport', () => {
69
- it('renders a header row above the edges on desktop, with public region ids', async () => {
70
- const shell = createShellState({ config });
71
- render(AdminShell, {
72
- props: {
73
- state: shell,
74
- header: createRawSnippet((ctx) => ({
75
- render: () => `<span>Header ${ctx().viewport}</span>`,
76
- })),
77
- phoneTopBar: html('<span>phone top</span>'),
78
- phoneBottomBar: html('<nav>phone bar</nav>'),
79
- children: html('<p>page</p>'),
80
- },
81
- });
82
- await settle();
83
- const header = document.getElementById(ADMIN_SHELL_REGION_IDS.header);
84
- expect(header?.textContent).toContain('Header desktop');
85
- expect(document.getElementById(ADMIN_SHELL_REGION_IDS.main)?.tagName).toBe('MAIN');
86
- expect(document.getElementById(ADMIN_SHELL_REGION_IDS.left)).not.toBeNull();
87
- expect(shellRoot().dataset.viewport).toBe('desktop');
88
- expect(shellRoot().getAttribute('style')).toContain('--smrt-admin-shell-header-track: var(--smrt-admin-shell-header-size)');
89
- expect(screen.queryByTestId('admin-shell-phone-top')).toBeNull();
90
- expect(screen.queryByTestId('admin-shell-phone-bar')).toBeNull();
91
- expect(shell.panels.left).toBe('expanded');
92
- });
93
- it('follows viewport classes: tablet collapses the nav, desktop reopens it', async () => {
94
- const shell = createShellState({ config });
95
- render(AdminShell, {
96
- props: { state: shell, children: html('<p>page</p>') },
97
- });
98
- await settle();
99
- setWidth(900);
100
- flushSync();
101
- expect(shell.viewport).toBe('tablet');
102
- expect(shell.panels.left).toBe('collapsed');
103
- setWidth(1400);
104
- flushSync();
105
- expect(shell.panels.left).toBe('expanded');
106
- });
107
- });
108
- describe('AdminShell on a phone', () => {
109
- beforeEach(() => setWidth(390));
110
- function renderPhone(extra = {}, page = '<p>page</p>') {
111
- const shell = createShellState({ config });
112
- const result = render(AdminShell, {
113
- props: {
114
- state: shell,
115
- header: html('<span>desktop header</span>'),
116
- phoneTopBar: createRawSnippet((ctx) => ({
117
- render: () => `<span>top ${ctx().hidden ? 'hidden' : 'shown'}</span>`,
118
- })),
119
- phoneBottomBar: html('<nav aria-label="Main">bar</nav>'),
120
- phone: { scrim: true, swipeToClose: true },
121
- path: '/a',
122
- children: html(page),
123
- ...extra,
124
- },
125
- });
126
- return { shell, ...result };
127
- }
128
- it('swaps the header for the phone top bar and shows the bottom bar', async () => {
129
- const { shell } = renderPhone();
130
- await settle();
131
- expect(shell.viewport).toBe('phone');
132
- expect(shell.panels.left).toBe('collapsed');
133
- expect(screen.queryByTestId('admin-shell-header')).toBeNull();
134
- expect(screen.getByTestId('admin-shell-phone-top').textContent).toContain('top shown');
135
- expect(screen.getByTestId('admin-shell-phone-bar')).toBeInTheDocument();
136
- expect(shellRoot().dataset.bottomBar).toBe('nav');
137
- expect(shellRoot().hasAttribute('data-phone-top')).toBe(true);
138
- });
139
- it('lets a form action bar replace the bottom bar', async () => {
140
- renderPhone({}, '<form><div data-form-action-bar><button>Save</button></div></form>');
141
- await settle();
142
- expect(screen.queryByTestId('admin-shell-phone-bar')).toBeNull();
143
- expect(shellRoot().dataset.bottomBar).toBe('form');
144
- });
145
- it('dims the page behind an open drawer; the scrim closes it', async () => {
146
- const { shell } = renderPhone();
147
- await settle();
148
- expect(screen.queryByTestId('admin-shell-scrim')).toBeNull();
149
- shell.expandPanel('left');
150
- flushSync();
151
- const scrim = screen.getByTestId('admin-shell-scrim');
152
- expect(scrim).toHaveAttribute('aria-label', 'Close Navigation');
153
- await fireEvent.click(scrim);
154
- expect(shell.panels.left).toBe('collapsed');
155
- });
156
- it('keeps a closed phone drawer out of the tab order and away from screen readers', async () => {
157
- const { shell } = renderPhone();
158
- await settle();
159
- const left = document.getElementById('smrt-admin-shell-left-panel');
160
- expect(left.inert).toBe(true);
161
- shell.expandPanel('left');
162
- flushSync();
163
- expect(left.inert).toBe(false);
164
- setWidth(1280);
165
- await settle();
166
- expect(left.inert).toBe(false);
167
- });
168
- it('moves focus into the phone drawer without animation enumeration', async () => {
169
- const { shell } = renderPhone({
170
- tenantPanel: html('<a href="/phone-target">Phone navigation target</a>'),
171
- });
172
- await settle();
173
- const left = document.getElementById('smrt-admin-shell-left-panel');
174
- Object.defineProperty(left, 'getAnimations', { value: undefined });
175
- shell.expandPanel('left');
176
- await settle();
177
- await waitFor(() => expect(left.contains(document.activeElement)).toBe(true));
178
- });
179
- it('closes an open drawer when the path changes', async () => {
180
- const { shell, rerender } = renderPhone();
181
- await settle();
182
- shell.expandPanel('left');
183
- flushSync();
184
- await rerender({ path: '/b' });
185
- await settle();
186
- expect(shell.panels.left).toBe('collapsed');
187
- });
188
- it('does not render a phone-hidden right edge and renders a sheet with a grabber', async () => {
189
- const hiddenShell = createShellState({
190
- config: {
191
- ...config,
192
- right: { label: 'Assistant', phone: 'hidden', initial: 'expanded' },
193
- },
194
- });
195
- const first = render(AdminShell, {
196
- props: { state: hiddenShell, children: html('<p>page</p>') },
197
- });
198
- await settle();
199
- expect(document.getElementById(ADMIN_SHELL_REGION_IDS.right)).toBeNull();
200
- first.unmount();
201
- const sheetShell = createShellState({
202
- config: {
203
- ...config,
204
- right: { label: 'Assistant', phone: 'sheet', initial: 'expanded' },
205
- },
206
- });
207
- render(AdminShell, {
208
- props: {
209
- state: sheetShell,
210
- focusPanel: html('<p>chat</p>'),
211
- phone: { scrim: true },
212
- children: html('<p>page</p>'),
213
- },
214
- });
215
- await settle();
216
- const aside = document.getElementById(ADMIN_SHELL_REGION_IDS.right);
217
- expect(aside.dataset.phone).toBe('sheet');
218
- expect(aside.querySelector('.smrt-admin-shell__sheet-grabber')).not.toBeNull();
219
- expect(screen.getByTestId('admin-shell-scrim')).toHaveAttribute('aria-label', 'Close Assistant');
220
- });
221
- it('renders host overlays with the viewport and bottom bar mode', async () => {
222
- renderPhone({
223
- overlays: createRawSnippet((ctx) => ({
224
- render: () => `<div data-testid="overlay">${ctx().viewport}/${ctx().bottomBar}</div>`,
225
- })),
226
- });
227
- await settle();
228
- expect(screen.getByTestId('overlay').textContent).toBe('phone/nav');
229
- });
230
- });
231
- describe('AdminShell resizable edges', () => {
232
- function storeAdapter() {
233
- const writes = [];
234
- return {
235
- writes,
236
- read: () => null,
237
- write: (delta) => {
238
- writes.push(JSON.parse(JSON.stringify(delta)));
239
- },
240
- };
241
- }
242
- function renderResizable(overrides = {}) {
243
- const adapter = storeAdapter();
244
- const shell = createShellState({
245
- config: {
246
- ...config,
247
- right: {
248
- label: 'Assistant',
249
- initial: 'expanded',
250
- expandedSize: '28rem',
251
- resizable: { min: 320, max: 640, step: 10 },
252
- hotkey: null,
253
- },
254
- ...overrides,
255
- },
256
- settingsAdapter: adapter,
257
- });
258
- const view = render(AdminShell, {
259
- props: {
260
- state: shell,
261
- focusPanel: html('<p>chat</p>'),
262
- children: html('<p>page</p>'),
263
- },
264
- });
265
- flushSync();
266
- return { shell, adapter, view };
267
- }
268
- it('does not render a separator unless the edge is resizable (backward compatible)', () => {
269
- const shell = createShellState({
270
- config: { right: { initial: 'expanded' } },
271
- });
272
- render(AdminShell, {
273
- props: { state: shell, children: html('<p>page</p>') },
274
- });
275
- expect(document.querySelector('[role="separator"]')).toBeNull();
276
- });
277
- it('exposes an accessible, keyboard-resizable separator', async () => {
278
- const { shell, adapter } = renderResizable();
279
- const separator = screen.getByRole('separator', {
280
- name: 'Resize Assistant',
281
- });
282
- expect(separator).toHaveAttribute('aria-orientation', 'vertical');
283
- expect(separator).toHaveAttribute('aria-controls', ADMIN_SHELL_REGION_IDS.right);
284
- expect(separator).toHaveAttribute('aria-valuemin', '320');
285
- expect(separator).toHaveAttribute('aria-valuemax', '640');
286
- expect(separator).toHaveAttribute('aria-valuenow', '448');
287
- expect(separator).toHaveAttribute('tabindex', '0');
288
- await fireEvent.keyDown(separator, { key: 'ArrowLeft' });
289
- expect(shell.panelSize('right')).toBe(458);
290
- expect(separator).toHaveAttribute('aria-valuenow', '458');
291
- await fireEvent.keyDown(separator, { key: 'ArrowRight', shiftKey: true });
292
- expect(shell.panelSize('right')).toBe(418);
293
- await fireEvent.keyDown(separator, { key: 'End' });
294
- expect(shell.panelSize('right')).toBe(640);
295
- await fireEvent.keyDown(separator, { key: 'Home' });
296
- expect(shell.panelSize('right')).toBe(320);
297
- expect(adapter.writes.at(-1)?.sizes).toEqual({ right: 320 });
298
- expect(shellRoot().getAttribute('style')).toContain('--smrt-admin-shell-right-track: 320px');
299
- await fireEvent.keyDown(separator, { key: 'Enter' });
300
- expect(shell.panelSize('right')).toBeNull();
301
- expect(separator).toHaveAttribute('aria-valuenow', '448');
302
- });
303
- it('resizes by dragging, persisting once at the end, and resets on double-click', async () => {
304
- const { shell, adapter } = renderResizable();
305
- const separator = screen.getByTestId('admin-shell-resizer-right');
306
- const before = adapter.writes.length;
307
- await fireEvent.pointerDown(separator, { button: 0, clientX: 800 });
308
- expect(shellRoot().dataset.resizing).toBe('right');
309
- await fireEvent.pointerMove(separator, { clientX: 760 });
310
- expect(shell.panelSize('right')).toBe(488);
311
- await fireEvent.pointerMove(separator, { clientX: 700 });
312
- expect(shell.panelSize('right')).toBe(548);
313
- expect(adapter.writes.length).toBe(before);
314
- await fireEvent.pointerUp(separator, { clientX: 700 });
315
- expect(shellRoot().dataset.resizing).toBeUndefined();
316
- expect(adapter.writes.length).toBe(before + 1);
317
- expect(adapter.writes.at(-1)?.sizes).toEqual({ right: 548 });
318
- await fireEvent.dblClick(separator);
319
- expect(shell.panelSize('right')).toBeNull();
320
- });
321
- it('ends the drag when pointer capture is lost, persisting once', async () => {
322
- const { shell, adapter } = renderResizable();
323
- const separator = screen.getByTestId('admin-shell-resizer-right');
324
- const before = adapter.writes.length;
325
- await fireEvent.pointerDown(separator, { button: 0, clientX: 800 });
326
- await fireEvent.pointerMove(separator, { clientX: 760 });
327
- expect(shellRoot().dataset.resizing).toBe('right');
328
- // The browser took the capture away (a system gesture, a window switch)
329
- // without a pointerup.
330
- await fireEvent(separator, new Event('lostpointercapture'));
331
- expect(shellRoot().dataset.resizing).toBeUndefined();
332
- expect(adapter.writes.length).toBe(before + 1);
333
- await fireEvent.pointerMove(separator, { clientX: 600 });
334
- expect(shell.panelSize('right')).toBe(488);
335
- await fireEvent.pointerUp(separator, { clientX: 600 });
336
- expect(adapter.writes.length).toBe(before + 1);
337
- });
338
- it('drops an in-flight drag when the shell unmounts', async () => {
339
- const { shell, view } = renderResizable();
340
- const separator = screen.getByTestId('admin-shell-resizer-right');
341
- await fireEvent.pointerDown(separator, { button: 0, clientX: 800 });
342
- await fireEvent.pointerMove(separator, { clientX: 760 });
343
- expect(shell.panelSize('right')).toBe(488);
344
- view.unmount();
345
- // The detached handle no longer drives the (still live) shell state.
346
- await fireEvent.pointerMove(separator, { clientX: 600 });
347
- expect(shell.panelSize('right')).toBe(488);
348
- });
349
- it('grows a left edge to the right', async () => {
350
- const { shell } = renderResizable({
351
- left: {
352
- label: 'Navigation',
353
- initial: 'expanded',
354
- expandedSize: '16rem',
355
- resizable: true,
356
- },
357
- });
358
- const separator = screen.getByRole('separator', {
359
- name: 'Resize Navigation',
360
- });
361
- await fireEvent.keyDown(separator, { key: 'ArrowRight' });
362
- expect(shell.panelSize('left')).toBe(272);
363
- });
364
- it('hides the separator while collapsed and on phones', async () => {
365
- const { shell } = renderResizable();
366
- shell.collapsePanel('right');
367
- flushSync();
368
- expect(screen.queryByRole('separator')).toBeNull();
369
- shell.expandPanel('right');
370
- flushSync();
371
- expect(screen.getByRole('separator')).toBeInTheDocument();
372
- setWidth(390);
373
- flushSync();
374
- expect(screen.queryByRole('separator')).toBeNull();
375
- });
376
- it('keeps the size out of storage when the edge opts out', async () => {
377
- const { shell, adapter } = renderResizable({
378
- right: {
379
- label: 'Assistant',
380
- initial: 'expanded',
381
- resizable: true,
382
- persist: { size: false },
383
- },
384
- });
385
- await fireEvent.keyDown(screen.getByRole('separator'), { key: 'End' });
386
- expect(shell.panelSize('right')).toBe(720);
387
- expect(adapter.writes.at(-1)?.sizes).toBeUndefined();
388
- });
389
- });
390
- describe('AdminShell overlay edges (overlayMedia)', () => {
391
- function overlayShell() {
392
- return createShellState({
393
- config: {
394
- ...config,
395
- right: {
396
- label: 'Assistant',
397
- initial: 'collapsed',
398
- hotkey: null,
399
- collapsedSize: '0rem',
400
- expandedSize: '28rem',
401
- resizable: { min: 320, max: 640 },
402
- overlayMedia: '(max-width: 99.9375rem)',
403
- },
404
- },
405
- });
406
- }
407
- function rightEdge() {
408
- return document.getElementById(ADMIN_SHELL_REGION_IDS.right);
409
- }
410
- it('slides over the page below the query and docks above it', async () => {
411
- setWidth(1280);
412
- const shell = overlayShell();
413
- render(AdminShell, {
414
- props: { state: shell, children: html('<button>page action</button>') },
415
- });
416
- await settle();
417
- shell.expandPanel('right');
418
- await settle();
419
- expect(shell.presentationFor('right')).toBe('overlay');
420
- expect(rightEdge().dataset.presentation).toBe('overlay');
421
- // The page keeps its width: the right track stays collapsed.
422
- expect(shellRoot().getAttribute('style')).toContain('--smrt-admin-shell-right-track: 0rem');
423
- expect(screen.getByTestId('admin-shell-overlay-scrim')).toBeTruthy();
424
- expect(document.getElementById('smrt-admin-shell-main')?.inert).toBe(true);
425
- expect(screen.queryByTestId('admin-shell-resizer-right')).toBeNull();
426
- setWidth(1600);
427
- await settle();
428
- expect(shell.presentationFor('right')).toBe('push');
429
- expect(rightEdge().dataset.presentation).toBe('push');
430
- expect(shellRoot().getAttribute('style')).toContain('--smrt-admin-shell-right-track: 28rem');
431
- expect(screen.queryByTestId('admin-shell-overlay-scrim')).toBeNull();
432
- expect(document.getElementById('smrt-admin-shell-main')?.inert).toBe(false);
433
- expect(screen.getByTestId('admin-shell-resizer-right')).toBeTruthy();
434
- });
435
- it('closes on a scrim click or Escape, moving focus in and back', async () => {
436
- setWidth(1100);
437
- const shell = overlayShell();
438
- render(AdminShell, {
439
- props: { state: shell, children: html('<p>page</p>') },
440
- });
441
- await settle();
442
- const opener = document.createElement('button');
443
- document.body.append(opener);
444
- opener.focus();
445
- shell.expandPanel('right');
446
- await settle();
447
- expect(document.activeElement).toBe(rightEdge());
448
- await fireEvent.keyDown(window, { key: 'Escape' });
449
- await settle();
450
- expect(shell.panels.right).toBe('collapsed');
451
- expect(document.activeElement).toBe(opener);
452
- opener.remove();
453
- shell.expandPanel('right');
454
- await settle();
455
- await fireEvent.click(screen.getByTestId('admin-shell-overlay-scrim'));
456
- await settle();
457
- expect(shell.panels.right).toBe('collapsed');
458
- shell.expandPanel('right');
459
- await settle();
460
- await fireEvent.keyDown(window, { key: 'Escape' });
461
- await settle();
462
- expect(shell.panels.right).toBe('collapsed');
463
- });
464
- it('does not open an overlay on load, but still restores a docked edge', async () => {
465
- const stored = { panels: { right: 'expanded' } };
466
- const adapter = { read: () => stored, write: vi.fn() };
467
- const make = () => createShellState({
468
- config: {
469
- ...config,
470
- right: {
471
- label: 'Assistant',
472
- initial: 'collapsed',
473
- hotkey: null,
474
- overlayMedia: '(max-width: 99.9375rem)',
475
- },
476
- },
477
- settingsAdapter: adapter,
478
- });
479
- setWidth(1280);
480
- const narrow = make();
481
- const first = render(AdminShell, {
482
- props: { state: narrow, children: html('<p>page</p>') },
483
- });
484
- await settle();
485
- await settle();
486
- expect(narrow.panels.right).toBe('collapsed');
487
- expect(adapter.write).not.toHaveBeenCalled();
488
- first.unmount();
489
- setWidth(1700);
490
- const wide = make();
491
- render(AdminShell, {
492
- props: { state: wide, children: html('<p>page</p>') },
493
- });
494
- await settle();
495
- await settle();
496
- expect(wide.panels.right).toBe('expanded');
497
- });
498
- it('slides a closed overlay back out before hiding it', async () => {
499
- vi.useFakeTimers();
500
- try {
501
- setWidth(1100);
502
- const shell = overlayShell();
503
- render(AdminShell, {
504
- props: { state: shell, children: html('<p>page</p>') },
505
- });
506
- await settle();
507
- shell.expandPanel('right');
508
- await settle();
509
- shell.collapsePanel('right');
510
- await settle();
511
- // Closed at once for the page (not inert), still shown while it slides.
512
- expect(document.getElementById('smrt-admin-shell-main')?.inert).toBe(false);
513
- expect(rightEdge().dataset.state).toBe('expanded');
514
- expect(rightEdge().hasAttribute('data-closing')).toBe(true);
515
- expect(rightEdge().inert).toBe(true);
516
- const scrim = screen.getByTestId('admin-shell-overlay-scrim');
517
- expect(scrim.hasAttribute('data-closing')).toBe(true);
518
- await fireEvent.click(scrim);
519
- expect(shell.panels.right).toBe('collapsed');
520
- vi.advanceTimersByTime(700);
521
- await settle();
522
- expect(rightEdge().dataset.state).toBe('collapsed');
523
- expect(rightEdge().hasAttribute('data-closing')).toBe(false);
524
- expect(screen.queryByTestId('admin-shell-overlay-scrim')).toBeNull();
525
- }
526
- finally {
527
- vi.useRealTimers();
528
- }
529
- });
530
- it('skips the slide-out when reduced motion is preferred', async () => {
531
- setWidth(1100);
532
- const base = window.matchMedia;
533
- window.matchMedia = ((query) => query.includes('prefers-reduced-motion')
534
- ? {
535
- matches: true,
536
- media: query,
537
- addEventListener: () => { },
538
- removeEventListener: () => { },
539
- }
540
- : base(query));
541
- const shell = overlayShell();
542
- render(AdminShell, {
543
- props: { state: shell, children: html('<p>page</p>') },
544
- });
545
- await settle();
546
- shell.expandPanel('right');
547
- await settle();
548
- shell.collapsePanel('right');
549
- await settle();
550
- expect(rightEdge().dataset.state).toBe('collapsed');
551
- expect(screen.queryByTestId('admin-shell-overlay-scrim')).toBeNull();
552
- });
553
- it('keeps the phone presentation on phones', async () => {
554
- setWidth(390);
555
- const shell = overlayShell();
556
- render(AdminShell, {
557
- props: { state: shell, children: html('<p>page</p>') },
558
- });
559
- await settle();
560
- shell.expandPanel('right');
561
- await settle();
562
- expect(shell.presentationFor('right')).toBe('push');
563
- expect(screen.queryByTestId('admin-shell-overlay-scrim')).toBeNull();
564
- });
565
- });
566
- describe('AdminShell backward compatibility', () => {
567
- it('adds no header, phone chrome, overlays, or scrim without the new props', async () => {
568
- setWidth(390);
569
- const shell = createShellState({
570
- config: { left: { initial: 'expanded' } },
571
- });
572
- render(AdminShell, {
573
- props: { state: shell, children: html('<p>page</p>') },
574
- });
575
- await settle();
576
- expect(screen.queryByTestId('admin-shell-header')).toBeNull();
577
- expect(screen.queryByTestId('admin-shell-phone-top')).toBeNull();
578
- expect(screen.queryByTestId('admin-shell-phone-bar')).toBeNull();
579
- expect(screen.queryByTestId('admin-shell-scrim')).toBeNull();
580
- expect(document.querySelector('.smrt-admin-shell__overlays')).toBeNull();
581
- // Without viewport defaults the left edge keeps its configured state.
582
- expect(shell.panels.left).toBe('expanded');
583
- expect(shellRoot().getAttribute('style')).toContain('--smrt-admin-shell-header-track: 0rem');
584
- });
585
- it('still renders a system bar in the bottom edge', () => {
586
- const shell = createShellState();
587
- render(AdminShell, {
588
- props: {
589
- state: shell,
590
- systemBar: html('<span>system chips</span>'),
591
- children: html('<p>page</p>'),
592
- },
593
- });
594
- expect(document.getElementById(ADMIN_SHELL_REGION_IDS.bottom)?.textContent).toContain('system chips');
595
- });
596
- });
597
- vi.setConfig({ testTimeout: 30000 });