@testspectra/cli 1.1.7 → 1.1.8-rc.2
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/bin/.testspectra-runner.hash +1 -1
- package/bin/spectra.js +0 -0
- package/bin/testspectra-runner.exe +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 -1
- package/dist/commands/__tests__/run-e2e.test.js +270 -29
- package/dist/commands/__tests__/run.test.js +92 -16
- package/dist/commands/demo.js +17 -7
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +154 -149
- package/dist/commands/lint.d.ts +5 -0
- package/dist/commands/lint.js +55 -0
- package/dist/commands/refactor.d.ts +2 -1
- package/dist/commands/refactor.js +129 -35
- package/dist/commands/run.d.ts +2 -3
- package/dist/commands/run.js +93 -28
- package/dist/commands/skills.d.ts +9 -0
- package/dist/commands/skills.js +28 -0
- package/dist/commands/sync-types.js +1 -0
- package/dist/commands/test.d.ts +17 -0
- package/dist/commands/test.js +104 -0
- package/dist/commands/watch.js +9 -3
- package/dist/config/loader.js +1 -1
- package/dist/config/schema.d.ts +5 -114
- package/dist/config/schema.js +1 -17
- package/dist/generator/__tests__/tsconfig-isolation.test.js +6 -2
- package/dist/generator/__tests__/type-generator.test.js +1 -1
- package/dist/generator/tsconfig-generator.js +44 -16
- package/dist/generator/type-generator.d.ts +24 -1
- package/dist/generator/type-generator.js +104 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +76 -40
- 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/refactor/__tests__/refactor-engine.test.js +698 -0
- package/dist/refactor/refactor-engine.d.ts +25 -0
- package/dist/refactor/refactor-engine.js +374 -42
- package/dist/reporter/semantic-formatter.js +22 -2
- package/dist/reporter/types.d.ts +1 -1
- package/dist/runner/bridge.d.ts +1 -1
- package/dist/runner/bridge.js +34 -21
- package/dist/runner/reporter.d.ts +2 -0
- package/dist/runner/reporter.js +11 -3
- 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 +8 -1
- package/package.json +29 -25
- package/templates/default/CLAUDE.md +16 -11
- 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 +3 -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 +70 -46
- package/templates/default/page-objects/MatchersPage/web.ts +43 -37
- 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 -36
- package/templates/default/page-objects/PlaygroundPage/web.ts +31 -31
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +53 -11
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +19 -12
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +31 -27
- 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 -16
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +19 -12
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +26 -24
- 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 -9
- 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 +9 -9
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +17 -12
- 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 -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 +19 -12
- 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 -12
- 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 -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 +11 -11
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +17 -12
- 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 -12
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +29 -29
- package/templates/default/specs/ElementMatchers/suite.md +10 -9
- 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 +6 -6
- package/templates/default/specs/Playground/TC-0001-form-controls/spec.md +18 -12
- 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 -12
- package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +6 -6
- package/templates/default/spectra.config.ts +52 -68
- 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 -0
- package/templates/default/support/actions/seedSession/web.action.ts +13 -0
- 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/nx/.nx/workspace-data/59842386-c7c4-44ca-b2c2-20e1700bd13d.db +0 -0
- package/templates/nx/.nx/workspace-data/59842386-c7c4-44ca-b2c2-20e1700bd13d.db-shm +0 -0
- package/templates/nx/.nx/workspace-data/59842386-c7c4-44ca-b2c2-20e1700bd13d.db-wal +0 -0
- package/templates/nx/.nx/workspace-data/d/daemon.log +1577 -168
- 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 +10 -10
- package/templates/nx/package.json +3 -3
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +27 -3
- 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 -3
- 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 -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 +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 -37
- 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 +19 -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 +52 -68
- 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/bin/testspectra-runner +0 -0
- package/demo-app/assets/index-DPfv5_EF.js +0 -116
- package/demo-app/assets/index-gIwu2EMV.css +0 -1
- package/dist/commands/__tests__/cloud-run.test.js +0 -93
- package/dist/commands/cloud-run.d.ts +0 -13
- package/dist/commands/cloud-run.js +0 -120
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -17
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -17
- /package/dist/{commands/__tests__/cloud-run.test.d.ts → linter/__tests__/anonymous-export.test.d.ts} +0 -0
package/dist/config/schema.js
CHANGED
|
@@ -25,22 +25,12 @@ export const DEFAULT_CONFIG_DATA = {
|
|
|
25
25
|
maxConcurrentSessions: '1',
|
|
26
26
|
headless: true,
|
|
27
27
|
implicitWait: '5000',
|
|
28
|
-
pageLoadTimeout: '30000',
|
|
29
|
-
scriptTimeout: '30000',
|
|
30
28
|
parallelizationMode: 'testcase',
|
|
31
29
|
},
|
|
32
|
-
browsers: [
|
|
33
|
-
{
|
|
34
|
-
id: 'chrome-desktop',
|
|
35
|
-
type: 'chrome',
|
|
36
|
-
mobileEmulation: false,
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
30
|
androidConfig: {
|
|
40
31
|
driverServer: 'http://127.0.0.1:4800',
|
|
41
32
|
appPackage: '',
|
|
42
33
|
appActivity: '',
|
|
43
|
-
autoGrantPermissions: true,
|
|
44
34
|
noReset: false,
|
|
45
35
|
implicitWait: 10000,
|
|
46
36
|
parallelizationMode: 'suite',
|
|
@@ -71,17 +61,11 @@ export const DEFAULT_CONFIG_DATA = {
|
|
|
71
61
|
},
|
|
72
62
|
],
|
|
73
63
|
},
|
|
74
|
-
loadConfig: {
|
|
75
|
-
virtualUsers: '10',
|
|
76
|
-
duration: '1m',
|
|
77
|
-
},
|
|
78
|
-
loadStages: [],
|
|
79
|
-
thresholds: [],
|
|
80
64
|
executionConfig: {
|
|
81
65
|
networkMonitoringEnabled: true,
|
|
82
66
|
fastResponseTime: '200',
|
|
83
67
|
normalResponseTime: '1000',
|
|
84
68
|
monitoredDomains: [],
|
|
85
|
-
environmentVariables:
|
|
69
|
+
environmentVariables: {},
|
|
86
70
|
},
|
|
87
71
|
};
|
|
@@ -261,7 +261,7 @@ describe('Platform TSConfigs & Type Isolation (docs/v2/cli/tsconfig-platform-iso
|
|
|
261
261
|
expect(threw).toBe(true);
|
|
262
262
|
expect(errorMessage).toContain("Cannot find name 'AuthLoginPage'");
|
|
263
263
|
});
|
|
264
|
-
it('E2E: compiles the full Nx monorepo template via tsc -b with 0 errors', () => {
|
|
264
|
+
it('E2E: compiles the full Nx monorepo template via tsc -b with 0 errors', async () => {
|
|
265
265
|
let root = process.cwd();
|
|
266
266
|
while (root && root !== path.dirname(root)) {
|
|
267
267
|
if (fs.existsSync(path.join(root, 'pnpm-workspace.yaml')))
|
|
@@ -269,8 +269,12 @@ describe('Platform TSConfigs & Type Isolation (docs/v2/cli/tsconfig-platform-iso
|
|
|
269
269
|
root = path.dirname(root);
|
|
270
270
|
}
|
|
271
271
|
const nxTemplateDir = path.join(root, 'cli', 'templates', 'nx');
|
|
272
|
-
// Generate latest ambient types for the nx template
|
|
272
|
+
// Generate latest ambient types for the nx template, including env.d.ts (a separate async
|
|
273
|
+
// step — see TypeGenerator.syncEnvDeclaration — since spectra.config.ts's
|
|
274
|
+
// executionConfig.environmentVariables is what the template's EnvironmentConfig suite
|
|
275
|
+
// exercises via the typed Env global).
|
|
273
276
|
TypeGenerator.generateAll(nxTemplateDir);
|
|
277
|
+
await TypeGenerator.syncEnvDeclaration(nxTemplateDir);
|
|
274
278
|
expect(() => {
|
|
275
279
|
execSync(`npx tsc -b ${nxTemplateDir}`, { stdio: 'pipe' });
|
|
276
280
|
}).not.toThrow();
|
|
@@ -52,7 +52,7 @@ describe('TypeGenerator Engine (docs/v2/cli/ambient-types-generator.md)', () =>
|
|
|
52
52
|
fs.writeFileSync(path.join(poDir, 'web.ts'), 'export default class LoginPage {\n static username = "#user";\n static async login() {}\n}');
|
|
53
53
|
const stepDir = path.join(tmpDir, 'support', 'steps', 'loginAsAdmin');
|
|
54
54
|
fs.mkdirSync(stepDir, { recursive: true });
|
|
55
|
-
fs.writeFileSync(path.join(stepDir, 'web.step.ts'), 'export default async function
|
|
55
|
+
fs.writeFileSync(path.join(stepDir, 'web.step.ts'), 'export default async function (role?: string) {}');
|
|
56
56
|
const fixDir = path.join(tmpDir, 'fixtures');
|
|
57
57
|
fs.mkdirSync(fixDir, { recursive: true });
|
|
58
58
|
fs.writeFileSync(path.join(fixDir, 'users.json'), JSON.stringify({ admin: { id: 101, email: 'admin@test.local' } }));
|
|
@@ -31,7 +31,7 @@ export class TsConfigGenerator {
|
|
|
31
31
|
static getStemExcludes(prefix, stems) {
|
|
32
32
|
const excludes = [];
|
|
33
33
|
for (const stem of stems) {
|
|
34
|
-
excludes.push(`${prefix}/**/page-objects/**/${stem}.ts`, `${prefix}/**/
|
|
34
|
+
excludes.push(`${prefix}/**/page-objects/**/${stem}.ts`, `${prefix}/**/support/**/${stem}.*`, `${prefix}/**/global-hooks/**/${stem}.*`, `${prefix}/**/specs/**/hooks/**/${stem}.*`, `${prefix}/**/specs/**/${stem}.test.ts`, `${prefix}/**/${stem}.ts`, `${prefix}/**/${stem}.*`, `${prefix}/**/${stem}.*.ts`, `${prefix}/**/*.${stem}.ts`, `${prefix}/**/*.${stem}.*`, `${prefix}/**/*.${stem}.*.ts`);
|
|
35
35
|
}
|
|
36
36
|
return excludes;
|
|
37
37
|
}
|
|
@@ -41,21 +41,28 @@ export class TsConfigGenerator {
|
|
|
41
41
|
target: 'ES2022',
|
|
42
42
|
module: 'NodeNext',
|
|
43
43
|
moduleResolution: 'NodeNext',
|
|
44
|
+
jsx: 'react-jsx',
|
|
44
45
|
composite: true,
|
|
45
46
|
noEmit: true,
|
|
46
47
|
skipLibCheck: true,
|
|
47
48
|
strict: true,
|
|
48
|
-
types: ['node'
|
|
49
|
+
types: ['node'],
|
|
49
50
|
},
|
|
50
51
|
include: [
|
|
51
52
|
'../types/web.d.ts',
|
|
52
53
|
'../types/fixtures.d.ts',
|
|
53
54
|
'../../**/specs/**/*.ts',
|
|
55
|
+
'../../**/specs/**/*.tsx',
|
|
54
56
|
'../../**/page-objects/**/*.ts',
|
|
55
|
-
'../../**/
|
|
57
|
+
'../../**/page-objects/**/*.tsx',
|
|
56
58
|
'../../**/support/**/*.ts',
|
|
59
|
+
'../../**/support/**/*.tsx',
|
|
57
60
|
'../../**/global-hooks/**/*.ts',
|
|
61
|
+
'../../**/global-hooks/**/*.tsx',
|
|
58
62
|
'../../**/fixtures/**/*.ts',
|
|
63
|
+
'../../**/fixtures/**/*.json',
|
|
64
|
+
'../../**/src/**/*.ts',
|
|
65
|
+
'../../**/src/**/*.tsx',
|
|
59
66
|
'../../spectra.config.ts',
|
|
60
67
|
],
|
|
61
68
|
exclude: [
|
|
@@ -74,21 +81,28 @@ export class TsConfigGenerator {
|
|
|
74
81
|
target: 'ES2022',
|
|
75
82
|
module: 'NodeNext',
|
|
76
83
|
moduleResolution: 'NodeNext',
|
|
84
|
+
jsx: 'react-jsx',
|
|
77
85
|
composite: true,
|
|
78
86
|
noEmit: true,
|
|
79
87
|
skipLibCheck: true,
|
|
80
88
|
strict: true,
|
|
81
|
-
types: ['node'
|
|
89
|
+
types: ['node'],
|
|
82
90
|
},
|
|
83
91
|
include: [
|
|
84
92
|
'../types/mobile.d.ts',
|
|
85
93
|
'../types/fixtures.d.ts',
|
|
86
94
|
'../../**/specs/**/*.ts',
|
|
95
|
+
'../../**/specs/**/*.tsx',
|
|
87
96
|
'../../**/page-objects/**/*.ts',
|
|
88
|
-
'../../**/
|
|
97
|
+
'../../**/page-objects/**/*.tsx',
|
|
89
98
|
'../../**/support/**/*.ts',
|
|
99
|
+
'../../**/support/**/*.tsx',
|
|
90
100
|
'../../**/global-hooks/**/*.ts',
|
|
101
|
+
'../../**/global-hooks/**/*.tsx',
|
|
91
102
|
'../../**/fixtures/**/*.ts',
|
|
103
|
+
'../../**/fixtures/**/*.json',
|
|
104
|
+
'../../**/src/**/*.ts',
|
|
105
|
+
'../../**/src/**/*.tsx',
|
|
92
106
|
'../../spectra.config.ts',
|
|
93
107
|
],
|
|
94
108
|
exclude: [
|
|
@@ -107,21 +121,28 @@ export class TsConfigGenerator {
|
|
|
107
121
|
target: 'ES2022',
|
|
108
122
|
module: 'NodeNext',
|
|
109
123
|
moduleResolution: 'NodeNext',
|
|
124
|
+
jsx: 'react-jsx',
|
|
110
125
|
composite: true,
|
|
111
126
|
noEmit: true,
|
|
112
127
|
skipLibCheck: true,
|
|
113
128
|
strict: true,
|
|
114
|
-
types: ['node'
|
|
129
|
+
types: ['node'],
|
|
115
130
|
},
|
|
116
131
|
include: [
|
|
117
132
|
'../types/android.d.ts',
|
|
118
133
|
'../types/fixtures.d.ts',
|
|
119
134
|
'../../**/specs/**/*.ts',
|
|
135
|
+
'../../**/specs/**/*.tsx',
|
|
120
136
|
'../../**/page-objects/**/*.ts',
|
|
121
|
-
'../../**/
|
|
137
|
+
'../../**/page-objects/**/*.tsx',
|
|
122
138
|
'../../**/support/**/*.ts',
|
|
139
|
+
'../../**/support/**/*.tsx',
|
|
123
140
|
'../../**/global-hooks/**/*.ts',
|
|
141
|
+
'../../**/global-hooks/**/*.tsx',
|
|
124
142
|
'../../**/fixtures/**/*.ts',
|
|
143
|
+
'../../**/fixtures/**/*.json',
|
|
144
|
+
'../../**/src/**/*.ts',
|
|
145
|
+
'../../**/src/**/*.tsx',
|
|
125
146
|
'../../spectra.config.ts',
|
|
126
147
|
],
|
|
127
148
|
exclude: [
|
|
@@ -140,21 +161,28 @@ export class TsConfigGenerator {
|
|
|
140
161
|
target: 'ES2022',
|
|
141
162
|
module: 'NodeNext',
|
|
142
163
|
moduleResolution: 'NodeNext',
|
|
164
|
+
jsx: 'react-jsx',
|
|
143
165
|
composite: true,
|
|
144
166
|
noEmit: true,
|
|
145
167
|
skipLibCheck: true,
|
|
146
168
|
strict: true,
|
|
147
|
-
types: ['node'
|
|
169
|
+
types: ['node'],
|
|
148
170
|
},
|
|
149
171
|
include: [
|
|
150
172
|
'../types/ios.d.ts',
|
|
151
173
|
'../types/fixtures.d.ts',
|
|
152
174
|
'../../**/specs/**/*.ts',
|
|
175
|
+
'../../**/specs/**/*.tsx',
|
|
153
176
|
'../../**/page-objects/**/*.ts',
|
|
154
|
-
'../../**/
|
|
177
|
+
'../../**/page-objects/**/*.tsx',
|
|
155
178
|
'../../**/support/**/*.ts',
|
|
179
|
+
'../../**/support/**/*.tsx',
|
|
156
180
|
'../../**/global-hooks/**/*.ts',
|
|
181
|
+
'../../**/global-hooks/**/*.tsx',
|
|
157
182
|
'../../**/fixtures/**/*.ts',
|
|
183
|
+
'../../**/fixtures/**/*.json',
|
|
184
|
+
'../../**/src/**/*.ts',
|
|
185
|
+
'../../**/src/**/*.tsx',
|
|
158
186
|
'../../spectra.config.ts',
|
|
159
187
|
],
|
|
160
188
|
exclude: [
|
|
@@ -173,21 +201,23 @@ export class TsConfigGenerator {
|
|
|
173
201
|
target: 'ES2022',
|
|
174
202
|
module: 'NodeNext',
|
|
175
203
|
moduleResolution: 'NodeNext',
|
|
204
|
+
jsx: 'react-jsx',
|
|
176
205
|
composite: true,
|
|
177
206
|
noEmit: true,
|
|
178
207
|
skipLibCheck: true,
|
|
179
208
|
strict: true,
|
|
180
|
-
types: ['node'
|
|
209
|
+
types: ['node'],
|
|
181
210
|
},
|
|
182
211
|
include: [
|
|
183
212
|
'../types/common.d.ts',
|
|
184
213
|
'../types/fixtures.d.ts',
|
|
185
214
|
'../../**/page-objects/**/common.ts',
|
|
186
|
-
'../../**/
|
|
215
|
+
'../../**/page-objects/**/common.tsx',
|
|
187
216
|
'../../**/support/**/common.*',
|
|
188
217
|
'../../**/global-hooks/**/common.*',
|
|
189
218
|
'../../**/specs/**/hooks/**/common.*',
|
|
190
219
|
'../../**/specs/**/common.test.ts',
|
|
220
|
+
'../../**/specs/**/common.test.tsx',
|
|
191
221
|
'../../spectra.config.ts',
|
|
192
222
|
],
|
|
193
223
|
exclude: [
|
|
@@ -215,7 +245,7 @@ export class TsConfigGenerator {
|
|
|
215
245
|
const relCache = path.relative(subConfigDir, path.join(options.cwd, '.testspectra', 'cache')).replace(/\\/g, '/');
|
|
216
246
|
const platformDts = `${relTypesDir}/${platform}.d.ts`;
|
|
217
247
|
const fixturesDts = `${relTypesDir}/fixtures.d.ts`;
|
|
218
|
-
const include = [platformDts, fixturesDts, `${relScope}/**/*.ts`, relSpectraConfig];
|
|
248
|
+
const include = [platformDts, fixturesDts, `${relScope}/**/*.ts`, `${relScope}/**/*.tsx`, relSpectraConfig];
|
|
219
249
|
const baseExcludes = [relNodeModules, relDist, relReports, relRuns, relCache];
|
|
220
250
|
const stemMap = {
|
|
221
251
|
web: ['android', 'ios', 'mobile'],
|
|
@@ -234,7 +264,7 @@ export class TsConfigGenerator {
|
|
|
234
264
|
noEmit: true,
|
|
235
265
|
skipLibCheck: true,
|
|
236
266
|
strict: true,
|
|
237
|
-
types: ['node'
|
|
267
|
+
types: ['node'],
|
|
238
268
|
},
|
|
239
269
|
include,
|
|
240
270
|
exclude: [...baseExcludes, ...platformExcludes],
|
|
@@ -269,9 +299,7 @@ export class TsConfigGenerator {
|
|
|
269
299
|
const sharedScope = scopes.find((s) => s.isShared);
|
|
270
300
|
const featureScopes = scopes.filter((s) => !s.isShared);
|
|
271
301
|
const hasScopes = Boolean(sharedScope || featureScopes.length > 0);
|
|
272
|
-
const hasRootEntities = fs.existsSync(path.join(cwd, 'specs')) ||
|
|
273
|
-
fs.existsSync(path.join(cwd, 'page-objects')) ||
|
|
274
|
-
fs.existsSync(path.join(cwd, 'pageobjects'));
|
|
302
|
+
const hasRootEntities = fs.existsSync(path.join(cwd, 'specs')) || fs.existsSync(path.join(cwd, 'page-objects'));
|
|
275
303
|
if (!hasScopes || hasRootEntities) {
|
|
276
304
|
for (const filename of Object.keys(platformConfigs)) {
|
|
277
305
|
references.push({ path: `./tsconfig/${filename}` });
|
|
@@ -18,11 +18,23 @@ export interface EntityScope {
|
|
|
18
18
|
* - Directory with page-objects/support/fixtures and NO specs => Shared Scope
|
|
19
19
|
*/
|
|
20
20
|
export declare function discoverEntityScopes(cwd: string): EntityScope[];
|
|
21
|
+
/**
|
|
22
|
+
* Detects a component-testing project (`@testspectra/react`'s Vitest browser-mode runner), via
|
|
23
|
+
* the same signal `cli/src/commands/test.ts` uses to gate `spectra test` itself. Used to augment
|
|
24
|
+
* the generated `Spectra` ambient type with `.mount()`, which only exists in that runtime.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isComponentTestingProject(cwd: string): boolean;
|
|
21
27
|
export declare class TypeGenerator {
|
|
22
28
|
/**
|
|
23
29
|
* Main entry point to generate all ambient type declarations.
|
|
24
30
|
*/
|
|
25
31
|
static generateAll(cwd: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Reloads `spectra.config.ts` and refreshes `.testspectra/types/env.d.ts` with the current
|
|
34
|
+
* `executionConfig.environmentVariables`. Separate from `writeDeclarationFiles`/`generateAll`
|
|
35
|
+
* (which must stay synchronous) because reading the config file is unavoidably async.
|
|
36
|
+
*/
|
|
37
|
+
static syncEnvDeclaration(cwd: string): Promise<void>;
|
|
26
38
|
/**
|
|
27
39
|
* Discovers all feature directories and shared library directories.
|
|
28
40
|
* Returns a map of scope -> base directory
|
|
@@ -30,7 +42,18 @@ export declare class TypeGenerator {
|
|
|
30
42
|
static getEntityScopes(cwd: string): EntityScope[];
|
|
31
43
|
static getPageObjectsDirsForScope(scopeDir: string, sharedDir?: string): string[];
|
|
32
44
|
static getEntityDirsForScope(entityType: 'actions' | 'steps' | 'fixtures', scopeDir: string, sharedDir?: string): string[];
|
|
33
|
-
static generateDeclarationsForScope(cwd: string, outputTypesDir: string, scopeDir: string, sharedDir?: string): Record<PlatformTarget, string>;
|
|
45
|
+
static generateDeclarationsForScope(cwd: string, outputTypesDir: string, scopeDir: string, sharedDir?: string, rootTypesDir?: string): Record<PlatformTarget, string>;
|
|
34
46
|
static generateFixturesDeclarationForScope(cwd: string, outputTypesDir: string, scopeDir: string, sharedDir?: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Generates the typed `Spectra.env` ambient declaration from `spectra.config.ts`'s
|
|
49
|
+
* `executionConfig.environmentVariables` — mirrors `generateFixturesDeclarationForScope`, but
|
|
50
|
+
* env vars come from a single project-level config rather than a scanned directory.
|
|
51
|
+
*
|
|
52
|
+
* Emits a bare global `interface SpectraEnv { readonly KEY: string; ... }`, which TypeScript
|
|
53
|
+
* interface-merges with the empty `SpectraEnv` shipped by `@testspectra/matchers` (the same
|
|
54
|
+
* mechanism `@types/node` uses for projects to augment `NodeJS.ProcessEnv`) — so `Spectra.env.KEY`
|
|
55
|
+
* resolves to `string`, never `string | undefined` like raw `process.env.KEY`.
|
|
56
|
+
*/
|
|
57
|
+
static generateEnvDeclaration(environmentVariables: Record<string, string>): string;
|
|
35
58
|
static writeDeclarationFiles(cwd: string): void;
|
|
36
59
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { ConfigLoader } from '../config/loader.js';
|
|
3
4
|
import { TsConfigGenerator } from './tsconfig-generator.js';
|
|
4
5
|
export const PLATFORM_HIERARCHY = {
|
|
5
6
|
web: ['web', 'common'],
|
|
@@ -180,6 +181,23 @@ export function discoverEntityScopes(cwd) {
|
|
|
180
181
|
fallbackScan(cwd, 5);
|
|
181
182
|
return scopes;
|
|
182
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Detects a component-testing project (`@testspectra/react`'s Vitest browser-mode runner), via
|
|
186
|
+
* the same signal `cli/src/commands/test.ts` uses to gate `spectra test` itself. Used to augment
|
|
187
|
+
* the generated `Spectra` ambient type with `.mount()`, which only exists in that runtime.
|
|
188
|
+
*/
|
|
189
|
+
export function isComponentTestingProject(cwd) {
|
|
190
|
+
try {
|
|
191
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
192
|
+
if (!fs.existsSync(pkgPath))
|
|
193
|
+
return false;
|
|
194
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
195
|
+
return Boolean(pkg.dependencies?.['@testspectra/react'] || pkg.devDependencies?.['@testspectra/react']);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
183
201
|
export class TypeGenerator {
|
|
184
202
|
/**
|
|
185
203
|
* Main entry point to generate all ambient type declarations.
|
|
@@ -188,6 +206,24 @@ export class TypeGenerator {
|
|
|
188
206
|
this.writeDeclarationFiles(cwd);
|
|
189
207
|
TsConfigGenerator.scaffoldConfigs(cwd);
|
|
190
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Reloads `spectra.config.ts` and refreshes `.testspectra/types/env.d.ts` with the current
|
|
211
|
+
* `executionConfig.environmentVariables`. Separate from `writeDeclarationFiles`/`generateAll`
|
|
212
|
+
* (which must stay synchronous) because reading the config file is unavoidably async.
|
|
213
|
+
*/
|
|
214
|
+
static async syncEnvDeclaration(cwd) {
|
|
215
|
+
const rootTypesDir = path.join(cwd, '.testspectra', 'types');
|
|
216
|
+
if (!fs.existsSync(rootTypesDir)) {
|
|
217
|
+
fs.mkdirSync(rootTypesDir, { recursive: true });
|
|
218
|
+
}
|
|
219
|
+
let environmentVariables = {};
|
|
220
|
+
try {
|
|
221
|
+
const config = await ConfigLoader.loadConfig(cwd);
|
|
222
|
+
environmentVariables = config.executionConfig?.environmentVariables ?? {};
|
|
223
|
+
}
|
|
224
|
+
catch { }
|
|
225
|
+
fs.writeFileSync(path.join(rootTypesDir, 'env.d.ts'), this.generateEnvDeclaration(environmentVariables), 'utf-8');
|
|
226
|
+
}
|
|
191
227
|
/**
|
|
192
228
|
* Discovers all feature directories and shared library directories.
|
|
193
229
|
* Returns a map of scope -> base directory
|
|
@@ -267,10 +303,11 @@ export class TypeGenerator {
|
|
|
267
303
|
}
|
|
268
304
|
return dirs;
|
|
269
305
|
}
|
|
270
|
-
static generateDeclarationsForScope(cwd, outputTypesDir, scopeDir, sharedDir) {
|
|
306
|
+
static generateDeclarationsForScope(cwd, outputTypesDir, scopeDir, sharedDir, rootTypesDir) {
|
|
271
307
|
const poDirs = this.getPageObjectsDirsForScope(scopeDir, sharedDir);
|
|
272
308
|
const actionsDirs = this.getEntityDirsForScope('actions', scopeDir, sharedDir);
|
|
273
309
|
const stepsDirs = this.getEntityDirsForScope('steps', scopeDir, sharedDir);
|
|
310
|
+
const isComponentTesting = isComponentTestingProject(cwd);
|
|
274
311
|
const platforms = ['web', 'android', 'ios', 'mobile', 'common'];
|
|
275
312
|
const results = {
|
|
276
313
|
web: '',
|
|
@@ -279,14 +316,39 @@ export class TypeGenerator {
|
|
|
279
316
|
mobile: '',
|
|
280
317
|
common: '',
|
|
281
318
|
};
|
|
319
|
+
// `env.d.ts` always lives at the workspace root types dir (env vars come from a single
|
|
320
|
+
// `spectra.config.ts`, unlike per-scope fixtures/page-objects), so a shared/feature scope's
|
|
321
|
+
// own declarations reference it via a relative path back up to the root.
|
|
322
|
+
let envRefPath = './env.d.ts';
|
|
323
|
+
if (rootTypesDir && rootTypesDir !== outputTypesDir) {
|
|
324
|
+
envRefPath = path.relative(outputTypesDir, path.join(rootTypesDir, 'env.d.ts')).replace(/\\/g, '/');
|
|
325
|
+
if (!envRefPath.startsWith('.'))
|
|
326
|
+
envRefPath = `./${envRefPath}`;
|
|
327
|
+
}
|
|
282
328
|
for (const platform of platforms) {
|
|
283
329
|
const hierarchy = PLATFORM_HIERARCHY[platform];
|
|
284
330
|
let content = `// Auto-generated ambient declarations for TestSpectra [${platform.toUpperCase()}]\n`;
|
|
285
331
|
content += `// Managed automatically by TestSpectra Language Service Plugin.\n\n`;
|
|
286
|
-
|
|
287
|
-
|
|
332
|
+
// TestSpectra's Rust-native orchestrator worker (core/orchestrator/src/worker/bdd_runner.ts)
|
|
333
|
+
// registers its own `it`/`test`/lifecycle-hook globals directly — there is no WDIO or Mocha
|
|
334
|
+
// runtime involved at all (not just for component testing; this is true across every
|
|
335
|
+
// platform). `describe` is intentionally NOT declared here even though the runtime has a
|
|
336
|
+
// transparent no-op implementation of it — spec-schema-linter's no-describe-block rule
|
|
337
|
+
// forbids authoring it, so leaving it undeclared makes that a compile error too, not just a
|
|
338
|
+
// lint error.
|
|
339
|
+
content += `declare function it(title: string, fn: () => Promise<void> | void): void;\n`;
|
|
340
|
+
if (isComponentTesting) {
|
|
341
|
+
// Vitest's own `expect` global (test.globals: true in tools/react/vitest.config.ts) — the
|
|
342
|
+
// one thing component specs legitimately need beyond the Spectra.* DSL, for asserting
|
|
343
|
+
// plain closure/callback state (e.g. "was this onClick handler invoked") that has no DOM
|
|
344
|
+
// element to target. Reuses @testspectra/react's own re-exported `ExpectStatic` type
|
|
345
|
+
// rather than hand-duplicating Vitest's expect API surface. Not declared for E2E projects
|
|
346
|
+
// — the Rust orchestrator's BDD runtime has no `expect` global at all.
|
|
347
|
+
content += `declare const expect: import('@testspectra/react').ExpectStatic;\n`;
|
|
348
|
+
}
|
|
288
349
|
content += `/// <reference types="@testspectra/matchers" />\n`;
|
|
289
|
-
content += `/// <reference path="./fixtures.d.ts" />\n
|
|
350
|
+
content += `/// <reference path="./fixtures.d.ts" />\n`;
|
|
351
|
+
content += `/// <reference path="${envRefPath}" />\n\n`;
|
|
290
352
|
// 1. Page Objects Global Declarations
|
|
291
353
|
const declaredPOMs = new Set();
|
|
292
354
|
for (const poDir of poDirs) {
|
|
@@ -423,7 +485,10 @@ export class TypeGenerator {
|
|
|
423
485
|
}
|
|
424
486
|
}
|
|
425
487
|
content += `}\n`;
|
|
426
|
-
|
|
488
|
+
// Reuses @testspectra/react's own exported `mount` type rather than hand-duplicating its
|
|
489
|
+
// signature here — stays in sync automatically if that signature ever changes.
|
|
490
|
+
const mountAugment = isComponentTesting ? ` & { mount: typeof import('@testspectra/react').mount }` : '';
|
|
491
|
+
content += `type TestSpectraActions = import('@testspectra/matchers').SpectraStatic & TestSpectraCustomActions${mountAugment};\n`;
|
|
427
492
|
content += `declare const Spectra: TestSpectraActions;\n\n`;
|
|
428
493
|
// 3. Built-in Steps Declaration
|
|
429
494
|
content += `interface TestSpectraSteps {\n`;
|
|
@@ -543,11 +608,42 @@ export class TypeGenerator {
|
|
|
543
608
|
content += `declare const Fixture: TestSpectraFixtures;\n`;
|
|
544
609
|
return content;
|
|
545
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* Generates the typed `Spectra.env` ambient declaration from `spectra.config.ts`'s
|
|
613
|
+
* `executionConfig.environmentVariables` — mirrors `generateFixturesDeclarationForScope`, but
|
|
614
|
+
* env vars come from a single project-level config rather than a scanned directory.
|
|
615
|
+
*
|
|
616
|
+
* Emits a bare global `interface SpectraEnv { readonly KEY: string; ... }`, which TypeScript
|
|
617
|
+
* interface-merges with the empty `SpectraEnv` shipped by `@testspectra/matchers` (the same
|
|
618
|
+
* mechanism `@types/node` uses for projects to augment `NodeJS.ProcessEnv`) — so `Spectra.env.KEY`
|
|
619
|
+
* resolves to `string`, never `string | undefined` like raw `process.env.KEY`.
|
|
620
|
+
*/
|
|
621
|
+
static generateEnvDeclaration(environmentVariables) {
|
|
622
|
+
let content = `// Auto-generated ambient Spectra.env declarations for TestSpectra\n`;
|
|
623
|
+
content += `// Managed automatically by TestSpectra Language Service Plugin.\n\n`;
|
|
624
|
+
content += `interface SpectraEnv {\n`;
|
|
625
|
+
for (const key of Object.keys(environmentVariables)) {
|
|
626
|
+
content += ` readonly ${JSON.stringify(key)}: string;\n`;
|
|
627
|
+
}
|
|
628
|
+
content += `}\n`;
|
|
629
|
+
return content;
|
|
630
|
+
}
|
|
546
631
|
static writeDeclarationFiles(cwd) {
|
|
547
632
|
const rootTypesDir = path.join(cwd, '.testspectra', 'types');
|
|
548
633
|
if (!fs.existsSync(rootTypesDir)) {
|
|
549
634
|
fs.mkdirSync(rootTypesDir, { recursive: true });
|
|
550
635
|
}
|
|
636
|
+
// env.d.ts always lives at the root, regardless of Nx scopes — a single spectra.config.ts's
|
|
637
|
+
// executionConfig.environmentVariables applies workspace-wide (see generateEnvDeclaration).
|
|
638
|
+
// Reading spectra.config.ts itself is unavoidably async (ESM dynamic import), which would ripple
|
|
639
|
+
// an async signature through every caller of this long-standing sync method — instead, this only
|
|
640
|
+
// guarantees env.d.ts *exists* (so the reference below never points at a missing file) and
|
|
641
|
+
// leaves it accurate as of the last real sync. `syncEnvDeclaration` (called at the actual
|
|
642
|
+
// execution entry points: run/watch/sync-types) is what keeps its content up to date.
|
|
643
|
+
const envDtsPath = path.join(rootTypesDir, 'env.d.ts');
|
|
644
|
+
if (!fs.existsSync(envDtsPath)) {
|
|
645
|
+
fs.writeFileSync(envDtsPath, this.generateEnvDeclaration({}), 'utf-8');
|
|
646
|
+
}
|
|
551
647
|
const scopes = this.getEntityScopes(cwd);
|
|
552
648
|
const sharedScope = scopes.find((s) => s.isShared);
|
|
553
649
|
const featureScopes = scopes.filter((s) => !s.isShared);
|
|
@@ -561,7 +657,7 @@ export class TypeGenerator {
|
|
|
561
657
|
if (!hasScopes || hasRootEntities) {
|
|
562
658
|
const rootFixtures = this.generateFixturesDeclarationForScope(cwd, rootTypesDir, cwd);
|
|
563
659
|
fs.writeFileSync(path.join(rootTypesDir, 'fixtures.d.ts'), rootFixtures, 'utf-8');
|
|
564
|
-
const rootDeclarations = this.generateDeclarationsForScope(cwd, rootTypesDir, cwd);
|
|
660
|
+
const rootDeclarations = this.generateDeclarationsForScope(cwd, rootTypesDir, cwd, undefined, rootTypesDir);
|
|
565
661
|
for (const [platform, content] of Object.entries(rootDeclarations)) {
|
|
566
662
|
fs.writeFileSync(path.join(rootTypesDir, `${platform}.d.ts`), content, 'utf-8');
|
|
567
663
|
}
|
|
@@ -587,7 +683,7 @@ export class TypeGenerator {
|
|
|
587
683
|
fs.mkdirSync(sharedTypesDir, { recursive: true });
|
|
588
684
|
const sharedFixtures = this.generateFixturesDeclarationForScope(cwd, sharedTypesDir, sharedScope.dir);
|
|
589
685
|
fs.writeFileSync(path.join(sharedTypesDir, 'fixtures.d.ts'), sharedFixtures, 'utf-8');
|
|
590
|
-
const sharedDeclarations = this.generateDeclarationsForScope(cwd, sharedTypesDir, sharedScope.dir);
|
|
686
|
+
const sharedDeclarations = this.generateDeclarationsForScope(cwd, sharedTypesDir, sharedScope.dir, undefined, rootTypesDir);
|
|
591
687
|
for (const [platform, content] of Object.entries(sharedDeclarations)) {
|
|
592
688
|
fs.writeFileSync(path.join(sharedTypesDir, `${platform}.d.ts`), content, 'utf-8');
|
|
593
689
|
}
|
|
@@ -609,7 +705,7 @@ export class TypeGenerator {
|
|
|
609
705
|
fs.mkdirSync(featureTypesDir, { recursive: true });
|
|
610
706
|
const featureFixtures = this.generateFixturesDeclarationForScope(cwd, featureTypesDir, feature.dir, sharedScope?.dir);
|
|
611
707
|
fs.writeFileSync(path.join(featureTypesDir, 'fixtures.d.ts'), featureFixtures, 'utf-8');
|
|
612
|
-
const featureDeclarations = this.generateDeclarationsForScope(cwd, featureTypesDir, feature.dir, sharedScope?.dir);
|
|
708
|
+
const featureDeclarations = this.generateDeclarationsForScope(cwd, featureTypesDir, feature.dir, sharedScope?.dir, rootTypesDir);
|
|
613
709
|
for (const [platform, content] of Object.entries(featureDeclarations)) {
|
|
614
710
|
fs.writeFileSync(path.join(featureTypesDir, `${platform}.d.ts`), content, 'utf-8');
|
|
615
711
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { Command } from 'commander';
|
|
|
2
2
|
export * from './config/schema.js';
|
|
3
3
|
export * from './config/loader.js';
|
|
4
4
|
export * from './generator/index.js';
|
|
5
|
-
export * from './lifecycle/index.js';
|
|
6
5
|
export * from './refactor/index.js';
|
|
7
6
|
export * from './mobile/index.js';
|
|
7
|
+
export * from './linter/index.js';
|
|
8
8
|
export * from './types/generator.js';
|
|
9
9
|
export * from '@testspectra/matchers';
|
|
10
10
|
export declare function createCliProgram(): Command;
|