@testspectra/cli 1.0.70 → 1.1.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 (277) 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-DPfv5_EF.js +116 -0
  7. package/demo-app/assets/index-gIwu2EMV.css +1 -0
  8. package/demo-app/index.html +2 -2
  9. package/dist/.tsbuildinfo +1 -0
  10. package/dist/commands/__tests__/cloud-run.test.d.ts +1 -0
  11. package/dist/commands/__tests__/cloud-run.test.js +93 -0
  12. package/dist/commands/__tests__/doctor.test.d.ts +1 -0
  13. package/dist/commands/__tests__/doctor.test.js +39 -0
  14. package/dist/commands/__tests__/init.test.d.ts +1 -0
  15. package/dist/commands/__tests__/init.test.js +148 -0
  16. package/dist/commands/__tests__/license.test.d.ts +1 -0
  17. package/dist/commands/__tests__/license.test.js +13 -0
  18. package/dist/commands/__tests__/refactor.test.d.ts +1 -0
  19. package/dist/commands/__tests__/refactor.test.js +64 -0
  20. package/dist/commands/__tests__/run-e2e.test.d.ts +1 -0
  21. package/dist/commands/__tests__/run-e2e.test.js +181 -0
  22. package/dist/commands/__tests__/run.test.d.ts +1 -0
  23. package/dist/commands/__tests__/run.test.js +197 -0
  24. package/dist/commands/__tests__/watch.test.d.ts +1 -0
  25. package/dist/commands/__tests__/watch.test.js +155 -0
  26. package/dist/commands/add.js +86 -85
  27. package/dist/commands/cloud-run.d.ts +11 -0
  28. package/dist/commands/cloud-run.js +118 -0
  29. package/dist/commands/demo.js +7 -7
  30. package/dist/commands/devices.d.ts +14 -2
  31. package/dist/commands/devices.js +44 -34
  32. package/dist/commands/doctor.d.ts +3 -1
  33. package/dist/commands/doctor.js +43 -264
  34. package/dist/commands/init.d.ts +1 -1
  35. package/dist/commands/init.js +206 -196
  36. package/dist/commands/install.d.ts +4 -0
  37. package/dist/commands/install.js +59 -0
  38. package/dist/commands/license.d.ts +4 -0
  39. package/dist/commands/license.js +30 -0
  40. package/dist/commands/refactor.d.ts +8 -0
  41. package/dist/commands/refactor.js +78 -0
  42. package/dist/commands/run.d.ts +22 -1
  43. package/dist/commands/run.js +252 -109
  44. package/dist/commands/sync-types.d.ts +4 -0
  45. package/dist/commands/sync-types.js +14 -0
  46. package/dist/commands/update.js +39 -43
  47. package/dist/commands/watch.d.ts +6 -0
  48. package/dist/commands/watch.js +47 -43
  49. package/dist/config/loader.d.ts +1 -1
  50. package/dist/config/loader.js +40 -25
  51. package/dist/config/schema.d.ts +117 -49
  52. package/dist/config/schema.js +41 -34
  53. package/dist/generator/__tests__/tsconfig-isolation.test.d.ts +1 -0
  54. package/dist/generator/__tests__/tsconfig-isolation.test.js +278 -0
  55. package/dist/generator/__tests__/type-generator.test.d.ts +1 -0
  56. package/dist/generator/__tests__/type-generator.test.js +386 -0
  57. package/dist/generator/index.d.ts +2 -0
  58. package/dist/generator/index.js +2 -0
  59. package/dist/generator/tsconfig-generator.d.ts +27 -0
  60. package/dist/generator/tsconfig-generator.js +391 -0
  61. package/dist/generator/type-generator.d.ts +36 -0
  62. package/dist/generator/type-generator.js +644 -0
  63. package/dist/index.d.ts +9 -5
  64. package/dist/index.js +124 -51
  65. package/dist/lifecycle/__tests__/lifecycle-engine.test.d.ts +1 -0
  66. package/dist/lifecycle/__tests__/lifecycle-engine.test.js +290 -0
  67. package/dist/lifecycle/hook-discovery.d.ts +24 -0
  68. package/dist/lifecycle/hook-discovery.js +60 -0
  69. package/dist/lifecycle/hook-dispatcher.d.ts +34 -0
  70. package/dist/lifecycle/hook-dispatcher.js +190 -0
  71. package/dist/lifecycle/index.d.ts +3 -0
  72. package/dist/lifecycle/index.js +3 -0
  73. package/dist/lifecycle/parallel-grouping.d.ts +27 -0
  74. package/dist/lifecycle/parallel-grouping.js +151 -0
  75. package/dist/mobile/__tests__/android-device-e2e.test.d.ts +1 -0
  76. package/dist/mobile/__tests__/android-device-e2e.test.js +53 -0
  77. package/dist/mobile/__tests__/device-pool.test.d.ts +1 -0
  78. package/dist/mobile/__tests__/device-pool.test.js +97 -0
  79. package/dist/mobile/device-pool.d.ts +23 -0
  80. package/dist/mobile/device-pool.js +1 -0
  81. package/dist/mobile/index.d.ts +1 -0
  82. package/dist/mobile/index.js +1 -0
  83. package/dist/refactor/__tests__/refactor-engine.test.d.ts +1 -0
  84. package/dist/refactor/__tests__/refactor-engine.test.js +175 -0
  85. package/dist/refactor/index.d.ts +1 -0
  86. package/dist/refactor/index.js +1 -0
  87. package/dist/refactor/refactor-engine.d.ts +25 -0
  88. package/dist/refactor/refactor-engine.js +255 -0
  89. package/dist/reporter/__tests__/semantic-formatter.test.d.ts +1 -0
  90. package/dist/reporter/__tests__/semantic-formatter.test.js +73 -0
  91. package/dist/reporter/semantic-formatter.d.ts +6 -0
  92. package/dist/reporter/semantic-formatter.js +191 -0
  93. package/dist/reporter/summary-view.d.ts +12 -0
  94. package/dist/reporter/summary-view.js +19 -0
  95. package/dist/reporter/terminal-stream.d.ts +32 -0
  96. package/dist/reporter/terminal-stream.js +82 -0
  97. package/dist/reporter/types.d.ts +2 -0
  98. package/dist/reporter/types.js +1 -0
  99. package/dist/runner/bridge.d.ts +10 -5
  100. package/dist/runner/bridge.js +69 -44
  101. package/dist/runner/reporter.d.ts +30 -2
  102. package/dist/runner/reporter.js +419 -13
  103. package/dist/server/demo.js +43 -44
  104. package/dist/types/generator.d.ts +1 -17
  105. package/dist/types/generator.js +1 -443
  106. package/dist/utils/demo-server.js +38 -35
  107. package/package.json +20 -12
  108. package/templates/default/CLAUDE.md +7 -5
  109. package/templates/default/fixtures/apiData.json +24 -0
  110. package/templates/default/package.json +13 -4
  111. package/templates/default/page-objects/MatchersPage/mobile.ts +41 -16
  112. package/templates/default/page-objects/MatchersPage/web.ts +14 -0
  113. package/templates/default/page-objects/NavigationPage/mobile.ts +10 -1
  114. package/templates/default/page-objects/PlaygroundPage/mobile.ts +27 -17
  115. package/templates/default/page-objects/PlaygroundPage/web.ts +2 -0
  116. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +11 -0
  117. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
  118. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
  119. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +16 -0
  120. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
  121. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
  122. package/templates/default/specs/ApiInterception/suite.md +9 -0
  123. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +7 -1
  124. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
  125. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +15 -1
  126. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +14 -4
  127. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +9 -1
  128. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +8 -3
  129. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +9 -1
  130. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
  131. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +27 -1
  132. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
  133. package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +4 -1
  134. package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +3 -3
  135. package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +4 -1
  136. package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +2 -2
  137. package/templates/default/spectra.config.ts +21 -14
  138. package/templates/default/support/actions/fillCredentials/mobile.action.ts +2 -2
  139. package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +2 -0
  140. package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +2 -2
  141. package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +3 -1
  142. package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +3 -3
  143. package/templates/default/tsconfig.json +3 -1
  144. package/templates/nx/.nx/workspace-data/d/daemon.log +168 -0
  145. package/templates/nx/CLAUDE.md +2 -2
  146. package/templates/nx/package.json +7 -5
  147. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +3 -0
  148. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
  149. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
  150. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +3 -0
  151. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
  152. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
  153. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/suite.md +9 -0
  154. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
  155. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +14 -4
  156. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +8 -3
  157. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
  158. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
  159. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +3 -3
  160. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +2 -2
  161. package/templates/nx/pnpm-lock.yaml +6663 -0
  162. package/templates/nx/pnpm-workspace.yaml +2 -1
  163. package/templates/nx/shared/testing/fixtures/apiData.json +24 -0
  164. package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +12 -0
  165. package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +14 -0
  166. package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +2 -0
  167. package/templates/nx/shared/testing/project.json +19 -0
  168. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +2 -2
  169. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +1 -1
  170. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +3 -3
  171. package/templates/nx/spectra.config.ts +19 -12
  172. package/templates/nx/tsconfig.json +3 -1
  173. package/demo-app/assets/index-DAUlrHTr.css +0 -1
  174. package/demo-app/assets/index-DN2Kb0A8.js +0 -100
  175. package/dist/index.cjs +0 -101
  176. package/dist/plugin.cjs +0 -575
  177. package/dist/plugin.d.ts +0 -16
  178. package/dist/plugin.js +0 -184
  179. package/dist/step/index.d.ts +0 -6
  180. package/dist/step/index.js +0 -6
  181. package/dist/step/matchers.d.ts +0 -14
  182. package/dist/step/matchers.js +0 -114
  183. package/dist/step/proto.d.ts +0 -46
  184. package/dist/step/proto.js +0 -114
  185. package/dist/step/runner/collection.d.ts +0 -13
  186. package/dist/step/runner/collection.js +0 -51
  187. package/dist/step/runner/single.d.ts +0 -21
  188. package/dist/step/runner/single.js +0 -138
  189. package/dist/step/spectra.d.ts +0 -34
  190. package/dist/step/spectra.js +0 -156
  191. package/dist/step/types.d.ts +0 -32
  192. package/dist/step/types.js +0 -5
  193. package/templates/default/tsconfig.spectra.android.json +0 -46
  194. package/templates/default/tsconfig.spectra.ios.json +0 -46
  195. package/templates/default/tsconfig.spectra.json +0 -22
  196. package/templates/default/tsconfig.spectra.web.json +0 -53
  197. package/templates/nx/fixtures/playgroundData.json +0 -7
  198. package/templates/nx/global-hooks/after/mobile.hook.ts +0 -3
  199. package/templates/nx/global-hooks/after/web.hook.ts +0 -3
  200. package/templates/nx/global-hooks/before/mobile.hook.ts +0 -3
  201. package/templates/nx/global-hooks/before/web.hook.ts +0 -3
  202. package/templates/nx/page-objects/MatchersPage/mobile.ts +0 -21
  203. package/templates/nx/page-objects/MatchersPage/web.ts +0 -23
  204. package/templates/nx/page-objects/NavigationPage/mobile.ts +0 -5
  205. package/templates/nx/page-objects/NavigationPage/web.ts +0 -8
  206. package/templates/nx/page-objects/PlaygroundPage/mobile.ts +0 -26
  207. package/templates/nx/page-objects/PlaygroundPage/web.ts +0 -29
  208. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +0 -3
  209. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +0 -12
  210. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +0 -5
  211. package/templates/nx/specs/BrowserContext/suite.md +0 -9
  212. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
  213. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/spec.md +0 -12
  214. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
  215. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +0 -3
  216. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +0 -12
  217. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +0 -6
  218. package/templates/nx/specs/ContentMatchers/suite.md +0 -9
  219. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +0 -3
  220. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +0 -12
  221. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +0 -5
  222. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +0 -3
  223. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +0 -12
  224. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +0 -8
  225. package/templates/nx/specs/ElementMatchers/hooks/after/mobile.hook.ts +0 -1
  226. package/templates/nx/specs/ElementMatchers/hooks/after/web.hook.ts +0 -1
  227. package/templates/nx/specs/ElementMatchers/hooks/afterEach/mobile.hook.ts +0 -1
  228. package/templates/nx/specs/ElementMatchers/hooks/afterEach/web.hook.ts +0 -1
  229. package/templates/nx/specs/ElementMatchers/hooks/before/mobile.hook.ts +0 -1
  230. package/templates/nx/specs/ElementMatchers/hooks/before/web.hook.ts +0 -1
  231. package/templates/nx/specs/ElementMatchers/hooks/beforeEach/mobile.hook.ts +0 -1
  232. package/templates/nx/specs/ElementMatchers/hooks/beforeEach/web.hook.ts +0 -1
  233. package/templates/nx/specs/ElementMatchers/suite.md +0 -9
  234. package/templates/nx/specs/Playground/TC-0001-form-controls/mobile.test.ts +0 -3
  235. package/templates/nx/specs/Playground/TC-0001-form-controls/spec.md +0 -12
  236. package/templates/nx/specs/Playground/TC-0001-form-controls/web.test.ts +0 -6
  237. package/templates/nx/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +0 -3
  238. package/templates/nx/specs/Playground/TC-0002-toggle-elements/spec.md +0 -12
  239. package/templates/nx/specs/Playground/TC-0002-toggle-elements/web.test.ts +0 -6
  240. package/templates/nx/specs/Playground/hooks/after/mobile.hook.ts +0 -1
  241. package/templates/nx/specs/Playground/hooks/after/web.hook.ts +0 -1
  242. package/templates/nx/specs/Playground/hooks/afterEach/mobile.hook.ts +0 -1
  243. package/templates/nx/specs/Playground/hooks/afterEach/web.hook.ts +0 -1
  244. package/templates/nx/specs/Playground/hooks/before/mobile.hook.ts +0 -1
  245. package/templates/nx/specs/Playground/hooks/before/web.hook.ts +0 -1
  246. package/templates/nx/specs/Playground/hooks/beforeEach/mobile.hook.ts +0 -1
  247. package/templates/nx/specs/Playground/hooks/beforeEach/web.hook.ts +0 -1
  248. package/templates/nx/specs/Playground/suite.md +0 -9
  249. package/templates/nx/support/actions/fillCredentials/mobile.action.ts +0 -4
  250. package/templates/nx/support/actions/fillCredentials/web.action.ts +0 -4
  251. package/templates/nx/support/steps/togglePlaygroundStates/mobile.step.ts +0 -3
  252. package/templates/nx/support/steps/togglePlaygroundStates/step.md +0 -7
  253. package/templates/nx/support/steps/togglePlaygroundStates/web.step.ts +0 -5
  254. package/templates/nx/support/steps/verifyPlaygroundState/mobile.step.ts +0 -4
  255. package/templates/nx/support/steps/verifyPlaygroundState/step.md +0 -7
  256. package/templates/nx/support/steps/verifyPlaygroundState/web.step.ts +0 -6
  257. package/templates/nx/tsconfig.spectra.android.json +0 -39
  258. package/templates/nx/tsconfig.spectra.ios.json +0 -39
  259. package/templates/nx/tsconfig.spectra.json +0 -25
  260. package/templates/nx/tsconfig.spectra.shared.json +0 -25
  261. package/templates/nx/tsconfig.spectra.web.json +0 -45
  262. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
  263. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
  264. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
  265. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
  266. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
  267. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
  268. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
  269. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
  270. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
  271. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
  272. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
  273. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
  274. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
  275. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
  276. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
  277. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
