@testspectra/cli 1.0.70 → 1.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +48 -0
- package/README.md +36 -270
- package/bin/.testspectra-runner.hash +1 -0
- package/bin/spectra.js +1 -1
- package/bin/testspectra-runner +0 -0
- package/demo-app/assets/index-BhlW-eXG.css +1 -0
- package/demo-app/assets/index-DOtRypCa.js +154 -0
- package/demo-app/index.html +2 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/commands/__tests__/doctor.test.d.ts +1 -0
- package/dist/commands/__tests__/doctor.test.js +39 -0
- package/dist/commands/__tests__/init.test.d.ts +1 -0
- package/dist/commands/__tests__/init.test.js +148 -0
- package/dist/commands/__tests__/license.test.d.ts +1 -0
- package/dist/commands/__tests__/license.test.js +13 -0
- package/dist/commands/__tests__/refactor.test.d.ts +1 -0
- package/dist/commands/__tests__/refactor.test.js +64 -0
- package/dist/commands/__tests__/run-e2e.test.d.ts +1 -0
- package/dist/commands/__tests__/run-e2e.test.js +422 -0
- package/dist/commands/__tests__/run.test.d.ts +1 -0
- package/dist/commands/__tests__/run.test.js +273 -0
- package/dist/commands/__tests__/watch.test.d.ts +1 -0
- package/dist/commands/__tests__/watch.test.js +155 -0
- package/dist/commands/add.js +86 -85
- package/dist/commands/demo.js +21 -11
- package/dist/commands/devices.d.ts +14 -2
- package/dist/commands/devices.js +44 -34
- package/dist/commands/doctor.d.ts +3 -1
- package/dist/commands/doctor.js +43 -264
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +211 -196
- package/dist/commands/install.d.ts +4 -0
- package/dist/commands/install.js +59 -0
- package/dist/commands/license.d.ts +4 -0
- package/dist/commands/license.js +30 -0
- package/dist/commands/lint.d.ts +5 -0
- package/dist/commands/lint.js +55 -0
- package/dist/commands/refactor.d.ts +9 -0
- package/dist/commands/refactor.js +172 -0
- package/dist/commands/run.d.ts +23 -2
- package/dist/commands/run.js +322 -111
- package/dist/commands/skills.d.ts +9 -0
- package/dist/commands/skills.js +28 -0
- package/dist/commands/sync-types.d.ts +4 -0
- package/dist/commands/sync-types.js +15 -0
- package/dist/commands/test.d.ts +17 -0
- package/dist/commands/test.js +76 -0
- package/dist/commands/update.js +39 -43
- package/dist/commands/watch.d.ts +6 -0
- package/dist/commands/watch.js +55 -45
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.js +40 -25
- package/dist/config/schema.d.ts +104 -145
- package/dist/config/schema.js +36 -45
- package/dist/generator/__tests__/tsconfig-isolation.test.d.ts +1 -0
- package/dist/generator/__tests__/tsconfig-isolation.test.js +282 -0
- package/dist/generator/__tests__/type-generator.test.d.ts +1 -0
- package/dist/generator/__tests__/type-generator.test.js +386 -0
- package/dist/generator/index.d.ts +2 -0
- package/dist/generator/index.js +2 -0
- package/dist/generator/tsconfig-generator.d.ts +27 -0
- package/dist/generator/tsconfig-generator.js +419 -0
- package/dist/generator/type-generator.d.ts +59 -0
- package/dist/generator/type-generator.js +740 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +165 -51
- package/dist/lifecycle/__tests__/lifecycle-engine.test.d.ts +1 -0
- package/dist/lifecycle/__tests__/lifecycle-engine.test.js +290 -0
- package/dist/lifecycle/hook-discovery.d.ts +24 -0
- package/dist/lifecycle/hook-discovery.js +60 -0
- package/dist/lifecycle/hook-dispatcher.d.ts +34 -0
- package/dist/lifecycle/hook-dispatcher.js +190 -0
- package/dist/lifecycle/index.d.ts +3 -0
- package/dist/lifecycle/index.js +3 -0
- package/dist/lifecycle/parallel-grouping.d.ts +27 -0
- package/dist/lifecycle/parallel-grouping.js +151 -0
- package/dist/linter/__tests__/anonymous-export.test.d.ts +1 -0
- package/dist/linter/__tests__/anonymous-export.test.js +184 -0
- package/dist/linter/__tests__/component-test-imports.test.d.ts +1 -0
- package/dist/linter/__tests__/component-test-imports.test.js +115 -0
- package/dist/linter/__tests__/shared-lib-boundary.test.d.ts +1 -0
- package/dist/linter/__tests__/shared-lib-boundary.test.js +270 -0
- package/dist/linter/__tests__/spec-schema.test.d.ts +1 -0
- package/dist/linter/__tests__/spec-schema.test.js +369 -0
- package/dist/linter/__tests__/step-parity.test.d.ts +1 -0
- package/dist/linter/__tests__/step-parity.test.js +372 -0
- package/dist/linter/discovery.d.ts +30 -0
- package/dist/linter/discovery.js +249 -0
- package/dist/linter/extractor.d.ts +67 -0
- package/dist/linter/extractor.js +245 -0
- package/dist/linter/index.d.ts +7 -0
- package/dist/linter/index.js +7 -0
- package/dist/linter/parser.d.ts +24 -0
- package/dist/linter/parser.js +219 -0
- package/dist/linter/schemas/spec.schema.d.ts +83 -0
- package/dist/linter/schemas/spec.schema.js +150 -0
- package/dist/linter/schemas/suite.schema.d.ts +59 -0
- package/dist/linter/schemas/suite.schema.js +83 -0
- package/dist/linter/spec-linter.d.ts +23 -0
- package/dist/linter/spec-linter.js +630 -0
- package/dist/linter/types.d.ts +28 -0
- package/dist/linter/types.js +1 -0
- package/dist/mobile/__tests__/android-device-e2e.test.d.ts +1 -0
- package/dist/mobile/__tests__/android-device-e2e.test.js +53 -0
- package/dist/mobile/__tests__/device-pool.test.d.ts +1 -0
- package/dist/mobile/__tests__/device-pool.test.js +97 -0
- package/dist/mobile/device-pool.d.ts +23 -0
- package/dist/mobile/device-pool.js +1 -0
- package/dist/mobile/index.d.ts +1 -0
- package/dist/mobile/index.js +1 -0
- package/dist/refactor/__tests__/refactor-engine.test.d.ts +1 -0
- package/dist/refactor/__tests__/refactor-engine.test.js +873 -0
- package/dist/refactor/index.d.ts +1 -0
- package/dist/refactor/index.js +1 -0
- package/dist/refactor/refactor-engine.d.ts +50 -0
- package/dist/refactor/refactor-engine.js +587 -0
- package/dist/reporter/__tests__/semantic-formatter.test.d.ts +1 -0
- package/dist/reporter/__tests__/semantic-formatter.test.js +73 -0
- package/dist/reporter/semantic-formatter.d.ts +6 -0
- package/dist/reporter/semantic-formatter.js +206 -0
- package/dist/reporter/summary-view.d.ts +12 -0
- package/dist/reporter/summary-view.js +19 -0
- package/dist/reporter/terminal-stream.d.ts +32 -0
- package/dist/reporter/terminal-stream.js +82 -0
- package/dist/reporter/types.d.ts +2 -0
- package/dist/reporter/types.js +1 -0
- package/dist/runner/bridge.d.ts +10 -5
- package/dist/runner/bridge.js +101 -45
- package/dist/runner/reporter.d.ts +32 -2
- package/dist/runner/reporter.js +427 -13
- package/dist/server/demo.js +43 -44
- package/dist/types/generator.d.ts +1 -17
- package/dist/types/generator.js +1 -443
- package/dist/utils/__tests__/api-server.test.d.ts +1 -0
- package/dist/utils/__tests__/api-server.test.js +62 -0
- package/dist/utils/__tests__/demo-server.test.d.ts +1 -0
- package/dist/utils/__tests__/demo-server.test.js +35 -0
- package/dist/utils/api-server.d.ts +19 -0
- package/dist/utils/api-server.js +179 -0
- package/dist/utils/demo-server.d.ts +5 -0
- package/dist/utils/demo-server.js +46 -36
- package/package.json +25 -13
- package/templates/default/CLAUDE.md +12 -5
- package/templates/default/fixtures/apiData.json +24 -0
- package/templates/default/package.json +12 -3
- package/templates/default/page-objects/AuthPage/mobile.ts +5 -0
- package/templates/default/page-objects/AuthPage/web.ts +10 -0
- package/templates/default/page-objects/MatchersPage/mobile.ts +66 -17
- package/templates/default/page-objects/MatchersPage/web.ts +22 -2
- package/templates/default/page-objects/NavigationPage/mobile.ts +11 -2
- package/templates/default/page-objects/NavigationPage/web.ts +1 -1
- package/templates/default/page-objects/PlaygroundPage/mobile.ts +34 -18
- package/templates/default/page-objects/PlaygroundPage/web.ts +4 -2
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +53 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +19 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +31 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/android.test.ts +3 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/common.test.ts +3 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +27 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +19 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +26 -0
- package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/common.test.ts +30 -0
- package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/spec.md +22 -0
- package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/common.test.ts +27 -0
- package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/spec.md +20 -0
- package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/spec.md +24 -0
- package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/web.test.ts +26 -0
- package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/spec.md +37 -0
- package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/web.test.ts +21 -0
- package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/spec.md +29 -0
- package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/web.test.ts +16 -0
- package/templates/default/specs/ApiInterception/suite.md +10 -0
- package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/common.test.ts +30 -0
- package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/spec.md +23 -0
- package/templates/default/specs/ApiSeeding/hooks/after/common.hook.ts +16 -0
- package/templates/default/specs/ApiSeeding/hooks/before/common.hook.ts +28 -0
- package/templates/default/specs/ApiSeeding/suite.md +9 -0
- package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/mobile.test.ts +7 -0
- package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/spec.md +19 -0
- package/templates/default/specs/Authentication/TC-0021-seed-authenticated-session/web.test.ts +9 -0
- package/templates/default/specs/Authentication/suite.md +9 -0
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +7 -1
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +5 -0
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
- package/templates/default/specs/BrowserContext/TC-0022-history-navigation/mobile.test.ts +17 -0
- package/templates/default/specs/BrowserContext/TC-0022-history-navigation/spec.md +28 -0
- package/templates/default/specs/BrowserContext/TC-0022-history-navigation/web.test.ts +26 -0
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/common.test.ts +26 -0
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/spec.md +7 -0
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +9 -1
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +5 -0
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +9 -4
- package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/common.test.ts +14 -0
- package/templates/default/specs/ContentMatchers/TC-0020-scoped-element-access/spec.md +21 -0
- package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/mobile.test.ts +28 -0
- package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/spec.md +29 -0
- package/templates/default/specs/DeepLink/suite.md +9 -0
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +9 -1
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +5 -0
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +27 -1
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +7 -0
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
- package/templates/default/specs/ElementMatchers/suite.md +2 -1
- package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -0
- package/templates/default/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -0
- package/templates/default/specs/EnvironmentConfig/suite.md +9 -0
- package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/mobile.test.ts +26 -0
- package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/spec.md +22 -0
- package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/mobile.test.ts +13 -0
- package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/spec.md +20 -0
- package/templates/default/specs/PermissionRationale/suite.md +9 -0
- package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +4 -1
- package/templates/default/specs/Playground/TC-0001-form-controls/spec.md +6 -0
- package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +4 -4
- package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +4 -1
- package/templates/default/specs/Playground/TC-0002-toggle-elements/spec.md +6 -0
- package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +3 -3
- package/templates/default/spectra.config.ts +22 -31
- package/templates/default/support/actions/fillCredentials/mobile.action.ts +3 -3
- package/templates/default/support/actions/fillCredentials/web.action.ts +1 -1
- package/templates/default/support/actions/seedSession/mobile.action.ts +9 -0
- package/templates/default/support/actions/seedSession/web.action.ts +13 -0
- package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +3 -1
- package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +3 -3
- package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +4 -2
- package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +4 -4
- package/templates/default/tsconfig.json +3 -1
- package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db +0 -0
- package/templates/nx/.nx/workspace-data/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 +5366 -0
- package/templates/nx/.nx/workspace-data/d/server-process.json +3 -0
- package/templates/nx/.nx/workspace-data/file-map.json +464 -0
- package/templates/nx/.nx/workspace-data/lockfile.hash +1 -0
- package/templates/nx/.nx/workspace-data/nx_files.nxt +0 -0
- package/templates/nx/.nx/workspace-data/parsed-lock-file.json +13485 -0
- package/templates/nx/.nx/workspace-data/project-graph.json +14389 -0
- package/templates/nx/CLAUDE.md +2 -2
- package/templates/nx/package.json +6 -4
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +27 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +24 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/suite.md +9 -0
- package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +1 -1
- package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +1 -1
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +15 -5
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +1 -1
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +9 -4
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +1 -1
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +1 -1
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
- package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/common.test.ts +5 -0
- package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/TC-0019-read-custom-environment-variable/spec.md +16 -0
- package/templates/nx/packages/matchers/e2e/specs/EnvironmentConfig/suite.md +9 -0
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/mobile.test.ts +1 -1
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +4 -4
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +1 -1
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +3 -3
- package/templates/nx/pnpm-lock.yaml +6663 -0
- package/templates/nx/pnpm-workspace.yaml +2 -1
- package/templates/nx/shared/testing/fixtures/apiData.json +24 -0
- package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +13 -1
- package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +85 -17
- package/templates/nx/shared/testing/page-objects/NavigationPage/mobile.ts +1 -1
- package/templates/nx/shared/testing/page-objects/NavigationPage/web.ts +1 -1
- package/templates/nx/shared/testing/page-objects/PlaygroundPage/mobile.ts +1 -1
- package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +4 -2
- package/templates/nx/shared/testing/project.json +19 -0
- package/templates/nx/shared/testing/support/actions/fillCredentials/mobile.action.ts +1 -1
- package/templates/nx/shared/testing/support/actions/fillCredentials/web.action.ts +1 -1
- package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/mobile.step.ts +1 -1
- package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +3 -3
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +2 -2
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +4 -4
- package/templates/nx/spectra.config.ts +20 -29
- package/templates/nx/tsconfig.json +3 -1
- package/templates/react-component/.cursorrules +17 -0
- package/templates/react-component/.vscode/extensions.json +5 -0
- package/templates/react-component/CLAUDE.md +14 -0
- package/templates/react-component/README.md +69 -0
- package/templates/react-component/fixtures/component-mock.json +12 -0
- package/templates/react-component/global-hooks/after/web.hook.ts +3 -0
- package/templates/react-component/global-hooks/before/web.hook.ts +3 -0
- package/templates/react-component/package.json +27 -0
- package/templates/react-component/page-objects/BadgeComponent/web.ts +23 -0
- package/templates/react-component/page-objects/ButtonComponent/web.ts +23 -0
- package/templates/react-component/page-objects/InputComponent/web.ts +13 -0
- package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/spec.md +18 -0
- package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/web.test.tsx +11 -0
- package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/spec.md +18 -0
- package/templates/react-component/specs/BadgeComponent/TC-0006-badge-success-with-dot/web.test.tsx +10 -0
- package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/spec.md +18 -0
- package/templates/react-component/specs/BadgeComponent/TC-0007-badge-by-severity-lookup/web.test.tsx +16 -0
- package/templates/react-component/specs/BadgeComponent/suite.md +12 -0
- package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/spec.md +19 -0
- package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/web.test.tsx +28 -0
- package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/spec.md +19 -0
- package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/web.test.tsx +22 -0
- package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/spec.md +18 -0
- package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/web.test.tsx +8 -0
- package/templates/react-component/specs/ButtonComponent/suite.md +12 -0
- package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/spec.md +20 -0
- package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/web.test.tsx +28 -0
- package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/spec.md +18 -0
- package/templates/react-component/specs/InputComponent/TC-0008-disabled-input-not-editable/web.test.tsx +9 -0
- package/templates/react-component/specs/InputComponent/suite.md +12 -0
- package/templates/react-component/spectra.config.ts +27 -0
- package/templates/react-component/src/components/Badge/Badge.tsx +60 -0
- package/templates/react-component/src/components/Button/Button.tsx +57 -0
- package/templates/react-component/src/components/Input/Input.tsx +41 -0
- package/templates/react-component/src/test-utils.tsx +23 -0
- package/templates/react-component/support/actions/fillInputField/web.action.ts +9 -0
- package/templates/react-component/support/steps/verifyButtonState/web.step.ts +12 -0
- package/templates/react-component/tsconfig.json +8 -0
- package/demo-app/assets/index-DAUlrHTr.css +0 -1
- package/demo-app/assets/index-DN2Kb0A8.js +0 -100
- package/dist/index.cjs +0 -101
- package/dist/plugin.cjs +0 -575
- package/dist/plugin.d.ts +0 -16
- package/dist/plugin.js +0 -184
- package/dist/step/index.d.ts +0 -6
- package/dist/step/index.js +0 -6
- package/dist/step/matchers.d.ts +0 -14
- package/dist/step/matchers.js +0 -114
- package/dist/step/proto.d.ts +0 -46
- package/dist/step/proto.js +0 -114
- package/dist/step/runner/collection.d.ts +0 -13
- package/dist/step/runner/collection.js +0 -51
- package/dist/step/runner/single.d.ts +0 -21
- package/dist/step/runner/single.js +0 -138
- package/dist/step/spectra.d.ts +0 -34
- package/dist/step/spectra.js +0 -156
- package/dist/step/types.d.ts +0 -32
- package/dist/step/types.js +0 -5
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
- package/templates/default/tsconfig.spectra.android.json +0 -46
- package/templates/default/tsconfig.spectra.ios.json +0 -46
- package/templates/default/tsconfig.spectra.json +0 -22
- package/templates/default/tsconfig.spectra.web.json +0 -53
- package/templates/nx/fixtures/playgroundData.json +0 -7
- package/templates/nx/global-hooks/after/mobile.hook.ts +0 -3
- package/templates/nx/global-hooks/after/web.hook.ts +0 -3
- package/templates/nx/global-hooks/before/mobile.hook.ts +0 -3
- package/templates/nx/global-hooks/before/web.hook.ts +0 -3
- package/templates/nx/page-objects/MatchersPage/mobile.ts +0 -21
- package/templates/nx/page-objects/MatchersPage/web.ts +0 -23
- package/templates/nx/page-objects/NavigationPage/mobile.ts +0 -5
- package/templates/nx/page-objects/NavigationPage/web.ts +0 -8
- package/templates/nx/page-objects/PlaygroundPage/mobile.ts +0 -26
- package/templates/nx/page-objects/PlaygroundPage/web.ts +0 -29
- package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +0 -3
- package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +0 -12
- package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +0 -5
- package/templates/nx/specs/BrowserContext/suite.md +0 -9
- package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
- package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/spec.md +0 -12
- package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
- package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +0 -3
- package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +0 -12
- package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +0 -6
- package/templates/nx/specs/ContentMatchers/suite.md +0 -9
- package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +0 -3
- package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +0 -12
- package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +0 -5
- package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +0 -3
- package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +0 -12
- package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +0 -8
- package/templates/nx/specs/ElementMatchers/hooks/after/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/after/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/afterEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/afterEach/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/before/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/before/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/beforeEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/beforeEach/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/suite.md +0 -9
- package/templates/nx/specs/Playground/TC-0001-form-controls/mobile.test.ts +0 -3
- package/templates/nx/specs/Playground/TC-0001-form-controls/spec.md +0 -12
- package/templates/nx/specs/Playground/TC-0001-form-controls/web.test.ts +0 -6
- package/templates/nx/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +0 -3
- package/templates/nx/specs/Playground/TC-0002-toggle-elements/spec.md +0 -12
- package/templates/nx/specs/Playground/TC-0002-toggle-elements/web.test.ts +0 -6
- package/templates/nx/specs/Playground/hooks/after/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/after/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/afterEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/afterEach/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/before/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/before/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/beforeEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/beforeEach/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/suite.md +0 -9
- package/templates/nx/support/actions/fillCredentials/mobile.action.ts +0 -4
- package/templates/nx/support/actions/fillCredentials/web.action.ts +0 -4
- package/templates/nx/support/steps/togglePlaygroundStates/mobile.step.ts +0 -3
- package/templates/nx/support/steps/togglePlaygroundStates/step.md +0 -7
- package/templates/nx/support/steps/togglePlaygroundStates/web.step.ts +0 -5
- package/templates/nx/support/steps/verifyPlaygroundState/mobile.step.ts +0 -4
- package/templates/nx/support/steps/verifyPlaygroundState/step.md +0 -7
- package/templates/nx/support/steps/verifyPlaygroundState/web.step.ts +0 -6
- package/templates/nx/tsconfig.spectra.android.json +0 -39
- package/templates/nx/tsconfig.spectra.ios.json +0 -39
- package/templates/nx/tsconfig.spectra.json +0 -25
- package/templates/nx/tsconfig.spectra.shared.json +0 -25
- package/templates/nx/tsconfig.spectra.web.json +0 -45
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mockPosts": [
|
|
3
|
+
{
|
|
4
|
+
"id": 1,
|
|
5
|
+
"title": "Mocked Post 1 - TestSpectra Matchers",
|
|
6
|
+
"body": "First mocked post body for verifying GET API interception in TestSpectra."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": 2,
|
|
10
|
+
"title": "Mocked Post 2 - Cross-Platform Automation",
|
|
11
|
+
"body": "Second mocked post body for verifying collection and item assertions."
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"mockNewPost": {
|
|
15
|
+
"title": "TestSpectra Automated Post",
|
|
16
|
+
"body": "End-to-End API mock verification with browser.intercept command."
|
|
17
|
+
},
|
|
18
|
+
"mockPostResponse": {
|
|
19
|
+
"id": 101,
|
|
20
|
+
"title": "TestSpectra Automated Post",
|
|
21
|
+
"body": "End-to-End API mock verification with browser.intercept command.",
|
|
22
|
+
"userId": 1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
class MatchersPage {
|
|
2
2
|
get visibleElement() { return Spectra.get("~visible_element"); }
|
|
3
3
|
get hiddenElement() { return Spectra.get("~hidden_element"); }
|
|
4
4
|
get existingElement() { return Spectra.get("~existing_element"); }
|
|
@@ -15,6 +15,18 @@ export class MatchersPage {
|
|
|
15
15
|
get productCards() { return Spectra.getAll("~product_card"); }
|
|
16
16
|
get emptyList() { return Spectra.getAll("~empty_list"); }
|
|
17
17
|
|
|
18
|
+
// API Demo elements
|
|
19
|
+
get fetchApiButton() { return Spectra.get("~fetch_api_btn"); }
|
|
20
|
+
get fetchStatusBadge() { return Spectra.get("~fetch_status_badge"); }
|
|
21
|
+
get fetchedItems() { return Spectra.getAll("~api_fetched_item"); }
|
|
22
|
+
get fetchLoadingIndicator() { return Spectra.get("~fetch_loading_indicator"); }
|
|
23
|
+
get postTitleInput() { return Spectra.get("~post_input_title"); }
|
|
24
|
+
get postBodyInput() { return Spectra.get("~post_input_body"); }
|
|
25
|
+
get submitPostButton() { return Spectra.get("~submit_post_btn"); }
|
|
26
|
+
get postStatusBadge() { return Spectra.get("~post_status_badge"); }
|
|
27
|
+
get postSuccessBanner() { return Spectra.get("~post_success_banner"); }
|
|
28
|
+
get postResponseJson() { return Spectra.get("~post_response_json"); }
|
|
29
|
+
|
|
18
30
|
async open(_section = "") {}
|
|
19
31
|
}
|
|
20
32
|
|
|
@@ -1,22 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
get visibleElement() {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
get
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
get
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
get
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
get
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
class MatchersPage {
|
|
2
|
+
get visibleElement() {
|
|
3
|
+
return Spectra.get("#demo-visible-el");
|
|
4
|
+
}
|
|
5
|
+
get hiddenElement() {
|
|
6
|
+
return Spectra.get("#demo-hidden-el");
|
|
7
|
+
}
|
|
8
|
+
get existingElement() {
|
|
9
|
+
return Spectra.get("#demo-existing-el");
|
|
10
|
+
}
|
|
11
|
+
get submitButton() {
|
|
12
|
+
return Spectra.get("#demo-submit-btn");
|
|
13
|
+
}
|
|
14
|
+
get disabledButton() {
|
|
15
|
+
return Spectra.get("#demo-disabled-btn");
|
|
16
|
+
}
|
|
17
|
+
get checkbox() {
|
|
18
|
+
return Spectra.get("#demo-checkbox");
|
|
19
|
+
}
|
|
20
|
+
get radio() {
|
|
21
|
+
return Spectra.get("#demo-radio");
|
|
22
|
+
}
|
|
23
|
+
get emailInput() {
|
|
24
|
+
return Spectra.get("#demo-email-input");
|
|
25
|
+
}
|
|
26
|
+
get tokenInput() {
|
|
27
|
+
return Spectra.get("#demo-token-input");
|
|
28
|
+
}
|
|
29
|
+
get exactText() {
|
|
30
|
+
return Spectra.get("#demo-exact-text");
|
|
31
|
+
}
|
|
32
|
+
get partialText() {
|
|
33
|
+
return Spectra.get("#demo-partial-text");
|
|
34
|
+
}
|
|
35
|
+
get activeTab() {
|
|
36
|
+
return Spectra.get("#demo-active-tab");
|
|
37
|
+
}
|
|
38
|
+
get navLink() {
|
|
39
|
+
return Spectra.get("#demo-nav-link");
|
|
40
|
+
}
|
|
41
|
+
get styledElement() {
|
|
42
|
+
return Spectra.get("#demo-styled-el");
|
|
43
|
+
}
|
|
44
|
+
get focusInput() {
|
|
45
|
+
return Spectra.get("#demo-focus-input");
|
|
46
|
+
}
|
|
47
|
+
get productCards() {
|
|
48
|
+
return Spectra.getAll(".demo-product-card");
|
|
49
|
+
}
|
|
50
|
+
get emptyList() {
|
|
51
|
+
return Spectra.getAll("#demo-empty-list > *");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// API Interception & Mocking elements
|
|
55
|
+
get fetchApiButton() {
|
|
56
|
+
return Spectra.get("#fetch-api-btn");
|
|
57
|
+
}
|
|
58
|
+
get fetchStatusBadge() {
|
|
59
|
+
return Spectra.get("#fetch-status-badge");
|
|
60
|
+
}
|
|
61
|
+
get fetchedItems() {
|
|
62
|
+
return Spectra.getAll(".api-fetched-item");
|
|
63
|
+
}
|
|
64
|
+
get fetchLoadingIndicator() {
|
|
65
|
+
return Spectra.get("#fetch-loading-indicator");
|
|
66
|
+
}
|
|
67
|
+
get postTitleInput() {
|
|
68
|
+
return Spectra.get("#post-input-title");
|
|
69
|
+
}
|
|
70
|
+
get postBodyInput() {
|
|
71
|
+
return Spectra.get("#post-input-body");
|
|
72
|
+
}
|
|
73
|
+
get submitPostButton() {
|
|
74
|
+
return Spectra.get("#submit-post-btn");
|
|
75
|
+
}
|
|
76
|
+
get postStatusBadge() {
|
|
77
|
+
return Spectra.get("#post-status-badge");
|
|
78
|
+
}
|
|
79
|
+
get postSuccessBanner() {
|
|
80
|
+
return Spectra.get("#post-success-banner");
|
|
81
|
+
}
|
|
82
|
+
get postResponseJson() {
|
|
83
|
+
return Spectra.get("#post-response-json");
|
|
84
|
+
}
|
|
17
85
|
|
|
18
86
|
async open(section = "") {
|
|
19
|
-
await
|
|
87
|
+
await Spectra.navigate("/" + (section ? "#" + section : ""));
|
|
20
88
|
}
|
|
21
89
|
}
|
|
22
90
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
class PlaygroundPage {
|
|
2
2
|
get visibleElement() { return Spectra.get("#demo-visible-el-pg"); }
|
|
3
3
|
get hiddenElement() { return Spectra.get("#demo-hidden-el-pg"); }
|
|
4
4
|
get existingElement() { return Spectra.get("#demo-existing-el-pg"); }
|
|
@@ -13,11 +13,13 @@ export class PlaygroundPage {
|
|
|
13
13
|
get partialText() { return Spectra.get("#demo-partial-text-pg"); }
|
|
14
14
|
get activeTab() { return Spectra.get("#demo-active-tab-pg"); }
|
|
15
15
|
get navLink() { return Spectra.get("#demo-nav-link-pg"); }
|
|
16
|
+
get styledElement() { return Spectra.get("#demo-styled-el-pg"); }
|
|
17
|
+
get focusInput() { return Spectra.get("#demo-focus-input-pg"); }
|
|
16
18
|
get productItems() { return Spectra.getAll(".demo-product-item"); }
|
|
17
19
|
get emptyList() { return Spectra.getAll("#demo-empty-list-pg > *"); }
|
|
18
20
|
|
|
19
21
|
async open() {
|
|
20
|
-
await
|
|
22
|
+
await Spectra.navigate("/#playground");
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
async fillCredentials(email = Fixture.playgroundData.defaultEmail, token = Fixture.playgroundData.defaultToken) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shared-testing",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"projectType": "library",
|
|
5
|
+
"sourceRoot": "shared/testing",
|
|
6
|
+
"targets": {
|
|
7
|
+
"type-check": {
|
|
8
|
+
"executor": "nx:run-commands",
|
|
9
|
+
"options": {
|
|
10
|
+
"command": "tsc -b",
|
|
11
|
+
"cwd": "."
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"tags": [
|
|
16
|
+
"scope:shared",
|
|
17
|
+
"type:shared"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default async function
|
|
1
|
+
export default async function (this: any, email: string, token: string) {
|
|
2
2
|
await this.get("#demo-email-input-pg").type(email);
|
|
3
3
|
await this.get("#demo-token-input-pg").type(token);
|
|
4
4
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export default async function
|
|
1
|
+
export default async function () {
|
|
2
2
|
await PlaygroundPage.open();
|
|
3
|
-
await PlaygroundPage.hiddenElement.
|
|
4
|
-
await PlaygroundPage.existingElement.
|
|
3
|
+
await PlaygroundPage.hiddenElement.shouldBeVisible();
|
|
4
|
+
await PlaygroundPage.existingElement.shouldExist();
|
|
5
5
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export default async function
|
|
1
|
+
export default async function () {
|
|
2
2
|
await PlaygroundPage.open();
|
|
3
|
-
await PlaygroundPage.visibleElement.
|
|
4
|
-
await PlaygroundPage.enabledButton.
|
|
5
|
-
await PlaygroundPage.termsCheckbox.
|
|
3
|
+
await PlaygroundPage.visibleElement.shouldBeVisible();
|
|
4
|
+
await PlaygroundPage.enabledButton.shouldBeEnabled();
|
|
5
|
+
await PlaygroundPage.termsCheckbox.shouldBeChecked();
|
|
6
6
|
}
|
|
@@ -4,58 +4,49 @@ export default defineConfig({
|
|
|
4
4
|
webConfig: {
|
|
5
5
|
baseUrl: "http://localhost:5173",
|
|
6
6
|
maxConcurrentSessions: "1",
|
|
7
|
-
|
|
7
|
+
headless: true,
|
|
8
8
|
implicitWait: "5000",
|
|
9
|
-
pageLoadTimeout: "30000",
|
|
10
|
-
scriptTimeout: "30000",
|
|
11
9
|
parallelizationMode: "testcase",
|
|
12
10
|
},
|
|
13
|
-
browsers: [
|
|
14
|
-
{
|
|
15
|
-
id: "chrome-desktop",
|
|
16
|
-
type: "chrome",
|
|
17
|
-
mobileEmulation: false,
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
11
|
androidConfig: {
|
|
21
|
-
|
|
22
|
-
platformName: "Android",
|
|
23
|
-
platformVersion: "13",
|
|
24
|
-
deviceName: "emulator-5554",
|
|
25
|
-
automationName: "UiAutomator2",
|
|
12
|
+
driverServer: "tcp://127.0.0.1:8200",
|
|
26
13
|
appPackage: "",
|
|
27
14
|
appActivity: "",
|
|
28
|
-
autoGrantPermissions: true,
|
|
29
15
|
noReset: false,
|
|
30
16
|
implicitWait: "10000",
|
|
31
17
|
parallelizationMode: "suite",
|
|
18
|
+
devices: [
|
|
19
|
+
{
|
|
20
|
+
id: "emulator-5554",
|
|
21
|
+
name: "Pixel 7 Pro Emulator",
|
|
22
|
+
version: "14.0",
|
|
23
|
+
systemPort: 8200,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
32
26
|
},
|
|
33
27
|
iosConfig: {
|
|
34
28
|
appiumServer: "http://127.0.0.1:4723",
|
|
35
|
-
platformName: "iOS",
|
|
36
|
-
platformVersion: "16.0",
|
|
37
|
-
deviceName: "iPhone 14",
|
|
38
29
|
automationName: "XCUITest",
|
|
39
30
|
bundleId: "",
|
|
40
|
-
udid: "auto",
|
|
41
|
-
xcodeOrgId: "",
|
|
42
|
-
xcodeSigningId: "iPhone Developer",
|
|
43
31
|
autoAcceptAlerts: true,
|
|
44
32
|
noReset: false,
|
|
45
33
|
implicitWait: "10000",
|
|
46
34
|
parallelizationMode: "suite",
|
|
35
|
+
devices: [
|
|
36
|
+
{
|
|
37
|
+
id: "iphone-15-pro",
|
|
38
|
+
name: "iPhone 15 Pro Simulator",
|
|
39
|
+
version: "17.0",
|
|
40
|
+
udid: "auto",
|
|
41
|
+
wdaLocalPort: 8100,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
47
44
|
},
|
|
48
|
-
loadConfig: {
|
|
49
|
-
virtualUsers: "10",
|
|
50
|
-
duration: "1m",
|
|
51
|
-
},
|
|
52
|
-
loadStages: [],
|
|
53
|
-
thresholds: [],
|
|
54
45
|
executionConfig: {
|
|
55
46
|
networkMonitoringEnabled: true,
|
|
56
47
|
fastResponseTime: "200",
|
|
57
48
|
normalResponseTime: "1000",
|
|
58
49
|
monitoredDomains: [],
|
|
59
|
-
environmentVariables:
|
|
50
|
+
environmentVariables: { DEMO_API_MODE: "sandbox" },
|
|
60
51
|
},
|
|
61
52
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# TestSpectra AI Instructions for Cursor
|
|
2
|
+
|
|
3
|
+
You are developing automated tests and React components with the TestSpectra testing framework.
|
|
4
|
+
|
|
5
|
+
## Key Rules & Conventions
|
|
6
|
+
1. **Zero-Import Standard**: Never add manual `import` statements for Page/Component Objects (`ButtonComponent`, `BadgeComponent`, `InputComponent`), Steps (`Step.*`), Fixtures (`Fixture.*`), or Actions (`Spectra.*`). All typings are provided globally and ambiently via `.testspectra/types/`.
|
|
7
|
+
2. **Component Testing Pattern**: Mount React components using `await Spectra.mount(<Component />)` (real JSX and static component imports are allowed in `*.test.tsx` files, unlike zero-import `*.web.test.ts` E2E specs), then inspect and interact using `Spectra.get(...)` / `Spectra.getAll(...)` or Page/Component Objects. Each `Spectra.mount()` call replaces the previous mount automatically — no cleanup command needed. Run via `spectra test` (a separate suite from E2E's `spectra run`).
|
|
8
|
+
3. **Platform Separation**:
|
|
9
|
+
- `web.test.ts` / `web.test.tsx` / `web.ts`: Web / Browser component implementations.
|
|
10
|
+
- `common.test.ts` / `common.ts`: Cross-platform shared implementations.
|
|
11
|
+
4. **CamelCase Naming Convention**:
|
|
12
|
+
- Component Objects (`page-objects/ButtonComponent/`, `page-objects/BadgeComponent/`)
|
|
13
|
+
- Reusable Actions (`support/actions/fillInputField/`)
|
|
14
|
+
- Reusable Steps (`support/steps/verifyButtonState/`)
|
|
15
|
+
5. **Spec-as-Code**:
|
|
16
|
+
- Suites are defined in `specs/<suite-name>/suite.md` with YAML frontmatter (`id`, `name`, `executionOrder`, `tags`).
|
|
17
|
+
- Test cases are defined in `specs/<suite-name>/<TC-ID-slug>/spec.md` with YAML frontmatter (`id`, `title`, `priority`, `coverage`).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# TestSpectra React Component Testing Workspace
|
|
2
|
+
|
|
3
|
+
## Commands
|
|
4
|
+
- `pnpm test` or `spectra test` — Run the component test suite (bundled Vitest browser mode via `@testspectra/react`)
|
|
5
|
+
- `pnpm run test:headed` — Run component tests with a visible browser window
|
|
6
|
+
- `pnpm run sync-types` — Scan workspace and regenerate ambient `.testspectra/types/`
|
|
7
|
+
- `pnpm run type-check` — Type check with `tsc -b`
|
|
8
|
+
|
|
9
|
+
## Architecture Rules
|
|
10
|
+
|
|
11
|
+
1. Zero-import standard for `Spectra.*`, `ButtonComponent`, `BadgeComponent`, `InputComponent`, `Step.*`, and `Fixture.*` — these stay ambient globals, auto-discovered from `page-objects/`, `support/steps/`, and `fixtures/`.
|
|
12
|
+
2. Component testing uses `Spectra.mount(<Component />)` — real JSX, real static imports for the component under test are allowed and expected in `*.test.tsx` files (unlike `*.web.test.ts` E2E specs). `Spectra.mount()` always replaces whatever was previously mounted; no manual cleanup call is needed between tests.
|
|
13
|
+
3. Component tests are a **separate test suite** from E2E (`spectra run`) — they live in `specs/<Suite>/<TC-ID>/web.test.tsx` alongside `spec.md`, run via `spectra test`, not `spectra run`. See `docs/v2/features/component-testing/react/`.
|
|
14
|
+
4. Assertions use the same TestSpectra DSL as E2E (`Spectra.get().shouldBeVisible()`, `.shouldHaveText()`, etc.) — nothing new to learn beyond `Spectra.mount()`.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# TestSpectra React Component Testing Template
|
|
2
|
+
|
|
3
|
+
A high-performance, real-browser React component testing template powered by **TestSpectra**, **WebdriverIO Browser Runner**, and **Testing Library**.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- **Direct Component Mounting**: Mount TSX components directly in real Chromium/Blink engines using `@testing-library/react`.
|
|
8
|
+
- **Zero Mock Browser**: Real layout calculations, CSS rendering, focus states, and browser events without JSDOM/HappyDOM limitations.
|
|
9
|
+
- **Fast Vite HMR Core**: Instant test startup powered by Vite bundler inside the browser runner.
|
|
10
|
+
- **TestSpectra Matchers**: Comprehensive semantic assertions (`.shouldBeVisible()`, `.shouldExist()`, `expect(el).toHaveText()`).
|
|
11
|
+
|
|
12
|
+
## 📁 Directory Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
.
|
|
16
|
+
├── spectra.config.ts # TestSpectra centralized configuration
|
|
17
|
+
├── wdio.conf.ts # WebdriverIO Browser Runner + Vite config
|
|
18
|
+
├── tsconfig.json # TypeScript configuration for JSX & runner types
|
|
19
|
+
└── src/
|
|
20
|
+
├── components/ # React components and tests
|
|
21
|
+
│ ├── Button/
|
|
22
|
+
│ │ ├── Button.tsx
|
|
23
|
+
│ │ └── Button.test.tsx
|
|
24
|
+
│ ├── Badge/
|
|
25
|
+
│ │ ├── Badge.tsx
|
|
26
|
+
│ │ └── Badge.test.tsx
|
|
27
|
+
│ └── Input/
|
|
28
|
+
│ ├── Input.tsx
|
|
29
|
+
│ └── Input.test.tsx
|
|
30
|
+
└── test-utils.tsx # Common testing helpers & providers
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 🛠️ Usage & Commands
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Run all component tests
|
|
37
|
+
pnpm test
|
|
38
|
+
|
|
39
|
+
# Run component tests in headless mode
|
|
40
|
+
pnpm run test:headless
|
|
41
|
+
|
|
42
|
+
# Run tests in high-concurrency chunked worker mode
|
|
43
|
+
pnpm run test:chunked
|
|
44
|
+
|
|
45
|
+
# Type check
|
|
46
|
+
pnpm run type-check
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 📝 Writing Component Tests
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import React from 'react';
|
|
53
|
+
import { render } from '@testing-library/react';
|
|
54
|
+
import { expect, $ } from '@wdio/globals';
|
|
55
|
+
import { Button } from './Button';
|
|
56
|
+
|
|
57
|
+
describe('Button Component', () => {
|
|
58
|
+
it('renders label and handles user clicks', async () => {
|
|
59
|
+
let clicked = false;
|
|
60
|
+
render(<Button label="Submit" onClick={() => (clicked = true)} />);
|
|
61
|
+
|
|
62
|
+
const button = await $('button=Submit');
|
|
63
|
+
await expect(button).toBeDisplayed();
|
|
64
|
+
|
|
65
|
+
await button.click();
|
|
66
|
+
expect(clicked).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@testspectra/template-react-component",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "spectra test",
|
|
8
|
+
"test:headed": "spectra test --headed",
|
|
9
|
+
"spectra": "spectra",
|
|
10
|
+
"doctor": "spectra doctor",
|
|
11
|
+
"watch": "spectra watch",
|
|
12
|
+
"type-check": "tsc -b",
|
|
13
|
+
"sync-types": "spectra sync-types",
|
|
14
|
+
"postinstall": "spectra sync-types"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@testspectra/cli": "link:../..",
|
|
18
|
+
"@testspectra/matchers": "link:../../../tools/matchers",
|
|
19
|
+
"@testspectra/react": "link:../../../tools/react",
|
|
20
|
+
"@types/node": "^20.14.0",
|
|
21
|
+
"@types/react": "^18.3.3",
|
|
22
|
+
"@types/react-dom": "^18.3.0",
|
|
23
|
+
"react": "^18.3.1",
|
|
24
|
+
"react-dom": "^18.3.1",
|
|
25
|
+
"typescript": "^5.4.5"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class BadgeComponent {
|
|
2
|
+
/** Root badge element */
|
|
3
|
+
get root() {
|
|
4
|
+
return Spectra.get("[data-testid='testspectra-badge']");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Dot indicator element */
|
|
8
|
+
get dot() {
|
|
9
|
+
return Spectra.get("[data-testid='badge-dot']");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Badge label text element */
|
|
13
|
+
get label() {
|
|
14
|
+
return Spectra.get("[data-testid='badge-label']");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Lookup badge by severity attribute */
|
|
18
|
+
bySeverity(severity: 'info' | 'success' | 'warning' | 'danger') {
|
|
19
|
+
return Spectra.get(`[data-testid='testspectra-badge'][data-severity='${severity}']`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default new BadgeComponent();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class ButtonComponent {
|
|
2
|
+
/** Root button element */
|
|
3
|
+
get root() {
|
|
4
|
+
return Spectra.get("[data-testid='testspectra-button']");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Label element inside button */
|
|
8
|
+
get label() {
|
|
9
|
+
return Spectra.get("[data-testid='button-label']");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Optional icon element */
|
|
13
|
+
get icon() {
|
|
14
|
+
return Spectra.get("[data-testid='button-icon']");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Lookup button element by visible text */
|
|
18
|
+
byText(text: string) {
|
|
19
|
+
return Spectra.get(`button*=${text}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default new ButtonComponent();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class InputComponent {
|
|
2
|
+
/** Root input element */
|
|
3
|
+
get root() {
|
|
4
|
+
return Spectra.get("[data-testid='testspectra-input']");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Lookup input element by placeholder substring */
|
|
8
|
+
byPlaceholder(placeholder: string) {
|
|
9
|
+
return Spectra.get(`input[placeholder*='${placeholder}']`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default new InputComponent();
|
package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/spec.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: TC-0002
|
|
3
|
+
title: Verify default badge with info severity
|
|
4
|
+
priority: Critical
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: automated
|
|
7
|
+
coverage:
|
|
8
|
+
web: automated
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# TC-0002: Badge Default Rendering
|
|
12
|
+
|
|
13
|
+
Verify that `<Badge />` renders with the default `info` severity when no `severity` prop is provided.
|
|
14
|
+
|
|
15
|
+
## Test Steps
|
|
16
|
+
|
|
17
|
+
1. Mount `<Badge label="System Active" />`.
|
|
18
|
+
2. Verify the badge is visible, shows the correct label text, and has `data-severity="info"`.
|
package/templates/react-component/specs/BadgeComponent/TC-0002-badge-severities-and-dot/web.test.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Badge } from '../../../src/components/Badge/Badge.js';
|
|
2
|
+
import { withProviders } from '../../../src/test-utils.js';
|
|
3
|
+
|
|
4
|
+
it('Verify default badge with info severity', async () => {
|
|
5
|
+
await Spectra.mount(withProviders(<Badge label="System Active" />));
|
|
6
|
+
|
|
7
|
+
// Assert via BadgeComponent component object
|
|
8
|
+
await BadgeComponent.root.shouldBeVisible();
|
|
9
|
+
await BadgeComponent.label.shouldHaveText('System Active');
|
|
10
|
+
await BadgeComponent.root.shouldHaveAttribute('data-severity', 'info');
|
|
11
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: TC-0006
|
|
3
|
+
title: Verify badge with success severity and dot indicator
|
|
4
|
+
priority: High
|
|
5
|
+
caseType: Positive
|
|
6
|
+
status: automated
|
|
7
|
+
coverage:
|
|
8
|
+
web: automated
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# TC-0006: Badge Success Severity with Dot Indicator
|
|
12
|
+
|
|
13
|
+
Verify that `<Badge />` renders the `success` severity styling and shows a dot indicator when the `dot` prop is set.
|
|
14
|
+
|
|
15
|
+
## Test Steps
|
|
16
|
+
|
|
17
|
+
1. Mount `<Badge label="Completed" severity="success" dot />`.
|
|
18
|
+
2. Verify the badge is visible with `data-severity="success"` and the dot indicator is visible.
|