@testspectra/cli 1.0.70 → 1.1.0-rc.1

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 (427) hide show
  1. package/LICENSE.md +48 -0
  2. package/README.md +36 -270
  3. package/bin/.testspectra-runner.hash +1 -0
  4. package/bin/spectra.js +1 -1
  5. package/bin/testspectra-runner +0 -0
  6. package/demo-app/assets/index-BhlW-eXG.css +1 -0
  7. package/demo-app/assets/index-DOtRypCa.js +154 -0
  8. package/demo-app/index.html +2 -2
  9. package/dist/.tsbuildinfo +1 -0
  10. package/dist/commands/__tests__/doctor.test.d.ts +1 -0
  11. package/dist/commands/__tests__/doctor.test.js +39 -0
  12. package/dist/commands/__tests__/init.test.d.ts +1 -0
  13. package/dist/commands/__tests__/init.test.js +148 -0
  14. package/dist/commands/__tests__/license.test.d.ts +1 -0
  15. package/dist/commands/__tests__/license.test.js +13 -0
  16. package/dist/commands/__tests__/refactor.test.d.ts +1 -0
  17. package/dist/commands/__tests__/refactor.test.js +64 -0
  18. package/dist/commands/__tests__/run-e2e.test.d.ts +1 -0
  19. package/dist/commands/__tests__/run-e2e.test.js +422 -0
  20. package/dist/commands/__tests__/run.test.d.ts +1 -0
  21. package/dist/commands/__tests__/run.test.js +273 -0
  22. package/dist/commands/__tests__/watch.test.d.ts +1 -0
  23. package/dist/commands/__tests__/watch.test.js +155 -0
  24. package/dist/commands/add.js +86 -85
  25. package/dist/commands/demo.js +21 -11
  26. package/dist/commands/devices.d.ts +14 -2
  27. package/dist/commands/devices.js +44 -34
  28. package/dist/commands/doctor.d.ts +3 -1
  29. package/dist/commands/doctor.js +43 -264
  30. package/dist/commands/init.d.ts +1 -1
  31. package/dist/commands/init.js +211 -196
  32. package/dist/commands/install.d.ts +4 -0
  33. package/dist/commands/install.js +59 -0
  34. package/dist/commands/license.d.ts +4 -0
  35. package/dist/commands/license.js +30 -0
  36. package/dist/commands/lint.d.ts +5 -0
  37. package/dist/commands/lint.js +55 -0
  38. package/dist/commands/refactor.d.ts +9 -0
  39. package/dist/commands/refactor.js +172 -0
  40. package/dist/commands/run.d.ts +23 -2
  41. package/dist/commands/run.js +322 -111
  42. package/dist/commands/skills.d.ts +9 -0
  43. package/dist/commands/skills.js +28 -0
  44. package/dist/commands/sync-types.d.ts +4 -0
  45. package/dist/commands/sync-types.js +15 -0
  46. package/dist/commands/test.d.ts +17 -0
  47. package/dist/commands/test.js +76 -0
  48. package/dist/commands/update.js +39 -43
  49. package/dist/commands/watch.d.ts +6 -0
  50. package/dist/commands/watch.js +55 -45
  51. package/dist/config/loader.d.ts +1 -1
  52. package/dist/config/loader.js +40 -25
  53. package/dist/config/schema.d.ts +104 -145
  54. package/dist/config/schema.js +36 -45
  55. package/dist/generator/__tests__/tsconfig-isolation.test.d.ts +1 -0
  56. package/dist/generator/__tests__/tsconfig-isolation.test.js +282 -0
  57. package/dist/generator/__tests__/type-generator.test.d.ts +1 -0
  58. package/dist/generator/__tests__/type-generator.test.js +386 -0
  59. package/dist/generator/index.d.ts +2 -0
  60. package/dist/generator/index.js +2 -0
  61. package/dist/generator/tsconfig-generator.d.ts +27 -0
  62. package/dist/generator/tsconfig-generator.js +419 -0
  63. package/dist/generator/type-generator.d.ts +59 -0
  64. package/dist/generator/type-generator.js +740 -0
  65. package/dist/index.d.ts +9 -5
  66. package/dist/index.js +165 -51
  67. package/dist/lifecycle/__tests__/lifecycle-engine.test.d.ts +1 -0
  68. package/dist/lifecycle/__tests__/lifecycle-engine.test.js +290 -0
  69. package/dist/lifecycle/hook-discovery.d.ts +24 -0
  70. package/dist/lifecycle/hook-discovery.js +60 -0
  71. package/dist/lifecycle/hook-dispatcher.d.ts +34 -0
  72. package/dist/lifecycle/hook-dispatcher.js +190 -0
  73. package/dist/lifecycle/index.d.ts +3 -0
  74. package/dist/lifecycle/index.js +3 -0
  75. package/dist/lifecycle/parallel-grouping.d.ts +27 -0
  76. package/dist/lifecycle/parallel-grouping.js +151 -0
  77. package/dist/linter/__tests__/anonymous-export.test.d.ts +1 -0
  78. package/dist/linter/__tests__/anonymous-export.test.js +184 -0
  79. package/dist/linter/__tests__/component-test-imports.test.d.ts +1 -0
  80. package/dist/linter/__tests__/component-test-imports.test.js +115 -0
  81. package/dist/linter/__tests__/shared-lib-boundary.test.d.ts +1 -0
  82. package/dist/linter/__tests__/shared-lib-boundary.test.js +270 -0
  83. package/dist/linter/__tests__/spec-schema.test.d.ts +1 -0
  84. package/dist/linter/__tests__/spec-schema.test.js +369 -0
  85. package/dist/linter/__tests__/step-parity.test.d.ts +1 -0
  86. package/dist/linter/__tests__/step-parity.test.js +372 -0
  87. package/dist/linter/discovery.d.ts +30 -0
  88. package/dist/linter/discovery.js +249 -0
  89. package/dist/linter/extractor.d.ts +67 -0
  90. package/dist/linter/extractor.js +245 -0
  91. package/dist/linter/index.d.ts +7 -0
  92. package/dist/linter/index.js +7 -0
  93. package/dist/linter/parser.d.ts +24 -0
  94. package/dist/linter/parser.js +219 -0
  95. package/dist/linter/schemas/spec.schema.d.ts +83 -0
  96. package/dist/linter/schemas/spec.schema.js +150 -0
  97. package/dist/linter/schemas/suite.schema.d.ts +59 -0
  98. package/dist/linter/schemas/suite.schema.js +83 -0
  99. package/dist/linter/spec-linter.d.ts +23 -0
  100. package/dist/linter/spec-linter.js +630 -0
  101. package/dist/linter/types.d.ts +28 -0
  102. package/dist/linter/types.js +1 -0
  103. package/dist/mobile/__tests__/android-device-e2e.test.d.ts +1 -0
  104. package/dist/mobile/__tests__/android-device-e2e.test.js +53 -0
  105. package/dist/mobile/__tests__/device-pool.test.d.ts +1 -0
  106. package/dist/mobile/__tests__/device-pool.test.js +97 -0
  107. package/dist/mobile/device-pool.d.ts +23 -0
  108. package/dist/mobile/device-pool.js +1 -0
  109. package/dist/mobile/index.d.ts +1 -0
  110. package/dist/mobile/index.js +1 -0
  111. package/dist/refactor/__tests__/refactor-engine.test.d.ts +1 -0
  112. package/dist/refactor/__tests__/refactor-engine.test.js +873 -0
  113. package/dist/refactor/index.d.ts +1 -0
  114. package/dist/refactor/index.js +1 -0
  115. package/dist/refactor/refactor-engine.d.ts +50 -0
  116. package/dist/refactor/refactor-engine.js +587 -0
  117. package/dist/reporter/__tests__/semantic-formatter.test.d.ts +1 -0
  118. package/dist/reporter/__tests__/semantic-formatter.test.js +73 -0
  119. package/dist/reporter/semantic-formatter.d.ts +6 -0
  120. package/dist/reporter/semantic-formatter.js +206 -0
  121. package/dist/reporter/summary-view.d.ts +12 -0
  122. package/dist/reporter/summary-view.js +19 -0
  123. package/dist/reporter/terminal-stream.d.ts +32 -0
  124. package/dist/reporter/terminal-stream.js +82 -0
  125. package/dist/reporter/types.d.ts +2 -0
  126. package/dist/reporter/types.js +1 -0
  127. package/dist/runner/bridge.d.ts +10 -5
  128. package/dist/runner/bridge.js +101 -45
  129. package/dist/runner/reporter.d.ts +32 -2
  130. package/dist/runner/reporter.js +427 -13
  131. package/dist/server/demo.js +43 -44
  132. package/dist/types/generator.d.ts +1 -17
  133. package/dist/types/generator.js +1 -443
  134. package/dist/utils/__tests__/api-server.test.d.ts +1 -0
  135. package/dist/utils/__tests__/api-server.test.js +62 -0
  136. package/dist/utils/__tests__/demo-server.test.d.ts +1 -0
  137. package/dist/utils/__tests__/demo-server.test.js +35 -0
  138. package/dist/utils/api-server.d.ts +19 -0
  139. package/dist/utils/api-server.js +179 -0
  140. package/dist/utils/demo-server.d.ts +5 -0
  141. package/dist/utils/demo-server.js +46 -36
  142. package/package.json +25 -13
  143. package/templates/default/CLAUDE.md +12 -5
  144. package/templates/default/fixtures/apiData.json +24 -0
  145. package/templates/default/package.json +12 -3
  146. package/templates/default/page-objects/AuthPage/mobile.ts +5 -0
  147. package/templates/default/page-objects/AuthPage/web.ts +10 -0
  148. package/templates/default/page-objects/MatchersPage/mobile.ts +66 -17
  149. package/templates/default/page-objects/MatchersPage/web.ts +22 -2
  150. package/templates/default/page-objects/NavigationPage/mobile.ts +11 -2
  151. package/templates/default/page-objects/NavigationPage/web.ts +1 -1
  152. package/templates/default/page-objects/PlaygroundPage/mobile.ts +34 -18
  153. package/templates/default/page-objects/PlaygroundPage/web.ts +4 -2
  154. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +53 -0
  155. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +19 -0
  156. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +31 -0
  157. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/android.test.ts +3 -0
  158. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/common.test.ts +3 -0
  159. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +27 -0
  160. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +19 -0
  161. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +26 -0
  162. package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/common.test.ts +30 -0
  163. package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/spec.md +22 -0
  164. package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/common.test.ts +27 -0
  165. package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/spec.md +20 -0
  166. package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/spec.md +24 -0
  167. package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/web.test.ts +26 -0
  168. package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/spec.md +37 -0
  169. package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/web.test.ts +21 -0
  170. package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/spec.md +29 -0
  171. package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/web.test.ts +16 -0
  172. package/templates/default/specs/ApiInterception/suite.md +10 -0
  173. package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/common.test.ts +30 -0
  174. package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/spec.md +23 -0
  175. package/templates/default/specs/ApiSeeding/hooks/after/common.hook.ts +16 -0
  176. package/templates/default/specs/ApiSeeding/hooks/before/common.hook.ts +28 -0
  177. package/templates/default/specs/ApiSeeding/suite.md +9 -0
  178. package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/mobile.test.ts +7 -0
  179. package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/spec.md +19 -0
  180. package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/web.test.ts +9 -0
  181. package/templates/default/specs/Authentication/suite.md +9 -0
  182. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +7 -1
  183. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +5 -0
  184. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
  185. package/templates/default/specs/BrowserContext/TC-0022-history-navigation/mobile.test.ts +17 -0
  186. package/templates/default/specs/BrowserContext/TC-0022-history-navigation/spec.md +28 -0
  187. package/templates/default/specs/BrowserContext/TC-0022-history-navigation/web.test.ts +26 -0
  188. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/common.test.ts +26 -0
  189. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/spec.md +7 -0
  190. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +9 -1
  191. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +5 -0
  192. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +9 -4
  193. package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/common.test.ts +14 -0
  194. package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/spec.md +21 -0
  195. package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/mobile.test.ts +28 -0
  196. package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/spec.md +29 -0
  197. package/templates/default/specs/DeepLink/suite.md +9 -0
  198. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +9 -1
  199. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +5 -0
  200. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
  201. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +27 -1
  202. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +7 -0
  203. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
  204. package/templates/default/specs/ElementMatchers/suite.md +2 -1
  205. package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -0
  206. package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -0
  207. package/templates/default/specs/EnvironmentConfig/suite.md +9 -0
  208. package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/mobile.test.ts +26 -0
  209. package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/spec.md +22 -0
  210. package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/mobile.test.ts +13 -0
  211. package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/spec.md +20 -0
  212. package/templates/default/specs/PermissionRationale/suite.md +9 -0
  213. package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +4 -1
  214. package/templates/default/specs/Playground/TC-0001-form-controls/spec.md +6 -0
  215. package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +4 -4
  216. package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +4 -1
  217. package/templates/default/specs/Playground/TC-0002-toggle-elements/spec.md +6 -0
  218. package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +3 -3
  219. package/templates/default/spectra.config.ts +22 -31
  220. package/templates/default/support/actions/fillCredentials/mobile.action.ts +3 -3
  221. package/templates/default/support/actions/fillCredentials/web.action.ts +1 -1
  222. package/templates/default/support/actions/seedSession/mobile.action.ts +9 -0
  223. package/templates/default/support/actions/seedSession/web.action.ts +13 -0
  224. package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +3 -1
  225. package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +3 -3
  226. package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +4 -2
  227. package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +4 -4
  228. package/templates/default/tsconfig.json +3 -1
  229. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db +0 -0
  230. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-shm +0 -0
  231. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-wal +0 -0
  232. package/templates/nx/.nx/workspace-data/d/daemon.log +5366 -0
  233. package/templates/nx/.nx/workspace-data/d/server-process.json +3 -0
  234. package/templates/nx/.nx/workspace-data/file-map.json +464 -0
  235. package/templates/nx/.nx/workspace-data/lockfile.hash +1 -0
  236. package/templates/nx/.nx/workspace-data/nx_files.nxt +0 -0
  237. package/templates/nx/.nx/workspace-data/parsed-lock-file.json +13485 -0
  238. package/templates/nx/.nx/workspace-data/project-graph.json +14389 -0
  239. package/templates/nx/CLAUDE.md +2 -2
  240. package/templates/nx/package.json +6 -4
  241. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +27 -0
  242. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
  243. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
  244. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +24 -0
  245. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
  246. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
  247. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/suite.md +9 -0
  248. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +1 -1
  249. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
  250. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +1 -1
  251. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +15 -5
  252. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +1 -1
  253. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +9 -4
  254. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +1 -1
  255. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
  256. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +1 -1
  257. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
  258. package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -0
  259. package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -0
  260. package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/suite.md +9 -0
  261. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/mobile.test.ts +1 -1
  262. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +4 -4
  263. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +1 -1
  264. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +3 -3
  265. package/templates/nx/pnpm-lock.yaml +6663 -0
  266. package/templates/nx/pnpm-workspace.yaml +2 -1
  267. package/templates/nx/shared/testing/fixtures/apiData.json +24 -0
  268. package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +13 -1
  269. package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +85 -17
  270. package/templates/nx/shared/testing/page-objects/NavigationPage/mobile.ts +1 -1
  271. package/templates/nx/shared/testing/page-objects/NavigationPage/web.ts +1 -1
  272. package/templates/nx/shared/testing/page-objects/PlaygroundPage/mobile.ts +1 -1
  273. package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +4 -2
  274. package/templates/nx/shared/testing/project.json +19 -0
  275. package/templates/nx/shared/testing/support/actions/fillCredentials/mobile.action.ts +1 -1
  276. package/templates/nx/shared/testing/support/actions/fillCredentials/web.action.ts +1 -1
  277. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/mobile.step.ts +1 -1
  278. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +3 -3
  279. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +2 -2
  280. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +4 -4
  281. package/templates/nx/spectra.config.ts +20 -29
  282. package/templates/nx/tsconfig.json +3 -1
  283. package/templates/react-component/.cursorrules +17 -0
  284. package/templates/react-component/.vscode/extensions.json +5 -0
  285. package/templates/react-component/CLAUDE.md +14 -0
  286. package/templates/react-component/README.md +69 -0
  287. package/templates/react-component/fixtures/component-mock.json +12 -0
  288. package/templates/react-component/global-hooks/after/web.hook.ts +3 -0
  289. package/templates/react-component/global-hooks/before/web.hook.ts +3 -0
  290. package/templates/react-component/package.json +27 -0
  291. package/templates/react-component/page-objects/BadgeComponent/web.ts +23 -0
  292. package/templates/react-component/page-objects/ButtonComponent/web.ts +23 -0
  293. package/templates/react-component/page-objects/InputComponent/web.ts +13 -0
  294. package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/spec.md +18 -0
  295. package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/web.test.tsx +11 -0
  296. package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/spec.md +18 -0
  297. package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/web.test.tsx +10 -0
  298. package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/spec.md +18 -0
  299. package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/web.test.tsx +16 -0
  300. package/templates/react-component/specs/BadgeComponent/suite.md +12 -0
  301. package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/spec.md +19 -0
  302. package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/web.test.tsx +28 -0
  303. package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/spec.md +19 -0
  304. package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/web.test.tsx +22 -0
  305. package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/spec.md +18 -0
  306. package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/web.test.tsx +8 -0
  307. package/templates/react-component/specs/ButtonComponent/suite.md +12 -0
  308. package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/spec.md +20 -0
  309. package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/web.test.tsx +28 -0
  310. package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/spec.md +18 -0
  311. package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/web.test.tsx +9 -0
  312. package/templates/react-component/specs/InputComponent/suite.md +12 -0
  313. package/templates/react-component/spectra.config.ts +27 -0
  314. package/templates/react-component/src/components/Badge/Badge.tsx +60 -0
  315. package/templates/react-component/src/components/Button/Button.tsx +57 -0
  316. package/templates/react-component/src/components/Input/Input.tsx +41 -0
  317. package/templates/react-component/src/test-utils.tsx +23 -0
  318. package/templates/react-component/support/actions/fillInputField/web.action.ts +9 -0
  319. package/templates/react-component/support/steps/verifyButtonState/web.step.ts +12 -0
  320. package/templates/react-component/tsconfig.json +8 -0
  321. package/demo-app/assets/index-DAUlrHTr.css +0 -1
  322. package/demo-app/assets/index-DN2Kb0A8.js +0 -100
  323. package/dist/index.cjs +0 -101
  324. package/dist/plugin.cjs +0 -575
  325. package/dist/plugin.d.ts +0 -16
  326. package/dist/plugin.js +0 -184
  327. package/dist/step/index.d.ts +0 -6
  328. package/dist/step/index.js +0 -6
  329. package/dist/step/matchers.d.ts +0 -14
  330. package/dist/step/matchers.js +0 -114
  331. package/dist/step/proto.d.ts +0 -46
  332. package/dist/step/proto.js +0 -114
  333. package/dist/step/runner/collection.d.ts +0 -13
  334. package/dist/step/runner/collection.js +0 -51
  335. package/dist/step/runner/single.d.ts +0 -21
  336. package/dist/step/runner/single.js +0 -138
  337. package/dist/step/spectra.d.ts +0 -34
  338. package/dist/step/spectra.js +0 -156
  339. package/dist/step/types.d.ts +0 -32
  340. package/dist/step/types.js +0 -5
  341. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
  342. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
  343. package/templates/default/tsconfig.spectra.android.json +0 -46
  344. package/templates/default/tsconfig.spectra.ios.json +0 -46
  345. package/templates/default/tsconfig.spectra.json +0 -22
  346. package/templates/default/tsconfig.spectra.web.json +0 -53
  347. package/templates/nx/fixtures/playgroundData.json +0 -7
  348. package/templates/nx/global-hooks/after/mobile.hook.ts +0 -3
  349. package/templates/nx/global-hooks/after/web.hook.ts +0 -3
  350. package/templates/nx/global-hooks/before/mobile.hook.ts +0 -3
  351. package/templates/nx/global-hooks/before/web.hook.ts +0 -3
  352. package/templates/nx/page-objects/MatchersPage/mobile.ts +0 -21
  353. package/templates/nx/page-objects/MatchersPage/web.ts +0 -23
  354. package/templates/nx/page-objects/NavigationPage/mobile.ts +0 -5
  355. package/templates/nx/page-objects/NavigationPage/web.ts +0 -8
  356. package/templates/nx/page-objects/PlaygroundPage/mobile.ts +0 -26
  357. package/templates/nx/page-objects/PlaygroundPage/web.ts +0 -29
  358. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +0 -3
  359. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +0 -12
  360. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +0 -5
  361. package/templates/nx/specs/BrowserContext/suite.md +0 -9
  362. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
  363. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/spec.md +0 -12
  364. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
  365. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +0 -3
  366. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +0 -12
  367. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +0 -6
  368. package/templates/nx/specs/ContentMatchers/suite.md +0 -9
  369. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +0 -3
  370. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +0 -12
  371. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +0 -5
  372. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +0 -3
  373. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +0 -12
  374. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +0 -8
  375. package/templates/nx/specs/ElementMatchers/hooks/after/mobile.hook.ts +0 -1
  376. package/templates/nx/specs/ElementMatchers/hooks/after/web.hook.ts +0 -1
  377. package/templates/nx/specs/ElementMatchers/hooks/afterEach/mobile.hook.ts +0 -1
  378. package/templates/nx/specs/ElementMatchers/hooks/afterEach/web.hook.ts +0 -1
  379. package/templates/nx/specs/ElementMatchers/hooks/before/mobile.hook.ts +0 -1
  380. package/templates/nx/specs/ElementMatchers/hooks/before/web.hook.ts +0 -1
  381. package/templates/nx/specs/ElementMatchers/hooks/beforeEach/mobile.hook.ts +0 -1
  382. package/templates/nx/specs/ElementMatchers/hooks/beforeEach/web.hook.ts +0 -1
  383. package/templates/nx/specs/ElementMatchers/suite.md +0 -9
  384. package/templates/nx/specs/Playground/TC-0001-form-controls/mobile.test.ts +0 -3
  385. package/templates/nx/specs/Playground/TC-0001-form-controls/spec.md +0 -12
  386. package/templates/nx/specs/Playground/TC-0001-form-controls/web.test.ts +0 -6
  387. package/templates/nx/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +0 -3
  388. package/templates/nx/specs/Playground/TC-0002-toggle-elements/spec.md +0 -12
  389. package/templates/nx/specs/Playground/TC-0002-toggle-elements/web.test.ts +0 -6
  390. package/templates/nx/specs/Playground/hooks/after/mobile.hook.ts +0 -1
  391. package/templates/nx/specs/Playground/hooks/after/web.hook.ts +0 -1
  392. package/templates/nx/specs/Playground/hooks/afterEach/mobile.hook.ts +0 -1
  393. package/templates/nx/specs/Playground/hooks/afterEach/web.hook.ts +0 -1
  394. package/templates/nx/specs/Playground/hooks/before/mobile.hook.ts +0 -1
  395. package/templates/nx/specs/Playground/hooks/before/web.hook.ts +0 -1
  396. package/templates/nx/specs/Playground/hooks/beforeEach/mobile.hook.ts +0 -1
  397. package/templates/nx/specs/Playground/hooks/beforeEach/web.hook.ts +0 -1
  398. package/templates/nx/specs/Playground/suite.md +0 -9
  399. package/templates/nx/support/actions/fillCredentials/mobile.action.ts +0 -4
  400. package/templates/nx/support/actions/fillCredentials/web.action.ts +0 -4
  401. package/templates/nx/support/steps/togglePlaygroundStates/mobile.step.ts +0 -3
  402. package/templates/nx/support/steps/togglePlaygroundStates/step.md +0 -7
  403. package/templates/nx/support/steps/togglePlaygroundStates/web.step.ts +0 -5
  404. package/templates/nx/support/steps/verifyPlaygroundState/mobile.step.ts +0 -4
  405. package/templates/nx/support/steps/verifyPlaygroundState/step.md +0 -7
  406. package/templates/nx/support/steps/verifyPlaygroundState/web.step.ts +0 -6
  407. package/templates/nx/tsconfig.spectra.android.json +0 -39
  408. package/templates/nx/tsconfig.spectra.ios.json +0 -39
  409. package/templates/nx/tsconfig.spectra.json +0 -25
  410. package/templates/nx/tsconfig.spectra.shared.json +0 -25
  411. package/templates/nx/tsconfig.spectra.web.json +0 -45
  412. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
  413. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
  414. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
  415. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
  416. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
  417. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
  418. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
  419. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
  420. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
  421. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
  422. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
  423. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
  424. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
  425. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
  426. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
  427. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
