testeranto 0.79.69 → 0.80.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 (236) hide show
  1. package/.eslintrc.js +5 -2
  2. package/README.md +7 -108
  3. package/build-tests.ts +16 -0
  4. package/dist/common/build-tests.js +38 -0
  5. package/dist/common/init-docs.js +8 -0
  6. package/dist/common/run-tests.js +34 -0
  7. package/dist/common/src/Aider.js +96 -0
  8. package/dist/common/src/Init.js +10 -0
  9. package/dist/common/{PM → src/PM}/main.js +9 -3
  10. package/dist/common/{Puppeteer.js → src/Puppeteer.js} +8 -4
  11. package/dist/common/{SubPackages → src/SubPackages}/react-dom/jsx/web.js +37 -38
  12. package/dist/common/{esbuildConfigs → src/esbuildConfigs}/inputFilesPlugin.js +5 -2
  13. package/dist/common/{esbuildConfigs → src/esbuildConfigs}/node.js +5 -3
  14. package/dist/common/{esbuildConfigs → src/esbuildConfigs}/web.js +1 -1
  15. package/dist/common/{lib → src/lib}/abstractBase.js +41 -13
  16. package/dist/common/{lib → src/lib}/basebuilder.js +8 -0
  17. package/dist/common/testeranto.js +15 -0
  18. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  19. package/dist/module/build-tests.js +10 -0
  20. package/dist/module/init-docs.js +3 -0
  21. package/dist/module/run-tests.js +6 -0
  22. package/dist/module/src/Aider.js +89 -0
  23. package/dist/module/src/Init.js +5 -0
  24. package/dist/module/{PM → src/PM}/main.js +9 -3
  25. package/dist/module/{Puppeteer.js → src/Puppeteer.js} +8 -4
  26. package/dist/module/{SubPackages → src/SubPackages}/react-dom/jsx/web.js +37 -38
  27. package/dist/module/{esbuildConfigs → src/esbuildConfigs}/inputFilesPlugin.js +5 -2
  28. package/dist/module/{esbuildConfigs → src/esbuildConfigs}/node.js +4 -2
  29. package/dist/module/{esbuildConfigs → src/esbuildConfigs}/web.js +1 -1
  30. package/dist/module/{lib → src/lib}/abstractBase.js +41 -13
  31. package/dist/module/{lib → src/lib}/basebuilder.js +8 -0
  32. package/dist/module/testeranto.js +13 -0
  33. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  34. package/dist/types/build-tests.d.ts +3 -0
  35. package/dist/types/init-docs.d.ts +2 -0
  36. package/dist/types/run-tests.d.ts +2 -0
  37. package/dist/types/src/Aider.d.ts +1 -0
  38. package/dist/types/{PM → src/PM}/index.d.ts +1 -1
  39. package/dist/types/{Types.d.ts → src/Types.d.ts} +3 -2
  40. package/dist/types/testeranto.d.ts +16 -0
  41. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  42. package/init-docs.ts +5 -0
  43. package/package.json +49 -20
  44. package/run-tests.ts +9 -0
  45. package/src/Aider.ts +125 -0
  46. package/src/Init.ts +0 -31
  47. package/src/PM/index.ts +1 -1
  48. package/src/PM/main.ts +11 -5
  49. package/src/Puppeteer.ts +11 -4
  50. package/src/SubPackages/react-dom/jsx/web.ts +46 -49
  51. package/src/Types.ts +3 -1
  52. package/src/esbuildConfigs/inputFilesPlugin.ts +32 -30
  53. package/src/esbuildConfigs/node.ts +2 -2
  54. package/src/esbuildConfigs/web.ts +1 -1
  55. package/src/lib/abstractBase.ts +42 -15
  56. package/src/lib/basebuilder.ts +9 -0
  57. package/testeranto.ts +13 -0
  58. package/tsconfig.common.json +12 -4
  59. package/tsconfig.json +9 -2
  60. package/tsconfig.module.json +2 -2
  61. package/tsconfig.types.json +1 -1
  62. package/Report.Dockerfile +0 -44
  63. package/dist/common/Features.js +0 -51
  64. package/dist/common/Init.js +0 -30
  65. package/dist/common/Reporter.js +0 -112
  66. package/dist/common/Scheduler.js +0 -1
  67. package/dist/common/TaskManBackEnd.js +0 -167
  68. package/dist/common/mongooseSchemas.js +0 -56
  69. package/dist/common/preload.js +0 -15
  70. package/dist/common/report.html.js +0 -31
  71. package/dist/module/ExampleTab.js +0 -112
  72. package/dist/module/Features.js +0 -41
  73. package/dist/module/Init.js +0 -25
  74. package/dist/module/Reporter.js +0 -107
  75. package/dist/module/Scheduler.js +0 -1
  76. package/dist/module/TaskManBackEnd.js +0 -162
  77. package/dist/module/TaskManFrontEnd.js +0 -605
  78. package/dist/module/mongooseSchemas.js +0 -50
  79. package/dist/module/preload.js +0 -15
  80. package/dist/module/report.html.js +0 -29
  81. package/dist/prebuild/TaskManBackEnd.mjs +0 -170
  82. package/dist/prebuild/TaskManFrontEnd.css +0 -12301
  83. package/dist/prebuild/TaskManFrontEnd.js +0 -81262
  84. package/dist/types/Features.d.ts +0 -35
  85. package/dist/types/Reporter.d.ts +0 -1
  86. package/dist/types/Scheduler.d.ts +0 -0
  87. package/dist/types/TaskManBackEnd.d.ts +0 -3
  88. package/dist/types/mongooseSchemas.d.ts +0 -124
  89. package/dist/types/preload.d.ts +0 -0
  90. package/dist/types/report.html.d.ts +0 -2
  91. package/src/ExampleTab.tsx +0 -219
  92. package/src/Features.ts +0 -64
  93. package/src/Reporter.ts +0 -126
  94. package/src/Scheduler.ts +0 -0
  95. package/src/TaskManBackEnd.ts +0 -226
  96. package/src/TaskManFrontEnd.tsx +0 -1254
  97. package/src/mongooseSchemas.ts +0 -105
  98. package/src/preload.ts +0 -17
  99. package/src/report.html.ts +0 -29
  100. package/tests/Rectangle.test.ts +0 -189
  101. package/trash/TaskMan.Dockerfile +0 -23
  102. package/trash/TaskMan1.Dockerfile +0 -43
  103. package/trash/devBot.dockerfile +0 -12
  104. package/trash/docker-compose-dev.yml +0 -9
  105. package/trash/docker-compose-prod.yml +0 -18
  106. package/trash/electronBuild.ts +0 -32
  107. /package/dist/common/{Node.js → src/Node.js} +0 -0
  108. /package/dist/common/{PM → src/PM}/index.js +0 -0
  109. /package/dist/common/{PM → src/PM}/node.js +0 -0
  110. /package/dist/common/{PM → src/PM}/web.js +0 -0
  111. /package/dist/common/{Project.js → src/Project.js} +0 -0
  112. /package/dist/common/{SubPackages → src/SubPackages}/puppeteer.js +0 -0
  113. /package/dist/common/{SubPackages → src/SubPackages}/react/component/node.js +0 -0
  114. /package/dist/common/{SubPackages → src/SubPackages}/react/component/web.js +0 -0
  115. /package/dist/common/{SubPackages → src/SubPackages}/react/jsx/index.js +0 -0
  116. /package/dist/common/{SubPackages → src/SubPackages}/react/jsx/node.js +0 -0
  117. /package/dist/common/{SubPackages → src/SubPackages}/react/jsx/web.js +0 -0
  118. /package/dist/common/{SubPackages → src/SubPackages}/react-dom/component/node.js +0 -0
  119. /package/dist/common/{SubPackages → src/SubPackages}/react-dom/component/web.js +0 -0
  120. /package/dist/common/{SubPackages → src/SubPackages}/react-dom/jsx/index.js +0 -0
  121. /package/dist/common/{SubPackages → src/SubPackages}/react-dom/jsx/node.js +0 -0
  122. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/MemoExoticComponent/node.js +0 -0
  123. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/component/index.js +0 -0
  124. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/component/interface.js +0 -0
  125. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/component/node.js +0 -0
  126. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/component/web.js +0 -0
  127. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/fc/node.js +0 -0
  128. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/fc/web.js +0 -0
  129. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/jsx/index.js +0 -0
  130. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/jsx/node.js +0 -0
  131. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/jsx/web.js +0 -0
  132. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/index.js +0 -0
  133. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/node.js +0 -0
  134. /package/dist/common/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/web.js +0 -0
  135. /package/dist/common/{Types.js → src/Types.js} +0 -0
  136. /package/dist/common/{Web.js → src/Web.js} +0 -0
  137. /package/dist/common/{esbuildConfigs → src/esbuildConfigs}/features.js +0 -0
  138. /package/dist/common/{esbuildConfigs → src/esbuildConfigs}/index.js +0 -0
  139. /package/dist/common/{esbuildConfigs → src/esbuildConfigs}/report.js +0 -0
  140. /package/dist/common/{esbuildConfigs → src/esbuildConfigs}/tests.js +0 -0
  141. /package/dist/common/{lib → src/lib}/classBuilder.js +0 -0
  142. /package/dist/common/{lib → src/lib}/core.js +0 -0
  143. /package/dist/common/{lib → src/lib}/index.js +0 -0
  144. /package/dist/common/{lib → src/lib}/types.js +0 -0
  145. /package/dist/common/{puppeteerConfiger.js → src/puppeteerConfiger.js} +0 -0
  146. /package/dist/common/{utils.js → src/utils.js} +0 -0
  147. /package/dist/common/{web.html.js → src/web.html.js} +0 -0
  148. /package/dist/module/{Node.js → src/Node.js} +0 -0
  149. /package/dist/module/{PM → src/PM}/index.js +0 -0
  150. /package/dist/module/{PM → src/PM}/node.js +0 -0
  151. /package/dist/module/{PM → src/PM}/web.js +0 -0
  152. /package/dist/module/{Project.js → src/Project.js} +0 -0
  153. /package/dist/module/{SubPackages → src/SubPackages}/puppeteer.js +0 -0
  154. /package/dist/module/{SubPackages → src/SubPackages}/react/component/node.js +0 -0
  155. /package/dist/module/{SubPackages → src/SubPackages}/react/component/web.js +0 -0
  156. /package/dist/module/{SubPackages → src/SubPackages}/react/jsx/index.js +0 -0
  157. /package/dist/module/{SubPackages → src/SubPackages}/react/jsx/node.js +0 -0
  158. /package/dist/module/{SubPackages → src/SubPackages}/react/jsx/web.js +0 -0
  159. /package/dist/module/{SubPackages → src/SubPackages}/react-dom/component/node.js +0 -0
  160. /package/dist/module/{SubPackages → src/SubPackages}/react-dom/component/web.js +0 -0
  161. /package/dist/module/{SubPackages → src/SubPackages}/react-dom/jsx/index.js +0 -0
  162. /package/dist/module/{SubPackages → src/SubPackages}/react-dom/jsx/node.js +0 -0
  163. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/MemoExoticComponent/node.js +0 -0
  164. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/component/index.js +0 -0
  165. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/component/interface.js +0 -0
  166. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/component/node.js +0 -0
  167. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/component/web.js +0 -0
  168. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/fc/node.js +0 -0
  169. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/fc/web.js +0 -0
  170. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/jsx/index.js +0 -0
  171. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/jsx/node.js +0 -0
  172. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/jsx/web.js +0 -0
  173. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/index.js +0 -0
  174. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/node.js +0 -0
  175. /package/dist/module/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/web.js +0 -0
  176. /package/dist/module/{Types.js → src/Types.js} +0 -0
  177. /package/dist/module/{Web.js → src/Web.js} +0 -0
  178. /package/dist/module/{esbuildConfigs → src/esbuildConfigs}/features.js +0 -0
  179. /package/dist/module/{esbuildConfigs → src/esbuildConfigs}/index.js +0 -0
  180. /package/dist/module/{esbuildConfigs → src/esbuildConfigs}/report.js +0 -0
  181. /package/dist/module/{esbuildConfigs → src/esbuildConfigs}/tests.js +0 -0
  182. /package/dist/module/{lib → src/lib}/classBuilder.js +0 -0
  183. /package/dist/module/{lib → src/lib}/core.js +0 -0
  184. /package/dist/module/{lib → src/lib}/index.js +0 -0
  185. /package/dist/module/{lib → src/lib}/types.js +0 -0
  186. /package/dist/module/{puppeteerConfiger.js → src/puppeteerConfiger.js} +0 -0
  187. /package/dist/module/{utils.js → src/utils.js} +0 -0
  188. /package/dist/module/{web.html.js → src/web.html.js} +0 -0
  189. /package/dist/types/{Init.d.ts → src/Init.d.ts} +0 -0
  190. /package/dist/types/{Node.d.ts → src/Node.d.ts} +0 -0
  191. /package/dist/types/{PM → src/PM}/main.d.ts +0 -0
  192. /package/dist/types/{PM → src/PM}/node.d.ts +0 -0
  193. /package/dist/types/{PM → src/PM}/web.d.ts +0 -0
  194. /package/dist/types/{Project.d.ts → src/Project.d.ts} +0 -0
  195. /package/dist/types/{Puppeteer.d.ts → src/Puppeteer.d.ts} +0 -0
  196. /package/dist/types/{SubPackages → src/SubPackages}/puppeteer.d.ts +0 -0
  197. /package/dist/types/{SubPackages → src/SubPackages}/react/component/node.d.ts +0 -0
  198. /package/dist/types/{SubPackages → src/SubPackages}/react/component/web.d.ts +0 -0
  199. /package/dist/types/{SubPackages → src/SubPackages}/react/jsx/index.d.ts +0 -0
  200. /package/dist/types/{SubPackages → src/SubPackages}/react/jsx/node.d.ts +0 -0
  201. /package/dist/types/{SubPackages → src/SubPackages}/react/jsx/web.d.ts +0 -0
  202. /package/dist/types/{SubPackages → src/SubPackages}/react-dom/component/node.d.ts +0 -0
  203. /package/dist/types/{SubPackages → src/SubPackages}/react-dom/component/web.d.ts +0 -0
  204. /package/dist/types/{SubPackages → src/SubPackages}/react-dom/jsx/index.d.ts +0 -0
  205. /package/dist/types/{SubPackages → src/SubPackages}/react-dom/jsx/node.d.ts +0 -0
  206. /package/dist/types/{SubPackages → src/SubPackages}/react-dom/jsx/web.d.ts +0 -0
  207. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/MemoExoticComponent/node.d.ts +0 -0
  208. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/component/index.d.ts +0 -0
  209. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/component/interface.d.ts +0 -0
  210. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/component/node.d.ts +0 -0
  211. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/component/web.d.ts +0 -0
  212. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/fc/node.d.ts +0 -0
  213. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/fc/web.d.ts +0 -0
  214. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/jsx/index.d.ts +0 -0
  215. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/jsx/node.d.ts +0 -0
  216. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/jsx/web.d.ts +0 -0
  217. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/index.d.ts +0 -0
  218. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/node.d.ts +0 -0
  219. /package/dist/types/{SubPackages → src/SubPackages}/react-test-renderer/jsx-promised/web.d.ts +0 -0
  220. /package/dist/types/{Web.d.ts → src/Web.d.ts} +0 -0
  221. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/features.d.ts +0 -0
  222. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/index.d.ts +0 -0
  223. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/inputFilesPlugin.d.ts +0 -0
  224. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/node.d.ts +0 -0
  225. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/report.d.ts +0 -0
  226. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/tests.d.ts +0 -0
  227. /package/dist/types/{esbuildConfigs → src/esbuildConfigs}/web.d.ts +0 -0
  228. /package/dist/types/{lib → src/lib}/abstractBase.d.ts +0 -0
  229. /package/dist/types/{lib → src/lib}/basebuilder.d.ts +0 -0
  230. /package/dist/types/{lib → src/lib}/classBuilder.d.ts +0 -0
  231. /package/dist/types/{lib → src/lib}/core.d.ts +0 -0
  232. /package/dist/types/{lib → src/lib}/index.d.ts +0 -0
  233. /package/dist/types/{lib → src/lib}/types.d.ts +0 -0
  234. /package/dist/types/{puppeteerConfiger.d.ts → src/puppeteerConfiger.d.ts} +0 -0
  235. /package/dist/types/{utils.d.ts → src/utils.d.ts} +0 -0
  236. /package/dist/types/{web.html.d.ts → src/web.html.d.ts} +0 -0
