@testspectra/cli 1.1.8-rc.1 → 1.1.8-rc.3

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 (188) hide show
  1. package/bin/.testspectra-runner.hash +1 -1
  2. package/bin/spectra.js +0 -0
  3. package/bin/{testspectra-runner → testspectra-runner.exe} +0 -0
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/commands/__tests__/run-e2e.test.js +49 -49
  6. package/dist/commands/init.js +148 -148
  7. package/dist/commands/test.js +29 -1
  8. package/dist/index.js +11 -11
  9. package/dist/linter/__tests__/component-test-imports.test.js +51 -51
  10. package/dist/linter/__tests__/spec-schema.test.js +167 -167
  11. package/dist/linter/schemas/spec.schema.d.ts +8 -8
  12. package/dist/linter/schemas/suite.schema.d.ts +4 -4
  13. package/dist/reporter/semantic-formatter.js +5 -0
  14. package/package.json +4 -4
  15. package/templates/default/CLAUDE.md +16 -16
  16. package/templates/default/global-hooks/after/mobile.hook.ts +3 -3
  17. package/templates/default/global-hooks/after/web.hook.ts +3 -3
  18. package/templates/default/global-hooks/before/mobile.hook.ts +3 -3
  19. package/templates/default/global-hooks/before/web.hook.ts +3 -3
  20. package/templates/default/package.json +2 -2
  21. package/templates/default/page-objects/AuthPage/mobile.ts +5 -5
  22. package/templates/default/page-objects/AuthPage/web.ts +10 -10
  23. package/templates/default/page-objects/MatchersPage/mobile.ts +70 -70
  24. package/templates/default/page-objects/MatchersPage/web.ts +43 -43
  25. package/templates/default/page-objects/NavigationPage/mobile.ts +14 -14
  26. package/templates/default/page-objects/NavigationPage/web.ts +8 -8
  27. package/templates/default/page-objects/PlaygroundPage/mobile.ts +42 -42
  28. package/templates/default/page-objects/PlaygroundPage/web.ts +31 -31
  29. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +53 -53
  30. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +19 -19
  31. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +31 -31
  32. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/android.test.ts +3 -3
  33. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/common.test.ts +3 -3
  34. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +27 -27
  35. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +19 -19
  36. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +26 -26
  37. package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/common.test.ts +30 -30
  38. package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/spec.md +22 -22
  39. package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/common.test.ts +27 -27
  40. package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/spec.md +20 -20
  41. package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/spec.md +24 -24
  42. package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/web.test.ts +26 -26
  43. package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/spec.md +37 -37
  44. package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/web.test.ts +21 -21
  45. package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/spec.md +29 -29
  46. package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/web.test.ts +16 -16
  47. package/templates/default/specs/ApiInterception/suite.md +10 -10
  48. package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/common.test.ts +30 -30
  49. package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/spec.md +23 -23
  50. package/templates/default/specs/ApiSeeding/hooks/after/common.hook.ts +16 -16
  51. package/templates/default/specs/ApiSeeding/hooks/before/common.hook.ts +28 -28
  52. package/templates/default/specs/ApiSeeding/suite.md +9 -9
  53. package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/mobile.test.ts +7 -7
  54. package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/spec.md +19 -19
  55. package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/web.test.ts +9 -9
  56. package/templates/default/specs/Authentication/suite.md +9 -9
  57. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +9 -9
  58. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +17 -17
  59. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +19 -19
  60. package/templates/default/specs/BrowserContext/TC-0022-history-navigation/mobile.test.ts +17 -17
  61. package/templates/default/specs/BrowserContext/TC-0022-history-navigation/spec.md +28 -28
  62. package/templates/default/specs/BrowserContext/TC-0022-history-navigation/web.test.ts +26 -26
  63. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/common.test.ts +26 -26
  64. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/spec.md +19 -19
  65. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +11 -11
  66. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +17 -17
  67. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +11 -11
  68. package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/common.test.ts +14 -14
  69. package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/spec.md +21 -21
  70. package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/mobile.test.ts +28 -28
  71. package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/spec.md +29 -29
  72. package/templates/default/specs/DeepLink/suite.md +9 -9
  73. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +11 -11
  74. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +17 -17
  75. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +11 -11
  76. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +29 -29
  77. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +19 -19
  78. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +29 -29
  79. package/templates/default/specs/ElementMatchers/suite.md +10 -10
  80. package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -5
  81. package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -16
  82. package/templates/default/specs/EnvironmentConfig/suite.md +9 -9
  83. package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/mobile.test.ts +26 -26
  84. package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/spec.md +22 -22
  85. package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/mobile.test.ts +13 -13
  86. package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/spec.md +20 -20
  87. package/templates/default/specs/PermissionRationale/suite.md +9 -9
  88. package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +6 -6
  89. package/templates/default/specs/Playground/TC-0001-form-controls/spec.md +18 -18
  90. package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +6 -6
  91. package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +6 -6
  92. package/templates/default/specs/Playground/TC-0002-toggle-elements/spec.md +18 -18
  93. package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +6 -6
  94. package/templates/default/spectra.config.ts +52 -52
  95. package/templates/default/support/actions/fillCredentials/mobile.action.ts +4 -4
  96. package/templates/default/support/actions/fillCredentials/web.action.ts +4 -4
  97. package/templates/default/support/actions/seedSession/mobile.action.ts +9 -9
  98. package/templates/default/support/actions/seedSession/web.action.ts +13 -13
  99. package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +5 -5
  100. package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +5 -5
  101. package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +6 -6
  102. package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +6 -6
  103. package/templates/nx/.nx/workspace-data/{70094CFD-E89B-57A1-9619-2FC5F4963C54.db-shm → 59842386-c7c4-44ca-b2c2-20e1700bd13d.db-shm} +0 -0
  104. package/templates/nx/.nx/workspace-data/{70094CFD-E89B-57A1-9619-2FC5F4963C54.db-wal → 59842386-c7c4-44ca-b2c2-20e1700bd13d.db-wal} +0 -0
  105. package/templates/nx/.nx/workspace-data/d/daemon.log +1612 -5388
  106. package/templates/nx/.nx/workspace-data/d/server-process.json +1 -1
  107. package/templates/nx/.nx/workspace-data/file-map.json +115 -115
  108. package/templates/nx/.nx/workspace-data/lockfile.hash +1 -1
  109. package/templates/nx/.nx/workspace-data/nx_files.nxt +0 -0
  110. package/templates/nx/.nx/workspace-data/parsed-lock-file.json +535 -535
  111. package/templates/nx/.nx/workspace-data/project-graph.json +584 -584
  112. package/templates/nx/CLAUDE.md +10 -10
  113. package/templates/nx/package.json +2 -2
  114. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +27 -27
  115. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -27
  116. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +24 -24
  117. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -24
  118. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +3 -3
  119. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +19 -19
  120. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +3 -3
  121. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +17 -17
  122. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +3 -3
  123. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +11 -11
  124. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +3 -3
  125. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +11 -11
  126. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +3 -3
  127. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +29 -29
  128. package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -5
  129. package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -16
  130. package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/suite.md +9 -9
  131. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/mobile.test.ts +3 -3
  132. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +6 -6
  133. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +3 -3
  134. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +6 -6
  135. package/templates/nx/pnpm-lock.yaml +6663 -6663
  136. package/templates/nx/pnpm-workspace.yaml +9 -9
  137. package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +33 -33
  138. package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +91 -91
  139. package/templates/nx/shared/testing/page-objects/NavigationPage/mobile.ts +5 -5
  140. package/templates/nx/shared/testing/page-objects/NavigationPage/web.ts +8 -8
  141. package/templates/nx/shared/testing/page-objects/PlaygroundPage/mobile.ts +26 -26
  142. package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +31 -31
  143. package/templates/nx/shared/testing/project.json +19 -19
  144. package/templates/nx/shared/testing/support/actions/fillCredentials/mobile.action.ts +4 -4
  145. package/templates/nx/shared/testing/support/actions/fillCredentials/web.action.ts +4 -4
  146. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/mobile.step.ts +3 -3
  147. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +5 -5
  148. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +4 -4
  149. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +6 -6
  150. package/templates/nx/spectra.config.ts +52 -52
  151. package/templates/react-component/.cursorrules +17 -17
  152. package/templates/react-component/.vscode/extensions.json +5 -5
  153. package/templates/react-component/CLAUDE.md +14 -14
  154. package/templates/react-component/README.md +69 -69
  155. package/templates/react-component/fixtures/component-mock.json +12 -12
  156. package/templates/react-component/global-hooks/after/web.hook.ts +3 -3
  157. package/templates/react-component/global-hooks/before/web.hook.ts +3 -3
  158. package/templates/react-component/package.json +27 -27
  159. package/templates/react-component/page-objects/BadgeComponent/web.ts +23 -23
  160. package/templates/react-component/page-objects/ButtonComponent/web.ts +23 -23
  161. package/templates/react-component/page-objects/InputComponent/web.ts +13 -13
  162. package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/spec.md +18 -18
  163. package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/web.test.tsx +11 -11
  164. package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/spec.md +18 -18
  165. package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/web.test.tsx +10 -10
  166. package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/spec.md +18 -18
  167. package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/web.test.tsx +16 -16
  168. package/templates/react-component/specs/BadgeComponent/suite.md +12 -12
  169. package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/spec.md +19 -19
  170. package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/web.test.tsx +28 -28
  171. package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/spec.md +19 -19
  172. package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/web.test.tsx +22 -22
  173. package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/spec.md +18 -18
  174. package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/web.test.tsx +8 -8
  175. package/templates/react-component/specs/ButtonComponent/suite.md +12 -12
  176. package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/spec.md +20 -20
  177. package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/web.test.tsx +28 -28
  178. package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/spec.md +18 -18
  179. package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/web.test.tsx +9 -9
  180. package/templates/react-component/specs/InputComponent/suite.md +12 -12
  181. package/templates/react-component/spectra.config.ts +27 -27
  182. package/templates/react-component/src/components/Badge/Badge.tsx +60 -60
  183. package/templates/react-component/src/components/Button/Button.tsx +57 -57
  184. package/templates/react-component/src/components/Input/Input.tsx +41 -41
  185. package/templates/react-component/src/test-utils.tsx +23 -23
  186. package/templates/react-component/support/actions/fillInputField/web.action.ts +9 -9
  187. package/templates/react-component/support/steps/verifyButtonState/web.step.ts +12 -12
  188. /package/templates/nx/.nx/workspace-data/{70094CFD-E89B-57A1-9619-2FC5F4963C54.db → 59842386-c7c4-44ca-b2c2-20e1700bd13d.db} +0 -0
