@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
package/dist/index.js
CHANGED
|
@@ -7,12 +7,13 @@ import { initCommand } from './commands/init.js';
|
|
|
7
7
|
import { installCommand } from './commands/install.js';
|
|
8
8
|
import { runCommand } from './commands/run.js';
|
|
9
9
|
import { testCommand } from './commands/test.js';
|
|
10
|
-
import {
|
|
10
|
+
import { upgradeCommand } from './commands/upgrade.js';
|
|
11
11
|
import { watchCommand } from './commands/watch.js';
|
|
12
12
|
import { syncTypesCommand } from './commands/sync-types.js';
|
|
13
13
|
import { refactorCommand } from './commands/refactor.js';
|
|
14
14
|
import { lintCommand } from './commands/lint.js';
|
|
15
15
|
import { licenseCommand } from './commands/license.js';
|
|
16
|
+
import { docsUpdateCommand } from './commands/docs.js';
|
|
16
17
|
import { skillsInitCommand, skillsListCommand, skillsAddCommand, skillsUpdateCommand, skillsRemoveCommand, } from './commands/skills.js';
|
|
17
18
|
export * from './config/schema.js';
|
|
18
19
|
export * from './config/loader.js';
|
|
@@ -24,10 +25,10 @@ export * from './types/generator.js';
|
|
|
24
25
|
export * from '@testspectra/matchers';
|
|
25
26
|
export function createCliProgram() {
|
|
26
27
|
const program = new Command();
|
|
27
|
-
program.name('spectra').description('TestSpectra
|
|
28
|
+
program.name('spectra').description('TestSpectra Cross-Platform Test Runner CLI').version('1.0.0');
|
|
28
29
|
program
|
|
29
30
|
.command('init')
|
|
30
|
-
.description('Initialize
|
|
31
|
+
.description('Initialize spectra.config.ts and project directories')
|
|
31
32
|
.option('-t, --template <template>', 'Project template: default, nx, react-component')
|
|
32
33
|
.option('-f, --force', 'Overwrite existing configuration if present')
|
|
33
34
|
.action(initCommand);
|
|
@@ -40,15 +41,16 @@ export function createCliProgram() {
|
|
|
40
41
|
program
|
|
41
42
|
.command('install [dependency]')
|
|
42
43
|
.description('Install missing testing dependencies, browser drivers, and workspace packages')
|
|
43
|
-
.option('-f, --force', '
|
|
44
|
-
.addHelpText('after', `
|
|
45
|
-
Examples:
|
|
46
|
-
$ spectra install Install all missing required dependencies automatically
|
|
47
|
-
$ spectra install chrome Install Google Chrome for Testing & matching Chromedriver
|
|
48
|
-
$ spectra install adb Install Google Android SDK Platform Tools (ADB)
|
|
49
|
-
$ spectra install bun Install Bun runtime
|
|
50
|
-
$ spectra install android-
|
|
51
|
-
$ spectra install
|
|
44
|
+
.option('-f, --force', 'Remove existing artifacts and perform a clean reinstall of the dependency')
|
|
45
|
+
.addHelpText('after', `
|
|
46
|
+
Examples:
|
|
47
|
+
$ spectra install Install all missing required dependencies automatically
|
|
48
|
+
$ spectra install chrome Install Google Chrome for Testing & matching Chromedriver
|
|
49
|
+
$ spectra install adb Install Google Android SDK Platform Tools (ADB)
|
|
50
|
+
$ spectra install bun Install Bun runtime
|
|
51
|
+
$ spectra install android-agent Install Spectra Android Native Agent (spectra-agent.jar)
|
|
52
|
+
$ spectra install android-agent -f Clean reinstall Spectra Android Native Agent
|
|
53
|
+
$ spectra install packages Install TestSpectra CLI, Matchers & Android Agent packages`)
|
|
52
54
|
.action(installCommand);
|
|
53
55
|
program
|
|
54
56
|
.command('demo')
|
|
@@ -85,30 +87,41 @@ Examples:
|
|
|
85
87
|
.action(lintCommand);
|
|
86
88
|
program
|
|
87
89
|
.command('doctor')
|
|
88
|
-
.description('Verify local environment prerequisites (ADB, Spectra Android
|
|
90
|
+
.description('Verify local environment prerequisites (Bun, Git, ADB, Chrome, Spectra Android Agent, workspace packages)')
|
|
89
91
|
.option('-v, --verbose', 'Show full installation paths for all detected runtimes and packages')
|
|
92
|
+
.option('--scope <category>', 'Only check one category: core, web, mobile (default: all)')
|
|
93
|
+
.option('--only <keys>', 'Only check specific dependencies (comma-separated): bun, git, cli, chrome, matchers, adb, agent')
|
|
90
94
|
.option('--fix', 'Attempt automatic fix / download of missing tools')
|
|
91
95
|
.option('--json', 'Output diagnostic results as JSON')
|
|
92
96
|
.action(doctorCommand);
|
|
93
97
|
program
|
|
94
|
-
.command('
|
|
95
|
-
.
|
|
98
|
+
.command('upgrade [packages...]')
|
|
99
|
+
.alias('update')
|
|
100
|
+
.description('Upgrade TestSpectra ecosystem packages and system drivers to the latest versions')
|
|
96
101
|
.option('--check', 'Only check for available updates without installing')
|
|
97
|
-
.
|
|
102
|
+
.option('--packages-only', 'Only upgrade NPM packages in package.json')
|
|
103
|
+
.option('--drivers-only', 'Only upgrade system binaries and drivers (ADB, Agent, Chrome)')
|
|
104
|
+
.option('--json', 'Output the update check (packages + drivers) as JSON (implies --check, no changes applied)')
|
|
105
|
+
.addHelpText('after', `
|
|
106
|
+
Examples:
|
|
107
|
+
$ spectra upgrade Upgrade all packages and system drivers
|
|
108
|
+
$ spectra upgrade @testspectra/cli Upgrade only the CLI package
|
|
109
|
+
$ spectra upgrade @testspectra/cli @testspectra/matchers Upgrade specific packages
|
|
110
|
+
$ spectra upgrade --check Check what is outdated (packages + drivers)`)
|
|
111
|
+
.action(upgradeCommand);
|
|
98
112
|
program
|
|
99
113
|
.command('devices')
|
|
100
|
-
.description('List connected Android
|
|
101
|
-
.option('-t, --target <target>', 'Filter scope: android, ios, web, all', 'all')
|
|
114
|
+
.description('List connected Android devices (ADB)')
|
|
102
115
|
.option('--json', 'Output results as JSON')
|
|
103
116
|
.action(devicesCommand);
|
|
104
117
|
program
|
|
105
118
|
.command('license [action] [key]')
|
|
106
119
|
.description('Manage TestSpectra commercial license (activate, status, remove)')
|
|
107
120
|
.option('--json', 'Output license details as JSON')
|
|
108
|
-
.addHelpText('after', `
|
|
109
|
-
Examples:
|
|
110
|
-
$ spectra license activate <KEY> Activate license key and auto-configure private driver registry
|
|
111
|
-
$ spectra license status Display active license organization, plan, and expiration
|
|
121
|
+
.addHelpText('after', `
|
|
122
|
+
Examples:
|
|
123
|
+
$ spectra license activate <KEY> Activate license key and auto-configure private driver registry
|
|
124
|
+
$ spectra license status Display active license organization, plan, and expiration
|
|
112
125
|
$ spectra license remove Remove locally activated license credentials`)
|
|
113
126
|
.action(licenseCommand);
|
|
114
127
|
const skills = program
|
|
@@ -147,11 +160,19 @@ Examples:
|
|
|
147
160
|
.option('-w, --cwd <dir>', 'Custom workspace directory')
|
|
148
161
|
.option('-a, --agent <ids>', 'One-off override: comma-separated agent(s) to target, bypassing the saved "init" selection (claude, opencode, kilo, agents, gemini)')
|
|
149
162
|
.action(skillsRemoveCommand);
|
|
163
|
+
const docs = program.command('docs').description('Manage generated TestSpectra workspace documentation');
|
|
164
|
+
docs
|
|
165
|
+
.command('update')
|
|
166
|
+
.description('Regenerate ARCHITECTURE.md from the current workspace state, without re-running init')
|
|
167
|
+
.option('-w, --cwd <dir>', 'Custom workspace directory')
|
|
168
|
+
.action(docsUpdateCommand);
|
|
150
169
|
program
|
|
151
170
|
.command('run [paths...]')
|
|
152
171
|
.description('Execute test suite or individual test case')
|
|
153
172
|
.option('-s, --spec <path>', 'Spec file path to execute')
|
|
154
173
|
.option('-t, --target <target>', 'Target platform: web, android, ios, common', 'web')
|
|
174
|
+
.option('--host <name>', 'Target specific named host defined in spectra.config.ts (webConfig.hosts)')
|
|
175
|
+
.option('--base-url <url>', 'Override webConfig.baseUrl')
|
|
155
176
|
.option('-d, --device <device>', 'Target device name or UDID')
|
|
156
177
|
.option('--all-devices', 'Distribute test execution across all connected devices')
|
|
157
178
|
.option('--multi-device', 'Distribute test execution across all connected devices (alias for --all-devices)')
|
|
@@ -170,20 +191,29 @@ Examples:
|
|
|
170
191
|
.action(runCommand);
|
|
171
192
|
program
|
|
172
193
|
.command('test')
|
|
173
|
-
.description('Run React component tests via @testspectra/react
|
|
194
|
+
.description('Run React component tests via @testspectra/react')
|
|
195
|
+
.option('-r, --runner <engine>', 'Component test runner engine: spectra (default, native CDP) or vitest (Playwright browser mode)', 'spectra')
|
|
174
196
|
.option('-w, --cwd <dir>', 'Custom workspace directory')
|
|
175
197
|
.option('-s, --spec <path>', 'Spec file path (or substring filter) to execute')
|
|
176
198
|
.option('--headless', 'Run in headless mode (default)')
|
|
177
199
|
.option('--no-headless', 'Run in headed mode')
|
|
178
200
|
.option('--headed', 'Run the browser in visible GUI mode (alias for --no-headless)')
|
|
179
|
-
.option('--step-delay <ms>', 'Delay after each action/assertion in milliseconds (slow motion, for observing DOM transitions in --headed mode)')
|
|
201
|
+
.option('-d, --step-delay <ms>', 'Delay after each action/assertion in milliseconds (slow motion, for observing DOM transitions in --headed mode)')
|
|
180
202
|
.option('--delay <ms>', 'Alias for --step-delay')
|
|
181
|
-
.option('-c, --concurrency <number>', 'Run spec files sequentially (1) or in parallel (>1, default).
|
|
182
|
-
.option('-o, --output <path>', 'Write a
|
|
203
|
+
.option('-c, --concurrency <number>', 'Run spec files sequentially (1) or in parallel (>1, default).')
|
|
204
|
+
.option('-o, --output <path>', 'Write a JSON test report to this path')
|
|
183
205
|
.action(testCommand);
|
|
184
206
|
return program;
|
|
185
207
|
}
|
|
186
208
|
export async function runCli(args = process.argv) {
|
|
187
209
|
const program = createCliProgram();
|
|
188
210
|
await program.parseAsync(args);
|
|
211
|
+
// Commands whose stdout must stay machine-readable or is purely diagnostic never emit the
|
|
212
|
+
// interactive "update available" banner.
|
|
213
|
+
const silentCommands = ['doctor', 'install', 'upgrade', 'update'];
|
|
214
|
+
if (silentCommands.includes(program.args[0]))
|
|
215
|
+
return;
|
|
216
|
+
const { checkUpdateInBackground, displayUpdateNotificationIfNeeded } = await import('./utils/update-notifier.js');
|
|
217
|
+
checkUpdateInBackground();
|
|
218
|
+
displayUpdateNotificationIfNeeded();
|
|
189
219
|
}
|
|
@@ -14,20 +14,20 @@ const __dirname = path.dirname(__filename);
|
|
|
14
14
|
*/
|
|
15
15
|
describe('Component Test (.tsx) Import Exception', () => {
|
|
16
16
|
const tempDir = path.join(__dirname, '__temp_tsx_imports__');
|
|
17
|
-
const specFrontmatter = `---
|
|
18
|
-
id: TC-0200
|
|
19
|
-
title: Sample component test
|
|
20
|
-
priority: High
|
|
21
|
-
caseType: Positive
|
|
22
|
-
status: automated
|
|
23
|
-
coverage:
|
|
24
|
-
web: automated
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
# Sample component test
|
|
28
|
-
|
|
29
|
-
## Test Steps
|
|
30
|
-
1. Mount the component and assert it is visible.
|
|
17
|
+
const specFrontmatter = `---
|
|
18
|
+
id: TC-0200
|
|
19
|
+
title: Sample component test
|
|
20
|
+
priority: High
|
|
21
|
+
caseType: Positive
|
|
22
|
+
status: automated
|
|
23
|
+
coverage:
|
|
24
|
+
web: automated
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Sample component test
|
|
28
|
+
|
|
29
|
+
## Test Steps
|
|
30
|
+
1. Mount the component and assert it is visible.
|
|
31
31
|
`;
|
|
32
32
|
beforeEach(() => {
|
|
33
33
|
fs.mkdirSync(tempDir, { recursive: true });
|
|
@@ -39,23 +39,23 @@ coverage:
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
it('does not flag no-manual-import for ordinary component/library imports in .test.tsx', () => {
|
|
42
|
-
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import { Button } from '../../src/components/Button/Button.js';
|
|
43
|
-
import React from 'react';
|
|
44
|
-
|
|
45
|
-
it('Sample component test', async () => {
|
|
46
|
-
await Spectra.mount(<Button label="Save" />);
|
|
47
|
-
});
|
|
42
|
+
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import { Button } from '../../src/components/Button/Button.js';
|
|
43
|
+
import React from 'react';
|
|
44
|
+
|
|
45
|
+
it('Sample component test', async () => {
|
|
46
|
+
await Spectra.mount(<Button label="Save" />);
|
|
47
|
+
});
|
|
48
48
|
`);
|
|
49
49
|
const { diagnostics } = SpecLinter.validateSpecFile(path.join(tempDir, 'spec.md'));
|
|
50
50
|
const importErrors = diagnostics.filter((d) => d.code === 'testspectra/no-manual-import');
|
|
51
51
|
expect(importErrors).toHaveLength(0);
|
|
52
52
|
});
|
|
53
53
|
it('still flags no-manual-import when a .test.tsx import resolves into page-objects/', () => {
|
|
54
|
-
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import ButtonComponent from '../../page-objects/ButtonComponent/web.js';
|
|
55
|
-
|
|
56
|
-
it('Sample component test', async () => {
|
|
57
|
-
await ButtonComponent.root.shouldBeVisible();
|
|
58
|
-
});
|
|
54
|
+
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import ButtonComponent from '../../page-objects/ButtonComponent/web.js';
|
|
55
|
+
|
|
56
|
+
it('Sample component test', async () => {
|
|
57
|
+
await ButtonComponent.root.shouldBeVisible();
|
|
58
|
+
});
|
|
59
59
|
`);
|
|
60
60
|
const { diagnostics } = SpecLinter.validateSpecFile(path.join(tempDir, 'spec.md'));
|
|
61
61
|
const importErrors = diagnostics.filter((d) => d.code === 'testspectra/no-manual-import');
|
|
@@ -63,50 +63,50 @@ it('Sample component test', async () => {
|
|
|
63
63
|
expect(importErrors[0].message).toContain('page-objects');
|
|
64
64
|
});
|
|
65
65
|
it('still flags no-manual-import when a .test.tsx import resolves into support/steps/', () => {
|
|
66
|
-
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import verifyButtonState from '../../support/steps/verifyButtonState/web.step.js';
|
|
67
|
-
|
|
68
|
-
it('Sample component test', async () => {
|
|
69
|
-
await verifyButtonState('Save', true);
|
|
70
|
-
});
|
|
66
|
+
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import verifyButtonState from '../../support/steps/verifyButtonState/web.step.js';
|
|
67
|
+
|
|
68
|
+
it('Sample component test', async () => {
|
|
69
|
+
await verifyButtonState('Save', true);
|
|
70
|
+
});
|
|
71
71
|
`);
|
|
72
72
|
const { diagnostics } = SpecLinter.validateSpecFile(path.join(tempDir, 'spec.md'));
|
|
73
73
|
const importErrors = diagnostics.filter((d) => d.code === 'testspectra/no-manual-import');
|
|
74
74
|
expect(importErrors).toHaveLength(1);
|
|
75
75
|
});
|
|
76
76
|
it('still flags no-manual-import when a .test.tsx import resolves into fixtures/', () => {
|
|
77
|
-
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import users from '../../fixtures/users.json';
|
|
78
|
-
|
|
79
|
-
it('Sample component test', async () => {
|
|
80
|
-
expect(users).toBeDefined();
|
|
81
|
-
});
|
|
77
|
+
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import users from '../../fixtures/users.json';
|
|
78
|
+
|
|
79
|
+
it('Sample component test', async () => {
|
|
80
|
+
expect(users).toBeDefined();
|
|
81
|
+
});
|
|
82
82
|
`);
|
|
83
83
|
const { diagnostics } = SpecLinter.validateSpecFile(path.join(tempDir, 'spec.md'));
|
|
84
84
|
const importErrors = diagnostics.filter((d) => d.code === 'testspectra/no-manual-import');
|
|
85
85
|
expect(importErrors).toHaveLength(1);
|
|
86
86
|
});
|
|
87
87
|
it('still enforces single-it-required and no-describe-block in .test.tsx files', () => {
|
|
88
|
-
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import { Button } from '../../src/components/Button/Button.js';
|
|
89
|
-
|
|
90
|
-
describe('Button', () => {
|
|
91
|
-
it('Sample component test', async () => {
|
|
92
|
-
await Spectra.mount(<Button label="Save" />);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('Another test', async () => {
|
|
96
|
-
await Spectra.mount(<Button label="Cancel" />);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
88
|
+
fs.writeFileSync(path.join(tempDir, 'web.test.tsx'), `import { Button } from '../../src/components/Button/Button.js';
|
|
89
|
+
|
|
90
|
+
describe('Button', () => {
|
|
91
|
+
it('Sample component test', async () => {
|
|
92
|
+
await Spectra.mount(<Button label="Save" />);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('Another test', async () => {
|
|
96
|
+
await Spectra.mount(<Button label="Cancel" />);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
99
|
`);
|
|
100
100
|
const { diagnostics } = SpecLinter.validateSpecFile(path.join(tempDir, 'spec.md'));
|
|
101
101
|
expect(diagnostics.some((d) => d.code === 'testspectra/no-describe-block')).toBe(true);
|
|
102
102
|
expect(diagnostics.some((d) => d.code === 'testspectra/single-it-required')).toBe(true);
|
|
103
103
|
});
|
|
104
104
|
it('still forbids all imports (unchanged behavior) in plain .test.ts E2E specs', () => {
|
|
105
|
-
fs.writeFileSync(path.join(tempDir, 'web.test.ts'), `import { LoginPage } from '../../page-objects/LoginPage/web.js';
|
|
106
|
-
|
|
107
|
-
it('Sample component test', async () => {
|
|
108
|
-
await LoginPage.submitButton.click();
|
|
109
|
-
});
|
|
105
|
+
fs.writeFileSync(path.join(tempDir, 'web.test.ts'), `import { LoginPage } from '../../page-objects/LoginPage/web.js';
|
|
106
|
+
|
|
107
|
+
it('Sample component test', async () => {
|
|
108
|
+
await LoginPage.submitButton.click();
|
|
109
|
+
});
|
|
110
110
|
`);
|
|
111
111
|
const { diagnostics } = SpecLinter.validateSpecFile(path.join(tempDir, 'spec.md'));
|
|
112
112
|
const importErrors = diagnostics.filter((d) => d.code === 'testspectra/no-manual-import');
|
|
@@ -17,16 +17,16 @@ describe('Shared Library Boundary (testspectra/no-specs-in-shared-lib)', () => {
|
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
describe('findSharedLibraryRoots()', () => {
|
|
20
|
-
it('discovers parent folders of project.json files containing
|
|
20
|
+
it('discovers parent folders of project.json files containing testspectra:shared', () => {
|
|
21
21
|
const sharedDir1 = path.join(tempDir, 'shared', 'testing');
|
|
22
22
|
const sharedDir2 = path.join(tempDir, 'libs', 'common-helpers');
|
|
23
23
|
const nonSharedDir = path.join(tempDir, 'packages', 'playground', 'e2e');
|
|
24
24
|
fs.mkdirSync(sharedDir1, { recursive: true });
|
|
25
25
|
fs.mkdirSync(sharedDir2, { recursive: true });
|
|
26
26
|
fs.mkdirSync(nonSharedDir, { recursive: true });
|
|
27
|
-
fs.writeFileSync(path.join(sharedDir1, 'project.json'), JSON.stringify({ name: 'shared-testing', tags: ['
|
|
28
|
-
fs.writeFileSync(path.join(sharedDir2, 'project.json'), JSON.stringify({ name: 'common-helpers', tags: ['
|
|
29
|
-
fs.writeFileSync(path.join(nonSharedDir, 'project.json'), JSON.stringify({ name: 'playground-e2e', tags: ['
|
|
27
|
+
fs.writeFileSync(path.join(sharedDir1, 'project.json'), JSON.stringify({ name: 'shared-testing', tags: ['testspectra:shared'] }));
|
|
28
|
+
fs.writeFileSync(path.join(sharedDir2, 'project.json'), JSON.stringify({ name: 'common-helpers', tags: ['testspectra:shared'] }));
|
|
29
|
+
fs.writeFileSync(path.join(nonSharedDir, 'project.json'), JSON.stringify({ name: 'playground-e2e', tags: ['testspectra:e2e', 'testspectra:scope:playground'] }));
|
|
30
30
|
const roots = findSharedLibraryRoots(tempDir);
|
|
31
31
|
expect(roots).toHaveLength(2);
|
|
32
32
|
expect(roots).toContain(sharedDir1);
|
|
@@ -35,12 +35,12 @@ describe('Shared Library Boundary (testspectra/no-specs-in-shared-lib)', () => {
|
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
describe('isInsideSharedLibrary()', () => {
|
|
38
|
-
it('returns true for files inside a project tagged with
|
|
38
|
+
it('returns true for files inside a project tagged with testspectra:shared in project.json', () => {
|
|
39
39
|
const sharedDir = path.join(tempDir, 'shared', 'testing');
|
|
40
40
|
fs.mkdirSync(sharedDir, { recursive: true });
|
|
41
41
|
fs.writeFileSync(path.join(sharedDir, 'project.json'), JSON.stringify({
|
|
42
42
|
name: 'shared-testing',
|
|
43
|
-
tags: ['
|
|
43
|
+
tags: ['testspectra:shared'],
|
|
44
44
|
}));
|
|
45
45
|
const stepFile = path.join(sharedDir, 'support', 'steps', 'web.step.ts');
|
|
46
46
|
const specFile = path.join(sharedDir, 'specs', 'TC-001', 'spec.md');
|
|
@@ -55,7 +55,7 @@ describe('Shared Library Boundary (testspectra/no-specs-in-shared-lib)', () => {
|
|
|
55
55
|
fs.mkdirSync(customLibDir, { recursive: true });
|
|
56
56
|
fs.writeFileSync(path.join(customLibDir, 'project.json'), JSON.stringify({
|
|
57
57
|
name: 'custom-common-lib',
|
|
58
|
-
tags: ['
|
|
58
|
+
tags: ['testspectra:shared'],
|
|
59
59
|
}));
|
|
60
60
|
const actionFile = path.join(customLibDir, 'support', 'actions', 'click.action.ts');
|
|
61
61
|
expect(isInsideSharedLibrary(actionFile)).toBe(true);
|
|
@@ -65,7 +65,7 @@ describe('Shared Library Boundary (testspectra/no-specs-in-shared-lib)', () => {
|
|
|
65
65
|
fs.mkdirSync(sharedAppDir, { recursive: true });
|
|
66
66
|
fs.writeFileSync(path.join(sharedAppDir, 'project.json'), JSON.stringify({
|
|
67
67
|
name: 'shared-app',
|
|
68
|
-
tags: ['
|
|
68
|
+
tags: ['testspectra:e2e', 'testspectra:scope:shared-app'],
|
|
69
69
|
}));
|
|
70
70
|
const specFile = path.join(sharedAppDir, 'specs', 'TC-001', 'spec.md');
|
|
71
71
|
expect(isInsideSharedLibrary(specFile)).toBe(false);
|
|
@@ -75,7 +75,7 @@ describe('Shared Library Boundary (testspectra/no-specs-in-shared-lib)', () => {
|
|
|
75
75
|
fs.mkdirSync(featureDir, { recursive: true });
|
|
76
76
|
fs.writeFileSync(path.join(featureDir, 'project.json'), JSON.stringify({
|
|
77
77
|
name: 'playground-e2e',
|
|
78
|
-
tags: ['
|
|
78
|
+
tags: ['testspectra:e2e', 'testspectra:scope:playground'],
|
|
79
79
|
}));
|
|
80
80
|
const specFile = path.join(featureDir, 'specs', 'TC-001', 'spec.md');
|
|
81
81
|
expect(isInsideSharedLibrary(specFile)).toBe(false);
|
|
@@ -91,7 +91,7 @@ describe('Shared Library Boundary (testspectra/no-specs-in-shared-lib)', () => {
|
|
|
91
91
|
fs.mkdirSync(sharedLibDir, { recursive: true });
|
|
92
92
|
fs.writeFileSync(path.join(sharedLibDir, 'project.json'), JSON.stringify({
|
|
93
93
|
name: 'shared-testing',
|
|
94
|
-
tags: ['
|
|
94
|
+
tags: ['testspectra:shared'],
|
|
95
95
|
}));
|
|
96
96
|
const sharedSpecDir = path.join(sharedLibDir, 'specs', 'TC-error');
|
|
97
97
|
fs.mkdirSync(sharedSpecDir, { recursive: true });
|
|
@@ -119,7 +119,7 @@ status: draft
|
|
|
119
119
|
fs.mkdirSync(sharedLibDir, { recursive: true });
|
|
120
120
|
fs.writeFileSync(path.join(sharedLibDir, 'project.json'), JSON.stringify({
|
|
121
121
|
name: 'shared-testing',
|
|
122
|
-
tags: ['
|
|
122
|
+
tags: ['testspectra:shared'],
|
|
123
123
|
}));
|
|
124
124
|
const sharedSuiteDir = path.join(sharedLibDir, 'support');
|
|
125
125
|
fs.mkdirSync(sharedSuiteDir, { recursive: true });
|
|
@@ -141,7 +141,7 @@ status: active
|
|
|
141
141
|
fs.mkdirSync(customLibDir, { recursive: true });
|
|
142
142
|
fs.writeFileSync(path.join(customLibDir, 'project.json'), JSON.stringify({
|
|
143
143
|
name: 'my-testing-utils',
|
|
144
|
-
tags: ['
|
|
144
|
+
tags: ['testspectra:shared'],
|
|
145
145
|
}));
|
|
146
146
|
const specDir = path.join(customLibDir, 'specs', 'TC-custom');
|
|
147
147
|
fs.mkdirSync(specDir, { recursive: true });
|
|
@@ -169,7 +169,7 @@ status: draft
|
|
|
169
169
|
fs.mkdirSync(featureDir, { recursive: true });
|
|
170
170
|
fs.writeFileSync(path.join(featureDir, 'project.json'), JSON.stringify({
|
|
171
171
|
name: 'playground-e2e',
|
|
172
|
-
tags: ['
|
|
172
|
+
tags: ['testspectra:e2e', 'testspectra:scope:playground'],
|
|
173
173
|
}));
|
|
174
174
|
const featureSpecDir = path.join(featureDir, 'specs', 'TC-001');
|
|
175
175
|
fs.mkdirSync(featureSpecDir, { recursive: true });
|
|
@@ -195,7 +195,7 @@ status: draft
|
|
|
195
195
|
fs.mkdirSync(sharedE2eDir, { recursive: true });
|
|
196
196
|
fs.writeFileSync(path.join(sharedE2eDir, 'project.json'), JSON.stringify({
|
|
197
197
|
name: 'shared-feature-e2e',
|
|
198
|
-
tags: ['
|
|
198
|
+
tags: ['testspectra:e2e', 'testspectra:scope:shared-feature'],
|
|
199
199
|
}));
|
|
200
200
|
const specDir = path.join(sharedE2eDir, 'specs', 'TC-001');
|
|
201
201
|
fs.mkdirSync(specDir, { recursive: true });
|
|
@@ -241,7 +241,7 @@ status: draft
|
|
|
241
241
|
fs.mkdirSync(sharedLibDir, { recursive: true });
|
|
242
242
|
fs.writeFileSync(path.join(sharedLibDir, 'project.json'), JSON.stringify({
|
|
243
243
|
name: 'shared-testing',
|
|
244
|
-
tags: ['
|
|
244
|
+
tags: ['testspectra:shared'],
|
|
245
245
|
}));
|
|
246
246
|
const sharedDir1 = path.join(sharedLibDir, 'specs', 'TC-001');
|
|
247
247
|
const sharedDir2 = path.join(sharedLibDir, 'specs', 'TC-002');
|