microui-wc 0.1.0 → 0.1.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 (343) hide show
  1. package/AGENTS.md +71 -71
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +14 -9
  4. package/dist/AGENTS.md +116 -116
  5. package/dist/README.md +21 -16
  6. package/dist/components.css +1 -1
  7. package/dist/microui.css +1 -1
  8. package/dist/microui.esm.js.map +1 -1
  9. package/dist/microui.min.js.map +1 -1
  10. package/dist/styles/components/switch.css +1 -1
  11. package/docs/getting-started.md +3 -3
  12. package/package.json +38 -10
  13. package/src/components/mu-schema-form.js +1 -1
  14. package/src/styles/components/switch.css +7 -8
  15. package/src/styles/components.css +6 -6
  16. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  17. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -33
  18. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  19. package/.github/workflows/ci.yml +0 -42
  20. package/.github/workflows/deploy-pages.yml +0 -112
  21. package/CODE_OF_CONDUCT.md +0 -59
  22. package/CONTRIBUTING.md +0 -156
  23. package/SECURITY.md +0 -58
  24. package/app/.generated/routes/alerts.js +0 -8
  25. package/app/.generated/routes/avatars.js +0 -8
  26. package/app/.generated/routes/badges.js +0 -8
  27. package/app/.generated/routes/buttons.js +0 -10
  28. package/app/.generated/routes/cards.js +0 -10
  29. package/app/.generated/routes/checkboxes.js +0 -9
  30. package/app/.generated/routes/chips.js +0 -8
  31. package/app/.generated/routes/dropdowns.js +0 -9
  32. package/app/.generated/routes/home.js +0 -7
  33. package/app/.generated/routes/icons.js +0 -9
  34. package/app/.generated/routes/inputs.js +0 -10
  35. package/app/.generated/routes/installation.js +0 -7
  36. package/app/.generated/routes/layout.js +0 -9
  37. package/app/.generated/routes/modals.js +0 -9
  38. package/app/.generated/routes/navbar.js +0 -7
  39. package/app/.generated/routes/progress.js +0 -9
  40. package/app/.generated/routes/radios.js +0 -9
  41. package/app/.generated/routes/switches.js +0 -9
  42. package/app/.generated/routes/tabs.js +0 -8
  43. package/app/.generated/routes/toasts.js +0 -9
  44. package/app/index.html +0 -67
  45. package/app/pages/alerts.html +0 -23
  46. package/app/pages/avatars.html +0 -22
  47. package/app/pages/badges.html +0 -22
  48. package/app/pages/buttons.html +0 -71
  49. package/app/pages/cards.html +0 -54
  50. package/app/pages/checkboxes.html +0 -39
  51. package/app/pages/chips.html +0 -23
  52. package/app/pages/dropdowns.html +0 -41
  53. package/app/pages/home.html +0 -59
  54. package/app/pages/icons.html +0 -29
  55. package/app/pages/inputs.html +0 -66
  56. package/app/pages/installation.html +0 -34
  57. package/app/pages/layout.html +0 -30
  58. package/app/pages/modals.html +0 -21
  59. package/app/pages/navbar.html +0 -22
  60. package/app/pages/progress.html +0 -35
  61. package/app/pages/radios.html +0 -40
  62. package/app/pages/switches.html +0 -39
  63. package/app/pages/tabs.html +0 -30
  64. package/app/pages/toasts.html +0 -22
  65. package/app-dist/index.html +0 -67
  66. package/app-dist/pages/alerts.html +0 -23
  67. package/app-dist/pages/avatars.html +0 -22
  68. package/app-dist/pages/badges.html +0 -22
  69. package/app-dist/pages/buttons.html +0 -71
  70. package/app-dist/pages/cards.html +0 -54
  71. package/app-dist/pages/checkboxes.html +0 -39
  72. package/app-dist/pages/chips.html +0 -23
  73. package/app-dist/pages/dropdowns.html +0 -41
  74. package/app-dist/pages/home.html +0 -59
  75. package/app-dist/pages/icons.html +0 -29
  76. package/app-dist/pages/inputs.html +0 -66
  77. package/app-dist/pages/installation.html +0 -34
  78. package/app-dist/pages/layout.html +0 -30
  79. package/app-dist/pages/modals.html +0 -21
  80. package/app-dist/pages/navbar.html +0 -22
  81. package/app-dist/pages/progress.html +0 -35
  82. package/app-dist/pages/radios.html +0 -40
  83. package/app-dist/pages/switches.html +0 -39
  84. package/app-dist/pages/tabs.html +0 -30
  85. package/app-dist/pages/toasts.html +0 -22
  86. package/app-dist/pages.json +0 -217
  87. package/app-dist/routes/alerts.js +0 -5
  88. package/app-dist/routes/avatars.js +0 -1
  89. package/app-dist/routes/badges.js +0 -1
  90. package/app-dist/routes/buttons.js +0 -1
  91. package/app-dist/routes/cards.js +0 -1
  92. package/app-dist/routes/checkboxes.js +0 -9
  93. package/app-dist/routes/chips.js +0 -4
  94. package/app-dist/routes/chunk-019e5e2f.js +0 -5
  95. package/app-dist/routes/chunk-0m4j19yd.js +0 -2
  96. package/app-dist/routes/chunk-0tmmp5q0.js +0 -1
  97. package/app-dist/routes/chunk-10xn709r.js +0 -1
  98. package/app-dist/routes/chunk-15m2qcda.js +0 -2
  99. package/app-dist/routes/chunk-1bh8g23n.js +0 -1
  100. package/app-dist/routes/chunk-1vg0v937.js +0 -1
  101. package/app-dist/routes/chunk-1zvcgy3j.js +0 -1
  102. package/app-dist/routes/chunk-2afb0861.js +0 -1
  103. package/app-dist/routes/chunk-2c6ttpzt.js +0 -5
  104. package/app-dist/routes/chunk-3dy30fhs.js +0 -1
  105. package/app-dist/routes/chunk-426dnces.js +0 -13
  106. package/app-dist/routes/chunk-44kgxery.js +0 -1
  107. package/app-dist/routes/chunk-47fdnejd.js +0 -33
  108. package/app-dist/routes/chunk-49a6t2vq.js +0 -1
  109. package/app-dist/routes/chunk-4fe1rm5b.js +0 -1
  110. package/app-dist/routes/chunk-4ggmvkta.js +0 -33
  111. package/app-dist/routes/chunk-4vkz81q7.js +0 -33
  112. package/app-dist/routes/chunk-4w4tmj8f.js +0 -31
  113. package/app-dist/routes/chunk-532s62kr.js +0 -31
  114. package/app-dist/routes/chunk-5hm3bssy.js +0 -33
  115. package/app-dist/routes/chunk-5vrh24hc.js +0 -1
  116. package/app-dist/routes/chunk-61pcg25a.js +0 -1
  117. package/app-dist/routes/chunk-6nfhygvf.js +0 -1
  118. package/app-dist/routes/chunk-700e7je6.js +0 -33
  119. package/app-dist/routes/chunk-7fsn17kg.js +0 -1
  120. package/app-dist/routes/chunk-7k789b32.js +0 -1
  121. package/app-dist/routes/chunk-7r46q0ys.js +0 -36
  122. package/app-dist/routes/chunk-86fmc1fr.js +0 -5
  123. package/app-dist/routes/chunk-8qth37vw.js +0 -1
  124. package/app-dist/routes/chunk-924wv8n0.js +0 -1
  125. package/app-dist/routes/chunk-9mbhgxk9.js +0 -1
  126. package/app-dist/routes/chunk-a216hyd9.js +0 -1
  127. package/app-dist/routes/chunk-akzxykh9.js +0 -33
  128. package/app-dist/routes/chunk-b3dcvy8c.js +0 -1
  129. package/app-dist/routes/chunk-b74zahz5.js +0 -31
  130. package/app-dist/routes/chunk-bftj53p2.js +0 -5
  131. package/app-dist/routes/chunk-c01hnz3e.js +0 -1
  132. package/app-dist/routes/chunk-d8pvv5km.js +0 -1
  133. package/app-dist/routes/chunk-dev0aezr.js +0 -2
  134. package/app-dist/routes/chunk-dh6vnv0e.js +0 -1
  135. package/app-dist/routes/chunk-dn2cbpva.js +0 -36
  136. package/app-dist/routes/chunk-dvn0my90.js +0 -1
  137. package/app-dist/routes/chunk-dvq8mnve.js +0 -36
  138. package/app-dist/routes/chunk-e8c2gc4d.js +0 -5
  139. package/app-dist/routes/chunk-ejf9ak2x.js +0 -1
  140. package/app-dist/routes/chunk-f083m55s.js +0 -1
  141. package/app-dist/routes/chunk-fnrj28s1.js +0 -31
  142. package/app-dist/routes/chunk-fvg3yjdp.js +0 -31
  143. package/app-dist/routes/chunk-g7k381n1.js +0 -1
  144. package/app-dist/routes/chunk-h01kq2ae.js +0 -13
  145. package/app-dist/routes/chunk-h4dk761v.js +0 -5
  146. package/app-dist/routes/chunk-hmx91z2x.js +0 -5
  147. package/app-dist/routes/chunk-hxbg4m42.js +0 -36
  148. package/app-dist/routes/chunk-jbjnfp2b.js +0 -2
  149. package/app-dist/routes/chunk-jxtz5vv6.js +0 -36
  150. package/app-dist/routes/chunk-jxzcs0ey.js +0 -36
  151. package/app-dist/routes/chunk-kt7wwhcx.js +0 -1
  152. package/app-dist/routes/chunk-kzptszyc.js +0 -33
  153. package/app-dist/routes/chunk-mhgca4w4.js +0 -2
  154. package/app-dist/routes/chunk-mhswxa20.js +0 -1
  155. package/app-dist/routes/chunk-n8zfeex6.js +0 -1
  156. package/app-dist/routes/chunk-pee47b2r.js +0 -1
  157. package/app-dist/routes/chunk-pesmw829.js +0 -1
  158. package/app-dist/routes/chunk-pgc4c6f3.js +0 -36
  159. package/app-dist/routes/chunk-q8egegm1.js +0 -1
  160. package/app-dist/routes/chunk-q9mn2qyq.js +0 -36
  161. package/app-dist/routes/chunk-qh0rtaf3.js +0 -5
  162. package/app-dist/routes/chunk-qqhmk6ye.js +0 -2
  163. package/app-dist/routes/chunk-qrxygmf7.js +0 -33
  164. package/app-dist/routes/chunk-r46yzksx.js +0 -36
  165. package/app-dist/routes/chunk-rgpbw2w0.js +0 -5
  166. package/app-dist/routes/chunk-rnpzv3d8.js +0 -2
  167. package/app-dist/routes/chunk-s5v8cv05.js +0 -2
  168. package/app-dist/routes/chunk-sbwn5bpc.js +0 -1
  169. package/app-dist/routes/chunk-sqbg8jbt.js +0 -33
  170. package/app-dist/routes/chunk-sv8dqnf7.js +0 -1
  171. package/app-dist/routes/chunk-t67sw3za.js +0 -1
  172. package/app-dist/routes/chunk-tjdpqwdf.js +0 -31
  173. package/app-dist/routes/chunk-tq2mfghg.js +0 -1
  174. package/app-dist/routes/chunk-ttn10vt6.js +0 -1
  175. package/app-dist/routes/chunk-v2hzpjxr.js +0 -1
  176. package/app-dist/routes/chunk-wfjjkw9y.js +0 -1
  177. package/app-dist/routes/chunk-wt8cxzmf.js +0 -31
  178. package/app-dist/routes/chunk-x45d372k.js +0 -5
  179. package/app-dist/routes/chunk-y3wsazkt.js +0 -1
  180. package/app-dist/routes/chunk-y7pmgc7t.js +0 -33
  181. package/app-dist/routes/chunk-zefdt2q3.js +0 -31
  182. package/app-dist/routes/dropdowns.js +0 -6
  183. package/app-dist/routes/home.js +0 -1
  184. package/app-dist/routes/icons.js +0 -1
  185. package/app-dist/routes/inputs.js +0 -12
  186. package/app-dist/routes/installation.js +0 -1
  187. package/app-dist/routes/layout.js +0 -1
  188. package/app-dist/routes/modals.js +0 -7
  189. package/app-dist/routes/navbar.js +0 -1
  190. package/app-dist/routes/progress.js +0 -1
  191. package/app-dist/routes/radios.js +0 -6
  192. package/app-dist/routes/switches.js +0 -6
  193. package/app-dist/routes/tabs.js +0 -1
  194. package/app-dist/routes/toasts.js +0 -16
  195. package/assets/fonts/material-symbols-mini.woff2 +0 -0
  196. package/assets/fonts/material-symbols.woff2 +0 -0
  197. package/assets/fonts/roboto-400.woff2 +0 -0
  198. package/assets/fonts/roboto-500.woff2 +0 -0
  199. package/assets/fonts/roboto-700.woff2 +0 -0
  200. package/assets/logo-banner-400.jpg +0 -0
  201. package/assets/logo-banner-400.webp +0 -0
  202. package/assets/logo-banner-800.webp +0 -0
  203. package/assets/logo-banner.jpg +0 -0
  204. package/assets/logo-icon-64.jpg +0 -0
  205. package/assets/logo-icon-64.webp +0 -0
  206. package/assets/logo-icon.jpg +0 -0
  207. package/assets/logo-square.jpg +0 -0
  208. package/bun.lock +0 -312
  209. package/bunfig.toml +0 -4
  210. package/custom-elements.json +0 -1916
  211. package/demo/api/sample-data.json +0 -38
  212. package/demo/content/alerts.html +0 -115
  213. package/demo/content/avatars.html +0 -70
  214. package/demo/content/badges.html +0 -65
  215. package/demo/content/buttons.html +0 -188
  216. package/demo/content/callouts.html +0 -91
  217. package/demo/content/cards.html +0 -121
  218. package/demo/content/checkboxes.html +0 -178
  219. package/demo/content/chips.html +0 -67
  220. package/demo/content/codeblocks.html +0 -101
  221. package/demo/content/confirms.html +0 -115
  222. package/demo/content/datatables.html +0 -149
  223. package/demo/content/dividers.html +0 -119
  224. package/demo/content/dropdowns.html +0 -89
  225. package/demo/content/enterprise.html +0 -252
  226. package/demo/content/home.html +0 -149
  227. package/demo/content/icons.html +0 -89
  228. package/demo/content/inputs.html +0 -135
  229. package/demo/content/installation.html +0 -16
  230. package/demo/content/layout.html +0 -136
  231. package/demo/content/modals.html +0 -141
  232. package/demo/content/navbar.html +0 -70
  233. package/demo/content/progress.html +0 -119
  234. package/demo/content/radios.html +0 -88
  235. package/demo/content/skeletons.html +0 -109
  236. package/demo/content/spinners.html +0 -96
  237. package/demo/content/switches.html +0 -84
  238. package/demo/content/tables.html +0 -124
  239. package/demo/content/tabs.html +0 -85
  240. package/demo/content/toasts.html +0 -116
  241. package/demo/content/tooltips.html +0 -107
  242. package/demo/content/virtual-lists.html +0 -233
  243. package/demo/favicon.ico +0 -0
  244. package/demo/favicon.png +0 -0
  245. package/demo/full.html +0 -52
  246. package/demo/iife.html +0 -46
  247. package/demo/manifest.json +0 -34
  248. package/demo/pages/datatable-demo.html +0 -237
  249. package/demo/pages/prompt-ui-demo.html +0 -218
  250. package/demo/pages/responsive-demo.html +0 -122
  251. package/demo/pages/schema-form-demo.html +0 -270
  252. package/demo/robots.txt +0 -6
  253. package/demo/shell.html +0 -712
  254. package/demo/sw.js +0 -387
  255. package/lighthouse-audit.mjs +0 -113
  256. package/scripts/analyze-components.js +0 -105
  257. package/scripts/build-app.js +0 -193
  258. package/scripts/build-framework.js +0 -444
  259. package/scripts/build-utils.js +0 -101
  260. package/scripts/test-isolated.js +0 -151
  261. package/server.js +0 -256
  262. package/tests/agents/agent-integration.test.js +0 -76
  263. package/tests/benchmark.html +0 -296
  264. package/tests/build/scan-components.test.js +0 -173
  265. package/tests/components/all-components.test.js +0 -245
  266. package/tests/components/all-missing-components.test.js +0 -574
  267. package/tests/components/mu-alert.test.js +0 -113
  268. package/tests/components/mu-avatar.test.js +0 -148
  269. package/tests/components/mu-badge.test.js +0 -92
  270. package/tests/components/mu-button.test.js +0 -112
  271. package/tests/components/mu-card.test.js +0 -89
  272. package/tests/components/mu-checkbox.test.js +0 -158
  273. package/tests/components/mu-chip.test.js +0 -118
  274. package/tests/components/mu-container.test.js +0 -120
  275. package/tests/components/mu-divider.test.js +0 -98
  276. package/tests/components/mu-drawer-item.test.js +0 -199
  277. package/tests/components/mu-drawer.test.js +0 -96
  278. package/tests/components/mu-dropdown.test.js +0 -125
  279. package/tests/components/mu-form.test.js +0 -138
  280. package/tests/components/mu-grid.test.js +0 -135
  281. package/tests/components/mu-icon.test.js +0 -110
  282. package/tests/components/mu-input.test.js +0 -131
  283. package/tests/components/mu-lazy.test.js +0 -103
  284. package/tests/components/mu-modal.test.js +0 -275
  285. package/tests/components/mu-navbar.test.js +0 -101
  286. package/tests/components/mu-progress.test.js +0 -115
  287. package/tests/components/mu-radio.test.js +0 -114
  288. package/tests/components/mu-repeat.test.js +0 -106
  289. package/tests/components/mu-sidebar.test.js +0 -126
  290. package/tests/components/mu-skeleton.test.js +0 -162
  291. package/tests/components/mu-stack.test.js +0 -143
  292. package/tests/components/mu-switch.test.js +0 -292
  293. package/tests/components/mu-table.test.js +0 -124
  294. package/tests/components/mu-tabs.test.js +0 -104
  295. package/tests/components/mu-textarea.test.js +0 -115
  296. package/tests/components/mu-toast.test.js +0 -321
  297. package/tests/components/mu-tooltip.test.js +0 -133
  298. package/tests/components/mu-virtual-list.test.js +0 -109
  299. package/tests/core/MuElement.test.js +0 -120
  300. package/tests/core/agent-api.test.js +0 -125
  301. package/tests/core/all-core-modules.test.js +0 -442
  302. package/tests/core/bus.test.js +0 -364
  303. package/tests/core/component-schema.test.js +0 -160
  304. package/tests/core/feature-registry.test.js +0 -198
  305. package/tests/core/form-state.test.js +0 -167
  306. package/tests/core/http.test.js +0 -119
  307. package/tests/core/keyboard.test.js +0 -319
  308. package/tests/core/layers.test.js +0 -129
  309. package/tests/core/namespaced-stores.test.js +0 -114
  310. package/tests/core/render.test.js +0 -121
  311. package/tests/core/ripple.test.js +0 -131
  312. package/tests/core/router.test.js +0 -89
  313. package/tests/core/scheduler.test.js +0 -121
  314. package/tests/core/signals.test.js +0 -128
  315. package/tests/core/store.test.js +0 -171
  316. package/tests/core/transitions.test.js +0 -82
  317. package/tests/e2e/accessibility-harness.html +0 -58
  318. package/tests/e2e/accessibility.test.js +0 -401
  319. package/tests/e2e/agent-features.test.js +0 -372
  320. package/tests/e2e/card-spacing.test.js +0 -287
  321. package/tests/e2e/components.test.js +0 -439
  322. package/tests/e2e/demo-routes.test.js +0 -478
  323. package/tests/e2e/layout-css-fallback.test.js +0 -334
  324. package/tests/e2e/mu-alert.e2e.test.js +0 -111
  325. package/tests/e2e/mu-checkbox.test.js +0 -489
  326. package/tests/e2e/mu-chip.test.js +0 -347
  327. package/tests/e2e/mu-form.test.js +0 -499
  328. package/tests/e2e/mu-icon.test.js +0 -114
  329. package/tests/e2e/mu-radio.test.js +0 -113
  330. package/tests/e2e/mu-skeleton.test.js +0 -140
  331. package/tests/e2e/mu-switch.test.js +0 -415
  332. package/tests/e2e/mu-tabs.test.js +0 -494
  333. package/tests/e2e/mu-textarea.test.js +0 -242
  334. package/tests/e2e/mu-virtual-list.test.js +0 -427
  335. package/tests/e2e/perf-memory.test.js +0 -161
  336. package/tests/e2e/puppeteer-helper.js +0 -137
  337. package/tests/e2e/puppeteer.test.js +0 -226
  338. package/tests/e2e/pwa.test.js +0 -261
  339. package/tests/e2e/test-harness.html +0 -319
  340. package/tests/manual/test-components.html +0 -120
  341. package/tests/memory-test.html +0 -309
  342. package/tests/setup-dom.js +0 -93
  343. package/tests/visual-test.html +0 -301
