@testspectra/cli 1.1.8-rc.3 → 1.1.8-rc.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/bin/spectra.js +0 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/commands/__tests__/doctor-filter.test.d.ts +1 -0
- package/dist/commands/__tests__/doctor-filter.test.js +37 -0
- package/dist/commands/__tests__/run-e2e.test.js +49 -49
- package/dist/commands/__tests__/test-error-streaming.test.d.ts +1 -0
- package/dist/commands/__tests__/test-error-streaming.test.js +85 -0
- package/dist/commands/__tests__/test-scaffolding.test.d.ts +1 -0
- package/dist/commands/__tests__/test-scaffolding.test.js +32 -0
- package/dist/commands/__tests__/upgrade.test.d.ts +1 -0
- package/dist/commands/__tests__/upgrade.test.js +95 -0
- package/dist/commands/add.js +5 -4
- package/dist/commands/devices.js +1 -0
- package/dist/commands/docs.d.ts +4 -0
- package/dist/commands/docs.js +17 -0
- package/dist/commands/doctor.d.ts +9 -1
- package/dist/commands/doctor.js +17 -3
- package/dist/commands/init.js +7 -160
- package/dist/commands/install.js +5 -0
- package/dist/commands/license.js +1 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +22 -0
- package/dist/commands/test.d.ts +13 -0
- package/dist/commands/test.js +115 -21
- package/dist/commands/upgrade.d.ts +12 -0
- package/dist/commands/upgrade.js +197 -0
- package/dist/config/schema.d.ts +53 -0
- package/dist/config/schema.js +2 -0
- package/dist/generator/__tests__/tsconfig-isolation.test.js +2 -1
- package/dist/generator/__tests__/type-generator.test.js +38 -0
- package/dist/generator/architecture-doc-generator.d.ts +14 -0
- package/dist/generator/architecture-doc-generator.js +80 -0
- package/dist/generator/index.d.ts +1 -0
- package/dist/generator/index.js +1 -0
- package/dist/generator/tsconfig-generator.js +1 -1
- package/dist/generator/type-generator.d.ts +5 -2
- package/dist/generator/type-generator.js +14 -17
- package/dist/index.js +56 -26
- package/dist/linter/__tests__/component-test-imports.test.js +51 -51
- package/dist/linter/__tests__/shared-lib-boundary.test.js +15 -15
- package/dist/linter/__tests__/spec-schema.test.js +167 -167
- package/dist/linter/discovery.d.ts +3 -3
- package/dist/linter/discovery.js +7 -7
- package/dist/linter/schemas/spec.schema.d.ts +8 -8
- package/dist/linter/schemas/suite.schema.d.ts +4 -4
- package/dist/runner/bridge.d.ts +1 -1
- package/dist/runner/bridge.js +101 -11
- package/dist/runner/reporter.d.ts +1 -0
- package/dist/runner/reporter.js +12 -6
- package/dist/utils/__tests__/dev-server-manager.test.d.ts +1 -0
- package/dist/utils/__tests__/dev-server-manager.test.js +72 -0
- package/dist/utils/background-update-check.d.ts +1 -0
- package/dist/utils/background-update-check.js +43 -0
- package/dist/utils/dependency-updates.d.ts +15 -0
- package/dist/utils/dependency-updates.js +107 -0
- package/dist/utils/dev-server-manager.d.ts +40 -0
- package/dist/utils/dev-server-manager.js +257 -0
- package/dist/utils/update-notifier.d.ts +2 -0
- package/dist/utils/update-notifier.js +67 -0
- package/package.json +36 -30
- package/templates/default/CLAUDE.md +16 -16
- package/templates/default/global-hooks/after/mobile.hook.ts +3 -3
- package/templates/default/global-hooks/after/web.hook.ts +3 -3
- package/templates/default/global-hooks/before/mobile.hook.ts +3 -3
- package/templates/default/global-hooks/before/web.hook.ts +3 -3
- package/templates/default/package.json +2 -2
- package/templates/default/page-objects/AuthPage/mobile.ts +5 -5
- package/templates/default/page-objects/AuthPage/web.ts +10 -10
- package/templates/default/page-objects/MatchersPage/mobile.ts +70 -70
- package/templates/default/page-objects/MatchersPage/web.ts +43 -43
- package/templates/default/page-objects/NavigationPage/mobile.ts +14 -14
- package/templates/default/page-objects/NavigationPage/web.ts +8 -8
- package/templates/default/page-objects/PlaygroundPage/mobile.ts +42 -42
- package/templates/default/page-objects/PlaygroundPage/web.ts +31 -31
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +53 -53
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +19 -19
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +31 -31
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/android.test.ts +3 -3
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/common.test.ts +3 -3
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +27 -27
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +19 -19
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +26 -26
- package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/common.test.ts +30 -30
- package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/spec.md +22 -22
- package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/common.test.ts +27 -27
- package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/spec.md +20 -20
- package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/spec.md +24 -24
- package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/web.test.ts +26 -26
- package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/spec.md +37 -37
- package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/web.test.ts +21 -21
- package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/spec.md +29 -29
- package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/web.test.ts +16 -16
- package/templates/default/specs/ApiInterception/suite.md +10 -10
- package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/common.test.ts +30 -30
- package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/spec.md +23 -23
- package/templates/default/specs/ApiSeeding/hooks/after/common.hook.ts +16 -16
- package/templates/default/specs/ApiSeeding/hooks/before/common.hook.ts +28 -28
- package/templates/default/specs/ApiSeeding/suite.md +9 -9
- package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/mobile.test.ts +7 -7
- package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/spec.md +19 -19
- package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/web.test.ts +9 -9
- package/templates/default/specs/Authentication/suite.md +9 -9
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +9 -9
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +17 -17
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +19 -19
- package/templates/default/specs/BrowserContext/TC-0022-history-navigation/mobile.test.ts +17 -17
- package/templates/default/specs/BrowserContext/TC-0022-history-navigation/spec.md +28 -28
- package/templates/default/specs/BrowserContext/TC-0022-history-navigation/web.test.ts +26 -26
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/common.test.ts +26 -26
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/spec.md +19 -19
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +11 -11
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +17 -17
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +11 -11
- package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/common.test.ts +14 -14
- package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/spec.md +21 -21
- package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/mobile.test.ts +28 -28
- package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/spec.md +29 -29
- package/templates/default/specs/DeepLink/suite.md +9 -9
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +11 -11
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +17 -17
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +11 -11
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +29 -29
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +19 -19
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +29 -29
- package/templates/default/specs/ElementMatchers/suite.md +10 -10
- package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -5
- package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -16
- package/templates/default/specs/EnvironmentConfig/suite.md +9 -9
- package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/mobile.test.ts +26 -26
- package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/spec.md +22 -22
- package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/mobile.test.ts +13 -13
- package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/spec.md +20 -20
- package/templates/default/specs/PermissionRationale/suite.md +9 -9
- package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +6 -6
- package/templates/default/specs/Playground/TC-0001-form-controls/spec.md +18 -18
- package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +6 -6
- package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +6 -6
- package/templates/default/specs/Playground/TC-0002-toggle-elements/spec.md +18 -18
- package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +6 -6
- package/templates/default/spectra.config.ts +52 -52
- package/templates/default/support/actions/fillCredentials/mobile.action.ts +4 -4
- package/templates/default/support/actions/fillCredentials/web.action.ts +4 -4
- package/templates/default/support/actions/seedSession/mobile.action.ts +9 -9
- package/templates/default/support/actions/seedSession/web.action.ts +13 -13
- package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +5 -5
- package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +5 -5
- package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +6 -6
- package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +6 -6
- package/templates/docs/ARCHITECTURE.default.md +26 -0
- package/templates/docs/ARCHITECTURE.nx.md +119 -0
- package/templates/nx/.nx/workspace-data/{59842386-c7c4-44ca-b2c2-20e1700bd13d.db-shm → 70094CFD-E89B-57A1-9619-2FC5F4963C54.db-shm} +0 -0
- package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-wal +0 -0
- package/templates/nx/.nx/workspace-data/d/daemon.log +6343 -1612
- package/templates/nx/.nx/workspace-data/d/server-process.json +1 -1
- package/templates/nx/.nx/workspace-data/file-map.json +116 -130
- package/templates/nx/.nx/workspace-data/lockfile.hash +1 -1
- package/templates/nx/.nx/workspace-data/nx_files.nxt +0 -0
- package/templates/nx/.nx/workspace-data/parsed-lock-file.json +504 -504
- package/templates/nx/.nx/workspace-data/project-graph.json +560 -559
- package/templates/nx/.nx/workspace-data/source-maps.json +336 -0
- package/templates/nx/CLAUDE.md +10 -10
- package/templates/nx/package.json +3 -3
- package/templates/nx/packages/matchers/e2e/project.json +2 -2
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +27 -27
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -27
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +24 -24
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -24
- package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +3 -3
- package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +19 -19
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +3 -3
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +17 -17
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +3 -3
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +11 -11
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +3 -3
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +11 -11
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +3 -3
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +29 -29
- package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -5
- package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -16
- package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/suite.md +9 -9
- package/templates/nx/packages/playground/e2e/project.json +2 -2
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/mobile.test.ts +3 -3
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +6 -6
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +3 -3
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +6 -6
- package/templates/nx/pnpm-lock.yaml +6663 -6663
- package/templates/nx/pnpm-workspace.yaml +9 -9
- package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +33 -33
- package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +91 -91
- package/templates/nx/shared/testing/page-objects/NavigationPage/mobile.ts +5 -5
- package/templates/nx/shared/testing/page-objects/NavigationPage/web.ts +8 -8
- package/templates/nx/shared/testing/page-objects/PlaygroundPage/mobile.ts +26 -26
- package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +31 -31
- package/templates/nx/shared/testing/project.json +18 -19
- package/templates/nx/shared/testing/support/actions/fillCredentials/mobile.action.ts +4 -4
- package/templates/nx/shared/testing/support/actions/fillCredentials/web.action.ts +4 -4
- package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/mobile.step.ts +3 -3
- package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +5 -5
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +4 -4
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +6 -6
- package/templates/nx/spectra.config.ts +65 -52
- package/templates/react-component/.cursorrules +17 -17
- package/templates/react-component/.vscode/extensions.json +5 -5
- package/templates/react-component/CLAUDE.md +14 -14
- package/templates/react-component/README.md +69 -69
- package/templates/react-component/fixtures/component-mock.json +12 -12
- package/templates/react-component/global-hooks/after/web.hook.ts +3 -3
- package/templates/react-component/global-hooks/before/web.hook.ts +3 -3
- package/templates/react-component/package.json +27 -27
- package/templates/react-component/page-objects/BadgeComponent/web.ts +23 -23
- package/templates/react-component/page-objects/ButtonComponent/web.ts +23 -23
- package/templates/react-component/page-objects/InputComponent/web.ts +13 -13
- package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/spec.md +18 -18
- package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/web.test.tsx +11 -11
- package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/spec.md +18 -18
- package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/web.test.tsx +10 -10
- package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/spec.md +18 -18
- package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/web.test.tsx +16 -16
- package/templates/react-component/specs/BadgeComponent/suite.md +12 -12
- package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/spec.md +19 -19
- package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/web.test.tsx +25 -28
- package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/spec.md +19 -19
- package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/web.test.tsx +13 -22
- package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/spec.md +18 -18
- package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/web.test.tsx +8 -8
- package/templates/react-component/specs/ButtonComponent/suite.md +12 -12
- package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/spec.md +20 -20
- package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/web.test.tsx +24 -28
- package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/spec.md +18 -18
- package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/web.test.tsx +9 -9
- package/templates/react-component/specs/InputComponent/suite.md +12 -12
- package/templates/react-component/spectra.config.ts +17 -27
- package/templates/react-component/src/components/Badge/Badge.tsx +60 -60
- package/templates/react-component/src/components/Button/Button.tsx +59 -57
- package/templates/react-component/src/components/Input/Input.tsx +40 -41
- package/templates/react-component/src/test-utils.tsx +23 -23
- package/templates/react-component/support/actions/fillInputField/web.action.ts +9 -9
- package/templates/react-component/support/steps/verifyButtonState/web.step.ts +12 -12
- package/bin/.testspectra-runner.hash +0 -1
- package/bin/testspectra-runner.exe +0 -0
- package/templates/nx/.nx/workspace-data/59842386-c7c4-44ca-b2c2-20e1700bd13d.db-wal +0 -0
- /package/templates/nx/.nx/workspace-data/{59842386-c7c4-44ca-b2c2-20e1700bd13d.db → 70094CFD-E89B-57A1-9619-2FC5F4963C54.db} +0 -0
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: TC-0022-history-navigation
|
|
3
|
-
title: Navigate browser/app history with Spectra.back(), forward(), and refresh()
|
|
4
|
-
priority: Medium
|
|
5
|
-
caseType: Positive
|
|
6
|
-
status: ready-for-automation
|
|
7
|
-
coverage:
|
|
8
|
-
web: automated
|
|
9
|
-
mobile: automated
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Navigate browser/app history with Spectra.back(), forward(), and refresh()
|
|
13
|
-
|
|
14
|
-
## Test Steps
|
|
15
|
-
|
|
16
|
-
### Web
|
|
17
|
-
1. Navigate to two distinct real URLs in sequence, each pushing its own genuine browser history
|
|
18
|
-
entry (this demo app's in-app hash navigation does not — see the test's own comment)
|
|
19
|
-
2. Verify `Spectra.back()` returns to the previously visited URL
|
|
20
|
-
3. Verify `Spectra.forward()` replays the entry just undone
|
|
21
|
-
4. Verify `Spectra.refresh()` reloads the document while the current URL survives
|
|
22
|
-
|
|
23
|
-
### Mobile
|
|
24
|
-
1. Navigate to a native route via deep link
|
|
25
|
-
2. Verify `Spectra.back()` (Android hardware back key) pops back to the Home screen
|
|
26
|
-
|
|
27
|
-
`Spectra.forward()`/`Spectra.refresh()` have no native-app equivalent (no browser history, no page
|
|
28
|
-
reload) and are intentional no-ops on Android — only `Spectra.back()` is exercised on mobile.
|
|
1
|
+
---
|
|
2
|
+
id: TC-0022-history-navigation
|
|
3
|
+
title: Navigate browser/app history with Spectra.back(), forward(), and refresh()
|
|
4
|
+
priority: Medium
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: ready-for-automation
|
|
7
|
+
coverage:
|
|
8
|
+
web: automated
|
|
9
|
+
mobile: automated
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Navigate browser/app history with Spectra.back(), forward(), and refresh()
|
|
13
|
+
|
|
14
|
+
## Test Steps
|
|
15
|
+
|
|
16
|
+
### Web
|
|
17
|
+
1. Navigate to two distinct real URLs in sequence, each pushing its own genuine browser history
|
|
18
|
+
entry (this demo app's in-app hash navigation does not — see the test's own comment)
|
|
19
|
+
2. Verify `Spectra.back()` returns to the previously visited URL
|
|
20
|
+
3. Verify `Spectra.forward()` replays the entry just undone
|
|
21
|
+
4. Verify `Spectra.refresh()` reloads the document while the current URL survives
|
|
22
|
+
|
|
23
|
+
### Mobile
|
|
24
|
+
1. Navigate to a native route via deep link
|
|
25
|
+
2. Verify `Spectra.back()` (Android hardware back key) pops back to the Home screen
|
|
26
|
+
|
|
27
|
+
`Spectra.forward()`/`Spectra.refresh()` have no native-app equivalent (no browser history, no page
|
|
28
|
+
reload) and are intentional no-ops on Android — only `Spectra.back()` is exercised on mobile.
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
it("Navigate browser history with Spectra.back(), forward(), and refresh()", async () => {
|
|
2
|
-
await MatchersPage.open();
|
|
3
|
-
|
|
4
|
-
// This demo app is single-page — its in-app "navigation" (Spectra.navigate("/#section")) only
|
|
5
|
-
// ever sets window.location.hash, which this browser does not push as a traversable history
|
|
6
|
-
// entry (history.length never grows), so there is nothing for back()/forward() to jump between.
|
|
7
|
-
// Two distinct real paths give them something real: Vite's dev server serves the same SPA shell
|
|
8
|
-
// for any path, but the browser still treats each as its own document and pushes a genuine
|
|
9
|
-
// history entry — exactly like a real multi-page site would.
|
|
10
|
-
await Spectra.navigate("/history-nav-a");
|
|
11
|
-
await Spectra.browser.shouldContainUrl("/history-nav-a");
|
|
12
|
-
|
|
13
|
-
await Spectra.navigate("/history-nav-b");
|
|
14
|
-
await Spectra.browser.shouldContainUrl("/history-nav-b");
|
|
15
|
-
|
|
16
|
-
await Spectra.back();
|
|
17
|
-
await Spectra.browser.shouldContainUrl("/history-nav-a");
|
|
18
|
-
|
|
19
|
-
await Spectra.forward();
|
|
20
|
-
await Spectra.browser.shouldContainUrl("/history-nav-b");
|
|
21
|
-
|
|
22
|
-
// The document reloads, but the current URL survives it.
|
|
23
|
-
await Spectra.refresh();
|
|
24
|
-
await Spectra.browser.shouldBeLoaded();
|
|
25
|
-
await Spectra.browser.shouldContainUrl("/history-nav-b");
|
|
26
|
-
});
|
|
1
|
+
it("Navigate browser history with Spectra.back(), forward(), and refresh()", async () => {
|
|
2
|
+
await MatchersPage.open();
|
|
3
|
+
|
|
4
|
+
// This demo app is single-page — its in-app "navigation" (Spectra.navigate("/#section")) only
|
|
5
|
+
// ever sets window.location.hash, which this browser does not push as a traversable history
|
|
6
|
+
// entry (history.length never grows), so there is nothing for back()/forward() to jump between.
|
|
7
|
+
// Two distinct real paths give them something real: Vite's dev server serves the same SPA shell
|
|
8
|
+
// for any path, but the browser still treats each as its own document and pushes a genuine
|
|
9
|
+
// history entry — exactly like a real multi-page site would.
|
|
10
|
+
await Spectra.navigate("/history-nav-a");
|
|
11
|
+
await Spectra.browser.shouldContainUrl("/history-nav-a");
|
|
12
|
+
|
|
13
|
+
await Spectra.navigate("/history-nav-b");
|
|
14
|
+
await Spectra.browser.shouldContainUrl("/history-nav-b");
|
|
15
|
+
|
|
16
|
+
await Spectra.back();
|
|
17
|
+
await Spectra.browser.shouldContainUrl("/history-nav-a");
|
|
18
|
+
|
|
19
|
+
await Spectra.forward();
|
|
20
|
+
await Spectra.browser.shouldContainUrl("/history-nav-b");
|
|
21
|
+
|
|
22
|
+
// The document reloads, but the current URL survives it.
|
|
23
|
+
await Spectra.refresh();
|
|
24
|
+
await Spectra.browser.shouldBeLoaded();
|
|
25
|
+
await Spectra.browser.shouldContainUrl("/history-nav-b");
|
|
26
|
+
});
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
// A single common.test.ts, not a web.test.ts/mobile.test.ts pair — the orchestrator's test-case
|
|
2
|
-
// discovery recognizes "common" as a platform stem for every target (web, android, ios, mobile),
|
|
3
|
-
// so this one file runs unmodified on all of them. This works here because every Spectra.*
|
|
4
|
-
// command below is genuinely platform-agnostic (the DSL layer has zero platform branching by
|
|
5
|
-
// design) and MatchersPage's selectors are already abstracted per-platform behind identically-
|
|
6
|
-
// named getters — nothing in this specific test depends on a page origin, a native-only gesture,
|
|
7
|
-
// or a browser-chrome-only assertion (see TC-0013's real-network test for a case that CAN'T be
|
|
8
|
-
// shared this way: Android has no implicit page origin to resolve a relative fetch URL against,
|
|
9
|
-
// so the URL itself has to differ per platform even though the commands stay identical).
|
|
10
|
-
it("Verify exact text, substring text, and input values", async () => {
|
|
11
|
-
await MatchersPage.open("text");
|
|
12
|
-
|
|
13
|
-
// Text assertions (positive and negative)
|
|
14
|
-
await MatchersPage.exactText.shouldHaveText(Fixture.playgroundData.welcomeText);
|
|
15
|
-
await MatchersPage.exactText.shouldNotHaveText("Unexpected Text");
|
|
16
|
-
|
|
17
|
-
await MatchersPage.partialText.shouldContainText("Welcome");
|
|
18
|
-
await MatchersPage.partialText.shouldNotContainText("Goodbye");
|
|
19
|
-
|
|
20
|
-
// Value assertions (positive and negative)
|
|
21
|
-
await MatchersPage.emailInput.shouldHaveValue(Fixture.playgroundData.defaultEmail);
|
|
22
|
-
await MatchersPage.emailInput.shouldNotHaveValue("wrong.user@testspectra.dev");
|
|
23
|
-
|
|
24
|
-
await MatchersPage.tokenInput.shouldContainValue("JWT_");
|
|
25
|
-
await MatchersPage.tokenInput.shouldNotContainValue("EXPIRED_SESSION");
|
|
26
|
-
});
|
|
1
|
+
// A single common.test.ts, not a web.test.ts/mobile.test.ts pair — the orchestrator's test-case
|
|
2
|
+
// discovery recognizes "common" as a platform stem for every target (web, android, ios, mobile),
|
|
3
|
+
// so this one file runs unmodified on all of them. This works here because every Spectra.*
|
|
4
|
+
// command below is genuinely platform-agnostic (the DSL layer has zero platform branching by
|
|
5
|
+
// design) and MatchersPage's selectors are already abstracted per-platform behind identically-
|
|
6
|
+
// named getters — nothing in this specific test depends on a page origin, a native-only gesture,
|
|
7
|
+
// or a browser-chrome-only assertion (see TC-0013's real-network test for a case that CAN'T be
|
|
8
|
+
// shared this way: Android has no implicit page origin to resolve a relative fetch URL against,
|
|
9
|
+
// so the URL itself has to differ per platform even though the commands stay identical).
|
|
10
|
+
it("Verify exact text, substring text, and input values", async () => {
|
|
11
|
+
await MatchersPage.open("text");
|
|
12
|
+
|
|
13
|
+
// Text assertions (positive and negative)
|
|
14
|
+
await MatchersPage.exactText.shouldHaveText(Fixture.playgroundData.welcomeText);
|
|
15
|
+
await MatchersPage.exactText.shouldNotHaveText("Unexpected Text");
|
|
16
|
+
|
|
17
|
+
await MatchersPage.partialText.shouldContainText("Welcome");
|
|
18
|
+
await MatchersPage.partialText.shouldNotContainText("Goodbye");
|
|
19
|
+
|
|
20
|
+
// Value assertions (positive and negative)
|
|
21
|
+
await MatchersPage.emailInput.shouldHaveValue(Fixture.playgroundData.defaultEmail);
|
|
22
|
+
await MatchersPage.emailInput.shouldNotHaveValue("wrong.user@testspectra.dev");
|
|
23
|
+
|
|
24
|
+
await MatchersPage.tokenInput.shouldContainValue("JWT_");
|
|
25
|
+
await MatchersPage.tokenInput.shouldNotContainValue("EXPIRED_SESSION");
|
|
26
|
+
});
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: TC-0005-text-and-values
|
|
3
|
-
title: Verify exact text, substring text, and input values
|
|
4
|
-
priority: High
|
|
5
|
-
caseType: Positive
|
|
6
|
-
status: ready-for-automation
|
|
7
|
-
coverage:
|
|
8
|
-
web: automated
|
|
9
|
-
mobile: automated
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Verify exact text, substring text, and input values
|
|
13
|
-
|
|
14
|
-
## Test Steps
|
|
15
|
-
1. Open text matchers section in matchers page
|
|
16
|
-
2. Verify exact text matches playground welcome text
|
|
17
|
-
3. Verify partial text contains welcome keyword
|
|
18
|
-
4. Verify email input value matches default email
|
|
19
|
-
5. Verify token input value contains JWT prefix
|
|
1
|
+
---
|
|
2
|
+
id: TC-0005-text-and-values
|
|
3
|
+
title: Verify exact text, substring text, and input values
|
|
4
|
+
priority: High
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: ready-for-automation
|
|
7
|
+
coverage:
|
|
8
|
+
web: automated
|
|
9
|
+
mobile: automated
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Verify exact text, substring text, and input values
|
|
13
|
+
|
|
14
|
+
## Test Steps
|
|
15
|
+
1. Open text matchers section in matchers page
|
|
16
|
+
2. Verify exact text matches playground welcome text
|
|
17
|
+
3. Verify partial text contains welcome keyword
|
|
18
|
+
4. Verify email input value matches default email
|
|
19
|
+
5. Verify token input value contains JWT prefix
|
package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
it("Verify collection lengths, counts, and empty lists", async () => {
|
|
2
|
-
await MatchersPage.open("length");
|
|
3
|
-
|
|
4
|
-
// Receiver assertion methods
|
|
5
|
-
await MatchersPage.productCards.shouldHaveLength(4);
|
|
6
|
-
await MatchersPage.productCards.shouldNotHaveLength(0);
|
|
7
|
-
await MatchersPage.productCards.shouldHaveLengthGreaterThan(0);
|
|
8
|
-
await MatchersPage.productCards.shouldHaveLengthLessThan(10);
|
|
9
|
-
await MatchersPage.emptyList.shouldBeEmpty();
|
|
10
|
-
await MatchersPage.productCards.shouldNotBeEmpty();
|
|
11
|
-
});
|
|
1
|
+
it("Verify collection lengths, counts, and empty lists", async () => {
|
|
2
|
+
await MatchersPage.open("length");
|
|
3
|
+
|
|
4
|
+
// Receiver assertion methods
|
|
5
|
+
await MatchersPage.productCards.shouldHaveLength(4);
|
|
6
|
+
await MatchersPage.productCards.shouldNotHaveLength(0);
|
|
7
|
+
await MatchersPage.productCards.shouldHaveLengthGreaterThan(0);
|
|
8
|
+
await MatchersPage.productCards.shouldHaveLengthLessThan(10);
|
|
9
|
+
await MatchersPage.emptyList.shouldBeEmpty();
|
|
10
|
+
await MatchersPage.productCards.shouldNotBeEmpty();
|
|
11
|
+
});
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: TC-0006-collections-and-empty
|
|
3
|
-
title: Verify collection lengths, counts, and empty lists
|
|
4
|
-
priority: High
|
|
5
|
-
caseType: Positive
|
|
6
|
-
status: ready-for-automation
|
|
7
|
-
coverage:
|
|
8
|
-
web: automated
|
|
9
|
-
mobile: automated
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Verify collection lengths, counts, and empty lists
|
|
13
|
-
|
|
14
|
-
## Test Steps
|
|
15
|
-
1. Open collection length section in matchers page
|
|
16
|
-
2. Assert product cards count equals 4 and is greater than 0
|
|
17
|
-
3. Assert empty list container is empty
|
|
1
|
+
---
|
|
2
|
+
id: TC-0006-collections-and-empty
|
|
3
|
+
title: Verify collection lengths, counts, and empty lists
|
|
4
|
+
priority: High
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: ready-for-automation
|
|
7
|
+
coverage:
|
|
8
|
+
web: automated
|
|
9
|
+
mobile: automated
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Verify collection lengths, counts, and empty lists
|
|
13
|
+
|
|
14
|
+
## Test Steps
|
|
15
|
+
1. Open collection length section in matchers page
|
|
16
|
+
2. Assert product cards count equals 4 and is greater than 0
|
|
17
|
+
3. Assert empty list container is empty
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
it("Verify collection lengths, counts, and empty lists", async () => {
|
|
2
|
-
await MatchersPage.open("length");
|
|
3
|
-
|
|
4
|
-
// Receiver assertion methods
|
|
5
|
-
await MatchersPage.productCards.shouldHaveLength(4);
|
|
6
|
-
await MatchersPage.productCards.shouldNotHaveLength(0);
|
|
7
|
-
await MatchersPage.productCards.shouldHaveLengthGreaterThan(0);
|
|
8
|
-
await MatchersPage.productCards.shouldHaveLengthLessThan(10);
|
|
9
|
-
await MatchersPage.emptyList.shouldBeEmpty();
|
|
10
|
-
await MatchersPage.productCards.shouldNotBeEmpty();
|
|
11
|
-
});
|
|
1
|
+
it("Verify collection lengths, counts, and empty lists", async () => {
|
|
2
|
+
await MatchersPage.open("length");
|
|
3
|
+
|
|
4
|
+
// Receiver assertion methods
|
|
5
|
+
await MatchersPage.productCards.shouldHaveLength(4);
|
|
6
|
+
await MatchersPage.productCards.shouldNotHaveLength(0);
|
|
7
|
+
await MatchersPage.productCards.shouldHaveLengthGreaterThan(0);
|
|
8
|
+
await MatchersPage.productCards.shouldHaveLengthLessThan(10);
|
|
9
|
+
await MatchersPage.emptyList.shouldBeEmpty();
|
|
10
|
+
await MatchersPage.productCards.shouldNotBeEmpty();
|
|
11
|
+
});
|
package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/common.test.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
it("element.get()/getAll() resolves a child scoped to its parent's own subtree", async () => {
|
|
2
|
-
await MatchersPage.open();
|
|
3
|
-
await MatchersPage.overviewSection.shouldBeVisible();
|
|
4
|
-
|
|
5
|
-
// Positive: the subtitle is a real descendant of the overview section, so the scoped lookup
|
|
6
|
-
// resolves it.
|
|
7
|
-
await MatchersPage.overviewSubtitle().shouldExist();
|
|
8
|
-
|
|
9
|
-
// Negative (the actual scoping proof): the submit button lives in a different section
|
|
10
|
-
// entirely. If .get() weren't genuinely scoped (e.g. silently fell back to a page-wide
|
|
11
|
-
// lookup), this would incorrectly resolve to the globally-existing element instead of
|
|
12
|
-
// correctly not finding it.
|
|
13
|
-
await MatchersPage.overviewOutsideElement().shouldNotExist();
|
|
14
|
-
});
|
|
1
|
+
it("element.get()/getAll() resolves a child scoped to its parent's own subtree", async () => {
|
|
2
|
+
await MatchersPage.open();
|
|
3
|
+
await MatchersPage.overviewSection.shouldBeVisible();
|
|
4
|
+
|
|
5
|
+
// Positive: the subtitle is a real descendant of the overview section, so the scoped lookup
|
|
6
|
+
// resolves it.
|
|
7
|
+
await MatchersPage.overviewSubtitle().shouldExist();
|
|
8
|
+
|
|
9
|
+
// Negative (the actual scoping proof): the submit button lives in a different section
|
|
10
|
+
// entirely. If .get() weren't genuinely scoped (e.g. silently fell back to a page-wide
|
|
11
|
+
// lookup), this would incorrectly resolve to the globally-existing element instead of
|
|
12
|
+
// correctly not finding it.
|
|
13
|
+
await MatchersPage.overviewOutsideElement().shouldNotExist();
|
|
14
|
+
});
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: TC-0020-scoped-element-access
|
|
3
|
-
title: element.get()/getAll() resolves a child scoped to its parent's own subtree
|
|
4
|
-
priority: High
|
|
5
|
-
caseType: Positive
|
|
6
|
-
status: ready-for-automation
|
|
7
|
-
coverage:
|
|
8
|
-
web: automated
|
|
9
|
-
mobile: automated
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# element.get()/getAll() resolves a child scoped to its parent's own subtree
|
|
13
|
-
|
|
14
|
-
## Test Steps
|
|
15
|
-
1. Open the matchers page and assert the overview section is visible
|
|
16
|
-
2. From the overview section, resolve the page subtitle via `.get()` and assert it exists — the
|
|
17
|
-
subtitle is a real descendant, so the scoped lookup finds it
|
|
18
|
-
3. From the same overview section, resolve the submit button via `.get()` and assert it does NOT
|
|
19
|
-
exist — the submit button lives in a different section entirely, so this only passes if the
|
|
20
|
-
lookup is genuinely scoped to overview's own subtree rather than silently falling back to a
|
|
21
|
-
page-wide match
|
|
1
|
+
---
|
|
2
|
+
id: TC-0020-scoped-element-access
|
|
3
|
+
title: element.get()/getAll() resolves a child scoped to its parent's own subtree
|
|
4
|
+
priority: High
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: ready-for-automation
|
|
7
|
+
coverage:
|
|
8
|
+
web: automated
|
|
9
|
+
mobile: automated
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# element.get()/getAll() resolves a child scoped to its parent's own subtree
|
|
13
|
+
|
|
14
|
+
## Test Steps
|
|
15
|
+
1. Open the matchers page and assert the overview section is visible
|
|
16
|
+
2. From the overview section, resolve the page subtitle via `.get()` and assert it exists — the
|
|
17
|
+
subtitle is a real descendant, so the scoped lookup finds it
|
|
18
|
+
3. From the same overview section, resolve the submit button via `.get()` and assert it does NOT
|
|
19
|
+
exist — the submit button lives in a different section entirely, so this only passes if the
|
|
20
|
+
lookup is genuinely scoped to overview's own subtree rather than silently falling back to a
|
|
21
|
+
page-wide match
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
it("Navigate directly to a native route via Spectra.navigate() and an Android deep link", async () => {
|
|
2
|
-
// The orchestrator's own bootstrap launches the app (fire-and-forget, ~1.5s wait) before any
|
|
3
|
-
// test code runs at all — other tests never notice because their first action is a click()
|
|
4
|
-
// with its own generous poll budget, which absorbs whatever's left of the cold start. This
|
|
5
|
-
// test's first action is Spectra.navigate() itself, which is also fire-and-forget and has no
|
|
6
|
-
// such budget, so without this it races the deep-link intent against the app's own still-in-
|
|
7
|
-
// progress initial boot. Waiting for the home screen to actually be up first avoids that race.
|
|
8
|
-
await Spectra.get("~toggle-sidebar-btn").waitForElement(30000);
|
|
9
|
-
|
|
10
|
-
// No prior navigation, no button clicks — this jumps straight to the route via
|
|
11
|
-
// `adb shell am start`, exactly like opening the app from a push notification or an
|
|
12
|
-
// external link would.
|
|
13
|
-
await Spectra.navigate("testspectra-demo://deeplink-target");
|
|
14
|
-
await Spectra.get("~deeplink-target-marker").waitForElement(10000);
|
|
15
|
-
|
|
16
|
-
await Spectra.get("~deeplink-target-marker").shouldHaveText("deeplink-target");
|
|
17
|
-
await Spectra.get("~deeplink-received-message").shouldHaveText("(none)");
|
|
18
|
-
|
|
19
|
-
await Spectra.get("~back-to-home-btn").click();
|
|
20
|
-
|
|
21
|
-
// Deep links can carry query params — assert they survive the intent all the way to the screen.
|
|
22
|
-
await Spectra.navigate("testspectra-demo://deeplink-target?message=hello-from-deep-link");
|
|
23
|
-
|
|
24
|
-
await Spectra.get("~deeplink-received-message").waitForElement(10000);
|
|
25
|
-
await Spectra.get("~deeplink-received-message").shouldHaveText("hello-from-deep-link");
|
|
26
|
-
|
|
27
|
-
await Spectra.get("~back-to-home-btn").click();
|
|
28
|
-
});
|
|
1
|
+
it("Navigate directly to a native route via Spectra.navigate() and an Android deep link", async () => {
|
|
2
|
+
// The orchestrator's own bootstrap launches the app (fire-and-forget, ~1.5s wait) before any
|
|
3
|
+
// test code runs at all — other tests never notice because their first action is a click()
|
|
4
|
+
// with its own generous poll budget, which absorbs whatever's left of the cold start. This
|
|
5
|
+
// test's first action is Spectra.navigate() itself, which is also fire-and-forget and has no
|
|
6
|
+
// such budget, so without this it races the deep-link intent against the app's own still-in-
|
|
7
|
+
// progress initial boot. Waiting for the home screen to actually be up first avoids that race.
|
|
8
|
+
await Spectra.get("~toggle-sidebar-btn").waitForElement(30000);
|
|
9
|
+
|
|
10
|
+
// No prior navigation, no button clicks — this jumps straight to the route via
|
|
11
|
+
// `adb shell am start`, exactly like opening the app from a push notification or an
|
|
12
|
+
// external link would.
|
|
13
|
+
await Spectra.navigate("testspectra-demo://deeplink-target");
|
|
14
|
+
await Spectra.get("~deeplink-target-marker").waitForElement(10000);
|
|
15
|
+
|
|
16
|
+
await Spectra.get("~deeplink-target-marker").shouldHaveText("deeplink-target");
|
|
17
|
+
await Spectra.get("~deeplink-received-message").shouldHaveText("(none)");
|
|
18
|
+
|
|
19
|
+
await Spectra.get("~back-to-home-btn").click();
|
|
20
|
+
|
|
21
|
+
// Deep links can carry query params — assert they survive the intent all the way to the screen.
|
|
22
|
+
await Spectra.navigate("testspectra-demo://deeplink-target?message=hello-from-deep-link");
|
|
23
|
+
|
|
24
|
+
await Spectra.get("~deeplink-received-message").waitForElement(10000);
|
|
25
|
+
await Spectra.get("~deeplink-received-message").shouldHaveText("hello-from-deep-link");
|
|
26
|
+
|
|
27
|
+
await Spectra.get("~back-to-home-btn").click();
|
|
28
|
+
});
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: TC-0018-navigate-via-deep-link
|
|
3
|
-
title: Navigate directly to a native route via Spectra.navigate() and an Android deep link
|
|
4
|
-
priority: High
|
|
5
|
-
caseType: Positive
|
|
6
|
-
status: ready-for-automation
|
|
7
|
-
coverage:
|
|
8
|
-
web: unsupported
|
|
9
|
-
mobile: automated
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Navigate directly to a native route via Spectra.navigate() and an Android deep link
|
|
13
|
-
|
|
14
|
-
On Android, `Spectra.navigate(uri)` runs `adb shell am start -a android.intent.action.VIEW -d
|
|
15
|
-
<uri>` against the app's own registered scheme (`testspectra-demo://`, declared in
|
|
16
|
-
`app.json`/`AndroidManifest.xml`) — jumping straight to a route without walking through the UI
|
|
17
|
-
first, the same way a push notification or an external link would open the app in production.
|
|
18
|
-
|
|
19
|
-
Web coverage is `unsupported`: on web, `Spectra.navigate()` already does the equivalent thing
|
|
20
|
-
via a normal URL (see any other TC's `browser.url(...)`/`Spectra.navigate(...)` call) — there's no
|
|
21
|
-
separate "deep link" concept to demonstrate there.
|
|
22
|
-
|
|
23
|
-
## Test Steps
|
|
24
|
-
1. Wait for the app home screen to finish booting
|
|
25
|
-
2. Navigate via a deep link to the target route without query params
|
|
26
|
-
3. Assert the target marker is shown and the received message is "(none)"
|
|
27
|
-
4. Navigate via a deep link carrying a query-param message
|
|
28
|
-
5. Assert the received message matches the deep-link param
|
|
29
|
-
6. Return to the home screen
|
|
1
|
+
---
|
|
2
|
+
id: TC-0018-navigate-via-deep-link
|
|
3
|
+
title: Navigate directly to a native route via Spectra.navigate() and an Android deep link
|
|
4
|
+
priority: High
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: ready-for-automation
|
|
7
|
+
coverage:
|
|
8
|
+
web: unsupported
|
|
9
|
+
mobile: automated
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Navigate directly to a native route via Spectra.navigate() and an Android deep link
|
|
13
|
+
|
|
14
|
+
On Android, `Spectra.navigate(uri)` runs `adb shell am start -a android.intent.action.VIEW -d
|
|
15
|
+
<uri>` against the app's own registered scheme (`testspectra-demo://`, declared in
|
|
16
|
+
`app.json`/`AndroidManifest.xml`) — jumping straight to a route without walking through the UI
|
|
17
|
+
first, the same way a push notification or an external link would open the app in production.
|
|
18
|
+
|
|
19
|
+
Web coverage is `unsupported`: on web, `Spectra.navigate()` already does the equivalent thing
|
|
20
|
+
via a normal URL (see any other TC's `browser.url(...)`/`Spectra.navigate(...)` call) — there's no
|
|
21
|
+
separate "deep link" concept to demonstrate there.
|
|
22
|
+
|
|
23
|
+
## Test Steps
|
|
24
|
+
1. Wait for the app home screen to finish booting
|
|
25
|
+
2. Navigate via a deep link to the target route without query params
|
|
26
|
+
3. Assert the target marker is shown and the received message is "(none)"
|
|
27
|
+
4. Navigate via a deep link carrying a query-param message
|
|
28
|
+
5. Assert the received message matches the deep-link param
|
|
29
|
+
6. Return to the home screen
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: suite-deep-link
|
|
3
|
-
name: DeepLink
|
|
4
|
-
description: Navigating directly to a native route via Spectra.navigate() and an adb deep link
|
|
5
|
-
executionOrder: 2.2
|
|
6
|
-
parallel: true
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Suite: DeepLink
|
|
1
|
+
---
|
|
2
|
+
id: suite-deep-link
|
|
3
|
+
name: DeepLink
|
|
4
|
+
description: Navigating directly to a native route via Spectra.navigate() and an adb deep link
|
|
5
|
+
executionOrder: 2.2
|
|
6
|
+
parallel: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Suite: DeepLink
|
|
@@ -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("~non-existent-element").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("~non-existent-element").shouldNotExist();
|
|
11
|
+
});
|
|
@@ -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
|
+
});
|
package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts
CHANGED
|
@@ -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
|
+
});
|