@@ -1,17 +1,17 @@
1
- ---
2
- id: TC-0003-visibility-and-dom
3
- title: Verify element visibility and existence matchers
4
- priority: High
5
- caseType: Positive
6
- status: ready-for-automation
7
- coverage:
8
- web: automated
9
- mobile: automated
10
- ---
11
-
12
- # Verify element visibility and existence matchers
13
-
14
- ## Test Steps
15
- 1. Open visibility section in matchers page
16
- 2. Assert visible element has be.visible state
17
- 3. Assert existing element exists in DOM
1
+ ---
2
+ id: TC-0003-visibility-and-dom
3
+ title: Verify element visibility and existence matchers
4
+ priority: High
5
+ caseType: Positive
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: automated
9
+ mobile: automated
10
+ ---
11
+
12
+ # Verify element visibility and existence matchers
13
+
14
+ ## Test Steps
15
+ 1. Open visibility section in matchers page
16
+ 2. Assert visible element has be.visible state
17
+ 3. Assert existing element exists in DOM
@@ -1,11 +1,11 @@
1
- it("Verify element visibility and existence matchers", async () => {
2
- await MatchersPage.open("visibility");
3
-
4
- // Element visibility (positive and negative)
5
- await MatchersPage.visibleElement.shouldBeVisible();
6
- await MatchersPage.hiddenElement.shouldNotBeVisible();
7
-
8
- // DOM existence (positive and negative)
9
- await MatchersPage.existingElement.shouldExist();
10
- await Spectra.get("#demo-non-existent-el").shouldNotExist();
11
- });
1
+ it("Verify element visibility and existence matchers", async () => {
2
+ await MatchersPage.open("visibility");
3
+
4
+ // Element visibility (positive and negative)
5
+ await MatchersPage.visibleElement.shouldBeVisible();
6
+ await MatchersPage.hiddenElement.shouldNotBeVisible();
7
+
8
+ // DOM existence (positive and negative)
9
+ await MatchersPage.existingElement.shouldExist();
10
+ await Spectra.get("#demo-non-existent-el").shouldNotExist();
11
+ });
@@ -1,29 +1,29 @@
1
- it("Verify button state, checkbox, radio and attributes", async () => {
2
- await MatchersPage.open("state");
3
-
4
- // Interactivity & state assertions
5
- await MatchersPage.submitButton.shouldBeEnabled();
6
- await MatchersPage.submitButton.shouldBeClickable();
7
-
8
- await MatchersPage.disabledButton.shouldBeDisabled();
9
- await MatchersPage.disabledButton.shouldNotBeClickable();
10
-
11
- // Checked states
12
- await MatchersPage.checkbox.shouldNotBeChecked();
13
- await MatchersPage.radio.shouldBeChecked();
14
-
15
- // Focus states
16
- await MatchersPage.focusInput.shouldNotBeFocused();
17
- await MatchersPage.focusInput.click();
18
- await MatchersPage.focusInput.shouldBeFocused();
19
-
20
- // Class, Attribute, and CSS assertions
21
- await MatchersPage.activeTab.shouldHaveClass("is-active");
22
- await MatchersPage.activeTab.shouldNotHaveClass("is-hidden");
23
-
24
- await MatchersPage.navLink.shouldHaveAttribute("accessibilityLabel", "nav-link");
25
- await MatchersPage.navLink.shouldNotHaveAttribute("disabled");
26
-
27
- await MatchersPage.styledElement.shouldHaveCss("color", "rgba(239,68,68,1)");
28
- await MatchersPage.styledElement.shouldNotHaveCss("color", "rgba(0,0,255,1)");
29
- });
1
+ it("Verify button state, checkbox, radio and attributes", async () => {
2
+ await MatchersPage.open("state");
3
+
4
+ // Interactivity & state assertions
5
+ await MatchersPage.submitButton.shouldBeEnabled();
6
+ await MatchersPage.submitButton.shouldBeClickable();
7
+
8
+ await MatchersPage.disabledButton.shouldBeDisabled();
9
+ await MatchersPage.disabledButton.shouldNotBeClickable();
10
+
11
+ // Checked states
12
+ await MatchersPage.checkbox.shouldNotBeChecked();
13
+ await MatchersPage.radio.shouldBeChecked();
14
+
15
+ // Focus states
16
+ await MatchersPage.focusInput.shouldNotBeFocused();
17
+ await MatchersPage.focusInput.click();
18
+ await MatchersPage.focusInput.shouldBeFocused();
19
+
20
+ // Class, Attribute, and CSS assertions
21
+ await MatchersPage.activeTab.shouldHaveClass("is-active");
22
+ await MatchersPage.activeTab.shouldNotHaveClass("is-hidden");
23
+
24
+ await MatchersPage.navLink.shouldHaveAttribute("accessibilityLabel", "nav-link");
25
+ await MatchersPage.navLink.shouldNotHaveAttribute("disabled");
26
+
27
+ await MatchersPage.styledElement.shouldHaveCss("color", "rgba(239,68,68,1)");
28
+ await MatchersPage.styledElement.shouldNotHaveCss("color", "rgba(0,0,255,1)");
29
+ });
@@ -1,19 +1,19 @@
1
- ---
2
- id: TC-0004-states-and-attributes
3
- title: Verify button state, checkbox, radio and attributes
4
- priority: High
5
- caseType: Positive
6
- status: ready-for-automation
7
- coverage:
8
- web: automated
9
- mobile: automated
10
- ---
11
-
12
- # Verify button state, checkbox, radio and attributes
13
-
14
- ## Test Steps
15
- 1. Open element state section in matchers page
16
- 2. Assert submit button is enabled and disabled button is disabled
17
- 3. Assert terms checkbox is not checked
18
- 4. Assert active tab has is-active class
19
- 5. Assert navigation link has correct href attribute
1
+ ---
2
+ id: TC-0004-states-and-attributes
3
+ title: Verify button state, checkbox, radio and attributes
4
+ priority: High
5
+ caseType: Positive
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: automated
9
+ mobile: automated
10
+ ---
11
+
12
+ # Verify button state, checkbox, radio and attributes
13
+
14
+ ## Test Steps
15
+ 1. Open element state section in matchers page
16
+ 2. Assert submit button is enabled and disabled button is disabled
17
+ 3. Assert terms checkbox is not checked
18
+ 4. Assert active tab has is-active class
19
+ 5. Assert navigation link has correct href attribute
@@ -1,29 +1,29 @@
1
- it("Verify button state, checkbox, radio and attributes", async () => {
2
- await MatchersPage.open("state");
3
-
4
- // Interactivity & state assertions
5
- await MatchersPage.submitButton.shouldBeEnabled();
6
- await MatchersPage.submitButton.shouldBeClickable();
7
-
8
- await MatchersPage.disabledButton.shouldBeDisabled();
9
- await MatchersPage.disabledButton.shouldNotBeClickable();
10
-
11
- // Checked states
12
- await MatchersPage.checkbox.shouldNotBeChecked();
13
- await MatchersPage.radio.shouldBeChecked();
14
-
15
- // Focus states
16
- await MatchersPage.focusInput.shouldNotBeFocused();
17
- await MatchersPage.focusInput.click();
18
- await MatchersPage.focusInput.shouldBeFocused();
19
-
20
- // Class, Attribute, and CSS assertions
21
- await MatchersPage.activeTab.shouldHaveClass("is-active");
22
- await MatchersPage.activeTab.shouldNotHaveClass("is-hidden");
23
-
24
- await MatchersPage.navLink.shouldHaveAttribute("href", Fixture.playgroundData.dashboardHref);
25
- await MatchersPage.navLink.shouldNotHaveAttribute("disabled");
26
-
27
- await MatchersPage.styledElement.shouldHaveCss("color", "rgba(239,68,68,1)");
28
- await MatchersPage.styledElement.shouldNotHaveCss("color", "rgba(0,0,255,1)");
29
- });
1
+ it("Verify button state, checkbox, radio and attributes", async () => {
2
+ await MatchersPage.open("state");
3
+
4
+ // Interactivity & state assertions
5
+ await MatchersPage.submitButton.shouldBeEnabled();
6
+ await MatchersPage.submitButton.shouldBeClickable();
7
+
8
+ await MatchersPage.disabledButton.shouldBeDisabled();
9
+ await MatchersPage.disabledButton.shouldNotBeClickable();
10
+
11
+ // Checked states
12
+ await MatchersPage.checkbox.shouldNotBeChecked();
13
+ await MatchersPage.radio.shouldBeChecked();
14
+
15
+ // Focus states
16
+ await MatchersPage.focusInput.shouldNotBeFocused();
17
+ await MatchersPage.focusInput.click();
18
+ await MatchersPage.focusInput.shouldBeFocused();
19
+
20
+ // Class, Attribute, and CSS assertions
21
+ await MatchersPage.activeTab.shouldHaveClass("is-active");
22
+ await MatchersPage.activeTab.shouldNotHaveClass("is-hidden");
23
+
24
+ await MatchersPage.navLink.shouldHaveAttribute("href", Fixture.playgroundData.dashboardHref);
25
+ await MatchersPage.navLink.shouldNotHaveAttribute("disabled");
26
+
27
+ await MatchersPage.styledElement.shouldHaveCss("color", "rgba(239,68,68,1)");
28
+ await MatchersPage.styledElement.shouldNotHaveCss("color", "rgba(0,0,255,1)");
29
+ });
@@ -1,10 +1,10 @@
1
- ---
2
- name: Untitled Suite
3
- id: suite-element-matchers
4
-
5
- description: Element visibility, existence, form states and attributes
6
- executionOrder: 1.0
7
- parallel: true
8
- ---
9
-
10
- # Suite: ElementMatchers
1
+ ---
2
+ name: Untitled Suite
3
+ id: suite-element-matchers
4
+
5
+ description: Element visibility, existence, form states and attributes
6
+ executionOrder: 1.0
7
+ parallel: true
8
+ ---
9
+
10
+ # Suite: ElementMatchers
@@ -1,5 +1,5 @@
1
- it("Verify a custom environmentVariables entry is readable via Spectra.env", async () => {
2
- if (Spectra.env.DEMO_API_MODE !== "sandbox") {
3
- throw new Error(`Expected Spectra.env.DEMO_API_MODE to be "sandbox", got "${Spectra.env.DEMO_API_MODE}"`);
4
- }
5
- });
1
+ it("Verify a custom environmentVariables entry is readable via Spectra.env", async () => {
2
+ if (Spectra.env.DEMO_API_MODE !== "sandbox") {
3
+ throw new Error(`Expected Spectra.env.DEMO_API_MODE to be "sandbox", got "${Spectra.env.DEMO_API_MODE}"`);
4
+ }
5
+ });
@@ -1,16 +1,16 @@
1
- ---
2
- id: TC-0019-read-custom-environment-variable
3
- title: Verify a custom environmentVariables entry is readable via Spectra.env
4
- priority: Medium
5
- caseType: Positive
6
- status: ready-for-automation
7
- coverage:
8
- web: automated
9
- mobile: automated
10
- ---
11
-
12
- # Verify a custom environmentVariables entry is readable via Spectra.env
13
-
14
- ## Test Steps
15
- 1. Read the DEMO_API_MODE variable via the typed Spectra.env
16
- 2. Assert it matches the value configured in spectra.config.ts's executionConfig.environmentVariables
1
+ ---
2
+ id: TC-0019-read-custom-environment-variable
3
+ title: Verify a custom environmentVariables entry is readable via Spectra.env
4
+ priority: Medium
5
+ caseType: Positive
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: automated
9
+ mobile: automated
10
+ ---
11
+
12
+ # Verify a custom environmentVariables entry is readable via Spectra.env
13
+
14
+ ## Test Steps
15
+ 1. Read the DEMO_API_MODE variable via the typed Spectra.env
16
+ 2. Assert it matches the value configured in spectra.config.ts's executionConfig.environmentVariables
@@ -1,9 +1,9 @@
1
- ---
2
- id: suite-environment-config
3
- name: EnvironmentConfig
4
- description: Reading custom executionConfig.environmentVariables values via Spectra.env
5
- executionOrder: 2.3
6
- parallel: true
7
- ---
8
-
9
- # Suite: EnvironmentConfig
1
+ ---
2
+ id: suite-environment-config
3
+ name: EnvironmentConfig
4
+ description: Reading custom executionConfig.environmentVariables values via Spectra.env
5
+ executionOrder: 2.3
6
+ parallel: true
7
+ ---
8
+
9
+ # Suite: EnvironmentConfig
@@ -1,26 +1,26 @@
1
- it("Confirm custom rationale dialog Allow triggers real permission request and grants camera access", async () => {
2
- // Navigate to the dedicated permission-rationale route (real router path, not a hash/scroll
3
- // section) via the header link.
4
- await Spectra.get("~nav-to-permission-demo").click();
5
-
6
- await Spectra.get("~permission-status-text").shouldHaveText("Not requested");
7
-
8
- await Spectra.get("~request-camera-permission-btn").click();
9
-
10
- // The custom rationale dialog appears first — no real permission dialog yet.
11
- await Spectra.get("~rationale-allow-btn").shouldBeVisible();
12
-
13
- await Spectra.get("~rationale-allow-btn").click();
14
-
15
- // Confirming the custom dialog triggers the real Android permission request. Grant it
16
- // on-demand right now, exactly like a real device automation flow would — the app itself
17
- // is resilient to the resulting race (see permission-rationale.tsx's recheck loop), so the
18
- // status still lands on "Granted" below regardless of exactly when this call resolves
19
- // relative to the OS dialog.
20
- await Spectra.grantPermission("android.permission.CAMERA");
21
-
22
- await Spectra.get("~permission-status-text").shouldHaveText("Granted");
23
-
24
- // Return to the home screen so later suites in the same batch don't inherit this route.
25
- await Spectra.get("~back-to-home-btn").click();
26
- });
1
+ it("Confirm custom rationale dialog Allow triggers real permission request and grants camera access", async () => {
2
+ // Navigate to the dedicated permission-rationale route (real router path, not a hash/scroll
3
+ // section) via the header link.
4
+ await Spectra.get("~nav-to-permission-demo").click();
5
+
6
+ await Spectra.get("~permission-status-text").shouldHaveText("Not requested");
7
+
8
+ await Spectra.get("~request-camera-permission-btn").click();
9
+
10
+ // The custom rationale dialog appears first — no real permission dialog yet.
11
+ await Spectra.get("~rationale-allow-btn").shouldBeVisible();
12
+
13
+ await Spectra.get("~rationale-allow-btn").click();
14
+
15
+ // Confirming the custom dialog triggers the real Android permission request. Grant it
16
+ // on-demand right now, exactly like a real device automation flow would — the app itself
17
+ // is resilient to the resulting race (see permission-rationale.tsx's recheck loop), so the
18
+ // status still lands on "Granted" below regardless of exactly when this call resolves
19
+ // relative to the OS dialog.
20
+ await Spectra.grantPermission("android.permission.CAMERA");
21
+
22
+ await Spectra.get("~permission-status-text").shouldHaveText("Granted");
23
+
24
+ // Return to the home screen so later suites in the same batch don't inherit this route.
25
+ await Spectra.get("~back-to-home-btn").click();
26
+ });
@@ -1,22 +1,22 @@
1
- ---
2
- id: TC-0010-camera-permission-allow
3
- title: Confirm custom rationale dialog Allow triggers real permission request and grants camera access
4
- priority: High
5
- caseType: Positive
6
- status: ready-for-automation
7
- coverage:
8
- web: unsupported
9
- mobile: automated
10
- ---
11
-
12
- # Confirm custom rationale dialog Allow triggers real permission request and grants camera access
13
-
14
- ## Test Steps
15
- 1. Navigate to the permission rationale demo route
16
- 2. Assert the initial status is "Not requested"
17
- 3. Click the request camera permission button
18
- 4. Assert the custom rationale dialog appears
19
- 5. Click Allow
20
- 6. Grant the real camera permission on demand
21
- 7. Assert the status becomes "Granted"
22
- 8. Return to the home screen
1
+ ---
2
+ id: TC-0010-camera-permission-allow
3
+ title: Confirm custom rationale dialog Allow triggers real permission request and grants camera access
4
+ priority: High
5
+ caseType: Positive
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: unsupported
9
+ mobile: automated
10
+ ---
11
+
12
+ # Confirm custom rationale dialog Allow triggers real permission request and grants camera access
13
+
14
+ ## Test Steps
15
+ 1. Navigate to the permission rationale demo route
16
+ 2. Assert the initial status is "Not requested"
17
+ 3. Click the request camera permission button
18
+ 4. Assert the custom rationale dialog appears
19
+ 5. Click Allow
20
+ 6. Grant the real camera permission on demand
21
+ 7. Assert the status becomes "Granted"
22
+ 8. Return to the home screen
@@ -1,13 +1,13 @@
1
- it("Confirm custom rationale dialog Deny never triggers the real permission request", async () => {
2
- await Spectra.get("~nav-to-permission-demo").click();
3
-
4
- await Spectra.get("~request-camera-permission-btn").click();
5
- await Spectra.get("~rationale-deny-btn").shouldBeVisible();
6
- await Spectra.get("~rationale-deny-btn").click();
7
-
8
- // Deliberately never calls the real permission API — the status must reflect the custom
9
- // dialog's own decision, not any OS-level request.
10
- await Spectra.get("~permission-status-text").shouldHaveText("Declined in rationale dialog");
11
-
12
- await Spectra.get("~back-to-home-btn").click();
13
- });
1
+ it("Confirm custom rationale dialog Deny never triggers the real permission request", async () => {
2
+ await Spectra.get("~nav-to-permission-demo").click();
3
+
4
+ await Spectra.get("~request-camera-permission-btn").click();
5
+ await Spectra.get("~rationale-deny-btn").shouldBeVisible();
6
+ await Spectra.get("~rationale-deny-btn").click();
7
+
8
+ // Deliberately never calls the real permission API — the status must reflect the custom
9
+ // dialog's own decision, not any OS-level request.
10
+ await Spectra.get("~permission-status-text").shouldHaveText("Declined in rationale dialog");
11
+
12
+ await Spectra.get("~back-to-home-btn").click();
13
+ });
@@ -1,20 +1,20 @@
1
- ---
2
- id: TC-0011-camera-permission-deny
3
- title: Confirm custom rationale dialog Deny never triggers the real permission request
4
- priority: High
5
- caseType: Negative
6
- status: ready-for-automation
7
- coverage:
8
- web: unsupported
9
- mobile: automated
10
- ---
11
-
12
- # Confirm custom rationale dialog Deny never triggers the real permission request
13
-
14
- ## Test Steps
15
- 1. Navigate to the permission rationale demo route
16
- 2. Click the request camera permission button
17
- 3. Assert the custom rationale dialog appears
18
- 4. Click Deny
19
- 5. Assert the status reflects the dialog's own decision without any real permission request
20
- 6. Return to the home screen
1
+ ---
2
+ id: TC-0011-camera-permission-deny
3
+ title: Confirm custom rationale dialog Deny never triggers the real permission request
4
+ priority: High
5
+ caseType: Negative
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: unsupported
9
+ mobile: automated
10
+ ---
11
+
12
+ # Confirm custom rationale dialog Deny never triggers the real permission request
13
+
14
+ ## Test Steps
15
+ 1. Navigate to the permission rationale demo route
16
+ 2. Click the request camera permission button
17
+ 3. Assert the custom rationale dialog appears
18
+ 4. Click Deny
19
+ 5. Assert the status reflects the dialog's own decision without any real permission request
20
+ 6. Return to the home screen
@@ -1,9 +1,9 @@
1
- ---
2
- id: suite-permission-rationale
3
- name: PermissionRationale
4
- description: Android runtime permission rationale dialog and on-demand Spectra.grantPermission()
5
- executionOrder: 2.0
6
- parallel: true
7
- ---
8
-
9
- # Suite: PermissionRationale
1
+ ---
2
+ id: suite-permission-rationale
3
+ name: PermissionRationale
4
+ description: Android runtime permission rationale dialog and on-demand Spectra.grantPermission()
5
+ executionOrder: 2.0
6
+ parallel: true
7
+ ---
8
+
9
+ # Suite: PermissionRationale
@@ -1,6 +1,6 @@
1
- it("Verify playground form inputs and default states", async () => {
2
- await Step.verifyPlaygroundState();
3
- await PlaygroundPage.emailInput.shouldHaveValue(Fixture.playgroundData.defaultEmail);
4
- await PlaygroundPage.tokenInput.shouldContainValue("JWT_");
5
- await PlaygroundPage.exactText.shouldHaveText(Fixture.playgroundData.welcomeText);
6
- });
1
+ it("Verify playground form inputs and default states", async () => {
2
+ await Step.verifyPlaygroundState();
3
+ await PlaygroundPage.emailInput.shouldHaveValue(Fixture.playgroundData.defaultEmail);
4
+ await PlaygroundPage.tokenInput.shouldContainValue("JWT_");
5
+ await PlaygroundPage.exactText.shouldHaveText(Fixture.playgroundData.welcomeText);
6
+ });
@@ -1,18 +1,18 @@
1
- ---
2
- id: TC-0001-form-controls
3
- title: Verify playground form inputs and default states
4
- priority: High
5
- caseType: Positive
6
- status: ready-for-automation
7
- coverage:
8
- web: automated
9
- mobile: automated
10
- ---
11
-
12
- # Verify playground form inputs and default states
13
-
14
- ## Test Steps
15
- 1. @step:verifyPlaygroundState
16
- 2. Verify playground email input has default email
17
- 3. Verify token input contains JWT token
18
- 4. Verify exact welcome text matches playground data
1
+ ---
2
+ id: TC-0001-form-controls
3
+ title: Verify playground form inputs and default states
4
+ priority: High
5
+ caseType: Positive
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: automated
9
+ mobile: automated
10
+ ---
11
+
12
+ # Verify playground form inputs and default states
13
+
14
+ ## Test Steps
15
+ 1. @step:verifyPlaygroundState
16
+ 2. Verify playground email input has default email
17
+ 3. Verify token input contains JWT token
18
+ 4. Verify exact welcome text matches playground data
@@ -1,6 +1,6 @@
1
- it("Verify playground form inputs and default states", async () => {
2
- await Step.verifyPlaygroundState();
3
- await PlaygroundPage.emailInput.shouldHaveValue(Fixture.playgroundData.defaultEmail);
4
- await PlaygroundPage.tokenInput.shouldContainValue("JWT_");
5
- await PlaygroundPage.exactText.shouldHaveText(Fixture.playgroundData.welcomeText);
6
- });
1
+ it("Verify playground form inputs and default states", async () => {
2
+ await Step.verifyPlaygroundState();
3
+ await PlaygroundPage.emailInput.shouldHaveValue(Fixture.playgroundData.defaultEmail);
4
+ await PlaygroundPage.tokenInput.shouldContainValue("JWT_");
5
+ await PlaygroundPage.exactText.shouldHaveText(Fixture.playgroundData.welcomeText);
6
+ });
@@ -1,6 +1,6 @@
1
- it("Verify typing credentials and updating playground inputs", async () => {
2
- await PlaygroundPage.open();
3
- await PlaygroundPage.fillCredentials("qa.expert@testspectra.dev", "JWT_custom_session_token");
4
- await PlaygroundPage.emailInput.shouldHaveValue("qa.expert@testspectra.dev");
5
- await PlaygroundPage.tokenInput.shouldContainValue("JWT_custom_session_token");
6
- });
1
+ it("Verify typing credentials and updating playground inputs", async () => {
2
+ await PlaygroundPage.open();
3
+ await PlaygroundPage.fillCredentials("qa.expert@testspectra.dev", "JWT_custom_session_token");
4
+ await PlaygroundPage.emailInput.shouldHaveValue("qa.expert@testspectra.dev");
5
+ await PlaygroundPage.tokenInput.shouldContainValue("JWT_custom_session_token");
6
+ });
@@ -1,18 +1,18 @@
1
- ---
2
- id: TC-0002-toggle-elements
3
- title: Verify typing credentials and updating playground inputs
4
- priority: High
5
- caseType: Positive
6
- status: ready-for-automation
7
- coverage:
8
- web: automated
9
- mobile: automated
10
- ---
11
-
12
- # Verify typing credentials and updating playground inputs
13
-
14
- ## Test Steps
15
- 1. Open playground page
16
- 2. Fill credentials into email and token input fields
17
- 3. Verify email input contains updated email
18
- 4. Verify token input contains updated session token
1
+ ---
2
+ id: TC-0002-toggle-elements
3
+ title: Verify typing credentials and updating playground inputs
4
+ priority: High
5
+ caseType: Positive
6
+ status: ready-for-automation
7
+ coverage:
8
+ web: automated
9
+ mobile: automated
10
+ ---
11
+
12
+ # Verify typing credentials and updating playground inputs
13
+
14
+ ## Test Steps
15
+ 1. Open playground page
16
+ 2. Fill credentials into email and token input fields
17
+ 3. Verify email input contains updated email
18
+ 4. Verify token input contains updated session token
@@ -1,6 +1,6 @@
1
- it("Verify typing credentials and updating playground inputs", async () => {
2
- await PlaygroundPage.open();
3
- await PlaygroundPage.fillCredentials("qa.expert@testspectra.dev", "JWT_custom_session_token");
4
- await PlaygroundPage.emailInput.shouldHaveValue("qa.expert@testspectra.dev");
5
- await PlaygroundPage.tokenInput.shouldContainValue("JWT_custom_session_token");
6
- });
1
+ it("Verify typing credentials and updating playground inputs", async () => {
2
+ await PlaygroundPage.open();
3
+ await PlaygroundPage.fillCredentials("qa.expert@testspectra.dev", "JWT_custom_session_token");
4
+ await PlaygroundPage.emailInput.shouldHaveValue("qa.expert@testspectra.dev");
5
+ await PlaygroundPage.tokenInput.shouldContainValue("JWT_custom_session_token");
6
+ });