package/.eslintrc.js CHANGED
@@ -17,12 +17,15 @@ module.exports = {
17
17
  },
18
18
  "plugins": [
19
19
  "react",
20
- "@typescript-eslint"
20
+ "@typescript-eslint",
21
+ "react-hooks"
21
22
  ],
22
23
  "rules": {
23
24
  "@typescript-eslint/ban-ts-comment": "warn",
24
25
  "prefer-const": "warn",
25
- "@typescript-eslint/no-unused-vars": "warn"
26
+ "@typescript-eslint/no-unused-vars": "warn",
27
+ "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
28
+ "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
26
29
  }
27
30
  }
28
31
 
package/README.md CHANGED
@@ -12,119 +12,18 @@ dev: [github.dev/adamwong246/testeranto](https://github.dev/adamwong246/testeran
12
12
 
13
13
  example repo: [kokomo bay](https://github.com/ChromaPDX/kokomoBay)
14
14
 
15
- ## tl;dr
16
-
17
- - Do you like TDD/BDD?
18
- - Do you love Typescript?
19
- - Do you hate Jira?
20
-
21
- If so, then testeranto might be the testing tool you have been looking for!
22
-
23
15
  ## about
24
16
 
25
- Testeranto.ts an typescript Acceptance Test Driven Development ([ATDD](https://en.wikipedia.org/wiki/Acceptance_test-driven_development)) framework. It includes a library of common patterns to help write your tests, a test runner to schedule the tests and a reporter to display the results. The tests are specified in a strongly-typed gherkin-like syntax. Features are tracked _as code_, rather than living in a separate app. Tests can be run in the browser frontend or the node backend, or both! Testeranto can be used to test _anything_ that can be bundled with esbuild.
26
-
27
- ## Getting started
28
-
29
- 1. Write some code.
30
- 2. Write some tests of that code.
31
- 3. Write some features of that code.
32
- 4. Write a `testeranto.mts`, which acts as a config file.
33
- 5. Launch testeranto. The test runner is now rebuilding the docs folder.
34
- 6. Commit the results of those tests.
35
- 7. Your github pages now shows your report, showing your features, linked with your test results.
36
- 8. Optionally add testeranto to your CI.
17
+ 1. Testeranto.ts an AI-first, Acceptance Test Driven Development ([ATDD](https://en.wikipedia.org/wiki/Acceptance_test-driven_development)) framework for typescript.
18
+ 2. Testeranto includes a library of common patterns to help write your tests and a test runner to schedule the tests.
19
+ 3. Testeranto tests are specified in a strongly-typed gherkin-like syntax. Rather than testing your code directly, Testeranto requires you wrap your code with a semantic interface which is based on TS type signatures. These interfaces can be shared and your code is tested through the gherkin-ish directives provided by that interface.
20
+ 4. Testeranto can be run in the browser frontend or the node backend, or both, and Testeranto can be used to test _anything_ that can be bundled with esbuild. Testeranto leverages puppeteer to provide both of these runtimes.
21
+ 5. Testeranto produces test results which can be fed to Aider.ai to automatically fix failing tests
37
22
 
38
23
  ## tech of note
39
24
 
40
- - esm - Testeranto uses modern js.
25
+ - esm - Testeranto uses modern js
41
26
  - typescript - tests are functions with type parameters
42
27
  - puppeteer - provides access to both node and chrome runtimes
43
28
  - esbuild - used to quickly generate test bundles
44
- - graphology - used to store features within a semantic network
45
-
46
- ## 3 distinguishing features of testeranto
47
-
48
- 1. Rather than testing your code directly, Testeranto requires you wrap your code with a semantic interface which is based on TS type signatures. These interfaces can be shared and your code is tested through the gherkin-ish directives provided by that interface.
49
-
50
- 2. Testeranto tracks features and tests results directly in the source code. You may be accustomed to using tools like Jira and Trello to define user stories and assign story points. Using Testeranto, this data lives within the code base _as_ typescript code. Features are defined as nodes within a directed graph, allowing the reporter to summarize these features and their test results.
51
-
52
- 3. Testeranto is designed for both the backend and the frontend. It leverages puppeteer to provide both of these runtimes. Each of your tests can be executed in the backend node runtime, within the frontend chromium browser runtime, or both.
53
-
54
- ## the good parts
55
-
56
- Your tests can be run in node, chromium, or both.
57
-
58
- Testeranto includes a test runner which bundles and executes your tests, taking care to only run the tests which have changed.
59
-
60
- Testeranto includes a test reporter which displays the state of your code in a web app. ([see example](https://chromapdx.github.io/kokomoBay/report.html)) This reporter can also be run locally for the developer's convenience.
61
-
62
- Testeranto exposes an extended gherkin syntax. You can use the given-when-then lingua-franca, AND you can also use an imperative `Check` which is a bit more flexible.
63
-
64
- Rather than the traditional method of specifying tests in plain text, Testeranto tests and features are just TS, editable and type-checkable from [github's online editor](https://github.dev/ChromaPDX/kokomoBay)!
65
-
66
- ## the bad parts
67
-
68
- Testeranto is very flexible and unopinionated, but not designed to maximize performance.
69
-
70
- Testeranto does not (yet!) allow a means of allowing non-coders to affect changes so, as they say, "git good 💪!"
71
-
72
- Testeranto uses ONLY node v8 and chromium. It does not support bun or deno, nor firefox nor safari.
73
-
74
- ## How it works
75
-
76
- Testeranto is comprised of 3 parts
77
-
78
- 1. The build process reads a config and builds the docs folder, then launches 3 esbuild build processes.
79
-
80
- - Build the features for the html report
81
- - Build the node-style tests
82
- - Build the web-style tests
83
-
84
- 2. The test runner watches the output of those build processes and launches the tests as those files change. It uses puppeteer to run web tests in chromium. It uses dynamic loading to import the node tests directly into the node v8 process.
85
-
86
- 3. A Report which links your features, your tests and the results of those tests into a handy website.
87
-
88
- ## CLI
89
-
90
- There are 3 commands you should add to your `package.json`
91
-
92
- ```
93
- // build the tests once
94
- "testeranto-esbuild": "ts-node-esm testeranto.mts",
95
-
96
- // build the tests, watching for changes
97
- "testeranto-esbuild-dev": "ts-node-esm testeranto.mts",
98
-
99
- // run the tests
100
- "testeranto-puppeteer":"ts-node-esm node_modules/testeranto/dist/module/Puppeteer.js",
101
- ```
102
-
103
- ## Hybrid tests
104
-
105
- Consider the a scenario: You have an http server which serves a frontend react component. You have multiple ways you can test this.
106
-
107
- - A node test of the logic of the http server.
108
- - A node test of the full http server, tested over http request.
109
- - A node test of the react component with react-test-render
110
- - A web test of the react component rendering it to the dom.
111
- - A node test of the logic of the server, rending the component as a paired artifact and communicated over IPC.
112
- - A node test of the full server, invoking puppeteer to drive the browser.
113
- - A web test, invoking the server as a shared artifact, serving http to the browser.
114
-
115
- ## API
116
-
117
- Testeranto's main API interface is 2 functions, 1 for each run time. You must pass to this function the following arguments
118
-
119
- - The "shape" - a TS type signature to which the other arguments must conform.
120
- - The "input" - the test subject. The "thing that is to be tested"
121
- - the "specification" - This is the Cucumber-style Given/When/Then steps.
122
- - the "implementation" - This is the code which implements the "test specification" in code.
123
- - the "interface" - The code which sets up the test.
124
-
125
- This is designed so that each piece can be worked upon separately. You can think of each argument as the responsibility of a different member of your team.
126
-
127
- - "Senior Engineer" handles the "shape" and "input"
128
- - "Product Manager" handles the "specification"
129
- - "Middle Engineer" handles the "interface"
130
- - "Junior Engineer" handles the "implementation"
29
+ - aider - AI to automatically fix broken tests
package/build-tests.ts ADDED
@@ -0,0 +1,16 @@
1
+ // import { ITProject } from "./src/Project.js";
2
+
3
+ // import Project from "./testeranto.js";
4
+
5
+ import process from "process";
6
+ import { ITProject } from "./src/Project";
7
+ // import { ITProject } from "testeranto/src/Project";
8
+
9
+ // process.chdir(__dirname);
10
+
11
+ // import Puppeteer from "./src/Puppeteer.js";
12
+
13
+ console.log(process.argv);
14
+ const Project = await import(process.argv[2]);
15
+
16
+ export default new ITProject(Project as any);
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ // import { ITProject } from "./src/Project.js";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __importDefault = (this && this.__importDefault) || function (mod) {
27
+ return (mod && mod.__esModule) ? mod : { "default": mod };
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ // import Project from "./testeranto.js";
31
+ const process_1 = __importDefault(require("process"));
32
+ const Project_1 = require("./src/Project");
33
+ // import { ITProject } from "testeranto/src/Project";
34
+ // process.chdir(__dirname);
35
+ // import Puppeteer from "./src/Puppeteer.js";
36
+ console.log(process_1.default.argv);
37
+ const Project = await Promise.resolve().then(() => __importStar(require(process_1.default.argv[2])));
38
+ exports.default = new Project_1.ITProject(Project);
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Init_js_1 = __importDefault(require("./src/Init.js"));
7
+ const testeranto_js_1 = __importDefault(require("./testeranto.js"));
8
+ exports.default = (0, Init_js_1.default)(testeranto_js_1.default);
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const process_1 = __importDefault(require("process"));
30
+ process_1.default.chdir(__dirname);
31
+ const Puppeteer_js_1 = __importDefault(require("./src/Puppeteer.js"));
32
+ console.log(process_1.default.argv);
33
+ const Project = await Promise.resolve().then(() => __importStar(require(process_1.default.argv[2])));
34
+ exports.default = (0, Puppeteer_js_1.default)(Project);
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.execCommand = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const child_process_1 = require("child_process");
9
+ const execCommand = async (command) => {
10
+ return new Promise((resolve, reject) => {
11
+ const [cmd, ...args] = command.split(" ");
12
+ const childProcess = (0, child_process_1.spawn)(cmd, args);
13
+ childProcess.stdout.on("data", (data) => {
14
+ process.stdout.write(data.toString());
15
+ });
16
+ childProcess.stderr.on("data", (data) => {
17
+ process.stderr.write(data.toString());
18
+ });
19
+ childProcess.on("error", (error) => {
20
+ reject(error);
21
+ });
22
+ childProcess.on("exit", (code) => {
23
+ if (code === 0) {
24
+ resolve();
25
+ }
26
+ else {
27
+ reject(new Error(`Command exited with code ${code}.`));
28
+ }
29
+ });
30
+ });
31
+ };
32
+ exports.execCommand = execCommand;
33
+ const key = process.argv[2];
34
+ console.log(key);
35
+ const exitcode = fs_1.default.readFileSync(`${key}/exitcode`).toString();
36
+ console.log("exitcode", exitcode);
37
+ // if (exitcode != "0") {
38
+ if (exitcode != "0") {
39
+ const inputFiles = JSON.parse(fs_1.default.readFileSync(`${key}/inputFiles.json`).toString());
40
+ inputFiles.push(`${key}/tests.json`);
41
+ const features = await (await Promise.all(Array.from(new Set(JSON.parse(fs_1.default.readFileSync(`${key}/tests.json`).toString())
42
+ .givens.reduce((mm, lm) => {
43
+ mm.push(lm.features.reduce((mm2, lm2) => {
44
+ mm2.push(lm2);
45
+ return mm2;
46
+ }, []));
47
+ return mm;
48
+ }, [])
49
+ .flat()
50
+ .flat()))))
51
+ .reduce(async (mm, feature) => {
52
+ const req = await octokit.request(`GET /repos/adamwong246/kokomobay-taskman/contents/Task/${feature}.json`, {
53
+ owner: "adamwong246",
54
+ repo: "kokomoBay-taskman",
55
+ path: `Task/${feature}.json`,
56
+ headers: {
57
+ "X-GitHub-Api-Version": "2022-11-28",
58
+ },
59
+ });
60
+ const j = JSON.parse(atob(req.data.content));
61
+ (await mm).push([
62
+ feature,
63
+ JSON.stringify({
64
+ name: j.name,
65
+ body: j.body,
66
+ }),
67
+ ]);
68
+ return mm;
69
+ }, Promise.resolve([]))
70
+ .then((z) => {
71
+ const final = z.reduce((mm, [k, v], ndx) => {
72
+ mm[k] = v;
73
+ return mm;
74
+ }, {});
75
+ const as = JSON.stringify(final);
76
+ fs_1.default.writeFile(`./${key}/features.json`, as, () => {
77
+ inputFiles.push(`./${key}/features.json`);
78
+ const scriptCommand = `aider --model deepseek --api-key deepseek=${process.env.DEEPSEEK_KEY} --message "Fix the failing tests" ${inputFiles.join(" ")}`;
79
+ console.log("scriptCommand", scriptCommand);
80
+ (0, exports.execCommand)(scriptCommand);
81
+ // itermTab(scriptCommand).then(() => console.log("yay"));
82
+ // const child = spawn("xterm -e", scriptCommand.split(" "), {
83
+ // detached: true,
84
+ // stdio: "ignore",
85
+ // });
86
+ // runCommandInITerm(scriptCommand);
87
+ });
88
+ //
89
+ });
90
+ // features.then((x) => {
91
+ // console.log("done", x);
92
+ // });
93
+ }
94
+ else {
95
+ console.log("that test is not failing");
96
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ exports.default = async (partialConfig) => {
8
+ const config = Object.assign(Object.assign({}, partialConfig), { buildDir: process.cwd() + "/" + partialConfig.outdir });
9
+ fs_1.default.writeFileSync(`${config.outdir}/testeranto.json`, JSON.stringify(Object.assign(Object.assign({}, config), { buildDir: process.cwd() + "/" + config.outdir }), null, 2));
10
+ };
@@ -437,7 +437,7 @@ class PM_Main extends index_js_1.PM {
437
437
  delete files[testName];
438
438
  Promise.all(screenshots[testName] || []).then(() => {
439
439
  delete screenshots[testName];
440
- page.close();
440
+ // page.close();
441
441
  });
442
442
  // globalThis["writeFileSync"](
443
443
  // p + "/manifest.json",
@@ -463,8 +463,14 @@ class PM_Main extends index_js_1.PM {
463
463
  .then(async (page) => {
464
464
  page.on("console", (log) => console.debug(`Log from client: [${log.text()}] `));
465
465
  await page.goto(`file://${`${dest}.html`}`, {});
466
- page.evaluate(evaluation).finally(() => {
466
+ page
467
+ .evaluate(evaluation)
468
+ .catch((e) => {
467
469
  console.log("evaluation failed.", dest);
470
+ console.log(e);
471
+ })
472
+ .finally(() => {
473
+ console.log("evaluation complete.", dest);
468
474
  });
469
475
  return page;
470
476
  });
@@ -573,7 +579,7 @@ class PM_Main extends index_js_1.PM {
573
579
  throw new Error("Method not implemented.");
574
580
  }
575
581
  async startPuppeteer(options, destfolder) {
576
- this.browser = await puppeteer_core_1.default.launch(options);
582
+ this.browser = (await puppeteer_core_1.default.launch(options));
577
583
  return this.browser;
578
584
  }
579
585
  end(accessObject) {
@@ -15,7 +15,7 @@ const childProcesses = {};
15
15
  readline_1.default.emitKeypressEvents(process.stdin);
16
16
  if (process.stdin.isTTY)
17
17
  process.stdin.setRawMode(true);
18
- console.log("hello Puppeteer", process.env);
18
+ // console.log("hello Puppeteer", process.env);
19
19
  console.log("\n Puppeteer is running. Press 'q' to quit\n");
20
20
  process.stdin.on("keypress", (str, key) => {
21
21
  if (key.name === "q") {
@@ -27,17 +27,21 @@ exports.default = async (partialConfig) => {
27
27
  fs_1.default.writeFileSync(`${config.outdir}/testeranto.json`, JSON.stringify(Object.assign(Object.assign({}, config), { buildDir: process.cwd() + "/" + config.outdir }), null, 2));
28
28
  const pm = new main_js_1.PM_Main(config);
29
29
  await pm.startPuppeteer({
30
+ // timeout: 1,
30
31
  waitForInitialPage: false,
31
- executablePath: process.env.CHROMIUM_PATH || "/opt/homebrew/bin/chromium",
32
+ executablePath:
33
+ // process.env.CHROMIUM_PATH || "/opt/homebrew/bin/chromium",
34
+ "/opt/homebrew/bin/chromium",
32
35
  headless: true,
33
- // dumpio: true,
36
+ dumpio: true,
37
+ // timeout: 0,
34
38
  args: [
39
+ // "--auto-open-devtools-for-tabs",
35
40
  "--disable-features=IsolateOrigins,site-per-process",
36
41
  "--disable-site-isolation-trials",
37
42
  "--allow-insecure-localhost",
38
43
  "--allow-file-access-from-files",
39
44
  "--allow-running-insecure-content",
40
- // "--auto-open-devtools-for-tabs",
41
45
  "--disable-dev-shm-usage",
42
46
  "--disable-extensions",
43
47
  "--disable-gpu",
@@ -29,19 +29,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
30
  const react_2 = require("react");
31
31
  const client_1 = __importDefault(require("react-dom/client"));
32
- const react_dom_1 = require("react-dom");
33
32
  const Web_js_1 = __importDefault(require("../../../Web.js"));
33
+ const TesterantoComponent = ({ done, innerComp, }) => {
34
+ const myContainer = (0, react_1.useRef)(null);
35
+ (0, react_1.useEffect)(() => {
36
+ console.log("useEffect called!", myContainer.current);
37
+ done(myContainer.current);
38
+ }, []);
39
+ return react_1.default.createElement("div", { ref: myContainer }, innerComp());
40
+ };
34
41
  exports.default = (testImplementations, testSpecifications, testInput) => {
35
- console.log("testInput", testInput);
36
- const TesterantoComponent = function ({ done, innerComp, }) {
37
- const myContainer = (0, react_1.useRef)(null);
38
- (0, react_1.useEffect)(() => {
39
- console.log("useEffect called!", myContainer.current);
40
- done(myContainer.current);
41
- }, []);
42
- // debugger;
43
- return react_1.default.createElement("div", { ref: myContainer }, innerComp());
44
- };
45
42
  const t = (0, Web_js_1.default)(testInput, testSpecifications, testImplementations, {
46
43
  beforeAll: async (reactElement, itr) => {
47
44
  return await new Promise((resolve, rej) => {
@@ -65,47 +62,49 @@ exports.default = (testImplementations, testSpecifications, testInput) => {
65
62
  },
66
63
  beforeEach: async (subject, initializer, artificer, testResource, pm) => {
67
64
  return new Promise((resolve, rej) => {
68
- (0, react_dom_1.createPortal)(TesterantoComponent({
69
- innerComp: () => testInput({
70
- port: 3003,
71
- address: "some-address",
72
- secretKey: "someSecretKey",
73
- abi: "foo",
74
- }),
75
- done: (reactElement) => {
76
- process.nextTick(() => {
77
- resolve(reactElement);
78
- });
79
- },
80
- }), subject.domRoot);
65
+ resolve(subject);
66
+ // const tc = TesterantoComponent({
67
+ // innerComp: () =>
68
+ // testInput({
69
+ // port: 3003,
70
+ // address: "some-address",
71
+ // secretKey: "someSecretKey",
72
+ // abi: "foo",
73
+ // }),
74
+ // done: (reactElement: any) => {
75
+ // console.log("mark9");
76
+ // resolve(reactElement);
77
+ // // process.nextTick(() => {
78
+ // // resolve(reactElement);
79
+ // // });
80
+ // },
81
+ // });
82
+ // console.log("mark9", tc);
83
+ // createPortal(tc, subject.domRoot);
81
84
  });
82
85
  },
83
- andWhen: function (s, whenCB) {
86
+ andWhen: function (s, whenCB, tr, utils) {
84
87
  return new Promise((resolve, rej) => {
85
- process.nextTick(() => {
86
- resolve(whenCB()(s));
87
- });
88
+ console.log("mark9", s, whenCB);
89
+ resolve(whenCB(s, utils));
90
+ // process.nextTick(() => {
91
+ // resolve(whenCB()(s));
92
+ // });
88
93
  });
89
94
  },
90
- butThen: async function (s) {
95
+ butThen: async function (s, thenCB) {
91
96
  return new Promise((resolve, rej) => {
92
- process.nextTick(() => {
93
- resolve(s);
94
- });
97
+ resolve(thenCB(s));
95
98
  });
96
99
  },
97
100
  afterEach: async function (store, ndx, artificer) {
98
101
  return new Promise((resolve, rej) => {
99
- process.nextTick(() => {
100
- resolve({});
101
- });
102
+ resolve({});
102
103
  });
103
104
  },
104
105
  afterAll: (store, artificer) => {
105
106
  return new Promise((resolve, rej) => {
106
- process.nextTick(() => {
107
- resolve({});
108
- });
107
+ resolve({});
109
108
  });
110
109
  },
111
110
  });
@@ -6,18 +6,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const fs_1 = __importDefault(require("fs"));
7
7
  const path_1 = __importDefault(require("path"));
8
8
  exports.default = (platform, entryPoints) => {
9
+ console.log("mark3", platform);
9
10
  return {
10
11
  name: "metafileWriter",
11
12
  setup(build) {
12
13
  build.onEnd((result) => {
13
14
  if (result.errors.length === 0) {
14
15
  entryPoints.forEach((entryPoint) => {
16
+ console.log("mark1", entryPoint);
15
17
  const filePath = path_1.default.join("./docs/", platform, entryPoint.split(".").slice(0, -1).join("."), `inputFiles.json`);
16
18
  const dirName = path_1.default.dirname(filePath);
17
19
  if (!fs_1.default.existsSync(dirName)) {
18
20
  fs_1.default.mkdirSync(dirName, { recursive: true });
19
21
  }
20
- fs_1.default.writeFileSync(filePath, JSON.stringify(Object.keys(Object.keys(result.metafile.outputs)
22
+ const jsonContent = JSON.stringify(Object.keys(Object.keys(result.metafile.outputs)
21
23
  .filter((s) => {
22
24
  if (!result.metafile.outputs[s].entryPoint) {
23
25
  return false;
@@ -40,7 +42,8 @@ exports.default = (platform, entryPoints) => {
40
42
  const matches = f.match(regex);
41
43
  const passes = (matches === null || matches === void 0 ? void 0 : matches.length) === 1;
42
44
  return !passes;
43
- })));
45
+ }));
46
+ fs_1.default.writeFileSync(filePath, jsonContent);
44
47
  });
45
48
  }
46
49
  });
@@ -4,9 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const index_js_1 = __importDefault(require("./index.js"));
7
- const inputFilesPlugin_1 = __importDefault(require("./inputFilesPlugin"));
7
+ const inputFilesPlugin_js_1 = __importDefault(require("./inputFilesPlugin.js"));
8
8
  exports.default = (config, entryPoints) => {
9
- return Object.assign(Object.assign({}, (0, index_js_1.default)(config)), { splitting: true, outdir: config.outdir + "/node", inject: [`./node_modules/testeranto/dist/cjs-shim.js`], metafile: true, supported: {
9
+ return Object.assign(Object.assign({}, (0, index_js_1.default)(config)), { splitting: true, outdir: config.outdir + "/node",
10
+ // inject: [`./node_modules/testeranto/dist/cjs-shim.js`],
11
+ metafile: true, supported: {
10
12
  "dynamic-import": true,
11
13
  }, define: {
12
14
  "process.env.FLUENTFFMPEG_COV": "0",
@@ -21,7 +23,7 @@ exports.default = (config, entryPoints) => {
21
23
  ...config.externals,
22
24
  ], entryPoints: [...entryPoints], plugins: [
23
25
  ...(config.nodePlugins || []),
24
- (0, inputFilesPlugin_1.default)("node", entryPoints),
26
+ (0, inputFilesPlugin_js_1.default)("node", entryPoints),
25
27
  {
26
28
  name: "rebuild-notify",
27
29
  setup(build) {
@@ -39,7 +39,7 @@ exports.default = (config, entryPoints) => {
39
39
  "dns",
40
40
  ], platform: "browser", entryPoints: [...entryPoints], plugins: [
41
41
  ...(config.webPlugins || []),
42
- (0, inputFilesPlugin_js_1.default)("node", entryPoints),
42
+ (0, inputFilesPlugin_js_1.default)("web", entryPoints),
43
43
  {
44
44
  name: "rebuild-notify",
45
45
  setup(build) {