@@ -1,8 +1,9 @@
1
1
  packages:
2
- - "modules/**/*"
2
+ - "packages/**/*"
3
3
  - "shared/**/*"
4
4
  allowBuilds:
5
5
  chromedriver: true
6
6
  edgedriver: true
7
+ esbuild: true
7
8
  geckodriver: true
8
9
  nx: true
@@ -0,0 +1,24 @@
1
+ {
2
+ "mockPosts": [
3
+ {
4
+ "id": 1,
5
+ "title": "Mocked Post 1 - TestSpectra Matchers",
6
+ "body": "First mocked post body for verifying GET API interception in TestSpectra."
7
+ },
8
+ {
9
+ "id": 2,
10
+ "title": "Mocked Post 2 - Cross-Platform Automation",
11
+ "body": "Second mocked post body for verifying collection and item assertions."
12
+ }
13
+ ],
14
+ "mockNewPost": {
15
+ "title": "TestSpectra Automated Post",
16
+ "body": "End-to-End API mock verification with browser.intercept command."
17
+ },
18
+ "mockPostResponse": {
19
+ "id": 101,
20
+ "title": "TestSpectra Automated Post",
21
+ "body": "End-to-End API mock verification with browser.intercept command.",
22
+ "userId": 1
23
+ }
24
+ }
@@ -1,4 +1,4 @@
1
- export class MatchersPage {
1
+ class MatchersPage {
2
2
  get visibleElement() { return Spectra.get("~visible_element"); }
3
3
  get hiddenElement() { return Spectra.get("~hidden_element"); }
4
4
  get existingElement() { return Spectra.get("~existing_element"); }
@@ -15,6 +15,18 @@ export class MatchersPage {
15
15
  get productCards() { return Spectra.getAll("~product_card"); }
16
16
  get emptyList() { return Spectra.getAll("~empty_list"); }
17
17
 
18
+ // API Demo elements
19
+ get fetchApiButton() { return Spectra.get("~fetch_api_btn"); }
20
+ get fetchStatusBadge() { return Spectra.get("~fetch_status_badge"); }
21
+ get fetchedItems() { return Spectra.getAll("~api_fetched_item"); }
22
+ get fetchLoadingIndicator() { return Spectra.get("~fetch_loading_indicator"); }
23
+ get postTitleInput() { return Spectra.get("~post_input_title"); }
24
+ get postBodyInput() { return Spectra.get("~post_input_body"); }
25
+ get submitPostButton() { return Spectra.get("~submit_post_btn"); }
26
+ get postStatusBadge() { return Spectra.get("~post_status_badge"); }
27
+ get postSuccessBanner() { return Spectra.get("~post_success_banner"); }
28
+ get postResponseJson() { return Spectra.get("~post_response_json"); }
29
+
18
30
  async open(_section = "") {}
19
31
  }
20
32
 
@@ -1,22 +1,90 @@
1
- export class MatchersPage {
2
- get visibleElement() { return Spectra.get("#demo-visible-el"); }
3
- get hiddenElement() { return Spectra.get("#demo-hidden-el"); }
4
- get existingElement() { return Spectra.get("#demo-existing-el"); }
5
- get submitButton() { return Spectra.get("#demo-submit-btn"); }
6
- get disabledButton() { return Spectra.get("#demo-disabled-btn"); }
7
- get checkbox() { return Spectra.get("#demo-checkbox"); }
8
- get radio() { return Spectra.get("#demo-radio"); }
9
- get emailInput() { return Spectra.get("#demo-email-input"); }
10
- get tokenInput() { return Spectra.get("#demo-token-input"); }
11
- get exactText() { return Spectra.get("#demo-exact-text"); }
12
- get partialText() { return Spectra.get("#demo-partial-text"); }
13
- get activeTab() { return Spectra.get("#demo-active-tab"); }
14
- get navLink() { return Spectra.get("#demo-nav-link"); }
15
- get productCards() { return Spectra.getAll(".demo-product-card"); }
16
- get emptyList() { return Spectra.getAll("#demo-empty-list > *"); }
1
+ class MatchersPage {
2
+ get visibleElement() {
3
+ return Spectra.get("#demo-visible-el");
4
+ }
5
+ get hiddenElement() {
6
+ return Spectra.get("#demo-hidden-el");
7
+ }
8
+ get existingElement() {
9
+ return Spectra.get("#demo-existing-el");
10
+ }
11
+ get submitButton() {
12
+ return Spectra.get("#demo-submit-btn");
13
+ }
14
+ get disabledButton() {
15
+ return Spectra.get("#demo-disabled-btn");
16
+ }
17
+ get checkbox() {
18
+ return Spectra.get("#demo-checkbox");
19
+ }
20
+ get radio() {
21
+ return Spectra.get("#demo-radio");
22
+ }
23
+ get emailInput() {
24
+ return Spectra.get("#demo-email-input");
25
+ }
26
+ get tokenInput() {
27
+ return Spectra.get("#demo-token-input");
28
+ }
29
+ get exactText() {
30
+ return Spectra.get("#demo-exact-text");
31
+ }
32
+ get partialText() {
33
+ return Spectra.get("#demo-partial-text");
34
+ }
35
+ get activeTab() {
36
+ return Spectra.get("#demo-active-tab");
37
+ }
38
+ get navLink() {
39
+ return Spectra.get("#demo-nav-link");
40
+ }
41
+ get styledElement() {
42
+ return Spectra.get("#demo-styled-el");
43
+ }
44
+ get focusInput() {
45
+ return Spectra.get("#demo-focus-input");
46
+ }
47
+ get productCards() {
48
+ return Spectra.getAll(".demo-product-card");
49
+ }
50
+ get emptyList() {
51
+ return Spectra.getAll("#demo-empty-list > *");
52
+ }
53
+
54
+ // API Interception & Mocking elements
55
+ get fetchApiButton() {
56
+ return Spectra.get("#fetch-api-btn");
57
+ }
58
+ get fetchStatusBadge() {
59
+ return Spectra.get("#fetch-status-badge");
60
+ }
61
+ get fetchedItems() {
62
+ return Spectra.getAll(".api-fetched-item");
63
+ }
64
+ get fetchLoadingIndicator() {
65
+ return Spectra.get("#fetch-loading-indicator");
66
+ }
67
+ get postTitleInput() {
68
+ return Spectra.get("#post-input-title");
69
+ }
70
+ get postBodyInput() {
71
+ return Spectra.get("#post-input-body");
72
+ }
73
+ get submitPostButton() {
74
+ return Spectra.get("#submit-post-btn");
75
+ }
76
+ get postStatusBadge() {
77
+ return Spectra.get("#post-status-badge");
78
+ }
79
+ get postSuccessBanner() {
80
+ return Spectra.get("#post-success-banner");
81
+ }
82
+ get postResponseJson() {
83
+ return Spectra.get("#post-response-json");
84
+ }
17
85
 
18
86
  async open(section = "") {
19
- await browser.url("/" + (section ? "#" + section : ""));
87
+ await Spectra.navigate("/" + (section ? "#" + section : ""));
20
88
  }
21
89
  }
22
90
 
@@ -1,4 +1,4 @@
1
- export class NavigationPage {
1
+ class NavigationPage {
2
2
  get sidebarLinks() { return Spectra.getAll("~sidebar_link"); }
3
3
  }
4
4
 
@@ -1,4 +1,4 @@
1
- export class NavigationPage {
1
+ class NavigationPage {
2
2
  get sidebarLinks() { return Spectra.getAll("aside a"); }
3
3
  get overviewLink() { return Spectra.get("aside a[href='#overview']"); }
4
4
  get visibilityLink() { return Spectra.get("aside a[href='#visibility']"); }
@@ -1,4 +1,4 @@
1
- export class PlaygroundPage {
1
+ class PlaygroundPage {
2
2
  get visibleElement() { return Spectra.get("~visible_element"); }
3
3
  get hiddenElement() { return Spectra.get("~hidden_element"); }
4
4
  get existingElement() { return Spectra.get("~existing_element"); }
@@ -1,4 +1,4 @@
1
- export class PlaygroundPage {
1
+ class PlaygroundPage {
2
2
  get visibleElement() { return Spectra.get("#demo-visible-el-pg"); }
3
3
  get hiddenElement() { return Spectra.get("#demo-hidden-el-pg"); }
4
4
  get existingElement() { return Spectra.get("#demo-existing-el-pg"); }
@@ -13,11 +13,13 @@ export class PlaygroundPage {
13
13
  get partialText() { return Spectra.get("#demo-partial-text-pg"); }
14
14
  get activeTab() { return Spectra.get("#demo-active-tab-pg"); }
15
15
  get navLink() { return Spectra.get("#demo-nav-link-pg"); }
16
+ get styledElement() { return Spectra.get("#demo-styled-el-pg"); }
17
+ get focusInput() { return Spectra.get("#demo-focus-input-pg"); }
16
18
  get productItems() { return Spectra.getAll(".demo-product-item"); }
17
19
  get emptyList() { return Spectra.getAll("#demo-empty-list-pg > *"); }
18
20
 
19
21
  async open() {
20
- await browser.url("/#playground");
22
+ await Spectra.navigate("/#playground");
21
23
  }
22
24
 
23
25
  async fillCredentials(email = Fixture.playgroundData.defaultEmail, token = Fixture.playgroundData.defaultToken) {
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "shared-testing",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "projectType": "library",
5
+ "sourceRoot": "shared/testing",
6
+ "targets": {
7
+ "type-check": {
8
+ "executor": "nx:run-commands",
9
+ "options": {
10
+ "command": "tsc -b",
11
+ "cwd": "."
12
+ }
13
+ }
14
+ },
15
+ "tags": [
16
+ "scope:shared",
17
+ "type:shared"
18
+ ]
19
+ }
@@ -1,4 +1,4 @@
1
- export default async function fillCredentials(this: any, email: string, token: string) {
1
+ export default async function (this: any, email: string, token: string) {
2
2
  await this.get("~email_input").type(email);
3
3
  await this.get("~token_input").type(token);
4
4
  }
@@ -1,4 +1,4 @@
1
- export default async function fillCredentials(this: any, email: string, token: string) {
1
+ export default async function (this: any, email: string, token: string) {
2
2
  await this.get("#demo-email-input-pg").type(email);
3
3
  await this.get("#demo-token-input-pg").type(token);
4
4
  }
@@ -1,3 +1,3 @@
1
- export default async function togglePlaygroundStates() {
1
+ export default async function () {
2
2
  await PlaygroundPage.open();
3
3
  }
@@ -1,5 +1,5 @@
1
- export default async function togglePlaygroundStates() {
1
+ export default async function () {
2
2
  await PlaygroundPage.open();
3
- await PlaygroundPage.hiddenElement.should("be.visible");
4
- await PlaygroundPage.existingElement.should("exist");
3
+ await PlaygroundPage.hiddenElement.shouldBeVisible();
4
+ await PlaygroundPage.existingElement.shouldExist();
5
5
  }
@@ -1,4 +1,4 @@
1
- export default async function verifyPlaygroundState() {
1
+ export default async function () {
2
2
  await PlaygroundPage.open();
3
- await PlaygroundPage.visibleElement.should("be.visible");
3
+ await PlaygroundPage.visibleElement.shouldBeVisible();
4
4
  }
@@ -1,6 +1,6 @@
1
- export default async function verifyPlaygroundState() {
1
+ export default async function () {
2
2
  await PlaygroundPage.open();
3
- await PlaygroundPage.visibleElement.should("be.visible");
4
- await PlaygroundPage.enabledButton.should("be.enabled");
5
- await PlaygroundPage.termsCheckbox.should("be.checked");
3
+ await PlaygroundPage.visibleElement.shouldBeVisible();
4
+ await PlaygroundPage.enabledButton.shouldBeEnabled();
5
+ await PlaygroundPage.termsCheckbox.shouldBeChecked();
6
6
  }
@@ -4,58 +4,49 @@ export default defineConfig({
4
4
  webConfig: {
5
5
  baseUrl: "http://localhost:5173",
6
6
  maxConcurrentSessions: "1",
7
- headlessMode: true,
7
+ headless: true,
8
8
  implicitWait: "5000",
9
- pageLoadTimeout: "30000",
10
- scriptTimeout: "30000",
11
9
  parallelizationMode: "testcase",
12
10
  },
13
- browsers: [
14
- {
15
- id: "chrome-desktop",
16
- type: "chrome",
17
- mobileEmulation: false,
18
- },
19
- ],
20
11
  androidConfig: {
21
- appiumServer: "http://127.0.0.1:4723",
22
- platformName: "Android",
23
- platformVersion: "13",
24
- deviceName: "emulator-5554",
25
- automationName: "UiAutomator2",
12
+ driverServer: "tcp://127.0.0.1:8200",
26
13
  appPackage: "",
27
14
  appActivity: "",
28
- autoGrantPermissions: true,
29
15
  noReset: false,
30
16
  implicitWait: "10000",
31
17
  parallelizationMode: "suite",
18
+ devices: [
19
+ {
20
+ id: "emulator-5554",
21
+ name: "Pixel 7 Pro Emulator",
22
+ version: "14.0",
23
+ systemPort: 8200,
24
+ },
25
+ ],
32
26
  },
33
27
  iosConfig: {
34
28
  appiumServer: "http://127.0.0.1:4723",
35
- platformName: "iOS",
36
- platformVersion: "16.0",
37
- deviceName: "iPhone 14",
38
29
  automationName: "XCUITest",
39
30
  bundleId: "",
40
- udid: "auto",
41
- xcodeOrgId: "",
42
- xcodeSigningId: "iPhone Developer",
43
31
  autoAcceptAlerts: true,
44
32
  noReset: false,
45
33
  implicitWait: "10000",
46
34
  parallelizationMode: "suite",
35
+ devices: [
36
+ {
37
+ id: "iphone-15-pro",
38
+ name: "iPhone 15 Pro Simulator",
39
+ version: "17.0",
40
+ udid: "auto",
41
+ wdaLocalPort: 8100,
42
+ },
43
+ ],
47
44
  },
48
- loadConfig: {
49
- virtualUsers: "10",
50
- duration: "1m",
51
- },
52
- loadStages: [],
53
- thresholds: [],
54
45
  executionConfig: {
55
46
  networkMonitoringEnabled: true,
56
47
  fastResponseTime: "200",
57
48
  normalResponseTime: "1000",
58
49
  monitoredDomains: [],
59
- environmentVariables: [],
50
+ environmentVariables: { DEMO_API_MODE: "sandbox" },
60
51
  },
61
52
  });
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "files": [],
3
3
  "references": [
4
- { "path": "./tsconfig.spectra.json" }
4
+ {
5
+ "path": "./.testspectra/tsconfig.json"
6
+ }
5
7
  ]
6
8
  }
@@ -0,0 +1,17 @@
1
+ # TestSpectra AI Instructions for Cursor
2
+
3
+ You are developing automated tests and React components with the TestSpectra testing framework.
4
+
5
+ ## Key Rules & Conventions
6
+ 1. **Zero-Import Standard**: Never add manual `import` statements for Page/Component Objects (`ButtonComponent`, `BadgeComponent`, `InputComponent`), Steps (`Step.*`), Fixtures (`Fixture.*`), or Actions (`Spectra.*`). All typings are provided globally and ambiently via `.testspectra/types/`.
7
+ 2. **Component Testing Pattern**: Mount React components using `await Spectra.mount(<Component />)` (real JSX and static component imports are allowed in `*.test.tsx` files, unlike zero-import `*.web.test.ts` E2E specs), then inspect and interact using `Spectra.get(...)` / `Spectra.getAll(...)` or Page/Component Objects. Each `Spectra.mount()` call replaces the previous mount automatically — no cleanup command needed. Run via `spectra test` (a separate suite from E2E's `spectra run`).
8
+ 3. **Platform Separation**:
9
+ - `web.test.ts` / `web.test.tsx` / `web.ts`: Web / Browser component implementations.
10
+ - `common.test.ts` / `common.ts`: Cross-platform shared implementations.
11
+ 4. **CamelCase Naming Convention**:
12
+ - Component Objects (`page-objects/ButtonComponent/`, `page-objects/BadgeComponent/`)
13
+ - Reusable Actions (`support/actions/fillInputField/`)
14
+ - Reusable Steps (`support/steps/verifyButtonState/`)
15
+ 5. **Spec-as-Code**:
16
+ - Suites are defined in `specs/<suite-name>/suite.md` with YAML frontmatter (`id`, `name`, `executionOrder`, `tags`).
17
+ - Test cases are defined in `specs/<suite-name>/<TC-ID-slug>/spec.md` with YAML frontmatter (`id`, `title`, `priority`, `coverage`).
@@ -0,0 +1,5 @@
1
+ {
2
+ "recommendations": [
3
+ "testspectra.testspectra-vscode"
4
+ ]
5
+ }
@@ -0,0 +1,14 @@
1
+ # TestSpectra React Component Testing Workspace
2
+
3
+ ## Commands
4
+ - `pnpm test` or `spectra test` — Run the component test suite (bundled Vitest browser mode via `@testspectra/react`)
5
+ - `pnpm run test:headed` — Run component tests with a visible browser window
6
+ - `pnpm run sync-types` — Scan workspace and regenerate ambient `.testspectra/types/`
7
+ - `pnpm run type-check` — Type check with `tsc -b`
8
+
9
+ ## Architecture Rules
10
+
11
+ 1. Zero-import standard for `Spectra.*`, `ButtonComponent`, `BadgeComponent`, `InputComponent`, `Step.*`, and `Fixture.*` — these stay ambient globals, auto-discovered from `page-objects/`, `support/steps/`, and `fixtures/`.
12
+ 2. Component testing uses `Spectra.mount(<Component />)` — real JSX, real static imports for the component under test are allowed and expected in `*.test.tsx` files (unlike `*.web.test.ts` E2E specs). `Spectra.mount()` always replaces whatever was previously mounted; no manual cleanup call is needed between tests.
13
+ 3. Component tests are a **separate test suite** from E2E (`spectra run`) — they live in `specs/<Suite>/<TC-ID>/web.test.tsx` alongside `spec.md`, run via `spectra test`, not `spectra run`. See `docs/v2/features/component-testing/react/`.
14
+ 4. Assertions use the same TestSpectra DSL as E2E (`Spectra.get().shouldBeVisible()`, `.shouldHaveText()`, etc.) — nothing new to learn beyond `Spectra.mount()`.
@@ -0,0 +1,69 @@
1
+ # TestSpectra React Component Testing Template
2
+
3
+ A high-performance, real-browser React component testing template powered by **TestSpectra**, **WebdriverIO Browser Runner**, and **Testing Library**.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **Direct Component Mounting**: Mount TSX components directly in real Chromium/Blink engines using `@testing-library/react`.
8
+ - **Zero Mock Browser**: Real layout calculations, CSS rendering, focus states, and browser events without JSDOM/HappyDOM limitations.
9
+ - **Fast Vite HMR Core**: Instant test startup powered by Vite bundler inside the browser runner.
10
+ - **TestSpectra Matchers**: Comprehensive semantic assertions (`.shouldBeVisible()`, `.shouldExist()`, `expect(el).toHaveText()`).
11
+
12
+ ## 📁 Directory Structure
13
+
14
+ ```
15
+ .
16
+ ├── spectra.config.ts # TestSpectra centralized configuration
17
+ ├── wdio.conf.ts # WebdriverIO Browser Runner + Vite config
18
+ ├── tsconfig.json # TypeScript configuration for JSX & runner types
19
+ └── src/
20
+ ├── components/ # React components and tests
21
+ │ ├── Button/
22
+ │ │ ├── Button.tsx
23
+ │ │ └── Button.test.tsx
24
+ │ ├── Badge/
25
+ │ │ ├── Badge.tsx
26
+ │ │ └── Badge.test.tsx
27
+ │ └── Input/
28
+ │ ├── Input.tsx
29
+ │ └── Input.test.tsx
30
+ └── test-utils.tsx # Common testing helpers & providers
31
+ ```
32
+
33
+ ## 🛠️ Usage & Commands
34
+
35
+ ```bash
36
+ # Run all component tests
37
+ pnpm test
38
+
39
+ # Run component tests in headless mode
40
+ pnpm run test:headless
41
+
42
+ # Run tests in high-concurrency chunked worker mode
43
+ pnpm run test:chunked
44
+
45
+ # Type check
46
+ pnpm run type-check
47
+ ```
48
+
49
+ ## 📝 Writing Component Tests
50
+
51
+ ```tsx
52
+ import React from 'react';
53
+ import { render } from '@testing-library/react';
54
+ import { expect, $ } from '@wdio/globals';
55
+ import { Button } from './Button';
56
+
57
+ describe('Button Component', () => {
58
+ it('renders label and handles user clicks', async () => {
59
+ let clicked = false;
60
+ render(<Button label="Submit" onClick={() => (clicked = true)} />);
61
+
62
+ const button = await $('button=Submit');
63
+ await expect(button).toBeDisplayed();
64
+
65
+ await button.click();
66
+ expect(clicked).toBe(true);
67
+ });
68
+ });
69
+ ```
@@ -0,0 +1,12 @@
1
+ {
2
+ "user": {
3
+ "name": "Alex Mercer",
4
+ "role": "Developer",
5
+ "status": "active"
6
+ },
7
+ "labels": {
8
+ "save": "Save Changes",
9
+ "cancel": "Cancel",
10
+ "delete": "Delete Item"
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ export default async function () {
2
+ // Global after hook for web component testing suite
3
+ }
@@ -0,0 +1,3 @@
1
+ export default async function () {
2
+ // Global before hook for web component testing suite
3
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@testspectra/template-react-component",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "test": "spectra test",
8
+ "test:headed": "spectra test --headed",
9
+ "spectra": "spectra",
10
+ "doctor": "spectra doctor",
11
+ "watch": "spectra watch",
12
+ "type-check": "tsc -b",
13
+ "sync-types": "spectra sync-types",
14
+ "postinstall": "spectra sync-types"
15
+ },
16
+ "devDependencies": {
17
+ "@testspectra/cli": "link:../..",
18
+ "@testspectra/matchers": "link:../../../tools/matchers",
19
+ "@testspectra/react": "link:../../../tools/react",
20
+ "@types/node": "^20.14.0",
21
+ "@types/react": "^18.3.3",
22
+ "@types/react-dom": "^18.3.0",
23
+ "react": "^18.3.1",
24
+ "react-dom": "^18.3.1",
25
+ "typescript": "^5.4.5"
26
+ }
27
+ }
@@ -0,0 +1,23 @@
1
+ class BadgeComponent {
2
+ /** Root badge element */
3
+ get root() {
4
+ return Spectra.get("[data-testid='testspectra-badge']");
5
+ }
6
+
7
+ /** Dot indicator element */
8
+ get dot() {
9
+ return Spectra.get("[data-testid='badge-dot']");
10
+ }
11
+
12
+ /** Badge label text element */
13
+ get label() {
14
+ return Spectra.get("[data-testid='badge-label']");
15
+ }
16
+
17
+ /** Lookup badge by severity attribute */
18
+ bySeverity(severity: 'info' | 'success' | 'warning' | 'danger') {
19
+ return Spectra.get(`[data-testid='testspectra-badge'][data-severity='${severity}']`);
20
+ }
21
+ }
22
+
23
+ export default new BadgeComponent();
@@ -0,0 +1,23 @@
1
+ class ButtonComponent {
2
+ /** Root button element */
3
+ get root() {
4
+ return Spectra.get("[data-testid='testspectra-button']");
5
+ }
6
+
7
+ /** Label element inside button */
8
+ get label() {
9
+ return Spectra.get("[data-testid='button-label']");
10
+ }
11
+
12
+ /** Optional icon element */
13
+ get icon() {
14
+ return Spectra.get("[data-testid='button-icon']");
15
+ }
16
+
17
+ /** Lookup button element by visible text */
18
+ byText(text: string) {
19
+ return Spectra.get(`button*=${text}`);
20
+ }
21
+ }
22
+
23
+ export default new ButtonComponent();
@@ -0,0 +1,13 @@
1
+ class InputComponent {
2
+ /** Root input element */
3
+ get root() {
4
+ return Spectra.get("[data-testid='testspectra-input']");
5
+ }
6
+
7
+ /** Lookup input element by placeholder substring */
8
+ byPlaceholder(placeholder: string) {
9
+ return Spectra.get(`input[placeholder*='${placeholder}']`);
10
+ }
11
+ }
12
+
13
+ export default new InputComponent();
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: TC-0002
3
+ title: Verify default badge with info severity
4
+ priority: Critical
5
+ caseType: Positive
6
+ status: automated
7
+ coverage:
8
+ web: automated
9
+ ---
10
+
11
+ # TC-0002: Badge Default Rendering
12
+
13
+ Verify that `<Badge />` renders with the default `info` severity when no `severity` prop is provided.
14
+
15
+ ## Test Steps
16
+
17
+ 1. Mount `<Badge label="System Active" />`.
18
+ 2. Verify the badge is visible, shows the correct label text, and has `data-severity="info"`.
@@ -0,0 +1,11 @@
1
+ import { Badge } from '../../../src/components/Badge/Badge.js';
2
+ import { withProviders } from '../../../src/test-utils.js';
3
+
4
+ it('Verify default badge with info severity', async () => {
5
+ await Spectra.mount(withProviders(<Badge label="System Active" />));
6
+
7
+ // Assert via BadgeComponent component object
8
+ await BadgeComponent.root.shouldBeVisible();
9
+ await BadgeComponent.label.shouldHaveText('System Active');
10
+ await BadgeComponent.root.shouldHaveAttribute('data-severity', 'info');
11
+ });
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: TC-0006
3
+ title: Verify badge with success severity and dot indicator
4
+ priority: High
5
+ caseType: Positive
6
+ status: automated
7
+ coverage:
8
+ web: automated
9
+ ---
10
+
11
+ # TC-0006: Badge Success Severity with Dot Indicator
12
+
13
+ Verify that `<Badge />` renders the `success` severity styling and shows a dot indicator when the `dot` prop is set.
14
+
15
+ ## Test Steps
16
+
17
+ 1. Mount `<Badge label="Completed" severity="success" dot />`.
18
+ 2. Verify the badge is visible with `data-severity="success"` and the dot indicator is visible.