@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.
- package/LICENSE +21 -0
- package/README.md +90 -2
- package/dist/audit/index.js +103 -0
- package/dist/audit/lexer.js +417 -0
- package/dist/audit/project.js +200 -0
- package/dist/audit/rules.js +661 -0
- package/dist/bootstrap/download.js +229 -0
- package/dist/bootstrap/install.js +280 -0
- package/dist/bootstrap/pin.js +85 -0
- package/dist/bootstrap/pin.json +119 -0
- package/dist/bootstrap/zip.js +258 -0
- package/dist/cli.js +200 -0
- package/dist/confine.js +244 -0
- package/dist/content/docs/en/cli.md +353 -0
- package/dist/content/docs/en/dev-channel.md +130 -0
- package/dist/content/docs/en/elements.md +469 -0
- package/dist/content/docs/en/forms.md +328 -0
- package/dist/content/docs/en/guide.md +253 -0
- package/dist/content/docs/en/index.md +85 -0
- package/dist/content/docs/en/limits.md +241 -0
- package/dist/content/docs/en/logic.md +446 -0
- package/dist/content/docs/en/manifest.md +381 -0
- package/dist/content/docs/en/mcp.md +165 -0
- package/dist/content/docs/en/package.md +131 -0
- package/dist/content/docs/en/publishing.md +162 -0
- package/dist/content/docs/en/reference.md +55 -0
- package/dist/content/docs/en/result-shapes.md +332 -0
- package/dist/content/docs/en/sdk.md +295 -0
- package/dist/content/docs/en/security.md +115 -0
- package/dist/content/docs/en/service-reference.md +344 -0
- package/dist/content/docs/en/services.md +517 -0
- package/dist/content/docs/en/style-properties.md +270 -0
- package/dist/content/docs/en/style.md +266 -0
- package/dist/content/docs/en/testing.md +400 -0
- package/dist/content/docs/en/view.md +338 -0
- package/dist/content/docs/en/widgets.md +76 -0
- package/dist/content/docs/fr/cli.md +367 -0
- package/dist/content/docs/fr/dev-channel.md +140 -0
- package/dist/content/docs/fr/elements.md +475 -0
- package/dist/content/docs/fr/forms.md +341 -0
- package/dist/content/docs/fr/guide.md +264 -0
- package/dist/content/docs/fr/index.md +90 -0
- package/dist/content/docs/fr/limits.md +244 -0
- package/dist/content/docs/fr/logic.md +461 -0
- package/dist/content/docs/fr/manifest.md +392 -0
- package/dist/content/docs/fr/mcp.md +173 -0
- package/dist/content/docs/fr/package.md +139 -0
- package/dist/content/docs/fr/publishing.md +172 -0
- package/dist/content/docs/fr/reference.md +59 -0
- package/dist/content/docs/fr/result-shapes.md +333 -0
- package/dist/content/docs/fr/sdk.md +301 -0
- package/dist/content/docs/fr/security.md +129 -0
- package/dist/content/docs/fr/service-reference.md +346 -0
- package/dist/content/docs/fr/services.md +540 -0
- package/dist/content/docs/fr/style-properties.md +272 -0
- package/dist/content/docs/fr/style.md +281 -0
- package/dist/content/docs/fr/testing.md +417 -0
- package/dist/content/docs/fr/view.md +352 -0
- package/dist/content/docs/fr/widgets.md +81 -0
- package/dist/content/examples/clock/LICENSE +21 -0
- package/dist/content/examples/clock/README.md +75 -0
- package/dist/content/examples/clock/listing.json +19 -0
- package/dist/content/examples/clock/locales/en.json +4 -0
- package/dist/content/examples/clock/locales/fr.json +4 -0
- package/dist/content/examples/clock/logic.ts +85 -0
- package/dist/content/examples/clock/manifest.json +44 -0
- package/dist/content/examples/clock/package.json +16 -0
- package/dist/content/examples/clock/style.ocss +26 -0
- package/dist/content/examples/clock/tests/hidden.scenario.json +68 -0
- package/dist/content/examples/clock/tests/load-logic.mjs +22 -0
- package/dist/content/examples/clock/tests/logic.test.mjs +89 -0
- package/dist/content/examples/clock/tests/options.scenario.json +108 -0
- package/dist/content/examples/clock/tests/preview.scenario.json +25 -0
- package/dist/content/examples/clock/tests/render.scenario.json +94 -0
- package/dist/content/examples/clock/tests/summer-time.scenario.json +74 -0
- package/dist/content/examples/clock/tests/ticks.scenario.json +120 -0
- package/dist/content/examples/clock/tsconfig.json +16 -0
- package/dist/content/examples/clock/view.ocml +8 -0
- package/dist/content/examples/countdown/LICENSE +20 -0
- package/dist/content/examples/countdown/listing.json +10 -0
- package/dist/content/examples/countdown/locales/en.json +15 -0
- package/dist/content/examples/countdown/locales/fr.json +15 -0
- package/dist/content/examples/countdown/logic.ts +179 -0
- package/dist/content/examples/countdown/manifest.json +34 -0
- package/dist/content/examples/countdown/package.json +15 -0
- package/dist/content/examples/countdown/style.ocss +94 -0
- package/dist/content/examples/countdown/tsconfig.json +16 -0
- package/dist/content/examples/countdown/view.ocml +42 -0
- package/dist/content/examples/fps/LICENSE +21 -0
- package/dist/content/examples/fps/README.md +64 -0
- package/dist/content/examples/fps/listing.json +19 -0
- package/dist/content/examples/fps/locales/en.json +11 -0
- package/dist/content/examples/fps/locales/fr.json +11 -0
- package/dist/content/examples/fps/logic.ts +64 -0
- package/dist/content/examples/fps/manifest.json +30 -0
- package/dist/content/examples/fps/package.json +16 -0
- package/dist/content/examples/fps/style.ocss +31 -0
- package/dist/content/examples/fps/tests/label.scenario.json +63 -0
- package/dist/content/examples/fps/tests/load-logic.mjs +22 -0
- package/dist/content/examples/fps/tests/logic.test.mjs +60 -0
- package/dist/content/examples/fps/tests/preview.scenario.json +29 -0
- package/dist/content/examples/fps/tests/refused.scenario.json +20 -0
- package/dist/content/examples/fps/tests/render.scenario.json +96 -0
- package/dist/content/examples/fps/tests/stale.scenario.json +91 -0
- package/dist/content/examples/fps/tests/unavailable.scenario.json +111 -0
- package/dist/content/examples/fps/tsconfig.json +16 -0
- package/dist/content/examples/fps/view.ocml +11 -0
- package/dist/content/examples/media/LICENSE +21 -0
- package/dist/content/examples/media/README.md +147 -0
- package/dist/content/examples/media/listing.json +19 -0
- package/dist/content/examples/media/locales/en.json +11 -0
- package/dist/content/examples/media/locales/fr.json +11 -0
- package/dist/content/examples/media/logic.ts +191 -0
- package/dist/content/examples/media/manifest.json +35 -0
- package/dist/content/examples/media/package.json +16 -0
- package/dist/content/examples/media/style.ocss +148 -0
- package/dist/content/examples/media/tests/covers.scenario.json +144 -0
- package/dist/content/examples/media/tests/gesture.scenario.json +173 -0
- package/dist/content/examples/media/tests/load-logic.mjs +22 -0
- package/dist/content/examples/media/tests/logic.test.mjs +176 -0
- package/dist/content/examples/media/tests/marquee.scenario.json +127 -0
- package/dist/content/examples/media/tests/preview.scenario.json +52 -0
- package/dist/content/examples/media/tests/read-only.scenario.json +53 -0
- package/dist/content/examples/media/tests/refused.scenario.json +22 -0
- package/dist/content/examples/media/tests/refused.test.mjs +31 -0
- package/dist/content/examples/media/tests/render.scenario.json +136 -0
- package/dist/content/examples/media/tests/states.scenario.json +257 -0
- package/dist/content/examples/media/tests/unavailable.scenario.json +120 -0
- package/dist/content/examples/media/tsconfig.json +16 -0
- package/dist/content/examples/media/view.ocml +41 -0
- package/dist/content/examples/notes/LICENSE +21 -0
- package/dist/content/examples/notes/README.md +219 -0
- package/dist/content/examples/notes/listing.json +19 -0
- package/dist/content/examples/notes/locales/en.json +25 -0
- package/dist/content/examples/notes/locales/fr.json +25 -0
- package/dist/content/examples/notes/logic.ts +799 -0
- package/dist/content/examples/notes/manifest.json +40 -0
- package/dist/content/examples/notes/package.json +16 -0
- package/dist/content/examples/notes/style.ocss +469 -0
- package/dist/content/examples/notes/tests/checks.scenario.json +237 -0
- package/dist/content/examples/notes/tests/create.scenario.json +260 -0
- package/dist/content/examples/notes/tests/delete.scenario.json +342 -0
- package/dist/content/examples/notes/tests/drafts.scenario.json +714 -0
- package/dist/content/examples/notes/tests/editor.scenario.json +232 -0
- package/dist/content/examples/notes/tests/frame.scenario.json +93 -0
- package/dist/content/examples/notes/tests/interactive.scenario.json +344 -0
- package/dist/content/examples/notes/tests/limits.scenario.json +1351 -0
- package/dist/content/examples/notes/tests/load-logic.mjs +22 -0
- package/dist/content/examples/notes/tests/logic.test.mjs +514 -0
- package/dist/content/examples/notes/tests/preview.scenario.json +99 -0
- package/dist/content/examples/notes/tests/read-only.scenario.json +105 -0
- package/dist/content/examples/notes/tests/refused.scenario.json +33 -0
- package/dist/content/examples/notes/tests/save.scenario.json +378 -0
- package/dist/content/examples/notes/tests/states.scenario.json +640 -0
- package/dist/content/examples/notes/tests/typing.scenario.json +562 -0
- package/dist/content/examples/notes/tests/unavailable.scenario.json +246 -0
- package/dist/content/examples/notes/tsconfig.json +16 -0
- package/dist/content/examples/notes/view.ocml +154 -0
- package/dist/content/examples/performance/LICENSE +21 -0
- package/dist/content/examples/performance/README.md +134 -0
- package/dist/content/examples/performance/listing.json +19 -0
- package/dist/content/examples/performance/locales/en.json +20 -0
- package/dist/content/examples/performance/locales/fr.json +20 -0
- package/dist/content/examples/performance/logic.ts +210 -0
- package/dist/content/examples/performance/manifest.json +83 -0
- package/dist/content/examples/performance/package.json +16 -0
- package/dist/content/examples/performance/style.ocss +75 -0
- package/dist/content/examples/performance/tests/fahrenheit.scenario.json +110 -0
- package/dist/content/examples/performance/tests/horizontal.scenario.json +96 -0
- package/dist/content/examples/performance/tests/load-logic.mjs +22 -0
- package/dist/content/examples/performance/tests/logic.test.mjs +226 -0
- package/dist/content/examples/performance/tests/menu.scenario.json +170 -0
- package/dist/content/examples/performance/tests/no-fps-source.scenario.json +47 -0
- package/dist/content/examples/performance/tests/preview.scenario.json +45 -0
- package/dist/content/examples/performance/tests/refused.scenario.json +20 -0
- package/dist/content/examples/performance/tests/refused.test.mjs +19 -0
- package/dist/content/examples/performance/tests/region.scenario.json +89 -0
- package/dist/content/examples/performance/tests/render.scenario.json +112 -0
- package/dist/content/examples/performance/tests/sources.scenario.json +151 -0
- package/dist/content/examples/performance/tests/stale.scenario.json +111 -0
- package/dist/content/examples/performance/tests/telemetry-only.scenario.json +44 -0
- package/dist/content/examples/performance/tests/thresholds.scenario.json +147 -0
- package/dist/content/examples/performance/tests/waiting.scenario.json +105 -0
- package/dist/content/examples/performance/tsconfig.json +16 -0
- package/dist/content/examples/performance/view.ocml +18 -0
- package/dist/content/examples/playervox-journal/LICENSE +21 -0
- package/dist/content/examples/playervox-journal/README.md +150 -0
- package/dist/content/examples/playervox-journal/listing.json +19 -0
- package/dist/content/examples/playervox-journal/locales/en.json +25 -0
- package/dist/content/examples/playervox-journal/locales/fr.json +25 -0
- package/dist/content/examples/playervox-journal/logic.ts +556 -0
- package/dist/content/examples/playervox-journal/manifest.json +19 -0
- package/dist/content/examples/playervox-journal/package.json +16 -0
- package/dist/content/examples/playervox-journal/style.ocss +142 -0
- package/dist/content/examples/playervox-journal/tests/changes.scenario.json +482 -0
- package/dist/content/examples/playervox-journal/tests/delete.scenario.json +432 -0
- package/dist/content/examples/playervox-journal/tests/frame.scenario.json +169 -0
- package/dist/content/examples/playervox-journal/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-journal/tests/logic.test.mjs +349 -0
- package/dist/content/examples/playervox-journal/tests/paging.scenario.json +428 -0
- package/dist/content/examples/playervox-journal/tests/preview.scenario.json +184 -0
- package/dist/content/examples/playervox-journal/tests/read-only.scenario.json +157 -0
- package/dist/content/examples/playervox-journal/tests/refused.scenario.json +39 -0
- package/dist/content/examples/playervox-journal/tests/scale.scenario.json +286 -0
- package/dist/content/examples/playervox-journal/tests/signed-out.scenario.json +134 -0
- package/dist/content/examples/playervox-journal/tests/states.scenario.json +741 -0
- package/dist/content/examples/playervox-journal/tests/unavailable.scenario.json +183 -0
- package/dist/content/examples/playervox-journal/tsconfig.json +16 -0
- package/dist/content/examples/playervox-journal/view.ocml +52 -0
- package/dist/content/examples/playervox-rating/LICENSE +21 -0
- package/dist/content/examples/playervox-rating/README.md +166 -0
- package/dist/content/examples/playervox-rating/listing.json +19 -0
- package/dist/content/examples/playervox-rating/locales/en.json +35 -0
- package/dist/content/examples/playervox-rating/locales/fr.json +35 -0
- package/dist/content/examples/playervox-rating/logic.ts +581 -0
- package/dist/content/examples/playervox-rating/manifest.json +19 -0
- package/dist/content/examples/playervox-rating/package.json +16 -0
- package/dist/content/examples/playervox-rating/style.ocss +333 -0
- package/dist/content/examples/playervox-rating/tests/account.scenario.json +125 -0
- package/dist/content/examples/playervox-rating/tests/bounds.scenario.json +73 -0
- package/dist/content/examples/playervox-rating/tests/draft.scenario.json +199 -0
- package/dist/content/examples/playervox-rating/tests/form.scenario.json +142 -0
- package/dist/content/examples/playervox-rating/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-rating/tests/logic.test.mjs +346 -0
- package/dist/content/examples/playervox-rating/tests/offline.scenario.json +142 -0
- package/dist/content/examples/playervox-rating/tests/preview.scenario.json +44 -0
- package/dist/content/examples/playervox-rating/tests/publish-keyboard.scenario.json +221 -0
- package/dist/content/examples/playervox-rating/tests/publish-pointer.scenario.json +314 -0
- package/dist/content/examples/playervox-rating/tests/read-only.scenario.json +70 -0
- package/dist/content/examples/playervox-rating/tests/refused.scenario.json +45 -0
- package/dist/content/examples/playervox-rating/tests/states.scenario.json +362 -0
- package/dist/content/examples/playervox-rating/tsconfig.json +16 -0
- package/dist/content/examples/playervox-rating/view.ocml +62 -0
- package/dist/content/examples/playervox-reviews/LICENSE +21 -0
- package/dist/content/examples/playervox-reviews/README.md +194 -0
- package/dist/content/examples/playervox-reviews/listing.json +19 -0
- package/dist/content/examples/playervox-reviews/locales/en.json +32 -0
- package/dist/content/examples/playervox-reviews/locales/fr.json +32 -0
- package/dist/content/examples/playervox-reviews/logic.ts +822 -0
- package/dist/content/examples/playervox-reviews/manifest.json +30 -0
- package/dist/content/examples/playervox-reviews/package.json +16 -0
- package/dist/content/examples/playervox-reviews/style.ocss +260 -0
- package/dist/content/examples/playervox-reviews/tests/account.scenario.json +249 -0
- package/dist/content/examples/playervox-reviews/tests/bounds.scenario.json +336 -0
- package/dist/content/examples/playervox-reviews/tests/changes.scenario.json +515 -0
- package/dist/content/examples/playervox-reviews/tests/filter.scenario.json +400 -0
- package/dist/content/examples/playervox-reviews/tests/frame.scenario.json +185 -0
- package/dist/content/examples/playervox-reviews/tests/keyboard.scenario.json +188 -0
- package/dist/content/examples/playervox-reviews/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-reviews/tests/logic.test.mjs +559 -0
- package/dist/content/examples/playervox-reviews/tests/offline-start.scenario.json +152 -0
- package/dist/content/examples/playervox-reviews/tests/offline.scenario.json +311 -0
- package/dist/content/examples/playervox-reviews/tests/paging.scenario.json +497 -0
- package/dist/content/examples/playervox-reviews/tests/preview.scenario.json +286 -0
- package/dist/content/examples/playervox-reviews/tests/reading.scenario.json +591 -0
- package/dist/content/examples/playervox-reviews/tests/refused.scenario.json +54 -0
- package/dist/content/examples/playervox-reviews/tests/scale.scenario.json +303 -0
- package/dist/content/examples/playervox-reviews/tests/states.scenario.json +700 -0
- package/dist/content/examples/playervox-reviews/tests/unavailable.scenario.json +192 -0
- package/dist/content/examples/playervox-reviews/tsconfig.json +16 -0
- package/dist/content/examples/playervox-reviews/view.ocml +110 -0
- package/dist/content/examples/playervox-score/LICENSE +21 -0
- package/dist/content/examples/playervox-score/README.md +131 -0
- package/dist/content/examples/playervox-score/listing.json +19 -0
- package/dist/content/examples/playervox-score/locales/en.json +23 -0
- package/dist/content/examples/playervox-score/locales/fr.json +23 -0
- package/dist/content/examples/playervox-score/logic.ts +430 -0
- package/dist/content/examples/playervox-score/manifest.json +47 -0
- package/dist/content/examples/playervox-score/package.json +16 -0
- package/dist/content/examples/playervox-score/style.ocss +247 -0
- package/dist/content/examples/playervox-score/tests/grades.scenario.json +279 -0
- package/dist/content/examples/playervox-score/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-score/tests/logic.test.mjs +229 -0
- package/dist/content/examples/playervox-score/tests/options.scenario.json +302 -0
- package/dist/content/examples/playervox-score/tests/preview.scenario.json +68 -0
- package/dist/content/examples/playervox-score/tests/pulse.scenario.json +157 -0
- package/dist/content/examples/playervox-score/tests/refused.scenario.json +21 -0
- package/dist/content/examples/playervox-score/tests/signed-out.scenario.json +46 -0
- package/dist/content/examples/playervox-score/tests/states.scenario.json +450 -0
- package/dist/content/examples/playervox-score/tests/unavailable.scenario.json +84 -0
- package/dist/content/examples/playervox-score/tsconfig.json +16 -0
- package/dist/content/examples/playervox-score/view.ocml +51 -0
- package/dist/content/examples/session/LICENSE +21 -0
- package/dist/content/examples/session/README.md +57 -0
- package/dist/content/examples/session/listing.json +19 -0
- package/dist/content/examples/session/locales/en.json +3 -0
- package/dist/content/examples/session/locales/fr.json +3 -0
- package/dist/content/examples/session/logic.ts +26 -0
- package/dist/content/examples/session/manifest.json +19 -0
- package/dist/content/examples/session/package.json +16 -0
- package/dist/content/examples/session/style.ocss +16 -0
- package/dist/content/examples/session/tests/hidden.scenario.json +45 -0
- package/dist/content/examples/session/tests/load-logic.mjs +22 -0
- package/dist/content/examples/session/tests/logic.test.mjs +37 -0
- package/dist/content/examples/session/tests/preview.scenario.json +28 -0
- package/dist/content/examples/session/tests/refused.scenario.json +20 -0
- package/dist/content/examples/session/tests/refused.test.mjs +16 -0
- package/dist/content/examples/session/tests/render.scenario.json +95 -0
- package/dist/content/examples/session/tests/ticks.scenario.json +139 -0
- package/dist/content/examples/session/tests/unknown.scenario.json +37 -0
- package/dist/content/examples/session/tsconfig.json +16 -0
- package/dist/content/examples/session/view.ocml +11 -0
- package/dist/content/examples/stopwatch/LICENSE +21 -0
- package/dist/content/examples/stopwatch/README.md +99 -0
- package/dist/content/examples/stopwatch/listing.json +19 -0
- package/dist/content/examples/stopwatch/locales/en.json +8 -0
- package/dist/content/examples/stopwatch/locales/fr.json +8 -0
- package/dist/content/examples/stopwatch/logic.ts +93 -0
- package/dist/content/examples/stopwatch/manifest.json +19 -0
- package/dist/content/examples/stopwatch/package.json +16 -0
- package/dist/content/examples/stopwatch/style.ocss +54 -0
- package/dist/content/examples/stopwatch/tests/errors.scenario.json +121 -0
- package/dist/content/examples/stopwatch/tests/gesture.scenario.json +154 -0
- package/dist/content/examples/stopwatch/tests/hidden.scenario.json +57 -0
- package/dist/content/examples/stopwatch/tests/hundredths.scenario.json +173 -0
- package/dist/content/examples/stopwatch/tests/load-logic.mjs +22 -0
- package/dist/content/examples/stopwatch/tests/logic.test.mjs +99 -0
- package/dist/content/examples/stopwatch/tests/preview.scenario.json +36 -0
- package/dist/content/examples/stopwatch/tests/read-only.scenario.json +42 -0
- package/dist/content/examples/stopwatch/tests/read-only.test.mjs +18 -0
- package/dist/content/examples/stopwatch/tests/refused.scenario.json +22 -0
- package/dist/content/examples/stopwatch/tests/refused.test.mjs +18 -0
- package/dist/content/examples/stopwatch/tests/render.scenario.json +105 -0
- package/dist/content/examples/stopwatch/tests/states.scenario.json +246 -0
- package/dist/content/examples/stopwatch/tests/unknown.scenario.json +40 -0
- package/dist/content/examples/stopwatch/tsconfig.json +16 -0
- package/dist/content/examples/stopwatch/view.ocml +29 -0
- package/dist/content/examples/twitch-chat/LICENSE +21 -0
- package/dist/content/examples/twitch-chat/README.md +283 -0
- package/dist/content/examples/twitch-chat/listing.json +19 -0
- package/dist/content/examples/twitch-chat/locales/en.json +52 -0
- package/dist/content/examples/twitch-chat/locales/fr.json +52 -0
- package/dist/content/examples/twitch-chat/logic.ts +887 -0
- package/dist/content/examples/twitch-chat/manifest.json +33 -0
- package/dist/content/examples/twitch-chat/package.json +16 -0
- package/dist/content/examples/twitch-chat/style.ocss +544 -0
- package/dist/content/examples/twitch-chat/tests/account.scenario.json +325 -0
- package/dist/content/examples/twitch-chat/tests/burst.scenario.json +1866 -0
- package/dist/content/examples/twitch-chat/tests/channel-refused.scenario.json +372 -0
- package/dist/content/examples/twitch-chat/tests/channel.scenario.json +480 -0
- package/dist/content/examples/twitch-chat/tests/draft.scenario.json +279 -0
- package/dist/content/examples/twitch-chat/tests/fade.scenario.json +269 -0
- package/dist/content/examples/twitch-chat/tests/failures.scenario.json +420 -0
- package/dist/content/examples/twitch-chat/tests/favorites.scenario.json +376 -0
- package/dist/content/examples/twitch-chat/tests/frame.scenario.json +152 -0
- package/dist/content/examples/twitch-chat/tests/lifetime.scenario.json +186 -0
- package/dist/content/examples/twitch-chat/tests/load-logic.mjs +22 -0
- package/dist/content/examples/twitch-chat/tests/logic.test.mjs +1053 -0
- package/dist/content/examples/twitch-chat/tests/passive.scenario.json +536 -0
- package/dist/content/examples/twitch-chat/tests/preview.scenario.json +147 -0
- package/dist/content/examples/twitch-chat/tests/read-only.scenario.json +202 -0
- package/dist/content/examples/twitch-chat/tests/read-only.test.mjs +63 -0
- package/dist/content/examples/twitch-chat/tests/refused.scenario.json +65 -0
- package/dist/content/examples/twitch-chat/tests/refused.test.mjs +43 -0
- package/dist/content/examples/twitch-chat/tests/render.scenario.json +347 -0
- package/dist/content/examples/twitch-chat/tests/reply.scenario.json +384 -0
- package/dist/content/examples/twitch-chat/tests/send-refused.scenario.json +383 -0
- package/dist/content/examples/twitch-chat/tests/send.scenario.json +300 -0
- package/dist/content/examples/twitch-chat/tests/states.scenario.json +455 -0
- package/dist/content/examples/twitch-chat/tests/unavailable.scenario.json +256 -0
- package/dist/content/examples/twitch-chat/tests/unread.scenario.json +997 -0
- package/dist/content/examples/twitch-chat/tsconfig.json +16 -0
- package/dist/content/examples/twitch-chat/view.ocml +141 -0
- package/dist/content/examples/warframe-market/LICENSE +21 -0
- package/dist/content/examples/warframe-market/README.md +176 -0
- package/dist/content/examples/warframe-market/listing.json +19 -0
- package/dist/content/examples/warframe-market/locales/en.json +44 -0
- package/dist/content/examples/warframe-market/locales/fr.json +44 -0
- package/dist/content/examples/warframe-market/logic.ts +1265 -0
- package/dist/content/examples/warframe-market/manifest.json +92 -0
- package/dist/content/examples/warframe-market/package.json +16 -0
- package/dist/content/examples/warframe-market/style.ocss +422 -0
- package/dist/content/examples/warframe-market/tests/bounds.scenario.json +60 -0
- package/dist/content/examples/warframe-market/tests/cached.scenario.json +70 -0
- package/dist/content/examples/warframe-market/tests/detail.scenario.json +251 -0
- package/dist/content/examples/warframe-market/tests/errors.scenario.json +105 -0
- package/dist/content/examples/warframe-market/tests/fixtures.json +295 -0
- package/dist/content/examples/warframe-market/tests/load-logic.mjs +22 -0
- package/dist/content/examples/warframe-market/tests/logic.test.mjs +505 -0
- package/dist/content/examples/warframe-market/tests/no-clipboard.scenario.json +104 -0
- package/dist/content/examples/warframe-market/tests/passive.scenario.json +87 -0
- package/dist/content/examples/warframe-market/tests/preview.scenario.json +146 -0
- package/dist/content/examples/warframe-market/tests/refresh.scenario.json +56 -0
- package/dist/content/examples/warframe-market/tests/refused.scenario.json +74 -0
- package/dist/content/examples/warframe-market/tests/render.scenario.json +210 -0
- package/dist/content/examples/warframe-market/tests/search.scenario.json +189 -0
- package/dist/content/examples/warframe-market/tests/unavailable.scenario.json +54 -0
- package/dist/content/examples/warframe-market/tsconfig.json +16 -0
- package/dist/content/examples/warframe-market/view.ocml +116 -0
- package/dist/content/examples/weather/LICENSE +20 -0
- package/dist/content/examples/weather/listing.json +10 -0
- package/dist/content/examples/weather/locales/en.json +9 -0
- package/dist/content/examples/weather/locales/fr.json +9 -0
- package/dist/content/examples/weather/logic.ts +62 -0
- package/dist/content/examples/weather/manifest.json +51 -0
- package/dist/content/examples/weather/package.json +15 -0
- package/dist/content/examples/weather/style.ocss +29 -0
- package/dist/content/examples/weather/tsconfig.json +16 -0
- package/dist/content/examples/weather/view.ocml +12 -0
- package/dist/content/index.json +3601 -0
- package/dist/content/reference/errors.json +1712 -0
- package/dist/content/reference/limits.json +1154 -0
- package/dist/content/reference/manifest.md +223 -0
- package/dist/content/reference/permissions.json +413 -0
- package/dist/content/templates/blank/locales/en.json +3 -0
- package/dist/content/templates/blank/locales/fr.json +3 -0
- package/dist/content/templates/blank/logic.ts +7 -0
- package/dist/content/templates/blank/manifest.json +16 -0
- package/dist/content/templates/blank/style.ocss +10 -0
- package/dist/content/templates/blank/tests/example.scenario.json +10 -0
- package/dist/content/templates/blank/view.ocml +6 -0
- package/dist/content/templates/chart/locales/en.json +3 -0
- package/dist/content/templates/chart/locales/fr.json +3 -0
- package/dist/content/templates/chart/logic.ts +27 -0
- package/dist/content/templates/chart/manifest.json +16 -0
- package/dist/content/templates/chart/style.ocss +27 -0
- package/dist/content/templates/chart/tests/example.scenario.json +10 -0
- package/dist/content/templates/chart/view.ocml +10 -0
- package/dist/content/templates/counter/locales/en.json +4 -0
- package/dist/content/templates/counter/locales/fr.json +4 -0
- package/dist/content/templates/counter/logic.ts +20 -0
- package/dist/content/templates/counter/manifest.json +16 -0
- package/dist/content/templates/counter/style.ocss +26 -0
- package/dist/content/templates/counter/tests/example.scenario.json +11 -0
- package/dist/content/templates/counter/view.ocml +13 -0
- package/dist/content/templates/list/locales/en.json +8 -0
- package/dist/content/templates/list/locales/fr.json +8 -0
- package/dist/content/templates/list/logic.ts +35 -0
- package/dist/content/templates/list/manifest.json +16 -0
- package/dist/content/templates/list/style.ocss +42 -0
- package/dist/content/templates/list/tests/example.scenario.json +10 -0
- package/dist/content/templates/list/view.ocml +17 -0
- package/dist/content/templates/shared/LICENSE +20 -0
- package/dist/content/templates/shared/package.json +14 -0
- package/dist/content/templates/shared/tsconfig.json +16 -0
- package/dist/content.js +68 -0
- package/dist/env.js +156 -0
- package/dist/fingerprint.js +32 -0
- package/dist/ids.js +27 -0
- package/dist/index.js +82 -0
- package/dist/knowledge.js +222 -0
- package/dist/npm.js +149 -0
- package/dist/prompts.js +47 -0
- package/dist/resources.js +82 -0
- package/dist/run.js +120 -0
- package/dist/server.js +43 -0
- package/dist/session.js +205 -0
- package/dist/sources.js +218 -0
- package/dist/text.js +80 -0
- package/dist/texts.js +44 -0
- package/dist/tools/audit.js +105 -0
- package/dist/tools/build.js +453 -0
- package/dist/tools/common.js +122 -0
- package/dist/tools/docs.js +196 -0
- package/dist/tools/preview.js +87 -0
- package/dist/tools/project.js +178 -0
- package/dist/tools/setup.js +146 -0
- package/dist/tools/submission.js +369 -0
- package/dist/version.js +3 -0
- package/npm-shrinkwrap.json +402 -0
- package/package.json +52 -4
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Testing a widget
|
|
2
|
+
|
|
3
|
+
A PlayerVox OverCrow widget is tested in two ways, both without a desktop,
|
|
4
|
+
a game or an account:
|
|
5
|
+
|
|
6
|
+
- **Unit tests of the logic**, in Node.js, with `@overcrow/sdk/testing`:
|
|
7
|
+
fast, for the functions of `logic.ts`.
|
|
8
|
+
- **Scenarios**, played by `overcrow-widget test` in OverCrow's **headless
|
|
9
|
+
runtime**: the real VM, style, layout and renderer, OverCrow's own
|
|
10
|
+
checks, simulated services, virtual time and reference images. What
|
|
11
|
+
passes there is what the overlay shows.
|
|
12
|
+
|
|
13
|
+
<!-- source: templates/counter/tests/example.scenario.json -->
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"scenarioVersion": 1,
|
|
17
|
+
"name": "example",
|
|
18
|
+
"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/).",
|
|
19
|
+
"host": { "mode": "interactive" },
|
|
20
|
+
"steps": [
|
|
21
|
+
{ "expect": { "state": "running", "text": ["0"], "image": "initial" } },
|
|
22
|
+
{ "pointer": { "click": { "label": "Increase" } } },
|
|
23
|
+
{ "expect": { "text": ["1"], "noText": ["0"], "image": "increased", "fault": "none" } }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This scenario starts the counter in Interactive mode, checks that it shows
|
|
29
|
+
`0` and compares its image with a reference, clicks the button whose label
|
|
30
|
+
is "Increase", then checks the new text and image.
|
|
31
|
+
|
|
32
|
+
## Unit tests
|
|
33
|
+
|
|
34
|
+
`@overcrow/sdk/testing` comes with the SDK: `npm install` in a project made
|
|
35
|
+
by `overcrow-widget init`, otherwise
|
|
36
|
+
`npm install --save-dev --save-exact @overcrow/sdk@1.0.0`.
|
|
37
|
+
|
|
38
|
+
`installRuntime()` puts a stand-in for OverCrow in place before the logic
|
|
39
|
+
is imported: service calls return promises that your test settles,
|
|
40
|
+
subscriptions take the values you push, timers fire when you advance the
|
|
41
|
+
time, and `Date.now()` is virtual.
|
|
42
|
+
|
|
43
|
+
<!-- source: widgets/clock/tests/logic.test.mjs -->
|
|
44
|
+
```js
|
|
45
|
+
const START = Date.UTC(2026, 6, 17, 12, 8, 42, 250);
|
|
46
|
+
const vm = installRuntime({
|
|
47
|
+
now: START,
|
|
48
|
+
host: {
|
|
49
|
+
region: { numberFormat: "us", dateOrder: "mdy", offsetMinutes: 120 },
|
|
50
|
+
messages: { label: "Local time {time}", "label-date": "Local time {time}, {date}" },
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
const logic = await loadLogic();
|
|
54
|
+
const { state } = await import("@overcrow/sdk");
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
<!-- source: widgets/clock/tests/logic.test.mjs -->
|
|
58
|
+
```js
|
|
59
|
+
test("one timer at the next local minute, then each minute", () => {
|
|
60
|
+
assert.equal(vm.timers.length, 1);
|
|
61
|
+
assert.equal(vm.timers[0].dueAt, Date.UTC(2026, 6, 17, 12, 9));
|
|
62
|
+
vm.advance(Date.UTC(2026, 6, 17, 12, 9) - vm.now);
|
|
63
|
+
assert.equal(logic.clockTime(state.now, state.seconds), "14:09");
|
|
64
|
+
assert.deepEqual(
|
|
65
|
+
vm.timers.map(({ intervalMs, repeat }) => ({ intervalMs, repeat })),
|
|
66
|
+
[{ intervalMs: 60_000, repeat: true }],
|
|
67
|
+
);
|
|
68
|
+
assert.equal(vm.advance(120_000), 2);
|
|
69
|
+
assert.equal(logic.clockTime(state.now, state.seconds), "14:11");
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| Member | Does |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `installRuntime({ now, host })` | Installs the stand-in; `Date.now()` returns the virtual time. One at a time. |
|
|
76
|
+
| `now`, `advance(ms)` | The virtual time; `advance` fires the timers that fall due, in order (a repeating one re-arms), and returns their count. |
|
|
77
|
+
| `setHost(changes)` | Changes `host` as OverCrow does: `region`, `locale`, `options`… |
|
|
78
|
+
| `calls`, `lastCall(service)` | Every service call, with `resolve(value)` and `reject(code)`. |
|
|
79
|
+
| `push(service, value)`, `fail(service, code)` | The next update, or the final failure, of the subscriptions to a service. |
|
|
80
|
+
| `menu(row)` | Chooses an `action` row of the options menu. |
|
|
81
|
+
| `draws`, `logs`, `timers`, `table` | What the logic sent: canvas drawings, logs, timers, and the functions of the view. |
|
|
82
|
+
| `uninstall()` | Removes the stand-in and gives `Date.now` back. |
|
|
83
|
+
|
|
84
|
+
The stand-in runs your logic only: it does not apply OverCrow's rules (the
|
|
85
|
+
grants, the accounts, the user-action rule) and renders nothing. Scenarios
|
|
86
|
+
do. The reference widgets compile their `logic.ts` with a small loader
|
|
87
|
+
before importing it:
|
|
88
|
+
|
|
89
|
+
<!-- source: widgets/clock/tests/load-logic.mjs -->
|
|
90
|
+
```js
|
|
91
|
+
export async function loadLogic() {
|
|
92
|
+
const root = new URL("../", import.meta.url);
|
|
93
|
+
const source = readFileSync(new URL("logic.ts", root), "utf8");
|
|
94
|
+
const { outputText } = ts.transpileModule(source, {
|
|
95
|
+
compilerOptions: {
|
|
96
|
+
module: ts.ModuleKind.ES2022,
|
|
97
|
+
target: ts.ScriptTarget.ES2023,
|
|
98
|
+
verbatimModuleSyntax: true,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
mkdirSync(new URL("dist/", root), { recursive: true });
|
|
102
|
+
// One file per test process: test files run in parallel.
|
|
103
|
+
const output = new URL(`dist/logic-${process.pid}.mjs`, root);
|
|
104
|
+
writeFileSync(output, outputText);
|
|
105
|
+
return import(output.href);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Scenarios
|
|
110
|
+
|
|
111
|
+
A scenario is a JSON file of the project, `tests/<name>.scenario.json`,
|
|
112
|
+
whose `name` is `<name>`. Its reference images are
|
|
113
|
+
`tests/reference/<name>/<image>.png`. Neither is packaged.
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
overcrow-widget test
|
|
117
|
+
overcrow-widget test --scenario example
|
|
118
|
+
overcrow-widget test --update
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`--update` records the captured images as the references: look at them
|
|
122
|
+
before you commit them. A failed image writes
|
|
123
|
+
`tests/output/<name>/<image>.actual.png` and, for a difference,
|
|
124
|
+
`<image>.diff.png`, with the differing pixels in red.
|
|
125
|
+
|
|
126
|
+
A scenario has four parts: `host` (the user's settings), `fixtures` (what
|
|
127
|
+
the services answer), `assets` (images for the fixtures) and `steps` (what
|
|
128
|
+
happens, and what must hold). The format is strict: an unknown field, name
|
|
129
|
+
or value is an error of the scenario, reported with its path
|
|
130
|
+
(`steps[3].pointer.click`) before anything runs. It is also checked against
|
|
131
|
+
the manifest: the grants the widget declares, the menu rows that exist, the
|
|
132
|
+
services of its capabilities.
|
|
133
|
+
|
|
134
|
+
### `host`
|
|
135
|
+
|
|
136
|
+
Everything is optional.
|
|
137
|
+
|
|
138
|
+
| Member | Default | Meaning |
|
|
139
|
+
| --- | --- | --- |
|
|
140
|
+
| `locale` | `en` | `en` or `fr`. |
|
|
141
|
+
| `theme` | `dark` | `dark` or `light`. |
|
|
142
|
+
| `scale` | `1000` | Content scale in thousandths: 500 to 1750 (50 % to 175 %). |
|
|
143
|
+
| `size` | the manifest's preferred size | `{ width, height }` of the frame, in logical pixels; the manifest's `fit` still applies. |
|
|
144
|
+
| `mode` | `passive` | `interactive` gives input to the widget. |
|
|
145
|
+
| `visible` | `true` | Hidden, the widget gets no timer tick. |
|
|
146
|
+
| `frame` | `false` | `true` captures OverCrow's frame around the content. |
|
|
147
|
+
| `background` | the theme's panel colour | `#rrggbb` behind the widget. |
|
|
148
|
+
| `region` | `us`, date order of the locale | `{ numberFormat, dateOrder }`. |
|
|
149
|
+
| `zone` | UTC | `{ offsetMinutes, transitions: [{ at, offsetMinutes }] }`: the user's UTC offset, and the instants at which it changes. |
|
|
150
|
+
| `startAt` | 2026-01-01T00:00:00Z | The virtual time at which the widget starts, in Unix milliseconds. |
|
|
151
|
+
| `options` | the rows' defaults | Values of the rows of the options menu. |
|
|
152
|
+
| `grants` | `"declared"` | Or the exact list of what the user granted (`storage`, `network`, `fps.read`…): OverCrow refuses the rest. |
|
|
153
|
+
| `accounts` | connected | `{ playervox, twitch }`, each `connected`, `disconnected`, `pending`, `expired` or `offline`. |
|
|
154
|
+
| `features` | all | The data sources of the machine, for `requires`. |
|
|
155
|
+
| `storage` | empty | The widget's storage before it starts. |
|
|
156
|
+
|
|
157
|
+
<!-- source: widgets/clock/tests/summer-time.scenario.json -->
|
|
158
|
+
```json
|
|
159
|
+
"host": {
|
|
160
|
+
"zone": {
|
|
161
|
+
"offsetMinutes": 60,
|
|
162
|
+
"transitions": [
|
|
163
|
+
{
|
|
164
|
+
"at": 1774746000000,
|
|
165
|
+
"offsetMinutes": 120
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"at": 1792890000000,
|
|
169
|
+
"offsetMinutes": 60
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
"startAt": 1774745970000
|
|
174
|
+
},
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
With an account that is not `connected`, OverCrow draws its own account
|
|
178
|
+
panel over the widget, as it does for the user; capture it with `frame`.
|
|
179
|
+
|
|
180
|
+
### `fixtures`
|
|
181
|
+
|
|
182
|
+
Fixtures replace where the data comes from, never OverCrow's checks. A call
|
|
183
|
+
first passes the grants, its parameters, the user-action rule and the
|
|
184
|
+
account check, exactly as in the overlay; only then does a fixture answer
|
|
185
|
+
it. Every value must have the shape of the service's
|
|
186
|
+
[result](result-shapes.md): one that does not is an error of the scenario,
|
|
187
|
+
not of the widget.
|
|
188
|
+
|
|
189
|
+
| Member | Answers |
|
|
190
|
+
| --- | --- |
|
|
191
|
+
| `subscriptions` | The value of a subscription when it starts; `publish` steps send the next ones. |
|
|
192
|
+
| `calls` | The calls of a service, in order: `{ "value": … }` or `{ "error": code }`. A call beyond them is an error of the scenario. |
|
|
193
|
+
| `http` | The `http.fetch` requests, each used once: `{ "request": { method, url }, "response": { status, contentType, body } }` (or `bodyBase64`), or `{ "request": …, "error": code }`. The manifest's network rules apply first, and the response bounds apply as in the overlay. |
|
|
194
|
+
| `confirmations` | `accept` or `cancel`, in order, for OverCrow's confirmation of `notes.delete` and `journal.delete`. |
|
|
195
|
+
| `intents` | The answer to each submitted [write intent](forms.md#forms-that-write-user-data), in order: `"accepted"`, `{ "error": code }` or `"pending"`. |
|
|
196
|
+
|
|
197
|
+
<!-- source: widgets/stopwatch/tests/errors.scenario.json -->
|
|
198
|
+
```json
|
|
199
|
+
"fixtures": {
|
|
200
|
+
"calls": {
|
|
201
|
+
"stopwatch.toggle": [
|
|
202
|
+
{
|
|
203
|
+
"error": "unavailable"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"value": {
|
|
207
|
+
"running": true,
|
|
208
|
+
"elapsedMs": 5000,
|
|
209
|
+
"at": 0,
|
|
210
|
+
"shortcuts": {
|
|
211
|
+
"toggle": "Super+Alt+T",
|
|
212
|
+
"reset": "Super+Alt+Z",
|
|
213
|
+
"bound": true
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
"stopwatch.reset": [
|
|
219
|
+
{
|
|
220
|
+
"error": "stale_context"
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
"subscriptions": {
|
|
225
|
+
"stopwatch.subscribe": {
|
|
226
|
+
"running": false,
|
|
227
|
+
"elapsedMs": 5000,
|
|
228
|
+
"at": 0,
|
|
229
|
+
"shortcuts": {
|
|
230
|
+
"toggle": "Super+Alt+T",
|
|
231
|
+
"reset": "Super+Alt+Z",
|
|
232
|
+
"bound": true
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
<!-- source: widgets/warframe-market/tests/errors.scenario.json -->
|
|
240
|
+
```json
|
|
241
|
+
"http": [
|
|
242
|
+
{
|
|
243
|
+
"request": {
|
|
244
|
+
"method": "GET",
|
|
245
|
+
"url": "https://api.warframe.market/v2/versions"
|
|
246
|
+
},
|
|
247
|
+
"error": "timeout"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"request": {
|
|
251
|
+
"method": "GET",
|
|
252
|
+
"url": "https://api.warframe.market/v2/orders/item/primed_flow"
|
|
253
|
+
},
|
|
254
|
+
"error": "transport_failed"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"request": {
|
|
258
|
+
"method": "GET",
|
|
259
|
+
"url": "https://api.warframe.market/v2/orders/item/primed_flow"
|
|
260
|
+
},
|
|
261
|
+
"response": {
|
|
262
|
+
"status": 200,
|
|
263
|
+
"contentType": "application/json",
|
|
264
|
+
"body": "{\"apiVersion\":\"0.25.0\",\"data\":[],\"error\":null}"
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
The codes that OverCrow gives itself (`permission_denied`,
|
|
271
|
+
`gesture_required`, `not_connected`, `invalid_request`) cannot be written
|
|
272
|
+
in a fixture: get them the real way, with `grants`, `accounts`, a call
|
|
273
|
+
outside a user action, or wrong parameters. Storage, timers and the
|
|
274
|
+
clipboard are OverCrow's own and need no fixture.
|
|
275
|
+
|
|
276
|
+
### `assets`
|
|
277
|
+
|
|
278
|
+
Images that a fixture hands to the widget, as OverCrow hands it a media
|
|
279
|
+
cover or a chat emote: `{ "<name>": "<path>" }`, at most 8, each a PNG or
|
|
280
|
+
JPEG of the project (`tests/assets/cover.png`). Where a result holds an
|
|
281
|
+
image handle, the fixture writes `"fixture:<name>"`.
|
|
282
|
+
|
|
283
|
+
### `steps`
|
|
284
|
+
|
|
285
|
+
| Step | Does |
|
|
286
|
+
| --- | --- |
|
|
287
|
+
| `{ "advance": { "ms": N } }` | Moves the virtual time by `N` ms. Every timer due on the way fires in order, and the UTC offset changes at its instant. |
|
|
288
|
+
| `{ "advance": { "ms": N, "jump": true } }` | Moves the time at once, as a machine waking from sleep: each due timer fires once, late. |
|
|
289
|
+
| `{ "host": { … } }` | Changes `locale`, `theme`, `scale`, `size`, `mode`, `visible`, `region`, `zone` or `accounts`. |
|
|
290
|
+
| `{ "pointer": { "click": target } }` | A click. Also `rightClick`, `move` (hover), `wheel` (`{ target, dx, dy }`) and `"leave"`. |
|
|
291
|
+
| `{ "key": { "key": "Enter", "modifiers": ["shift"] } }` | A key press: `Tab`, `Escape`, `ArrowUp`, letters, digits… |
|
|
292
|
+
| `{ "text": "…" }` | Text typed into the focused field. |
|
|
293
|
+
| `{ "menu": { "id": "row", "value": … } }` | A row of the options menu: the value of a toggle, slider or choice, none for an action. |
|
|
294
|
+
| `{ "publish": { "service": "fps.subscribe", "value": … } }` | The next value of a subscription. |
|
|
295
|
+
| `{ "publish": { "service": "media.subscribe", "error": "unavailable" } }` | Ends the subscription with this failure. |
|
|
296
|
+
| `{ "expect": { … } }` | What must hold once the previous steps settled. |
|
|
297
|
+
|
|
298
|
+
A pointer target is `{ "at": [x, y] }` (logical pixels of the content),
|
|
299
|
+
`{ "text": "…" }` (the first element showing exactly this text) or
|
|
300
|
+
`{ "label": "…" }` (its accessible label). Input reaches the widget in
|
|
301
|
+
Interactive mode only. A click is a user action; a menu row never is.
|
|
302
|
+
|
|
303
|
+
Each step settles before the next: the widget has answered everything it
|
|
304
|
+
was sent and nothing is in flight. There is no real waiting.
|
|
305
|
+
|
|
306
|
+
### `expect`
|
|
307
|
+
|
|
308
|
+
| Member | Holds when |
|
|
309
|
+
| --- | --- |
|
|
310
|
+
| `image` | The capture matches `tests/reference/<scenario>/<image>.png`. Names are unique in a scenario. |
|
|
311
|
+
| `text`, `noText` | Each text is (is not) the whole text of an element the widget shows. |
|
|
312
|
+
| `calls` | Exactly these service calls were made since the previous `calls` expectation, in order: `{ service, params?, outcome? }`, `outcome` being `ok` or the error code the widget received. |
|
|
313
|
+
| `state` | `starting`, `running`, `restarting`, `failed`, `refused` or `stopped`. |
|
|
314
|
+
| `fault` | The last fault of the widget's VM, or `none`. |
|
|
315
|
+
| `clipboard` | The last text the widget wrote to the clipboard. |
|
|
316
|
+
| `intents` | Exactly these write intents were submitted since the previous `intents` expectation, in order: `{ intent, fields?, outcome? }`. `fields` are the exact values OverCrow's form sent. |
|
|
317
|
+
|
|
318
|
+
<!-- source: templates/chart/tests/example.scenario.json -->
|
|
319
|
+
```json
|
|
320
|
+
"steps": [
|
|
321
|
+
{ "expect": { "state": "running", "text": ["Activity", "50"], "image": "initial" } },
|
|
322
|
+
{ "advance": { "ms": 10000 } },
|
|
323
|
+
{ "expect": { "noText": ["50"], "image": "ten-seconds", "fault": "none" } }
|
|
324
|
+
]
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
The faults a widget's VM can report:
|
|
328
|
+
|
|
329
|
+
<!-- generated:fault-categories -->
|
|
330
|
+
| Category | Fatal | Meaning |
|
|
331
|
+
| --- | --- | --- |
|
|
332
|
+
| `resource_limit` | yes | Heap, stack, job queue or message budget exhausted inside the VM. |
|
|
333
|
+
| `unresponsive` | yes | The turn budget interrupted the VM. |
|
|
334
|
+
| `protocol_violation` | yes | The host sent a message the VM cannot accept. |
|
|
335
|
+
| `invalid_bundle` | yes | `logic.js` or the compiled view failed to load or register. |
|
|
336
|
+
| `handler_exception` | no | An event handler threw; the VM keeps running. |
|
|
337
|
+
<!-- /generated:fault-categories -->
|
|
338
|
+
|
|
339
|
+
## Reference images
|
|
340
|
+
|
|
341
|
+
An image is the widget's content, rendered at the scenario's scale, theme
|
|
342
|
+
and size. Record the states that matter in both themes, both languages and
|
|
343
|
+
two scales, as the reference widgets do: a scenario can change `theme`,
|
|
344
|
+
`locale` and `scale` between two `expect` steps.
|
|
345
|
+
|
|
346
|
+
<!-- source: templates/list/tests/example.scenario.json -->
|
|
347
|
+
```json
|
|
348
|
+
"steps": [
|
|
349
|
+
{ "expect": { "state": "running", "text": ["Today", "2 left"], "image": "initial" } },
|
|
350
|
+
{ "host": { "locale": "fr", "theme": "light" } },
|
|
351
|
+
{ "expect": { "image": "french-light", "fault": "none" } }
|
|
352
|
+
]
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Images are compared with a small tolerance: a pixel differs when one of its
|
|
356
|
+
channels differs by more than 2 levels, and the image differs when more
|
|
357
|
+
than 100 pixels per million do. One wrong letter is far above that. A
|
|
358
|
+
reference is never rewritten by a test run: only `--update` records images.
|
|
359
|
+
|
|
360
|
+
## Time and determinism
|
|
361
|
+
|
|
362
|
+
The runtime is deterministic: the same package and scenario render the same
|
|
363
|
+
bytes, on Linux and on Windows.
|
|
364
|
+
|
|
365
|
+
- Time is virtual: `Date.now()` and `new Date()` return the scenario's
|
|
366
|
+
time, timers fire when the scenario moves it.
|
|
367
|
+
- `Math.random()` is seeded with a fixed value.
|
|
368
|
+
- Text uses the fonts bundled with OverCrow, never the system's.
|
|
369
|
+
- Rendering does not depend on the graphics card.
|
|
370
|
+
|
|
371
|
+
This holds for the test runtime only: in the overlay, time and randomness
|
|
372
|
+
are real.
|
|
373
|
+
|
|
374
|
+
## The headless runtime
|
|
375
|
+
|
|
376
|
+
`overcrow-widget-headless` is OverCrow's own code without a window: it
|
|
377
|
+
validates the package as the overlay does and runs the widget's logic in
|
|
378
|
+
the same sandbox. `overcrow-widget test` runs the version this CLI pins,
|
|
379
|
+
0.6.0-beta.2, and prints its version and SHA-256. Without the operating
|
|
380
|
+
system's sandbox the runtime refuses to run and says so; the test command
|
|
381
|
+
then ends with status 2.
|
|
382
|
+
|
|
383
|
+
The first time `test` needs the runtime, it downloads it: from the
|
|
384
|
+
creator tools ZIP of your platform in the OverCrow release that
|
|
385
|
+
published it, it keeps only the runtime, and only once its SHA-256 is the
|
|
386
|
+
one this CLI pins. The ZIP is not kept. The runtime then stays in the CLI's cache:
|
|
387
|
+
|
|
388
|
+
| Platform | Path |
|
|
389
|
+
| --- | --- |
|
|
390
|
+
| Linux | `~/.cache/overcrow-widget/runtime/0.6.0-beta.2/` (`$XDG_CACHE_HOME` instead of `~/.cache` when set) |
|
|
391
|
+
| Windows | `%LOCALAPPDATA%\overcrow-widget\runtime\0.6.0-beta.2\` |
|
|
392
|
+
|
|
393
|
+
To work offline, put the runtime of the creator tools ZIP there yourself
|
|
394
|
+
(executable on Linux): `test` finds it and downloads nothing. With
|
|
395
|
+
`--offline`, `test` never downloads. A proxy set in `HTTPS_PROXY` is used.
|
|
396
|
+
|
|
397
|
+
The CLI checks its SHA-256 before every run. When a download fails,
|
|
398
|
+
nothing is kept and `test` says to try again or to pass `--runtime`.
|
|
399
|
+
`--runtime <path>` runs another runtime instead, such as one built from
|
|
400
|
+
OverCrow; the output then says it is not the pinned one.
|