@overcrow/mcp 0.0.0-stage → 0.1.0

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 (461) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -2
  3. package/dist/audit/index.js +103 -0
  4. package/dist/audit/lexer.js +417 -0
  5. package/dist/audit/project.js +200 -0
  6. package/dist/audit/rules.js +661 -0
  7. package/dist/bootstrap/download.js +229 -0
  8. package/dist/bootstrap/install.js +280 -0
  9. package/dist/bootstrap/pin.js +85 -0
  10. package/dist/bootstrap/pin.json +119 -0
  11. package/dist/bootstrap/zip.js +258 -0
  12. package/dist/cli.js +200 -0
  13. package/dist/confine.js +244 -0
  14. package/dist/content/docs/en/cli.md +353 -0
  15. package/dist/content/docs/en/dev-channel.md +130 -0
  16. package/dist/content/docs/en/elements.md +469 -0
  17. package/dist/content/docs/en/forms.md +328 -0
  18. package/dist/content/docs/en/guide.md +253 -0
  19. package/dist/content/docs/en/index.md +85 -0
  20. package/dist/content/docs/en/limits.md +241 -0
  21. package/dist/content/docs/en/logic.md +446 -0
  22. package/dist/content/docs/en/manifest.md +381 -0
  23. package/dist/content/docs/en/mcp.md +165 -0
  24. package/dist/content/docs/en/package.md +131 -0
  25. package/dist/content/docs/en/publishing.md +162 -0
  26. package/dist/content/docs/en/reference.md +55 -0
  27. package/dist/content/docs/en/result-shapes.md +332 -0
  28. package/dist/content/docs/en/sdk.md +295 -0
  29. package/dist/content/docs/en/security.md +115 -0
  30. package/dist/content/docs/en/service-reference.md +344 -0
  31. package/dist/content/docs/en/services.md +517 -0
  32. package/dist/content/docs/en/style-properties.md +270 -0
  33. package/dist/content/docs/en/style.md +266 -0
  34. package/dist/content/docs/en/testing.md +400 -0
  35. package/dist/content/docs/en/view.md +338 -0
  36. package/dist/content/docs/en/widgets.md +76 -0
  37. package/dist/content/docs/fr/cli.md +367 -0
  38. package/dist/content/docs/fr/dev-channel.md +140 -0
  39. package/dist/content/docs/fr/elements.md +475 -0
  40. package/dist/content/docs/fr/forms.md +341 -0
  41. package/dist/content/docs/fr/guide.md +264 -0
  42. package/dist/content/docs/fr/index.md +90 -0
  43. package/dist/content/docs/fr/limits.md +244 -0
  44. package/dist/content/docs/fr/logic.md +461 -0
  45. package/dist/content/docs/fr/manifest.md +392 -0
  46. package/dist/content/docs/fr/mcp.md +173 -0
  47. package/dist/content/docs/fr/package.md +139 -0
  48. package/dist/content/docs/fr/publishing.md +172 -0
  49. package/dist/content/docs/fr/reference.md +59 -0
  50. package/dist/content/docs/fr/result-shapes.md +333 -0
  51. package/dist/content/docs/fr/sdk.md +301 -0
  52. package/dist/content/docs/fr/security.md +129 -0
  53. package/dist/content/docs/fr/service-reference.md +346 -0
  54. package/dist/content/docs/fr/services.md +540 -0
  55. package/dist/content/docs/fr/style-properties.md +272 -0
  56. package/dist/content/docs/fr/style.md +281 -0
  57. package/dist/content/docs/fr/testing.md +417 -0
  58. package/dist/content/docs/fr/view.md +352 -0
  59. package/dist/content/docs/fr/widgets.md +81 -0
  60. package/dist/content/examples/clock/LICENSE +21 -0
  61. package/dist/content/examples/clock/README.md +75 -0
  62. package/dist/content/examples/clock/listing.json +19 -0
  63. package/dist/content/examples/clock/locales/en.json +4 -0
  64. package/dist/content/examples/clock/locales/fr.json +4 -0
  65. package/dist/content/examples/clock/logic.ts +85 -0
  66. package/dist/content/examples/clock/manifest.json +44 -0
  67. package/dist/content/examples/clock/package.json +16 -0
  68. package/dist/content/examples/clock/style.ocss +26 -0
  69. package/dist/content/examples/clock/tests/hidden.scenario.json +68 -0
  70. package/dist/content/examples/clock/tests/load-logic.mjs +22 -0
  71. package/dist/content/examples/clock/tests/logic.test.mjs +89 -0
  72. package/dist/content/examples/clock/tests/options.scenario.json +108 -0
  73. package/dist/content/examples/clock/tests/preview.scenario.json +25 -0
  74. package/dist/content/examples/clock/tests/render.scenario.json +94 -0
  75. package/dist/content/examples/clock/tests/summer-time.scenario.json +74 -0
  76. package/dist/content/examples/clock/tests/ticks.scenario.json +120 -0
  77. package/dist/content/examples/clock/tsconfig.json +16 -0
  78. package/dist/content/examples/clock/view.ocml +8 -0
  79. package/dist/content/examples/countdown/LICENSE +20 -0
  80. package/dist/content/examples/countdown/listing.json +10 -0
  81. package/dist/content/examples/countdown/locales/en.json +15 -0
  82. package/dist/content/examples/countdown/locales/fr.json +15 -0
  83. package/dist/content/examples/countdown/logic.ts +179 -0
  84. package/dist/content/examples/countdown/manifest.json +34 -0
  85. package/dist/content/examples/countdown/package.json +15 -0
  86. package/dist/content/examples/countdown/style.ocss +94 -0
  87. package/dist/content/examples/countdown/tsconfig.json +16 -0
  88. package/dist/content/examples/countdown/view.ocml +42 -0
  89. package/dist/content/examples/fps/LICENSE +21 -0
  90. package/dist/content/examples/fps/README.md +64 -0
  91. package/dist/content/examples/fps/listing.json +19 -0
  92. package/dist/content/examples/fps/locales/en.json +11 -0
  93. package/dist/content/examples/fps/locales/fr.json +11 -0
  94. package/dist/content/examples/fps/logic.ts +64 -0
  95. package/dist/content/examples/fps/manifest.json +30 -0
  96. package/dist/content/examples/fps/package.json +16 -0
  97. package/dist/content/examples/fps/style.ocss +31 -0
  98. package/dist/content/examples/fps/tests/label.scenario.json +63 -0
  99. package/dist/content/examples/fps/tests/load-logic.mjs +22 -0
  100. package/dist/content/examples/fps/tests/logic.test.mjs +60 -0
  101. package/dist/content/examples/fps/tests/preview.scenario.json +29 -0
  102. package/dist/content/examples/fps/tests/refused.scenario.json +20 -0
  103. package/dist/content/examples/fps/tests/render.scenario.json +96 -0
  104. package/dist/content/examples/fps/tests/stale.scenario.json +91 -0
  105. package/dist/content/examples/fps/tests/unavailable.scenario.json +111 -0
  106. package/dist/content/examples/fps/tsconfig.json +16 -0
  107. package/dist/content/examples/fps/view.ocml +11 -0
  108. package/dist/content/examples/media/LICENSE +21 -0
  109. package/dist/content/examples/media/README.md +147 -0
  110. package/dist/content/examples/media/listing.json +19 -0
  111. package/dist/content/examples/media/locales/en.json +11 -0
  112. package/dist/content/examples/media/locales/fr.json +11 -0
  113. package/dist/content/examples/media/logic.ts +191 -0
  114. package/dist/content/examples/media/manifest.json +35 -0
  115. package/dist/content/examples/media/package.json +16 -0
  116. package/dist/content/examples/media/style.ocss +148 -0
  117. package/dist/content/examples/media/tests/covers.scenario.json +144 -0
  118. package/dist/content/examples/media/tests/gesture.scenario.json +173 -0
  119. package/dist/content/examples/media/tests/load-logic.mjs +22 -0
  120. package/dist/content/examples/media/tests/logic.test.mjs +176 -0
  121. package/dist/content/examples/media/tests/marquee.scenario.json +127 -0
  122. package/dist/content/examples/media/tests/preview.scenario.json +52 -0
  123. package/dist/content/examples/media/tests/read-only.scenario.json +53 -0
  124. package/dist/content/examples/media/tests/refused.scenario.json +22 -0
  125. package/dist/content/examples/media/tests/refused.test.mjs +31 -0
  126. package/dist/content/examples/media/tests/render.scenario.json +136 -0
  127. package/dist/content/examples/media/tests/states.scenario.json +257 -0
  128. package/dist/content/examples/media/tests/unavailable.scenario.json +120 -0
  129. package/dist/content/examples/media/tsconfig.json +16 -0
  130. package/dist/content/examples/media/view.ocml +41 -0
  131. package/dist/content/examples/notes/LICENSE +21 -0
  132. package/dist/content/examples/notes/README.md +219 -0
  133. package/dist/content/examples/notes/listing.json +19 -0
  134. package/dist/content/examples/notes/locales/en.json +25 -0
  135. package/dist/content/examples/notes/locales/fr.json +25 -0
  136. package/dist/content/examples/notes/logic.ts +799 -0
  137. package/dist/content/examples/notes/manifest.json +40 -0
  138. package/dist/content/examples/notes/package.json +16 -0
  139. package/dist/content/examples/notes/style.ocss +469 -0
  140. package/dist/content/examples/notes/tests/checks.scenario.json +237 -0
  141. package/dist/content/examples/notes/tests/create.scenario.json +260 -0
  142. package/dist/content/examples/notes/tests/delete.scenario.json +342 -0
  143. package/dist/content/examples/notes/tests/drafts.scenario.json +714 -0
  144. package/dist/content/examples/notes/tests/editor.scenario.json +232 -0
  145. package/dist/content/examples/notes/tests/frame.scenario.json +93 -0
  146. package/dist/content/examples/notes/tests/interactive.scenario.json +344 -0
  147. package/dist/content/examples/notes/tests/limits.scenario.json +1351 -0
  148. package/dist/content/examples/notes/tests/load-logic.mjs +22 -0
  149. package/dist/content/examples/notes/tests/logic.test.mjs +514 -0
  150. package/dist/content/examples/notes/tests/preview.scenario.json +99 -0
  151. package/dist/content/examples/notes/tests/read-only.scenario.json +105 -0
  152. package/dist/content/examples/notes/tests/refused.scenario.json +33 -0
  153. package/dist/content/examples/notes/tests/save.scenario.json +378 -0
  154. package/dist/content/examples/notes/tests/states.scenario.json +640 -0
  155. package/dist/content/examples/notes/tests/typing.scenario.json +562 -0
  156. package/dist/content/examples/notes/tests/unavailable.scenario.json +246 -0
  157. package/dist/content/examples/notes/tsconfig.json +16 -0
  158. package/dist/content/examples/notes/view.ocml +154 -0
  159. package/dist/content/examples/performance/LICENSE +21 -0
  160. package/dist/content/examples/performance/README.md +134 -0
  161. package/dist/content/examples/performance/listing.json +19 -0
  162. package/dist/content/examples/performance/locales/en.json +20 -0
  163. package/dist/content/examples/performance/locales/fr.json +20 -0
  164. package/dist/content/examples/performance/logic.ts +210 -0
  165. package/dist/content/examples/performance/manifest.json +83 -0
  166. package/dist/content/examples/performance/package.json +16 -0
  167. package/dist/content/examples/performance/style.ocss +75 -0
  168. package/dist/content/examples/performance/tests/fahrenheit.scenario.json +110 -0
  169. package/dist/content/examples/performance/tests/horizontal.scenario.json +96 -0
  170. package/dist/content/examples/performance/tests/load-logic.mjs +22 -0
  171. package/dist/content/examples/performance/tests/logic.test.mjs +226 -0
  172. package/dist/content/examples/performance/tests/menu.scenario.json +170 -0
  173. package/dist/content/examples/performance/tests/no-fps-source.scenario.json +47 -0
  174. package/dist/content/examples/performance/tests/preview.scenario.json +45 -0
  175. package/dist/content/examples/performance/tests/refused.scenario.json +20 -0
  176. package/dist/content/examples/performance/tests/refused.test.mjs +19 -0
  177. package/dist/content/examples/performance/tests/region.scenario.json +89 -0
  178. package/dist/content/examples/performance/tests/render.scenario.json +112 -0
  179. package/dist/content/examples/performance/tests/sources.scenario.json +151 -0
  180. package/dist/content/examples/performance/tests/stale.scenario.json +111 -0
  181. package/dist/content/examples/performance/tests/telemetry-only.scenario.json +44 -0
  182. package/dist/content/examples/performance/tests/thresholds.scenario.json +147 -0
  183. package/dist/content/examples/performance/tests/waiting.scenario.json +105 -0
  184. package/dist/content/examples/performance/tsconfig.json +16 -0
  185. package/dist/content/examples/performance/view.ocml +18 -0
  186. package/dist/content/examples/playervox-journal/LICENSE +21 -0
  187. package/dist/content/examples/playervox-journal/README.md +150 -0
  188. package/dist/content/examples/playervox-journal/listing.json +19 -0
  189. package/dist/content/examples/playervox-journal/locales/en.json +25 -0
  190. package/dist/content/examples/playervox-journal/locales/fr.json +25 -0
  191. package/dist/content/examples/playervox-journal/logic.ts +556 -0
  192. package/dist/content/examples/playervox-journal/manifest.json +19 -0
  193. package/dist/content/examples/playervox-journal/package.json +16 -0
  194. package/dist/content/examples/playervox-journal/style.ocss +142 -0
  195. package/dist/content/examples/playervox-journal/tests/changes.scenario.json +482 -0
  196. package/dist/content/examples/playervox-journal/tests/delete.scenario.json +432 -0
  197. package/dist/content/examples/playervox-journal/tests/frame.scenario.json +169 -0
  198. package/dist/content/examples/playervox-journal/tests/load-logic.mjs +22 -0
  199. package/dist/content/examples/playervox-journal/tests/logic.test.mjs +349 -0
  200. package/dist/content/examples/playervox-journal/tests/paging.scenario.json +428 -0
  201. package/dist/content/examples/playervox-journal/tests/preview.scenario.json +184 -0
  202. package/dist/content/examples/playervox-journal/tests/read-only.scenario.json +157 -0
  203. package/dist/content/examples/playervox-journal/tests/refused.scenario.json +39 -0
  204. package/dist/content/examples/playervox-journal/tests/scale.scenario.json +286 -0
  205. package/dist/content/examples/playervox-journal/tests/signed-out.scenario.json +134 -0
  206. package/dist/content/examples/playervox-journal/tests/states.scenario.json +741 -0
  207. package/dist/content/examples/playervox-journal/tests/unavailable.scenario.json +183 -0
  208. package/dist/content/examples/playervox-journal/tsconfig.json +16 -0
  209. package/dist/content/examples/playervox-journal/view.ocml +52 -0
  210. package/dist/content/examples/playervox-rating/LICENSE +21 -0
  211. package/dist/content/examples/playervox-rating/README.md +166 -0
  212. package/dist/content/examples/playervox-rating/listing.json +19 -0
  213. package/dist/content/examples/playervox-rating/locales/en.json +35 -0
  214. package/dist/content/examples/playervox-rating/locales/fr.json +35 -0
  215. package/dist/content/examples/playervox-rating/logic.ts +581 -0
  216. package/dist/content/examples/playervox-rating/manifest.json +19 -0
  217. package/dist/content/examples/playervox-rating/package.json +16 -0
  218. package/dist/content/examples/playervox-rating/style.ocss +333 -0
  219. package/dist/content/examples/playervox-rating/tests/account.scenario.json +125 -0
  220. package/dist/content/examples/playervox-rating/tests/bounds.scenario.json +73 -0
  221. package/dist/content/examples/playervox-rating/tests/draft.scenario.json +199 -0
  222. package/dist/content/examples/playervox-rating/tests/form.scenario.json +142 -0
  223. package/dist/content/examples/playervox-rating/tests/load-logic.mjs +22 -0
  224. package/dist/content/examples/playervox-rating/tests/logic.test.mjs +346 -0
  225. package/dist/content/examples/playervox-rating/tests/offline.scenario.json +142 -0
  226. package/dist/content/examples/playervox-rating/tests/preview.scenario.json +44 -0
  227. package/dist/content/examples/playervox-rating/tests/publish-keyboard.scenario.json +221 -0
  228. package/dist/content/examples/playervox-rating/tests/publish-pointer.scenario.json +314 -0
  229. package/dist/content/examples/playervox-rating/tests/read-only.scenario.json +70 -0
  230. package/dist/content/examples/playervox-rating/tests/refused.scenario.json +45 -0
  231. package/dist/content/examples/playervox-rating/tests/states.scenario.json +362 -0
  232. package/dist/content/examples/playervox-rating/tsconfig.json +16 -0
  233. package/dist/content/examples/playervox-rating/view.ocml +62 -0
  234. package/dist/content/examples/playervox-reviews/LICENSE +21 -0
  235. package/dist/content/examples/playervox-reviews/README.md +194 -0
  236. package/dist/content/examples/playervox-reviews/listing.json +19 -0
  237. package/dist/content/examples/playervox-reviews/locales/en.json +32 -0
  238. package/dist/content/examples/playervox-reviews/locales/fr.json +32 -0
  239. package/dist/content/examples/playervox-reviews/logic.ts +822 -0
  240. package/dist/content/examples/playervox-reviews/manifest.json +30 -0
  241. package/dist/content/examples/playervox-reviews/package.json +16 -0
  242. package/dist/content/examples/playervox-reviews/style.ocss +260 -0
  243. package/dist/content/examples/playervox-reviews/tests/account.scenario.json +249 -0
  244. package/dist/content/examples/playervox-reviews/tests/bounds.scenario.json +336 -0
  245. package/dist/content/examples/playervox-reviews/tests/changes.scenario.json +515 -0
  246. package/dist/content/examples/playervox-reviews/tests/filter.scenario.json +400 -0
  247. package/dist/content/examples/playervox-reviews/tests/frame.scenario.json +185 -0
  248. package/dist/content/examples/playervox-reviews/tests/keyboard.scenario.json +188 -0
  249. package/dist/content/examples/playervox-reviews/tests/load-logic.mjs +22 -0
  250. package/dist/content/examples/playervox-reviews/tests/logic.test.mjs +559 -0
  251. package/dist/content/examples/playervox-reviews/tests/offline-start.scenario.json +152 -0
  252. package/dist/content/examples/playervox-reviews/tests/offline.scenario.json +311 -0
  253. package/dist/content/examples/playervox-reviews/tests/paging.scenario.json +497 -0
  254. package/dist/content/examples/playervox-reviews/tests/preview.scenario.json +286 -0
  255. package/dist/content/examples/playervox-reviews/tests/reading.scenario.json +591 -0
  256. package/dist/content/examples/playervox-reviews/tests/refused.scenario.json +54 -0
  257. package/dist/content/examples/playervox-reviews/tests/scale.scenario.json +303 -0
  258. package/dist/content/examples/playervox-reviews/tests/states.scenario.json +700 -0
  259. package/dist/content/examples/playervox-reviews/tests/unavailable.scenario.json +192 -0
  260. package/dist/content/examples/playervox-reviews/tsconfig.json +16 -0
  261. package/dist/content/examples/playervox-reviews/view.ocml +110 -0
  262. package/dist/content/examples/playervox-score/LICENSE +21 -0
  263. package/dist/content/examples/playervox-score/README.md +131 -0
  264. package/dist/content/examples/playervox-score/listing.json +19 -0
  265. package/dist/content/examples/playervox-score/locales/en.json +23 -0
  266. package/dist/content/examples/playervox-score/locales/fr.json +23 -0
  267. package/dist/content/examples/playervox-score/logic.ts +430 -0
  268. package/dist/content/examples/playervox-score/manifest.json +47 -0
  269. package/dist/content/examples/playervox-score/package.json +16 -0
  270. package/dist/content/examples/playervox-score/style.ocss +247 -0
  271. package/dist/content/examples/playervox-score/tests/grades.scenario.json +279 -0
  272. package/dist/content/examples/playervox-score/tests/load-logic.mjs +22 -0
  273. package/dist/content/examples/playervox-score/tests/logic.test.mjs +229 -0
  274. package/dist/content/examples/playervox-score/tests/options.scenario.json +302 -0
  275. package/dist/content/examples/playervox-score/tests/preview.scenario.json +68 -0
  276. package/dist/content/examples/playervox-score/tests/pulse.scenario.json +157 -0
  277. package/dist/content/examples/playervox-score/tests/refused.scenario.json +21 -0
  278. package/dist/content/examples/playervox-score/tests/signed-out.scenario.json +46 -0
  279. package/dist/content/examples/playervox-score/tests/states.scenario.json +450 -0
  280. package/dist/content/examples/playervox-score/tests/unavailable.scenario.json +84 -0
  281. package/dist/content/examples/playervox-score/tsconfig.json +16 -0
  282. package/dist/content/examples/playervox-score/view.ocml +51 -0
  283. package/dist/content/examples/session/LICENSE +21 -0
  284. package/dist/content/examples/session/README.md +57 -0
  285. package/dist/content/examples/session/listing.json +19 -0
  286. package/dist/content/examples/session/locales/en.json +3 -0
  287. package/dist/content/examples/session/locales/fr.json +3 -0
  288. package/dist/content/examples/session/logic.ts +26 -0
  289. package/dist/content/examples/session/manifest.json +19 -0
  290. package/dist/content/examples/session/package.json +16 -0
  291. package/dist/content/examples/session/style.ocss +16 -0
  292. package/dist/content/examples/session/tests/hidden.scenario.json +45 -0
  293. package/dist/content/examples/session/tests/load-logic.mjs +22 -0
  294. package/dist/content/examples/session/tests/logic.test.mjs +37 -0
  295. package/dist/content/examples/session/tests/preview.scenario.json +28 -0
  296. package/dist/content/examples/session/tests/refused.scenario.json +20 -0
  297. package/dist/content/examples/session/tests/refused.test.mjs +16 -0
  298. package/dist/content/examples/session/tests/render.scenario.json +95 -0
  299. package/dist/content/examples/session/tests/ticks.scenario.json +139 -0
  300. package/dist/content/examples/session/tests/unknown.scenario.json +37 -0
  301. package/dist/content/examples/session/tsconfig.json +16 -0
  302. package/dist/content/examples/session/view.ocml +11 -0
  303. package/dist/content/examples/stopwatch/LICENSE +21 -0
  304. package/dist/content/examples/stopwatch/README.md +99 -0
  305. package/dist/content/examples/stopwatch/listing.json +19 -0
  306. package/dist/content/examples/stopwatch/locales/en.json +8 -0
  307. package/dist/content/examples/stopwatch/locales/fr.json +8 -0
  308. package/dist/content/examples/stopwatch/logic.ts +93 -0
  309. package/dist/content/examples/stopwatch/manifest.json +19 -0
  310. package/dist/content/examples/stopwatch/package.json +16 -0
  311. package/dist/content/examples/stopwatch/style.ocss +54 -0
  312. package/dist/content/examples/stopwatch/tests/errors.scenario.json +121 -0
  313. package/dist/content/examples/stopwatch/tests/gesture.scenario.json +154 -0
  314. package/dist/content/examples/stopwatch/tests/hidden.scenario.json +57 -0
  315. package/dist/content/examples/stopwatch/tests/hundredths.scenario.json +173 -0
  316. package/dist/content/examples/stopwatch/tests/load-logic.mjs +22 -0
  317. package/dist/content/examples/stopwatch/tests/logic.test.mjs +99 -0
  318. package/dist/content/examples/stopwatch/tests/preview.scenario.json +36 -0
  319. package/dist/content/examples/stopwatch/tests/read-only.scenario.json +42 -0
  320. package/dist/content/examples/stopwatch/tests/read-only.test.mjs +18 -0
  321. package/dist/content/examples/stopwatch/tests/refused.scenario.json +22 -0
  322. package/dist/content/examples/stopwatch/tests/refused.test.mjs +18 -0
  323. package/dist/content/examples/stopwatch/tests/render.scenario.json +105 -0
  324. package/dist/content/examples/stopwatch/tests/states.scenario.json +246 -0
  325. package/dist/content/examples/stopwatch/tests/unknown.scenario.json +40 -0
  326. package/dist/content/examples/stopwatch/tsconfig.json +16 -0
  327. package/dist/content/examples/stopwatch/view.ocml +29 -0
  328. package/dist/content/examples/twitch-chat/LICENSE +21 -0
  329. package/dist/content/examples/twitch-chat/README.md +283 -0
  330. package/dist/content/examples/twitch-chat/listing.json +19 -0
  331. package/dist/content/examples/twitch-chat/locales/en.json +52 -0
  332. package/dist/content/examples/twitch-chat/locales/fr.json +52 -0
  333. package/dist/content/examples/twitch-chat/logic.ts +887 -0
  334. package/dist/content/examples/twitch-chat/manifest.json +33 -0
  335. package/dist/content/examples/twitch-chat/package.json +16 -0
  336. package/dist/content/examples/twitch-chat/style.ocss +544 -0
  337. package/dist/content/examples/twitch-chat/tests/account.scenario.json +325 -0
  338. package/dist/content/examples/twitch-chat/tests/burst.scenario.json +1866 -0
  339. package/dist/content/examples/twitch-chat/tests/channel-refused.scenario.json +372 -0
  340. package/dist/content/examples/twitch-chat/tests/channel.scenario.json +480 -0
  341. package/dist/content/examples/twitch-chat/tests/draft.scenario.json +279 -0
  342. package/dist/content/examples/twitch-chat/tests/fade.scenario.json +269 -0
  343. package/dist/content/examples/twitch-chat/tests/failures.scenario.json +420 -0
  344. package/dist/content/examples/twitch-chat/tests/favorites.scenario.json +376 -0
  345. package/dist/content/examples/twitch-chat/tests/frame.scenario.json +152 -0
  346. package/dist/content/examples/twitch-chat/tests/lifetime.scenario.json +186 -0
  347. package/dist/content/examples/twitch-chat/tests/load-logic.mjs +22 -0
  348. package/dist/content/examples/twitch-chat/tests/logic.test.mjs +1053 -0
  349. package/dist/content/examples/twitch-chat/tests/passive.scenario.json +536 -0
  350. package/dist/content/examples/twitch-chat/tests/preview.scenario.json +147 -0
  351. package/dist/content/examples/twitch-chat/tests/read-only.scenario.json +202 -0
  352. package/dist/content/examples/twitch-chat/tests/read-only.test.mjs +63 -0
  353. package/dist/content/examples/twitch-chat/tests/refused.scenario.json +65 -0
  354. package/dist/content/examples/twitch-chat/tests/refused.test.mjs +43 -0
  355. package/dist/content/examples/twitch-chat/tests/render.scenario.json +347 -0
  356. package/dist/content/examples/twitch-chat/tests/reply.scenario.json +384 -0
  357. package/dist/content/examples/twitch-chat/tests/send-refused.scenario.json +383 -0
  358. package/dist/content/examples/twitch-chat/tests/send.scenario.json +300 -0
  359. package/dist/content/examples/twitch-chat/tests/states.scenario.json +455 -0
  360. package/dist/content/examples/twitch-chat/tests/unavailable.scenario.json +256 -0
  361. package/dist/content/examples/twitch-chat/tests/unread.scenario.json +997 -0
  362. package/dist/content/examples/twitch-chat/tsconfig.json +16 -0
  363. package/dist/content/examples/twitch-chat/view.ocml +141 -0
  364. package/dist/content/examples/warframe-market/LICENSE +21 -0
  365. package/dist/content/examples/warframe-market/README.md +176 -0
  366. package/dist/content/examples/warframe-market/listing.json +19 -0
  367. package/dist/content/examples/warframe-market/locales/en.json +44 -0
  368. package/dist/content/examples/warframe-market/locales/fr.json +44 -0
  369. package/dist/content/examples/warframe-market/logic.ts +1265 -0
  370. package/dist/content/examples/warframe-market/manifest.json +92 -0
  371. package/dist/content/examples/warframe-market/package.json +16 -0
  372. package/dist/content/examples/warframe-market/style.ocss +422 -0
  373. package/dist/content/examples/warframe-market/tests/bounds.scenario.json +60 -0
  374. package/dist/content/examples/warframe-market/tests/cached.scenario.json +70 -0
  375. package/dist/content/examples/warframe-market/tests/detail.scenario.json +251 -0
  376. package/dist/content/examples/warframe-market/tests/errors.scenario.json +105 -0
  377. package/dist/content/examples/warframe-market/tests/fixtures.json +295 -0
  378. package/dist/content/examples/warframe-market/tests/load-logic.mjs +22 -0
  379. package/dist/content/examples/warframe-market/tests/logic.test.mjs +505 -0
  380. package/dist/content/examples/warframe-market/tests/no-clipboard.scenario.json +104 -0
  381. package/dist/content/examples/warframe-market/tests/passive.scenario.json +87 -0
  382. package/dist/content/examples/warframe-market/tests/preview.scenario.json +146 -0
  383. package/dist/content/examples/warframe-market/tests/refresh.scenario.json +56 -0
  384. package/dist/content/examples/warframe-market/tests/refused.scenario.json +74 -0
  385. package/dist/content/examples/warframe-market/tests/render.scenario.json +210 -0
  386. package/dist/content/examples/warframe-market/tests/search.scenario.json +189 -0
  387. package/dist/content/examples/warframe-market/tests/unavailable.scenario.json +54 -0
  388. package/dist/content/examples/warframe-market/tsconfig.json +16 -0
  389. package/dist/content/examples/warframe-market/view.ocml +116 -0
  390. package/dist/content/examples/weather/LICENSE +20 -0
  391. package/dist/content/examples/weather/listing.json +10 -0
  392. package/dist/content/examples/weather/locales/en.json +9 -0
  393. package/dist/content/examples/weather/locales/fr.json +9 -0
  394. package/dist/content/examples/weather/logic.ts +62 -0
  395. package/dist/content/examples/weather/manifest.json +51 -0
  396. package/dist/content/examples/weather/package.json +15 -0
  397. package/dist/content/examples/weather/style.ocss +29 -0
  398. package/dist/content/examples/weather/tsconfig.json +16 -0
  399. package/dist/content/examples/weather/view.ocml +12 -0
  400. package/dist/content/index.json +3601 -0
  401. package/dist/content/reference/errors.json +1712 -0
  402. package/dist/content/reference/limits.json +1154 -0
  403. package/dist/content/reference/manifest.md +223 -0
  404. package/dist/content/reference/permissions.json +413 -0
  405. package/dist/content/templates/blank/locales/en.json +3 -0
  406. package/dist/content/templates/blank/locales/fr.json +3 -0
  407. package/dist/content/templates/blank/logic.ts +7 -0
  408. package/dist/content/templates/blank/manifest.json +16 -0
  409. package/dist/content/templates/blank/style.ocss +10 -0
  410. package/dist/content/templates/blank/tests/example.scenario.json +10 -0
  411. package/dist/content/templates/blank/view.ocml +6 -0
  412. package/dist/content/templates/chart/locales/en.json +3 -0
  413. package/dist/content/templates/chart/locales/fr.json +3 -0
  414. package/dist/content/templates/chart/logic.ts +27 -0
  415. package/dist/content/templates/chart/manifest.json +16 -0
  416. package/dist/content/templates/chart/style.ocss +27 -0
  417. package/dist/content/templates/chart/tests/example.scenario.json +10 -0
  418. package/dist/content/templates/chart/view.ocml +10 -0
  419. package/dist/content/templates/counter/locales/en.json +4 -0
  420. package/dist/content/templates/counter/locales/fr.json +4 -0
  421. package/dist/content/templates/counter/logic.ts +20 -0
  422. package/dist/content/templates/counter/manifest.json +16 -0
  423. package/dist/content/templates/counter/style.ocss +26 -0
  424. package/dist/content/templates/counter/tests/example.scenario.json +11 -0
  425. package/dist/content/templates/counter/view.ocml +13 -0
  426. package/dist/content/templates/list/locales/en.json +8 -0
  427. package/dist/content/templates/list/locales/fr.json +8 -0
  428. package/dist/content/templates/list/logic.ts +35 -0
  429. package/dist/content/templates/list/manifest.json +16 -0
  430. package/dist/content/templates/list/style.ocss +42 -0
  431. package/dist/content/templates/list/tests/example.scenario.json +10 -0
  432. package/dist/content/templates/list/view.ocml +17 -0
  433. package/dist/content/templates/shared/LICENSE +20 -0
  434. package/dist/content/templates/shared/package.json +14 -0
  435. package/dist/content/templates/shared/tsconfig.json +16 -0
  436. package/dist/content.js +68 -0
  437. package/dist/env.js +156 -0
  438. package/dist/fingerprint.js +32 -0
  439. package/dist/ids.js +27 -0
  440. package/dist/index.js +82 -0
  441. package/dist/knowledge.js +222 -0
  442. package/dist/npm.js +149 -0
  443. package/dist/prompts.js +47 -0
  444. package/dist/resources.js +82 -0
  445. package/dist/run.js +120 -0
  446. package/dist/server.js +43 -0
  447. package/dist/session.js +205 -0
  448. package/dist/sources.js +218 -0
  449. package/dist/text.js +80 -0
  450. package/dist/texts.js +44 -0
  451. package/dist/tools/audit.js +105 -0
  452. package/dist/tools/build.js +453 -0
  453. package/dist/tools/common.js +122 -0
  454. package/dist/tools/docs.js +196 -0
  455. package/dist/tools/preview.js +87 -0
  456. package/dist/tools/project.js +178 -0
  457. package/dist/tools/setup.js +146 -0
  458. package/dist/tools/submission.js +369 -0
  459. package/dist/version.js +3 -0
  460. package/npm-shrinkwrap.json +402 -0
  461. package/package.json +52 -4