@@ -1,138 +0,0 @@
1
- import { executeSingleMatcher, resolveElement } from "../matchers.js";
2
- export class SingleElementRunner {
3
- _target;
4
- _action = null;
5
- _assertions = [];
6
- constructor(target, action) {
7
- this._target = target;
8
- this._action = action || null;
9
- }
10
- // --- Chained Actions on current target ---
11
- click() {
12
- const target = this.requireTarget("click");
13
- this._action = async () => {
14
- const el = await resolveElement(target);
15
- await el.click();
16
- };
17
- return this;
18
- }
19
- doubleClick() {
20
- const target = this.requireTarget("doubleClick");
21
- this._action = async () => {
22
- const el = await resolveElement(target);
23
- await el.doubleClick();
24
- };
25
- return this;
26
- }
27
- longPress(durationMs = 1000) {
28
- const target = this.requireTarget("longPress");
29
- this._action = async () => {
30
- const el = await resolveElement(target);
31
- if (typeof el.touchAction === "function") {
32
- await el.touchAction([
33
- { action: "longPress", ms: durationMs },
34
- { action: "release" },
35
- ]);
36
- }
37
- else {
38
- await el.click();
39
- }
40
- };
41
- return this;
42
- }
43
- type(value, options) {
44
- const target = this.requireTarget("type");
45
- this._action = async () => {
46
- const el = await resolveElement(target);
47
- if (options?.clearFirst) {
48
- await el.clearValue();
49
- }
50
- await el.setValue(value);
51
- };
52
- return this;
53
- }
54
- clear() {
55
- const target = this.requireTarget("clear");
56
- this._action = async () => {
57
- const el = await resolveElement(target);
58
- await el.clearValue();
59
- };
60
- return this;
61
- }
62
- select(value) {
63
- const target = this.requireTarget("select");
64
- this._action = async () => {
65
- const el = await resolveElement(target);
66
- await el.selectByVisibleText(value);
67
- };
68
- return this;
69
- }
70
- hover() {
71
- const target = this.requireTarget("hover");
72
- this._action = async () => {
73
- const el = await resolveElement(target);
74
- await el.moveTo();
75
- };
76
- return this;
77
- }
78
- waitForElement(timeoutMs = 10000) {
79
- const target = this.requireTarget("waitForElement");
80
- this._action = async () => {
81
- const el = await resolveElement(target);
82
- await el.waitForDisplayed({ timeout: timeoutMs });
83
- };
84
- return this;
85
- }
86
- should(a, b, ...rest) {
87
- const isFirstArgMatcher = typeof a === "string" &&
88
- (a.includes(".") ||
89
- a.includes("exist") ||
90
- a.includes("visible") ||
91
- a.includes("enabled") ||
92
- a.includes("disabled") ||
93
- a.includes("selected") ||
94
- a.includes("checked"));
95
- if (b !== undefined && !isFirstArgMatcher) {
96
- // Form: should(target, matcher, ...args)
97
- this._assertions.push({
98
- target: a,
99
- matcher: b,
100
- args: rest,
101
- });
102
- }
103
- else {
104
- // Form: should(matcher, ...args) -> on current target
105
- this._assertions.push({
106
- target: this._target,
107
- matcher: a,
108
- args: b !== undefined ? [b, ...rest] : rest,
109
- });
110
- }
111
- return this;
112
- }
113
- // --- Execution when awaited ---
114
- async then(onfulfilled, onrejected) {
115
- try {
116
- if (this._action) {
117
- await this._action();
118
- }
119
- for (const assert of this._assertions) {
120
- await executeSingleMatcher(assert.target, assert.matcher, assert.args);
121
- }
122
- const res = (onfulfilled ? await onfulfilled() : undefined);
123
- return res;
124
- }
125
- catch (err) {
126
- if (onrejected) {
127
- return onrejected(err);
128
- }
129
- throw err;
130
- }
131
- }
132
- requireTarget(actionName) {
133
- if (!this._target) {
134
- throw new Error(`Cannot execute '${actionName}' without specifying an element target.`);
135
- }
136
- return this._target;
137
- }
138
- }
@@ -1,34 +0,0 @@
1
- import { ClickOptions, ElementTarget, KeyOption, LongPressOptions, ScrollOptions, SwipeOptions, TypeOptions } from "./types.js";
2
- import { SingleElementRunner } from "./runner/single.js";
3
- import { MultiElementRunner } from "./runner/collection.js";
4
- /**
5
- * Main Spectra testing API orchestrator.
6
- * Combines direct actions, single element queries (get), and collections (getAll).
7
- */
8
- export declare class SpectraStatic {
9
- /**
10
- * Targets a single element by selector or Page Object element.
11
- */
12
- get(target: ElementTarget): SingleElementRunner;
13
- /**
14
- * Targets multiple elements / collections by selector.
15
- */
16
- getAll(selector: string): MultiElementRunner;
17
- navigate(url: string): SingleElementRunner;
18
- back(): SingleElementRunner;
19
- refresh(): SingleElementRunner;
20
- click(target: ElementTarget, textOrOptions?: string | ClickOptions): SingleElementRunner;
21
- doubleClick(target: ElementTarget, textOrOptions?: string | ClickOptions): SingleElementRunner;
22
- longPress(target: ElementTarget, options?: LongPressOptions | number): SingleElementRunner;
23
- type(target: ElementTarget, value: string, options?: TypeOptions): SingleElementRunner;
24
- clear(target: ElementTarget): SingleElementRunner;
25
- select(target: ElementTarget, value: string): SingleElementRunner;
26
- hover(target: ElementTarget): SingleElementRunner;
27
- pressKey(key: KeyOption | string): SingleElementRunner;
28
- dragDrop(sourceTarget: ElementTarget, destTarget: ElementTarget): SingleElementRunner;
29
- scroll(options?: ScrollOptions): SingleElementRunner;
30
- swipe(options: SwipeOptions): SingleElementRunner;
31
- wait(durationMs: number): SingleElementRunner;
32
- waitForElement(target: ElementTarget, timeoutMs?: number): SingleElementRunner;
33
- }
34
- export declare const Spectra: SpectraStatic;
@@ -1,156 +0,0 @@
1
- import { SingleElementRunner } from "./runner/single.js";
2
- import { MultiElementRunner } from "./runner/collection.js";
3
- import { resolveElement } from "./matchers.js";
4
- /**
5
- * Main Spectra testing API orchestrator.
6
- * Combines direct actions, single element queries (get), and collections (getAll).
7
- */
8
- export class SpectraStatic {
9
- /**
10
- * Targets a single element by selector or Page Object element.
11
- */
12
- get(target) {
13
- return new SingleElementRunner(target);
14
- }
15
- /**
16
- * Targets multiple elements / collections by selector.
17
- */
18
- getAll(selector) {
19
- return new MultiElementRunner(selector);
20
- }
21
- // --- Browser & Navigation Actions ---
22
- navigate(url) {
23
- return new SingleElementRunner(undefined, async () => {
24
- await browser.url(url);
25
- });
26
- }
27
- back() {
28
- return new SingleElementRunner(undefined, async () => {
29
- await browser.back();
30
- });
31
- }
32
- refresh() {
33
- return new SingleElementRunner(undefined, async () => {
34
- await browser.refresh();
35
- });
36
- }
37
- // --- Direct Interaction Actions ---
38
- click(target, textOrOptions) {
39
- return new SingleElementRunner(target, async () => {
40
- const el = await resolveElement(target);
41
- await el.click();
42
- });
43
- }
44
- doubleClick(target, textOrOptions) {
45
- return new SingleElementRunner(target, async () => {
46
- const el = await resolveElement(target);
47
- await el.doubleClick();
48
- });
49
- }
50
- longPress(target, options) {
51
- const duration = typeof options === "number" ? options : options?.duration || 1000;
52
- return new SingleElementRunner(target, async () => {
53
- const el = await resolveElement(target);
54
- if (typeof el.touchAction === "function") {
55
- await el.touchAction([
56
- { action: "longPress", ms: duration },
57
- { action: "release" },
58
- ]);
59
- }
60
- else {
61
- await el.click();
62
- }
63
- });
64
- }
65
- type(target, value, options) {
66
- return new SingleElementRunner(target, async () => {
67
- const el = await resolveElement(target);
68
- if (options?.clearFirst) {
69
- await el.clearValue();
70
- }
71
- await el.setValue(value);
72
- });
73
- }
74
- clear(target) {
75
- return new SingleElementRunner(target, async () => {
76
- const el = await resolveElement(target);
77
- await el.clearValue();
78
- });
79
- }
80
- select(target, value) {
81
- return new SingleElementRunner(target, async () => {
82
- const el = await resolveElement(target);
83
- await el.selectByVisibleText(value);
84
- });
85
- }
86
- hover(target) {
87
- return new SingleElementRunner(target, async () => {
88
- const el = await resolveElement(target);
89
- await el.moveTo();
90
- });
91
- }
92
- pressKey(key) {
93
- return new SingleElementRunner(undefined, async () => {
94
- await browser.keys(key);
95
- });
96
- }
97
- dragDrop(sourceTarget, destTarget) {
98
- return new SingleElementRunner(sourceTarget, async () => {
99
- const source = await resolveElement(sourceTarget);
100
- const target = await resolveElement(destTarget);
101
- await source.dragAndDrop(target);
102
- });
103
- }
104
- // --- Gesture Actions ---
105
- scroll(options) {
106
- return new SingleElementRunner(options?.selector, async () => {
107
- if (options?.selector) {
108
- const el = await resolveElement(options.selector);
109
- await el.scrollIntoView();
110
- }
111
- else {
112
- await browser.execute((direction, pixels) => {
113
- const delta = pixels || 500;
114
- window.scrollBy({
115
- top: direction === "up" ? -delta : direction === "down" ? delta : 0,
116
- left: direction === "left" ? -delta : direction === "right" ? delta : 0,
117
- behavior: "smooth",
118
- });
119
- }, options?.direction || "down", options?.pixels || 500);
120
- }
121
- });
122
- }
123
- swipe(options) {
124
- return new SingleElementRunner(options.selector, async () => {
125
- if (typeof browser.touchAction === "function") {
126
- const distance = options.distance || 300;
127
- await browser.touchAction([
128
- { action: "press", x: 200, y: 500 },
129
- {
130
- action: "moveTo",
131
- x: options.direction === "right" ? 200 + distance : options.direction === "left" ? 200 - distance : 200,
132
- y: options.direction === "down" ? 500 + distance : options.direction === "up" ? 500 - distance : 500,
133
- },
134
- { action: "release" },
135
- ]);
136
- }
137
- else {
138
- // Fallback to web scroll
139
- await this.scroll({ direction: options.direction, pixels: options.distance });
140
- }
141
- });
142
- }
143
- // --- Timing Actions ---
144
- wait(durationMs) {
145
- return new SingleElementRunner(undefined, async () => {
146
- await browser.pause(durationMs);
147
- });
148
- }
149
- waitForElement(target, timeoutMs = 10000) {
150
- return new SingleElementRunner(target, async () => {
151
- const el = await resolveElement(target);
152
- await el.waitForDisplayed({ timeout: timeoutMs });
153
- });
154
- }
155
- }
156
- export const Spectra = new SpectraStatic();
@@ -1,32 +0,0 @@
1
- /**
2
- * Database Canonical Action and Assertion Types
3
- * Matches backend/src/models/test_step.rs
4
- */
5
- export type ActionKey = "navigate" | "click" | "type" | "clear" | "select" | "scroll" | "swipe" | "wait" | "waitForElement" | "pressKey" | "longPress" | "doubleClick" | "hover" | "dragDrop" | "back" | "refresh";
6
- export type AssertionKey = "elementDisplayed" | "elementNotDisplayed" | "elementExists" | "elementEnabled" | "elementDisabled" | "textContains" | "textEquals" | "textNotContains" | "urlContains" | "urlEquals" | "valueEquals" | "valueContains" | "attributeEquals" | "attributeContains" | "hasClass" | "hasAttribute" | "isSelected" | "elementCount" | "elementCountGreaterThan" | "pageLoaded" | "noErrors";
7
- export type KeyOption = "Enter" | "Tab" | "Escape" | "Backspace" | "Delete" | "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight" | "Space";
8
- export type Direction = "up" | "down" | "left" | "right";
9
- export type ElementTarget = string | WebdriverIO.Element | ChainablePromiseElement;
10
- export interface ScrollOptions {
11
- direction?: Direction;
12
- pixels?: number;
13
- selector?: ElementTarget;
14
- }
15
- export interface SwipeOptions {
16
- direction: Direction;
17
- distance?: number;
18
- selector?: ElementTarget;
19
- }
20
- export interface LongPressOptions {
21
- text?: string;
22
- duration?: number;
23
- }
24
- export interface ClickOptions {
25
- text?: string;
26
- clickType?: "single" | "double";
27
- }
28
- export interface TypeOptions {
29
- clearFirst?: boolean;
30
- }
31
- export type SingleElementMatcher = "be.visible" | "not.be.visible" | "exist" | "not.exist" | "be.enabled" | "be.disabled" | "be.checked" | "be.selected" | "have.value" | "contain.value" | "have.text" | "contain.text" | "have.class" | "have.attr" | "have.url" | "contain.url" | "have.title" | "contain.title";
32
- export type MultiElementMatcher = "have.length" | "have.length.greaterThan" | "be.empty" | "exist";
@@ -1,5 +0,0 @@
1
- /**
2
- * Database Canonical Action and Assertion Types
3
- * Matches backend/src/models/test_step.rs
4
- */
5
- export {};
@@ -1,46 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "composite": true,
7
- "noEmit": true,
8
- "skipLibCheck": true,
9
- "strict": true,
10
- "types": [
11
- "node",
12
- "@wdio/globals/types",
13
- "@wdio/mocha-framework"
14
- ]
15
- },
16
- "include": [
17
- ".testspectra/types/android.d.ts",
18
- ".testspectra/types/fixtures.d.ts",
19
- "page-objects/**/*.ts",
20
- "support/**/*.ts",
21
- "steps/**/*.ts",
22
- "actions/**/*.ts",
23
- "global-hooks/**/*.ts",
24
- "specs/**/hooks/**/*.ts",
25
- "specs/**/*.ts",
26
- "spectra.config.ts"
27
- ],
28
- "exclude": [
29
- "node_modules",
30
- "dist",
31
- "page-objects/**/web.ts",
32
- "page-objects/**/ios.ts",
33
- "support/**/web.*",
34
- "support/**/ios.*",
35
- "steps/**/web.step.ts",
36
- "steps/**/ios.step.ts",
37
- "actions/**/web.action.ts",
38
- "actions/**/ios.action.ts",
39
- "global-hooks/**/web.*",
40
- "global-hooks/**/ios.*",
41
- "specs/**/hooks/**/web.*",
42
- "specs/**/hooks/**/ios.*",
43
- "specs/**/web.test.ts",
44
- "specs/**/ios.test.ts"
45
- ]
46
- }
@@ -1,46 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "composite": true,
7
- "noEmit": true,
8
- "skipLibCheck": true,
9
- "strict": true,
10
- "types": [
11
- "node",
12
- "@wdio/globals/types",
13
- "@wdio/mocha-framework"
14
- ]
15
- },
16
- "include": [
17
- ".testspectra/types/ios.d.ts",
18
- ".testspectra/types/fixtures.d.ts",
19
- "page-objects/**/*.ts",
20
- "support/**/*.ts",
21
- "steps/**/*.ts",
22
- "actions/**/*.ts",
23
- "global-hooks/**/*.ts",
24
- "specs/**/hooks/**/*.ts",
25
- "specs/**/*.ts",
26
- "spectra.config.ts"
27
- ],
28
- "exclude": [
29
- "node_modules",
30
- "dist",
31
- "page-objects/**/web.ts",
32
- "page-objects/**/android.ts",
33
- "support/**/web.*",
34
- "support/**/android.*",
35
- "steps/**/web.step.ts",
36
- "steps/**/android.step.ts",
37
- "actions/**/web.action.ts",
38
- "actions/**/android.action.ts",
39
- "global-hooks/**/web.*",
40
- "global-hooks/**/android.*",
41
- "specs/**/hooks/**/web.*",
42
- "specs/**/hooks/**/android.*",
43
- "specs/**/web.test.ts",
44
- "specs/**/android.test.ts"
45
- ]
46
- }
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "skipLibCheck": true,
7
- "strict": true,
8
- "noEmit": true
9
- },
10
- "files": [],
11
- "references": [
12
- {
13
- "path": "./tsconfig.spectra.web.json"
14
- },
15
- {
16
- "path": "./tsconfig.spectra.android.json"
17
- },
18
- {
19
- "path": "./tsconfig.spectra.ios.json"
20
- }
21
- ]
22
- }
@@ -1,53 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "composite": true,
7
- "noEmit": true,
8
- "skipLibCheck": true,
9
- "strict": true,
10
- "types": [
11
- "node",
12
- "@wdio/globals/types",
13
- "@wdio/mocha-framework"
14
- ]
15
- },
16
- "include": [
17
- ".testspectra/types/web.d.ts",
18
- ".testspectra/types/fixtures.d.ts",
19
- "page-objects/**/*.ts",
20
- "support/**/*.ts",
21
- "steps/**/*.ts",
22
- "actions/**/*.ts",
23
- "global-hooks/**/*.ts",
24
- "specs/**/hooks/**/*.ts",
25
- "specs/**/*.ts",
26
- "spectra.config.ts"
27
- ],
28
- "exclude": [
29
- "node_modules",
30
- "dist",
31
- "page-objects/**/android.ts",
32
- "page-objects/**/ios.ts",
33
- "page-objects/**/mobile.ts",
34
- "support/**/android.*",
35
- "support/**/ios.*",
36
- "support/**/mobile.*",
37
- "steps/**/android.step.ts",
38
- "steps/**/ios.step.ts",
39
- "steps/**/mobile.step.ts",
40
- "actions/**/android.action.ts",
41
- "actions/**/ios.action.ts",
42
- "actions/**/mobile.action.ts",
43
- "global-hooks/**/android.*",
44
- "global-hooks/**/ios.*",
45
- "global-hooks/**/mobile.*",
46
- "specs/**/hooks/**/android.*",
47
- "specs/**/hooks/**/ios.*",
48
- "specs/**/hooks/**/mobile.*",
49
- "specs/**/android.test.ts",
50
- "specs/**/ios.test.ts",
51
- "specs/**/mobile.test.ts"
52
- ]
53
- }
@@ -1,7 +0,0 @@
1
- {
2
- "defaultEmail": "admin@testspectra.dev",
3
- "defaultToken": "JWT_abc123xyz",
4
- "pageTitle": "TestSpectra — Matchers API Reference",
5
- "welcomeText": "Welcome to TestSpectra",
6
- "dashboardHref": "/dashboard"
7
- }
@@ -1,3 +0,0 @@
1
- export default async function () {
2
- // Global mobile teardown
3
- }
@@ -1,3 +0,0 @@
1
- export default async function () {
2
- // Global web teardown
3
- }
@@ -1,3 +0,0 @@
1
- export default async function () {
2
- // Global mobile initialization
3
- }
@@ -1,3 +0,0 @@
1
- export default async function () {
2
- // Global web initialization
3
- }
@@ -1,21 +0,0 @@
1
- export class MatchersPage {
2
- get visibleElement() { return Spectra.get("~visible_element"); }
3
- get hiddenElement() { return Spectra.get("~hidden_element"); }
4
- get existingElement() { return Spectra.get("~existing_element"); }
5
- get submitButton() { return Spectra.get("~submit_button"); }
6
- get disabledButton() { return Spectra.get("~disabled_button"); }
7
- get checkbox() { return Spectra.get("~checkbox"); }
8
- get radio() { return Spectra.get("~radio"); }
9
- get emailInput() { return Spectra.get("~email_input"); }
10
- get tokenInput() { return Spectra.get("~token_input"); }
11
- get exactText() { return Spectra.get("~exact_text"); }
12
- get partialText() { return Spectra.get("~partial_text"); }
13
- get activeTab() { return Spectra.get("~active_tab"); }
14
- get navLink() { return Spectra.get("~nav_link"); }
15
- get productCards() { return Spectra.getAll("~product_card"); }
16
- get emptyList() { return Spectra.getAll("~empty_list"); }
17
-
18
- async open(_section = "") {}
19
- }
20
-
21
- export default new MatchersPage();
@@ -1,23 +0,0 @@
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 > *"); }
17
-
18
- async open(section = "") {
19
- await browser.url("/" + (section ? "#" + section : ""));
20
- }
21
- }
22
-
23
- export default new MatchersPage();
@@ -1,5 +0,0 @@
1
- export class NavigationPage {
2
- get sidebarLinks() { return Spectra.getAll("~sidebar_link"); }
3
- }
4
-
5
- export default new NavigationPage();
@@ -1,8 +0,0 @@
1
- export class NavigationPage {
2
- get sidebarLinks() { return Spectra.getAll("aside a"); }
3
- get overviewLink() { return Spectra.get("aside a[href='#overview']"); }
4
- get visibilityLink() { return Spectra.get("aside a[href='#visibility']"); }
5
- get playgroundLink() { return Spectra.get("aside a[href='#playground']"); }
6
- }
7
-
8
- export default new NavigationPage();
@@ -1,26 +0,0 @@
1
- export class PlaygroundPage {
2
- get visibleElement() { return Spectra.get("~visible_element"); }
3
- get hiddenElement() { return Spectra.get("~hidden_element"); }
4
- get existingElement() { return Spectra.get("~existing_element"); }
5
- get removedElement() { return Spectra.get("~removed_element"); }
6
- get enabledButton() { return Spectra.get("~enabled_button"); }
7
- get disabledButton() { return Spectra.get("~disabled_button"); }
8
- get termsCheckbox() { return Spectra.get("~terms_checkbox"); }
9
- get modeRadio() { return Spectra.get("~mode_radio"); }
10
- get emailInput() { return Spectra.get("~email_input"); }
11
- get tokenInput() { return Spectra.get("~token_input"); }
12
- get exactText() { return Spectra.get("~exact_text"); }
13
- get partialText() { return Spectra.get("~partial_text"); }
14
- get activeTab() { return Spectra.get("~active_tab"); }
15
- get navLink() { return Spectra.get("~nav_link"); }
16
- get productItems() { return Spectra.getAll("~product_item"); }
17
- get emptyList() { return Spectra.getAll("~empty_list"); }
18
-
19
- async open() {}
20
- async fillCredentials(email = Fixture.playgroundData.defaultEmail, token = Fixture.playgroundData.defaultToken) {
21
- await this.emailInput.type(email);
22
- await this.tokenInput.type(token);
23
- }
24
- }
25
-
26
- export default new PlaygroundPage();