@@ -1,372 +0,0 @@
1
- /**
2
- * @fileoverview E2E Tests for 2026 Agent Features
3
- *
4
- * Tests Agent API, Visual Markers, Component Schema, MCP Actions with real browser
5
- */
6
-
7
- import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
8
- import { launchBrowser, puppeteer } from './puppeteer-helper.js';
9
- import { fileURLToPath } from 'url';
10
- import { dirname, join } from 'path';
11
- import { mkdirSync, rmSync } from 'fs';
12
-
13
- const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
15
-
16
- describe('2026 Agent Features E2E', () => {
17
- let browser;
18
- let page;
19
- let server;
20
- const userDataDir = `./.tmp/puppeteer-agent-${Date.now()}-${Math.random().toString(36).slice(2)}`;
21
-
22
- beforeAll(async () => {
23
- mkdirSync(userDataDir, { recursive: true });
24
-
25
- // Start server
26
- const projectRoot = join(__dirname, '../..');
27
- server = Bun.serve({
28
- port: 0,
29
- async fetch(req) {
30
- const url = new URL(req.url);
31
- let filePath = join(projectRoot, url.pathname);
32
-
33
- // Serve a simple test page that loads IIFE bundle
34
- if (url.pathname === '/') {
35
- return new Response(`<!DOCTYPE html>
36
- <html>
37
- <head><title>Agent Test</title></head>
38
- <body>
39
- <mu-button id="test-btn" variant="filled">Save</mu-button>
40
- <mu-button id="cancel-btn" variant="text">Cancel</mu-button>
41
- <mu-input id="test-input" label="Email"></mu-input>
42
- <mu-checkbox id="test-check">Agree</mu-checkbox>
43
- <mu-card id="test-card">Card Content</mu-card>
44
- <script src="/dist/microui.min.js"></script>
45
- </body>
46
- </html>`, { headers: { 'Content-Type': 'text/html' } });
47
- }
48
-
49
- try {
50
- const file = Bun.file(filePath);
51
- if (!await file.exists()) {
52
- return new Response('Not Found', { status: 404 });
53
- }
54
- const content = await file.text();
55
- const ext = filePath.split('.').pop();
56
- const mimeTypes = { 'html': 'text/html', 'js': 'text/javascript', 'css': 'text/css', 'json': 'application/json' };
57
- return new Response(content, { headers: { 'Content-Type': mimeTypes[ext] || 'text/plain' } });
58
- } catch (e) {
59
- return new Response('Error: ' + e.message, { status: 500 });
60
- }
61
- }
62
- });
63
-
64
- browser = await launchBrowser({ testName: 'e2e' });
65
- page = await browser.newPage();
66
- await page.goto(`http://localhost:${server.port}`, { waitUntil: 'networkidle0', timeout: 30000 });
67
-
68
- // Wait for microUI to be fully loaded
69
- await page.waitForFunction(() => window.microUI !== undefined, { timeout: 10000 });
70
- }, 60000);
71
-
72
- afterAll(async () => {
73
- await browser?.close();
74
- server?.stop();
75
- try { rmSync(userDataDir, { recursive: true, force: true }); } catch { }
76
- });
77
-
78
- // ========================================
79
- // AGENT API TESTS
80
- // ========================================
81
-
82
- describe('Agent API', () => {
83
- test('getMuComponentTree should return array of components', async () => {
84
- const result = await page.evaluate(() => {
85
- const tree = window.microUI.getMuComponentTree(document.body);
86
- return Array.isArray(tree) && tree.length > 0;
87
- });
88
- expect(result).toBe(true);
89
- });
90
-
91
- test('getMuComponentTree should include tag names', async () => {
92
- const result = await page.evaluate(() => {
93
- const tree = window.microUI.getMuComponentTree(document.body);
94
- return tree.some(item => item.tag && item.tag.startsWith('mu-'));
95
- });
96
- expect(result).toBe(true);
97
- });
98
-
99
- test('describeComponent should return string description', async () => {
100
- const result = await page.evaluate(() => {
101
- const btn = document.querySelector('mu-button');
102
- if (!btn) return 'no-button';
103
- const desc = window.microUI.describeComponent(btn);
104
- return typeof desc === 'string' && desc.length > 0;
105
- });
106
- expect(result).toBe(true);
107
- });
108
-
109
- test('findByLabel should find components by text', async () => {
110
- const result = await page.evaluate(() => {
111
- const results = window.microUI.findByLabel('Components', document.body);
112
- return Array.isArray(results);
113
- });
114
- expect(result).toBe(true);
115
- });
116
-
117
- test('getRegisteredComponents should return Map', async () => {
118
- const result = await page.evaluate(() => {
119
- const components = window.microUI.getRegisteredComponents();
120
- return components instanceof Map && components.size > 0;
121
- });
122
- expect(result).toBe(true);
123
- });
124
- });
125
-
126
- // ========================================
127
- // VISUAL MARKERS TESTS
128
- // ========================================
129
-
130
- describe('Visual Markers', () => {
131
- test('enableVisualMarkers should be a function', async () => {
132
- const result = await page.evaluate(() => typeof window.microUI.enableVisualMarkers === 'function');
133
- expect(result).toBe(true);
134
- });
135
-
136
- test('disableVisualMarkers should be a function', async () => {
137
- const result = await page.evaluate(() => typeof window.microUI.disableVisualMarkers === 'function');
138
- expect(result).toBe(true);
139
- });
140
-
141
- test('enableVisualMarkers should create marker mapping', async () => {
142
- const result = await page.evaluate(() => {
143
- window.microUI.enableVisualMarkers({ style: 'badge' });
144
- const map = window.microUI.getMarkerMap();
145
- const markersExist = Object.keys(map).length > 0;
146
- window.microUI.disableVisualMarkers();
147
- return markersExist;
148
- });
149
- expect(result).toBe(true);
150
- });
151
-
152
- test('getMarkerMap should return marker mappings', async () => {
153
- const result = await page.evaluate(() => {
154
- window.microUI.enableVisualMarkers();
155
- const map = window.microUI.getMarkerMap();
156
- window.microUI.disableVisualMarkers();
157
- return typeof map === 'object' && Object.keys(map).length > 0;
158
- });
159
- expect(result).toBe(true);
160
- });
161
-
162
- test('getMarkerElement should retrieve element by marker ID', async () => {
163
- const result = await page.evaluate(() => {
164
- window.microUI.enableVisualMarkers();
165
- const map = window.microUI.getMarkerMap();
166
- const firstKey = Object.keys(map)[0];
167
- const element = window.microUI.getMarkerElement(firstKey);
168
- window.microUI.disableVisualMarkers();
169
- return element !== null && element instanceof HTMLElement;
170
- });
171
- expect(result).toBe(true);
172
- });
173
-
174
- test('disableVisualMarkers should remove all markers', async () => {
175
- const result = await page.evaluate(() => {
176
- window.microUI.enableVisualMarkers();
177
- window.microUI.disableVisualMarkers();
178
- const markers = document.querySelectorAll('[data-mu-marker]');
179
- return markers.length === 0;
180
- });
181
- expect(result).toBe(true);
182
- });
183
- });
184
-
185
- // ========================================
186
- // COMPONENT SCHEMA TESTS
187
- // ========================================
188
-
189
- describe('Component Schema', () => {
190
- test('getComponentSchema should return schema for mu-button', async () => {
191
- const result = await page.evaluate(() => {
192
- const schema = window.microUI.getComponentSchema('mu-button');
193
- return schema !== null && schema.title === 'mu-button';
194
- });
195
- expect(result).toBe(true);
196
- });
197
-
198
- test('schema should include properties', async () => {
199
- const result = await page.evaluate(() => {
200
- const schema = window.microUI.getComponentSchema('mu-button');
201
- return schema.properties && schema.properties.variant;
202
- });
203
- expect(result).toBeTruthy();
204
- });
205
-
206
- test('schema should include actions', async () => {
207
- const result = await page.evaluate(() => {
208
- const schema = window.microUI.getComponentSchema('mu-button');
209
- return Array.isArray(schema.actions) && schema.actions.includes('click');
210
- });
211
- expect(result).toBe(true);
212
- });
213
-
214
- test('getAllSchemas should return Map with multiple schemas', async () => {
215
- const result = await page.evaluate(() => {
216
- const schemas = window.microUI.getAllSchemas();
217
- return schemas instanceof Map && schemas.size >= 10;
218
- });
219
- expect(result).toBe(true);
220
- });
221
-
222
- test('getSchemaComponents should return array of tag names', async () => {
223
- const result = await page.evaluate(() => {
224
- const components = window.microUI.getSchemaComponents();
225
- return Array.isArray(components) && components.includes('mu-button');
226
- });
227
- expect(result).toBe(true);
228
- });
229
-
230
- test('getSchemaQuickRef should return minimal summary', async () => {
231
- const result = await page.evaluate(() => {
232
- const ref = window.microUI.getSchemaQuickRef('mu-input');
233
- return ref && ref.tag === 'mu-input' && Array.isArray(ref.properties);
234
- });
235
- expect(result).toBe(true);
236
- });
237
- });
238
-
239
- // ========================================
240
- // MCP ACTIONS TESTS
241
- // ========================================
242
-
243
- describe('MCP Actions', () => {
244
- test('getMCPActions should return MCP-compatible schema', async () => {
245
- const result = await page.evaluate(() => {
246
- const actions = window.microUI.getMCPActions();
247
- return actions && actions.name === 'microui' && Array.isArray(actions.actions);
248
- });
249
- expect(result).toBe(true);
250
- });
251
-
252
- test('should include click_button action', async () => {
253
- const result = await page.evaluate(() => {
254
- const actions = window.microUI.getMCPActions();
255
- return actions.actions.some(a => a.name === 'click_button');
256
- });
257
- expect(result).toBe(true);
258
- });
259
-
260
- test('should include fill_input action', async () => {
261
- const result = await page.evaluate(() => {
262
- const actions = window.microUI.getMCPActions();
263
- return actions.actions.some(a => a.name === 'fill_input');
264
- });
265
- expect(result).toBe(true);
266
- });
267
-
268
- test('should include toggle_checkbox action', async () => {
269
- const result = await page.evaluate(() => {
270
- const actions = window.microUI.getMCPActions();
271
- return actions.actions.some(a => a.name === 'toggle_checkbox');
272
- });
273
- expect(result).toBe(true);
274
- });
275
-
276
- test('actions should have parameters with types', async () => {
277
- const result = await page.evaluate(() => {
278
- const actions = window.microUI.getMCPActions();
279
- const clickAction = actions.actions.find(a => a.name === 'click_button');
280
- return clickAction.parameters && clickAction.parameters.selector && clickAction.parameters.selector.type;
281
- });
282
- expect(result).toBeTruthy();
283
- });
284
- });
285
-
286
- // ========================================
287
- // SEMANTIC ATTRIBUTES TESTS
288
- // ========================================
289
-
290
- describe('Semantic Attributes', () => {
291
- test('buttons should have data-mu-action attribute', async () => {
292
- const result = await page.evaluate(() => {
293
- const btn = document.querySelector('mu-button');
294
- return btn && btn.hasAttribute('data-mu-action');
295
- });
296
- expect(result).toBe(true);
297
- });
298
-
299
- test('buttons should have data-mu-role attribute', async () => {
300
- const result = await page.evaluate(() => {
301
- const btn = document.querySelector('mu-button');
302
- return btn && btn.hasAttribute('data-mu-role');
303
- });
304
- expect(result).toBe(true);
305
- });
306
-
307
- test('filled button should have primary-action role', async () => {
308
- const result = await page.evaluate(() => {
309
- const btn = document.querySelector('mu-button[variant="filled"]');
310
- return btn && btn.getAttribute('data-mu-role') === 'primary-action';
311
- });
312
- expect(result).toBe(true);
313
- });
314
- });
315
-
316
- // ========================================
317
- // ENTERPRISE FEATURES TESTS
318
- // ========================================
319
-
320
- describe('Enterprise Features', () => {
321
- test('createNamespacedStore should be available', async () => {
322
- const result = await page.evaluate(() => typeof window.microUI.createNamespacedStore === 'function');
323
- expect(result).toBe(true);
324
- });
325
-
326
- test('getStore should be available', async () => {
327
- const result = await page.evaluate(() => typeof window.microUI.getStore === 'function');
328
- expect(result).toBe(true);
329
- });
330
-
331
- test('captureAppState should be available', async () => {
332
- const result = await page.evaluate(() => typeof window.microUI.captureAppState === 'function');
333
- expect(result).toBe(true);
334
- });
335
-
336
- test('createFeature should be available', async () => {
337
- const result = await page.evaluate(() => typeof window.microUI.createFeature === 'function');
338
- expect(result).toBe(true);
339
- });
340
-
341
- test('getFeatures should be available', async () => {
342
- const result = await page.evaluate(() => typeof window.microUI.getFeatures === 'function');
343
- expect(result).toBe(true);
344
- });
345
- });
346
-
347
- // ========================================
348
- // NEW COMPONENTS TESTS
349
- // ========================================
350
-
351
- describe('New Components', () => {
352
- test('mu-error-boundary should be registered', async () => {
353
- const result = await page.evaluate(() => customElements.get('mu-error-boundary') !== undefined);
354
- expect(result).toBe(true);
355
- });
356
-
357
- test('mu-confirm should be registered', async () => {
358
- const result = await page.evaluate(() => customElements.get('mu-confirm') !== undefined);
359
- expect(result).toBe(true);
360
- });
361
-
362
- test('mu-fetch should be registered', async () => {
363
- const result = await page.evaluate(() => customElements.get('mu-fetch') !== undefined);
364
- expect(result).toBe(true);
365
- });
366
-
367
- test('muConfirm function should be available', async () => {
368
- const result = await page.evaluate(() => typeof window.microUI.muConfirm === 'function');
369
- expect(result).toBe(true);
370
- });
371
- });
372
- });
@@ -1,287 +0,0 @@
1
- /**
2
- * @fileoverview Card Spacing E2E Tests - MD3 Compliance
3
- *
4
- * Material Design 3 specifies:
5
- * - Cards should have 8-24dp spacing between them (16dp default)
6
- * - mu-stack gap="md" should apply 16px gap
7
- * - Layout containers should use consistent spacing tokens
8
- *
9
- * These tests verify that card spacing is correctly applied.
10
- */
11
-
12
- import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
13
- import { launchBrowser, puppeteer } from './puppeteer-helper.js';
14
- import { fileURLToPath } from 'url';
15
- import { dirname, join } from 'path';
16
-
17
- const __filename = fileURLToPath(import.meta.url);
18
- const __dirname = dirname(__filename);
19
-
20
- const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
21
-
22
- // MD3 spacing tokens in pixels
23
- const MD3_SPACING = {
24
- xs: 4,
25
- sm: 8,
26
- md: 16,
27
- lg: 24,
28
- xl: 32
29
- };
30
-
31
- describe('Card Spacing E2E Tests (MD3 Compliance)', () => {
32
- let browser;
33
- let page;
34
- let server;
35
-
36
- beforeAll(async () => {
37
- const projectRoot = join(__dirname, '../..');
38
-
39
- server = Bun.serve({
40
- port: 0,
41
- async fetch(req) {
42
- const url = new URL(req.url);
43
- let filePath = join(projectRoot, url.pathname);
44
-
45
- if (url.pathname === '/' || url.pathname === '/shell.html') {
46
- filePath = join(projectRoot, 'demo/shell.html');
47
- }
48
-
49
- try {
50
- const file = Bun.file(filePath);
51
- const exists = await file.exists();
52
- if (!exists) {
53
- return new Response('Not Found', { status: 404 });
54
- }
55
-
56
- const content = await file.arrayBuffer();
57
- const ext = filePath.split('.').pop();
58
- const mimeTypes = {
59
- 'html': 'text/html',
60
- 'js': 'text/javascript',
61
- 'css': 'text/css',
62
- 'json': 'application/json'
63
- };
64
-
65
- return new Response(content, {
66
- headers: { 'Content-Type': mimeTypes[ext] || 'application/octet-stream' }
67
- });
68
- } catch (e) {
69
- return new Response('Error: ' + e.message, { status: 500 });
70
- }
71
- }
72
- });
73
-
74
- console.log(`Test server started at http://localhost:${server.port}`);
75
-
76
- browser = await puppeteer.launch({
77
- headless: true,
78
- executablePath: '/tmp/puppeteer/chrome-headless-shell/mac_arm-144.0.7559.96/chrome-headless-shell-mac-arm64/chrome-headless-shell',
79
- args: ['--no-sandbox', '--disable-setuid-sandbox'],
80
- userDataDir: `./.tmp/puppeteer-card_spacing-${Date.now()}-${Math.random().toString(36).slice(2)}`
81
- });
82
- page = await browser.newPage();
83
- }, 60000);
84
-
85
- afterAll(async () => {
86
- if (browser) await browser.close();
87
- if (server) server.stop();
88
- });
89
-
90
- // ========================================
91
- // TEST 1: mu-stack gap="md" applies 16px
92
- // ========================================
93
- test('mu-stack with gap="md" should apply 16px spacing', async () => {
94
- await page.goto(`http://localhost:${server.port}/demo/shell.html#cards`, {
95
- waitUntil: 'networkidle0'
96
- });
97
- await delay(800);
98
-
99
- const gapValue = await page.evaluate(() => {
100
- const stack = document.querySelector('mu-stack[gap="md"]');
101
- if (!stack) return null;
102
-
103
- // Check computed style
104
- const computed = window.getComputedStyle(stack);
105
- return parseInt(computed.gap || computed.rowGap || '0');
106
- });
107
-
108
- expect(gapValue).toBe(MD3_SPACING.md);
109
- }, 15000);
110
-
111
- // ========================================
112
- // TEST 2: Cards in stack have visible gap
113
- // ========================================
114
- test('cards inside mu-stack should have visible gap between them', async () => {
115
- await page.goto(`http://localhost:${server.port}/demo/shell.html#cards`, {
116
- waitUntil: 'networkidle0'
117
- });
118
- await delay(800);
119
-
120
- const spacing = await page.evaluate(() => {
121
- const stack = document.querySelector('mu-stack[gap="md"]');
122
- if (!stack) return { found: false };
123
-
124
- const cards = stack.querySelectorAll('mu-card');
125
- if (cards.length < 2) return { found: false, cardCount: cards.length };
126
-
127
- // Measure distance between first two cards
128
- const rect1 = cards[0].getBoundingClientRect();
129
- const rect2 = cards[1].getBoundingClientRect();
130
-
131
- // Vertical stack: gap = top of card2 - bottom of card1
132
- const gap = rect2.top - rect1.bottom;
133
-
134
- return {
135
- found: true,
136
- cardCount: cards.length,
137
- gap: Math.round(gap)
138
- };
139
- });
140
-
141
- // If structure found with positive gap, verify gap is MD3 compliant
142
- if (spacing.found && spacing.gap > 0) {
143
- expect(spacing.gap).toBeGreaterThanOrEqual(MD3_SPACING.sm); // At least 8px
144
- expect(spacing.gap).toBeLessThanOrEqual(MD3_SPACING.lg); // At most 24px
145
- } else if (spacing.found && spacing.gap <= 0) {
146
- // Structure found but gap=0 or negative (measurement issue)
147
- console.log('Skipping: mu-stack with cards found but gap measurement is', spacing.gap);
148
- expect(true).toBe(true);
149
- } else {
150
- // Structure not found - skip test gracefully
151
- console.log('Skipping: mu-stack[gap=md] with mu-card children not found in demo page');
152
- expect(true).toBe(true);
153
- }
154
- }, 15000);
155
-
156
- // ========================================
157
- // TEST 3: mu-stack custom element is upgraded
158
- // ========================================
159
- test('mu-stack custom element should be properly upgraded', async () => {
160
- await page.goto(`http://localhost:${server.port}/demo/shell.html#cards`, {
161
- waitUntil: 'networkidle0'
162
- });
163
- await delay(800);
164
-
165
- const isUpgraded = await page.evaluate(() => {
166
- const stack = document.querySelector('mu-stack');
167
- if (!stack) return { exists: false };
168
-
169
- // Check if custom element is defined
170
- const isDefined = customElements.get('mu-stack') !== undefined;
171
-
172
- // Check if instance has expected styles
173
- const hasStyles = stack.style.display === 'flex';
174
-
175
- return {
176
- exists: true,
177
- isDefined,
178
- hasStyles,
179
- display: stack.style.display,
180
- gap: stack.style.gap
181
- };
182
- });
183
-
184
- expect(isUpgraded.exists).toBe(true);
185
- expect(isUpgraded.isDefined).toBe(true);
186
- expect(isUpgraded.hasStyles).toBe(true);
187
- }, 15000);
188
-
189
- // ========================================
190
- // TEST 4: mu-card has correct internal padding
191
- // ========================================
192
- test('mu-card should have MD3-compliant internal padding (20px default)', async () => {
193
- await page.goto(`http://localhost:${server.port}/demo/shell.html#cards`, {
194
- waitUntil: 'networkidle0'
195
- });
196
- await delay(800);
197
-
198
- const padding = await page.evaluate(() => {
199
- const card = document.querySelector('mu-card');
200
- if (!card) return null;
201
-
202
- const computed = window.getComputedStyle(card);
203
- return {
204
- top: parseInt(computed.paddingTop),
205
- right: parseInt(computed.paddingRight),
206
- bottom: parseInt(computed.paddingBottom),
207
- left: parseInt(computed.paddingLeft)
208
- };
209
- });
210
-
211
- expect(padding).not.toBeNull();
212
- // mu-card uses --mu-spacing-5 (20px) as default padding
213
- expect(padding.top).toBe(20);
214
- expect(padding.left).toBe(20);
215
- }, 15000);
216
-
217
- // ========================================
218
- // TEST 5: mu-grid applies correct gap
219
- // ========================================
220
- test('mu-grid with gap="md" should apply 16px grid gap', async () => {
221
- await page.goto(`http://localhost:${server.port}/demo/shell.html#cards`, {
222
- waitUntil: 'networkidle0'
223
- });
224
- await delay(800);
225
-
226
- const gridGap = await page.evaluate(() => {
227
- const grid = document.querySelector('mu-grid[gap="md"]');
228
- if (!grid) return null;
229
-
230
- const computed = window.getComputedStyle(grid);
231
- return parseInt(computed.gap || computed.gridGap || '0');
232
- });
233
-
234
- // If grid exists, verify gap
235
- if (gridGap !== null) {
236
- expect(gridGap).toBe(MD3_SPACING.md);
237
- }
238
- }, 15000);
239
-
240
- // ========================================
241
- // TEST 6: No overlapping cards (visual regression)
242
- // ========================================
243
- test('cards should not visually overlap each other', async () => {
244
- await page.goto(`http://localhost:${server.port}/demo/shell.html#cards`, {
245
- waitUntil: 'networkidle0'
246
- });
247
- await delay(800);
248
-
249
- const noOverlap = await page.evaluate(() => {
250
- const cards = Array.from(document.querySelectorAll('#page-cards mu-card'));
251
- if (cards.length < 2) return { valid: true, reason: 'not_enough_cards' };
252
-
253
- const rects = cards.map(c => c.getBoundingClientRect());
254
-
255
- // Check each pair of adjacent cards
256
- for (let i = 0; i < rects.length - 1; i++) {
257
- for (let j = i + 1; j < rects.length; j++) {
258
- const a = rects[i];
259
- const b = rects[j];
260
-
261
- // Check for overlap
262
- const overlapsHorizontally = a.left < b.right && a.right > b.left;
263
- const overlapsVertically = a.top < b.bottom && a.bottom > b.top;
264
-
265
- if (overlapsHorizontally && overlapsVertically) {
266
- // Some overlap is allowed for nested cards, but not same-level cards
267
- // Check if one contains the other (allowed)
268
- const aContainsB = a.left <= b.left && a.right >= b.right && a.top <= b.top && a.bottom >= b.bottom;
269
- const bContainsA = b.left <= a.left && b.right >= a.right && b.top <= a.top && b.bottom >= a.bottom;
270
-
271
- if (!aContainsB && !bContainsA) {
272
- return {
273
- valid: false,
274
- reason: 'overlapping_cards',
275
- cards: [i, j]
276
- };
277
- }
278
- }
279
- }
280
- }
281
-
282
- return { valid: true, cardCount: cards.length };
283
- });
284
-
285
- expect(noOverlap.valid).toBe(true);
286
- }, 15000);
287
- });