@@ -0,0 +1,417 @@
1
+ # Tester un widget
2
+
3
+ Un widget PlayerVox OverCrow se teste de deux façons, toutes deux sans
4
+ bureau, sans jeu et sans compte :
5
+
6
+ - **Les tests unitaires de la logique**, dans Node.js, avec
7
+ `@overcrow/sdk/testing` : rapides, pour les fonctions de `logic.ts`.
8
+ - **Les scénarios**, joués par `overcrow-widget test` dans le **runtime
9
+ headless** d’OverCrow : la vraie VM, le vrai style, la vraie mise en page
10
+ et le vrai moteur de rendu, les vérifications d’OverCrow lui-même, des
11
+ services simulés, un temps virtuel et des images de référence. Ce qui
12
+ passe là est ce que l’overlay affiche.
13
+
14
+ <!-- source: templates/counter/tests/example.scenario.json -->
15
+ ```json
16
+ {
17
+ "scenarioVersion": 1,
18
+ "name": "example",
19
+ "description": "The counter starts at 0 and Increase adds one. `overcrow-widget test` plays it and compares the images with tests/reference/example/; `--update` records them again (https://overcrow.playervox.com/docs/en/testing/).",
20
+ "host": { "mode": "interactive" },
21
+ "steps": [
22
+ { "expect": { "state": "running", "text": ["0"], "image": "initial" } },
23
+ { "pointer": { "click": { "label": "Increase" } } },
24
+ { "expect": { "text": ["1"], "noText": ["0"], "image": "increased", "fault": "none" } }
25
+ ]
26
+ }
27
+ ```
28
+
29
+ Ce scénario démarre le compteur en mode interactif, vérifie qu’il affiche
30
+ `0` et compare son image avec une référence, clique sur le bouton dont le
31
+ libellé est « Increase », puis vérifie le nouveau texte et la nouvelle
32
+ image.
33
+
34
+ ## Tests unitaires
35
+
36
+ `@overcrow/sdk/testing` est fourni avec le SDK : `npm install` dans un
37
+ projet créé par `overcrow-widget init`, sinon
38
+ `npm install --save-dev --save-exact @overcrow/sdk@1.0.0`.
39
+
40
+ `installRuntime()` met en place une doublure d’OverCrow avant l’import de la
41
+ logique : les appels de service renvoient des promesses que votre test
42
+ résout ou rejette, les abonnements reçoivent les valeurs que vous poussez,
43
+ les minuteurs se déclenchent quand vous avancez le temps, et `Date.now()`
44
+ est virtuel.
45
+
46
+ <!-- source: widgets/clock/tests/logic.test.mjs -->
47
+ ```js
48
+ const START = Date.UTC(2026, 6, 17, 12, 8, 42, 250);
49
+ const vm = installRuntime({
50
+ now: START,
51
+ host: {
52
+ region: { numberFormat: "us", dateOrder: "mdy", offsetMinutes: 120 },
53
+ messages: { label: "Local time {time}", "label-date": "Local time {time}, {date}" },
54
+ },
55
+ });
56
+ const logic = await loadLogic();
57
+ const { state } = await import("@overcrow/sdk");
58
+ ```
59
+
60
+ <!-- source: widgets/clock/tests/logic.test.mjs -->
61
+ ```js
62
+ test("one timer at the next local minute, then each minute", () => {
63
+ assert.equal(vm.timers.length, 1);
64
+ assert.equal(vm.timers[0].dueAt, Date.UTC(2026, 6, 17, 12, 9));
65
+ vm.advance(Date.UTC(2026, 6, 17, 12, 9) - vm.now);
66
+ assert.equal(logic.clockTime(state.now, state.seconds), "14:09");
67
+ assert.deepEqual(
68
+ vm.timers.map(({ intervalMs, repeat }) => ({ intervalMs, repeat })),
69
+ [{ intervalMs: 60_000, repeat: true }],
70
+ );
71
+ assert.equal(vm.advance(120_000), 2);
72
+ assert.equal(logic.clockTime(state.now, state.seconds), "14:11");
73
+ });
74
+ ```
75
+
76
+ | Membre | Rôle |
77
+ | --- | --- |
78
+ | `installRuntime({ now, host })` | Installe la doublure ; `Date.now()` renvoie le temps virtuel. Une seule à la fois. |
79
+ | `now`, `advance(ms)` | Le temps virtuel ; `advance` déclenche, dans l’ordre, les minuteurs arrivés à échéance (un minuteur répétitif se réarme) et renvoie leur nombre. |
80
+ | `setHost(changes)` | Modifie `host` comme le fait OverCrow : `region`, `locale`, `options`… |
81
+ | `calls`, `lastCall(service)` | Chaque appel de service, avec `resolve(value)` et `reject(code)`. |
82
+ | `push(service, value)`, `fail(service, code)` | La prochaine mise à jour, ou l’échec final, des abonnements à un service. |
83
+ | `menu(row)` | Choisit une ligne `action` du menu d’options. |
84
+ | `draws`, `logs`, `timers`, `table` | Ce que la logique a envoyé : dessins du canvas, journaux, minuteurs et fonctions de la vue. |
85
+ | `uninstall()` | Retire la doublure et restaure `Date.now`. |
86
+
87
+ La doublure n’exécute que votre logique : elle n’applique pas les règles
88
+ d’OverCrow (les autorisations accordées, les comptes, la règle de l’action
89
+ de l’utilisateur) et ne rend rien. Les scénarios, eux, le font. Les widgets
90
+ de référence compilent leur `logic.ts` avec un petit chargeur avant de
91
+ l’importer :
92
+
93
+ <!-- source: widgets/clock/tests/load-logic.mjs -->
94
+ ```js
95
+ export async function loadLogic() {
96
+ const root = new URL("../", import.meta.url);
97
+ const source = readFileSync(new URL("logic.ts", root), "utf8");
98
+ const { outputText } = ts.transpileModule(source, {
99
+ compilerOptions: {
100
+ module: ts.ModuleKind.ES2022,
101
+ target: ts.ScriptTarget.ES2023,
102
+ verbatimModuleSyntax: true,
103
+ },
104
+ });
105
+ mkdirSync(new URL("dist/", root), { recursive: true });
106
+ // One file per test process: test files run in parallel.
107
+ const output = new URL(`dist/logic-${process.pid}.mjs`, root);
108
+ writeFileSync(output, outputText);
109
+ return import(output.href);
110
+ }
111
+ ```
112
+
113
+ ## Scénarios
114
+
115
+ Un scénario est un fichier JSON du projet, `tests/<name>.scenario.json`,
116
+ dont le `name` vaut `<name>`. Ses images de référence sont
117
+ `tests/reference/<name>/<image>.png`. Ni l’un ni les autres ne sont
118
+ empaquetés.
119
+
120
+ ```sh
121
+ overcrow-widget test
122
+ overcrow-widget test --scenario example
123
+ overcrow-widget test --update
124
+ ```
125
+
126
+ `--update` enregistre les images capturées comme références : regardez-les
127
+ avant de les commiter. Une image en échec écrit
128
+ `tests/output/<name>/<image>.actual.png` et, pour une différence,
129
+ `<image>.diff.png`, où les pixels différents sont en rouge.
130
+
131
+ Un scénario a quatre parties : `host` (les réglages de l’utilisateur),
132
+ `fixtures` (les données simulées : ce que répondent les services), `assets`
133
+ (des images pour les fixtures) et `steps` (ce qui se passe, et ce qui doit
134
+ être vrai). Le format est strict : un champ, un nom ou une valeur inconnus
135
+ sont une erreur du scénario, signalée avec son chemin
136
+ (`steps[3].pointer.click`) avant toute exécution. Le scénario est aussi
137
+ vérifié par rapport au manifeste : les autorisations que le widget déclare,
138
+ les lignes de menu qui existent, les services de ses capabilities.
139
+
140
+ ### `host`
141
+
142
+ Tout est facultatif.
143
+
144
+ | Membre | Par défaut | Signification |
145
+ | --- | --- | --- |
146
+ | `locale` | `en` | `en` ou `fr`. |
147
+ | `theme` | `dark` | `dark` ou `light`. |
148
+ | `scale` | `1000` | Échelle du contenu en millièmes : de 500 à 1750 (de 50 % à 175 %). |
149
+ | `size` | la taille préférée du manifeste | `{ width, height }` du cadre, en pixels logiques ; le `fit` du manifeste s’applique quand même. |
150
+ | `mode` | `passive` | `interactive` donne les entrées au widget. |
151
+ | `visible` | `true` | Masqué, le widget ne reçoit aucun déclenchement de minuteur. |
152
+ | `frame` | `false` | `true` capture le cadre d’OverCrow autour du contenu. |
153
+ | `background` | la couleur de panneau du thème | `#rrggbb` derrière le widget. |
154
+ | `region` | `us`, ordre de date de la langue | `{ numberFormat, dateOrder }`. |
155
+ | `zone` | UTC | `{ offsetMinutes, transitions: [{ at, offsetMinutes }] }` : le décalage UTC de l’utilisateur, et les instants où il change. |
156
+ | `startAt` | 2026-01-01T00:00:00Z | Le temps virtuel auquel le widget démarre, en millisecondes Unix. |
157
+ | `options` | les valeurs par défaut des lignes | Les valeurs des lignes du menu d’options. |
158
+ | `grants` | `"declared"` | Ou la liste exacte de ce que l’utilisateur a accordé (`storage`, `network`, `fps.read`…) : OverCrow refuse le reste. |
159
+ | `accounts` | connectés | `{ playervox, twitch }`, chacun valant `connected`, `disconnected`, `pending`, `expired` ou `offline`. |
160
+ | `features` | toutes | Les sources de données de la machine, pour `requires`. |
161
+ | `storage` | vide | Le stockage du widget avant son démarrage. |
162
+
163
+ <!-- source: widgets/clock/tests/summer-time.scenario.json -->
164
+ ```json
165
+ "host": {
166
+ "zone": {
167
+ "offsetMinutes": 60,
168
+ "transitions": [
169
+ {
170
+ "at": 1774746000000,
171
+ "offsetMinutes": 120
172
+ },
173
+ {
174
+ "at": 1792890000000,
175
+ "offsetMinutes": 60
176
+ }
177
+ ]
178
+ },
179
+ "startAt": 1774745970000
180
+ },
181
+ ```
182
+
183
+ Avec un compte qui n’est pas `connected`, OverCrow dessine son propre
184
+ panneau de compte par-dessus le widget, comme il le fait pour
185
+ l’utilisateur ; capturez-le avec `frame`.
186
+
187
+ ### `fixtures`
188
+
189
+ Les fixtures remplacent la provenance des données, jamais les vérifications
190
+ d’OverCrow. Un appel franchit d’abord les mêmes contrôles que dans
191
+ l’overlay : autorisations accordées, paramètres, règle de l’action de
192
+ l’utilisateur et compte. C’est seulement ensuite qu’une fixture lui répond.
193
+ Chaque valeur doit avoir la forme du [résultat](result-shapes.md) du
194
+ service : une valeur qui ne l’a pas est une erreur du scénario, pas du
195
+ widget.
196
+
197
+ | Membre | Fournit |
198
+ | --- | --- |
199
+ | `subscriptions` | La valeur d’un abonnement à son démarrage ; les étapes `publish` envoient les suivantes. |
200
+ | `calls` | Les réponses aux appels d’un service, dans l’ordre : `{ "value": … }` ou `{ "error": code }`. Un appel au-delà est une erreur du scénario. |
201
+ | `http` | Les réponses aux requêtes `http.fetch`, chacune utilisée une fois : `{ "request": { method, url }, "response": { status, contentType, body } }` (ou `bodyBase64`), ou `{ "request": …, "error": code }`. Les règles réseau du manifeste s’appliquent d’abord, et les limites de réponse s’appliquent comme dans l’overlay. |
202
+ | `confirmations` | `accept` ou `cancel`, dans l’ordre, pour la confirmation par OverCrow de `notes.delete` et `journal.delete`. |
203
+ | `intents` | La réponse à chaque [intent d’écriture](forms.md#les-formulaires-qui-écrivent-des-données-de-lutilisateur) envoyé, dans l’ordre : `"accepted"`, `{ "error": code }` ou `"pending"`. |
204
+
205
+ <!-- source: widgets/stopwatch/tests/errors.scenario.json -->
206
+ ```json
207
+ "fixtures": {
208
+ "calls": {
209
+ "stopwatch.toggle": [
210
+ {
211
+ "error": "unavailable"
212
+ },
213
+ {
214
+ "value": {
215
+ "running": true,
216
+ "elapsedMs": 5000,
217
+ "at": 0,
218
+ "shortcuts": {
219
+ "toggle": "Super+Alt+T",
220
+ "reset": "Super+Alt+Z",
221
+ "bound": true
222
+ }
223
+ }
224
+ }
225
+ ],
226
+ "stopwatch.reset": [
227
+ {
228
+ "error": "stale_context"
229
+ }
230
+ ]
231
+ },
232
+ "subscriptions": {
233
+ "stopwatch.subscribe": {
234
+ "running": false,
235
+ "elapsedMs": 5000,
236
+ "at": 0,
237
+ "shortcuts": {
238
+ "toggle": "Super+Alt+T",
239
+ "reset": "Super+Alt+Z",
240
+ "bound": true
241
+ }
242
+ }
243
+ }
244
+ },
245
+ ```
246
+
247
+ <!-- source: widgets/warframe-market/tests/errors.scenario.json -->
248
+ ```json
249
+ "http": [
250
+ {
251
+ "request": {
252
+ "method": "GET",
253
+ "url": "https://api.warframe.market/v2/versions"
254
+ },
255
+ "error": "timeout"
256
+ },
257
+ {
258
+ "request": {
259
+ "method": "GET",
260
+ "url": "https://api.warframe.market/v2/orders/item/primed_flow"
261
+ },
262
+ "error": "transport_failed"
263
+ },
264
+ {
265
+ "request": {
266
+ "method": "GET",
267
+ "url": "https://api.warframe.market/v2/orders/item/primed_flow"
268
+ },
269
+ "response": {
270
+ "status": 200,
271
+ "contentType": "application/json",
272
+ "body": "{\"apiVersion\":\"0.25.0\",\"data\":[],\"error\":null}"
273
+ }
274
+ }
275
+ ]
276
+ ```
277
+
278
+ Les codes qu’OverCrow attribue lui-même (`permission_denied`,
279
+ `gesture_required`, `not_connected`, `invalid_request`) ne peuvent pas
280
+ s’écrire dans une fixture : obtenez-les par la voie réelle, avec `grants`,
281
+ `accounts`, un appel hors d’une action de l’utilisateur ou des paramètres
282
+ incorrects. Le stockage, les minuteurs et le presse-papiers sont ceux
283
+ d’OverCrow et n’ont besoin d’aucune fixture.
284
+
285
+ ### `assets`
286
+
287
+ Des images qu’une fixture remet au widget, comme OverCrow lui remet la
288
+ pochette d’un média ou une emote du chat : `{ "<name>": "<path>" }`, 8 au
289
+ plus, chacune étant un PNG ou un JPEG du projet (`tests/assets/cover.png`).
290
+ Là où un résultat contient un identifiant d’image, la fixture écrit
291
+ `"fixture:<name>"`.
292
+
293
+ ### `steps`
294
+
295
+ | Étape | Effet |
296
+ | --- | --- |
297
+ | `{ "advance": { "ms": N } }` | Avance le temps virtuel de `N` ms. Chaque minuteur qui arrive à échéance en chemin se déclenche, dans l’ordre, et le décalage UTC change à son instant. |
298
+ | `{ "advance": { "ms": N, "jump": true } }` | Déplace le temps d’un coup, comme une machine qui sort de veille : chaque minuteur échu se déclenche une fois, en retard. |
299
+ | `{ "host": { … } }` | Modifie `locale`, `theme`, `scale`, `size`, `mode`, `visible`, `region`, `zone` ou `accounts`. |
300
+ | `{ "pointer": { "click": target } }` | Un clic. Aussi `rightClick`, `move` (survol), `wheel` (`{ target, dx, dy }`) et `"leave"`. |
301
+ | `{ "key": { "key": "Enter", "modifiers": ["shift"] } }` | Un appui sur une touche : `Tab`, `Escape`, `ArrowUp`, lettres, chiffres… |
302
+ | `{ "text": "…" }` | Du texte saisi dans le champ qui a le focus. |
303
+ | `{ "menu": { "id": "row", "value": … } }` | Une ligne du menu d’options : la valeur d’une bascule, d’un curseur ou d’un choix, aucune pour une action. |
304
+ | `{ "publish": { "service": "fps.subscribe", "value": … } }` | La prochaine valeur d’un abonnement. |
305
+ | `{ "publish": { "service": "media.subscribe", "error": "unavailable" } }` | Termine l’abonnement par cet échec. |
306
+ | `{ "expect": { … } }` | Ce qui doit être vrai une fois les étapes précédentes stabilisées. |
307
+
308
+ Une cible de pointeur est `{ "at": [x, y] }` (pixels logiques du contenu),
309
+ `{ "text": "…" }` (le premier élément qui affiche exactement ce texte) ou
310
+ `{ "label": "…" }` (son libellé accessible). Les entrées n’atteignent le
311
+ widget qu’en mode interactif. Un clic est une action de l’utilisateur ; une
312
+ ligne de menu n’en est jamais une.
313
+
314
+ Chaque étape se stabilise avant la suivante : le widget a répondu à tout ce
315
+ qu’il a reçu et plus rien n’est en cours. Il n’y a aucune attente réelle.
316
+
317
+ ### `expect`
318
+
319
+ | Membre | Vérifié quand |
320
+ | --- | --- |
321
+ | `image` | La capture correspond à `tests/reference/<scenario>/<image>.png`. Les noms sont uniques dans un scénario. |
322
+ | `text`, `noText` | Chaque texte est (n’est pas) le texte entier d’un élément que le widget affiche. |
323
+ | `calls` | Exactement ces appels de service ont eu lieu depuis la vérification `calls` précédente, dans l’ordre : `{ service, params?, outcome? }`, `outcome` valant `ok` ou le code d’erreur que le widget a reçu. |
324
+ | `state` | `starting`, `running`, `restarting`, `failed`, `refused` ou `stopped`. |
325
+ | `fault` | La dernière faute de la VM du widget, ou `none`. |
326
+ | `clipboard` | Le dernier texte que le widget a écrit dans le presse-papiers. |
327
+ | `intents` | Exactement ces intents d’écriture ont été envoyés depuis la vérification `intents` précédente, dans l’ordre : `{ intent, fields?, outcome? }`. `fields` contient les valeurs exactes que le formulaire d’OverCrow a envoyées. |
328
+
329
+ <!-- source: templates/chart/tests/example.scenario.json -->
330
+ ```json
331
+ "steps": [
332
+ { "expect": { "state": "running", "text": ["Activity", "50"], "image": "initial" } },
333
+ { "advance": { "ms": 10000 } },
334
+ { "expect": { "noText": ["50"], "image": "ten-seconds", "fault": "none" } }
335
+ ]
336
+ ```
337
+
338
+ Les fautes que la VM d’un widget peut signaler :
339
+
340
+ <!-- generated:fault-categories -->
341
+ | Catégorie | Fatale | Signification |
342
+ | --- | --- | --- |
343
+ | `resource_limit` | oui | Le tas, la pile, la file des tâches ou le budget de messages est épuisé dans la VM. |
344
+ | `unresponsive` | oui | Le budget de temps d’un tour a interrompu la VM. |
345
+ | `protocol_violation` | oui | L’hôte a envoyé un message que la VM ne peut pas accepter. |
346
+ | `invalid_bundle` | oui | `logic.js` ou la vue compilée n’a pas pu être chargé ou enregistré. |
347
+ | `handler_exception` | non | Un gestionnaire d’événement a levé une exception ; la VM continue. |
348
+ <!-- /generated:fault-categories -->
349
+
350
+ ## Images de référence
351
+
352
+ Une image est le contenu du widget, rendu à l’échelle, dans le thème et à la
353
+ taille du scénario. Enregistrez les états qui comptent dans les deux thèmes,
354
+ les deux langues et à deux échelles, comme le font les widgets de
355
+ référence : un scénario peut changer `theme`, `locale` et `scale` entre deux
356
+ étapes `expect`.
357
+
358
+ <!-- source: templates/list/tests/example.scenario.json -->
359
+ ```json
360
+ "steps": [
361
+ { "expect": { "state": "running", "text": ["Today", "2 left"], "image": "initial" } },
362
+ { "host": { "locale": "fr", "theme": "light" } },
363
+ { "expect": { "image": "french-light", "fault": "none" } }
364
+ ]
365
+ ```
366
+
367
+ Les images sont comparées avec une petite tolérance : un pixel diffère quand
368
+ l’un de ses canaux diffère de plus de 2 niveaux, et l’image diffère quand
369
+ plus de 100 pixels par million diffèrent. Une seule lettre fausse dépasse
370
+ largement ce seuil. Une exécution des tests ne réécrit jamais une
371
+ référence : seul `--update` enregistre des images.
372
+
373
+ ## Temps et déterminisme
374
+
375
+ Le runtime est déterministe : le même paquet et le même scénario rendent les
376
+ mêmes octets, sous Linux comme sous Windows.
377
+
378
+ - Le temps est virtuel : `Date.now()` et `new Date()` renvoient le temps du
379
+ scénario, et les minuteurs se déclenchent quand le scénario l’avance.
380
+ - `Math.random()` est initialisé avec une graine fixe.
381
+ - Le texte utilise les polices fournies avec OverCrow, jamais celles du
382
+ système.
383
+ - Le rendu ne dépend pas de la carte graphique.
384
+
385
+ Cela ne vaut que pour le runtime de test : dans l’overlay, le temps et le
386
+ hasard sont réels.
387
+
388
+ ## Le runtime headless
389
+
390
+ `overcrow-widget-headless` est le code d’OverCrow lui-même, sans fenêtre :
391
+ il valide le paquet comme le fait l’overlay et exécute la logique du widget
392
+ dans le même sandbox. `overcrow-widget test` exécute la version que la CLI
393
+ épingle, 0.6.0-beta.2, et affiche sa version et son SHA-256. Sans le
394
+ sandbox du système d’exploitation, le runtime refuse de s’exécuter et le
395
+ dit ; la commande de test se termine alors avec le code 2.
396
+
397
+ La première fois que `test` a besoin du runtime, il le télécharge : dans
398
+ le ZIP des outils créateurs de votre plateforme, dans la release OverCrow
399
+ qui l’a publié, il ne garde que le runtime, et seulement si son SHA-256
400
+ est celui que la CLI épingle. Le ZIP n’est pas conservé. Le runtime reste
401
+ ensuite dans le cache de la CLI :
402
+
403
+ | Plateforme | Chemin |
404
+ | --- | --- |
405
+ | Linux | `~/.cache/overcrow-widget/runtime/0.6.0-beta.2/` (`$XDG_CACHE_HOME` au lieu de `~/.cache` s’il est défini) |
406
+ | Windows | `%LOCALAPPDATA%\overcrow-widget\runtime\0.6.0-beta.2\` |
407
+
408
+ Pour travailler hors ligne, placez-y vous-même le runtime du ZIP des
409
+ outils créateurs (exécutable sous Linux) : `test` le trouve et ne
410
+ télécharge rien. Avec `--offline`, `test` ne télécharge jamais. Un proxy
411
+ défini dans `HTTPS_PROXY` est utilisé.
412
+
413
+ La CLI vérifie son SHA-256 avant chaque exécution. Si un téléchargement
414
+ échoue, rien n’est conservé et `test` propose de réessayer ou de passer
415
+ `--runtime`. `--runtime <path>` exécute un autre runtime à la place, par
416
+ exemple compilé depuis OverCrow ; la sortie dit alors que ce n’est pas le
417
+ runtime épinglé.