@testspectra/cli 1.0.70 → 1.1.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-DPfv5_EF.js +116 -0
- package/demo-app/assets/index-gIwu2EMV.css +1 -0
- package/demo-app/index.html +2 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/commands/__tests__/cloud-run.test.d.ts +1 -0
- package/dist/commands/__tests__/cloud-run.test.js +93 -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 +181 -0
- package/dist/commands/__tests__/run.test.d.ts +1 -0
- package/dist/commands/__tests__/run.test.js +197 -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/cloud-run.d.ts +11 -0
- package/dist/commands/cloud-run.js +118 -0
- package/dist/commands/demo.js +7 -7
- 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 +206 -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/refactor.d.ts +8 -0
- package/dist/commands/refactor.js +78 -0
- package/dist/commands/run.d.ts +22 -1
- package/dist/commands/run.js +252 -109
- package/dist/commands/sync-types.d.ts +4 -0
- package/dist/commands/sync-types.js +14 -0
- package/dist/commands/update.js +39 -43
- package/dist/commands/watch.d.ts +6 -0
- package/dist/commands/watch.js +47 -43
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.js +40 -25
- package/dist/config/schema.d.ts +117 -49
- package/dist/config/schema.js +41 -34
- package/dist/generator/__tests__/tsconfig-isolation.test.d.ts +1 -0
- package/dist/generator/__tests__/tsconfig-isolation.test.js +278 -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 +391 -0
- package/dist/generator/type-generator.d.ts +36 -0
- package/dist/generator/type-generator.js +644 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +124 -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/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 +175 -0
- package/dist/refactor/index.d.ts +1 -0
- package/dist/refactor/index.js +1 -0
- package/dist/refactor/refactor-engine.d.ts +25 -0
- package/dist/refactor/refactor-engine.js +255 -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 +191 -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 +69 -44
- package/dist/runner/reporter.d.ts +30 -2
- package/dist/runner/reporter.js +419 -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/demo-server.js +38 -35
- package/package.json +20 -12
- package/templates/default/CLAUDE.md +7 -5
- package/templates/default/fixtures/apiData.json +24 -0
- package/templates/default/package.json +13 -4
- package/templates/default/page-objects/MatchersPage/mobile.ts +41 -16
- package/templates/default/page-objects/MatchersPage/web.ts +14 -0
- package/templates/default/page-objects/NavigationPage/mobile.ts +10 -1
- package/templates/default/page-objects/PlaygroundPage/mobile.ts +27 -17
- package/templates/default/page-objects/PlaygroundPage/web.ts +2 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +11 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +16 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
- package/templates/default/specs/ApiInterception/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/web.test.ts +17 -3
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +15 -1
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +14 -4
- 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/web.test.ts +8 -3
- 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/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/web.test.ts +27 -6
- package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +4 -1
- package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +3 -3
- package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +4 -1
- package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +2 -2
- package/templates/default/spectra.config.ts +21 -14
- package/templates/default/support/actions/fillCredentials/mobile.action.ts +2 -2
- package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +2 -0
- package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +2 -2
- package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +3 -1
- package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +3 -3
- package/templates/default/tsconfig.json +3 -1
- package/templates/nx/.nx/workspace-data/d/daemon.log +168 -0
- package/templates/nx/CLAUDE.md +2 -2
- package/templates/nx/package.json +7 -5
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +3 -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 +3 -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/web.test.ts +17 -3
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +14 -4
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +8 -3
- 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/web.test.ts +27 -6
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +3 -3
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +2 -2
- 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 +12 -0
- package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +14 -0
- package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +2 -0
- package/templates/nx/shared/testing/project.json +19 -0
- package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +2 -2
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +1 -1
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +3 -3
- package/templates/nx/spectra.config.ts +19 -12
- package/templates/nx/tsconfig.json +3 -1
- 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/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
package/dist/plugin.cjs
DELETED
|
@@ -1,575 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/plugin.ts
|
|
31
|
-
var plugin_exports = {};
|
|
32
|
-
__export(plugin_exports, {
|
|
33
|
-
default: () => plugin_default,
|
|
34
|
-
init: () => init
|
|
35
|
-
});
|
|
36
|
-
module.exports = __toCommonJS(plugin_exports);
|
|
37
|
-
var import_fs2 = __toESM(require("fs"), 1);
|
|
38
|
-
var import_path2 = __toESM(require("path"), 1);
|
|
39
|
-
|
|
40
|
-
// src/types/generator.ts
|
|
41
|
-
var import_fs = __toESM(require("fs"), 1);
|
|
42
|
-
var import_path = __toESM(require("path"), 1);
|
|
43
|
-
var PLATFORM_HIERARCHY = {
|
|
44
|
-
web: ["web", "common"],
|
|
45
|
-
ios: ["ios", "mobile", "common"],
|
|
46
|
-
android: ["android", "mobile", "common"],
|
|
47
|
-
mobile: ["mobile", "common"],
|
|
48
|
-
common: ["common"]
|
|
49
|
-
};
|
|
50
|
-
var TypeGenerator = class {
|
|
51
|
-
/**
|
|
52
|
-
* Discovers all feature directories and shared library directories.
|
|
53
|
-
* Returns a map of scope -> base directory (e.g. { "shared": ".../shared/testing", "auth": ".../packages/features/auth/e2e" })
|
|
54
|
-
*/
|
|
55
|
-
static getEntityScopes(cwd) {
|
|
56
|
-
const scopes = [];
|
|
57
|
-
const sharedCandidates = [
|
|
58
|
-
import_path.default.join(cwd, "shared", "testing"),
|
|
59
|
-
import_path.default.join(cwd, "shared"),
|
|
60
|
-
import_path.default.join(cwd, "testing")
|
|
61
|
-
];
|
|
62
|
-
for (const cand of sharedCandidates) {
|
|
63
|
-
if (import_fs.default.existsSync(cand) && (import_fs.default.existsSync(import_path.default.join(cand, "page-objects")) || import_fs.default.existsSync(import_path.default.join(cand, "steps")) || import_fs.default.existsSync(import_path.default.join(cand, "actions")))) {
|
|
64
|
-
if (!scopes.some((s) => s.dir === cand)) {
|
|
65
|
-
scopes.push({ name: "shared", dir: cand, isShared: true });
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function scanForFeatures(dir, depth) {
|
|
70
|
-
if (depth <= 0 || !import_fs.default.existsSync(dir)) return;
|
|
71
|
-
const base = import_path.default.basename(dir);
|
|
72
|
-
if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra") return;
|
|
73
|
-
if (base === "e2e" || base === "tests" || base === "specs") {
|
|
74
|
-
const featureDir = import_path.default.dirname(dir);
|
|
75
|
-
const featureName = import_path.default.basename(featureDir);
|
|
76
|
-
if (!scopes.some((s) => s.dir === dir)) {
|
|
77
|
-
scopes.push({ name: featureName, dir, isShared: false });
|
|
78
|
-
}
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
try {
|
|
82
|
-
const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
83
|
-
for (const entry of entries) {
|
|
84
|
-
if (entry.isDirectory()) {
|
|
85
|
-
scanForFeatures(import_path.default.join(dir, entry.name), depth - 1);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
} catch {
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
scanForFeatures(cwd, 6);
|
|
92
|
-
return scopes;
|
|
93
|
-
}
|
|
94
|
-
static getPageObjectsDirsForScope(scopeDir, sharedDir) {
|
|
95
|
-
const dirs = [];
|
|
96
|
-
function scanDir(dir, maxDepth) {
|
|
97
|
-
if (maxDepth <= 0 || !import_fs.default.existsSync(dir)) return;
|
|
98
|
-
const base = import_path.default.basename(dir);
|
|
99
|
-
if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra") return;
|
|
100
|
-
if (base === "page-objects" || base === "pageobjects") {
|
|
101
|
-
if (!dirs.includes(dir)) dirs.push(dir);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
try {
|
|
105
|
-
const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
106
|
-
for (const entry of entries) {
|
|
107
|
-
if (entry.isDirectory()) {
|
|
108
|
-
scanDir(import_path.default.join(dir, entry.name), maxDepth - 1);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
} catch {
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (!sharedDir && (import_fs.default.existsSync(import_path.default.join(scopeDir, "pnpm-workspace.yaml")) || import_fs.default.existsSync(import_path.default.join(scopeDir, "nx.json")))) {
|
|
115
|
-
scanDir(scopeDir, 6);
|
|
116
|
-
} else {
|
|
117
|
-
const candidates = [
|
|
118
|
-
import_path.default.join(scopeDir, "page-objects"),
|
|
119
|
-
import_path.default.join(scopeDir, "pageobjects")
|
|
120
|
-
];
|
|
121
|
-
if (sharedDir) {
|
|
122
|
-
candidates.push(import_path.default.join(sharedDir, "page-objects"));
|
|
123
|
-
candidates.push(import_path.default.join(sharedDir, "pageobjects"));
|
|
124
|
-
}
|
|
125
|
-
for (const c of candidates) {
|
|
126
|
-
if (import_fs.default.existsSync(c) && !dirs.includes(c)) dirs.push(c);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return dirs;
|
|
130
|
-
}
|
|
131
|
-
static getEntityDirsForScope(entityType, scopeDir, sharedDir) {
|
|
132
|
-
const dirs = [];
|
|
133
|
-
function scanDir(dir, maxDepth) {
|
|
134
|
-
if (maxDepth <= 0 || !import_fs.default.existsSync(dir)) return;
|
|
135
|
-
const base = import_path.default.basename(dir);
|
|
136
|
-
if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra") return;
|
|
137
|
-
if (base === entityType) {
|
|
138
|
-
if (!dirs.includes(dir)) dirs.push(dir);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
143
|
-
for (const entry of entries) {
|
|
144
|
-
if (entry.isDirectory()) {
|
|
145
|
-
scanDir(import_path.default.join(dir, entry.name), maxDepth - 1);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
} catch {
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if (!sharedDir && (import_fs.default.existsSync(import_path.default.join(scopeDir, "pnpm-workspace.yaml")) || import_fs.default.existsSync(import_path.default.join(scopeDir, "nx.json")))) {
|
|
152
|
-
scanDir(scopeDir, 6);
|
|
153
|
-
} else {
|
|
154
|
-
const candidates = [import_path.default.join(scopeDir, entityType)];
|
|
155
|
-
if (sharedDir) {
|
|
156
|
-
candidates.push(import_path.default.join(sharedDir, entityType));
|
|
157
|
-
}
|
|
158
|
-
for (const c of candidates) {
|
|
159
|
-
if (import_fs.default.existsSync(c) && !dirs.includes(c)) dirs.push(c);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return dirs;
|
|
163
|
-
}
|
|
164
|
-
static generateDeclarationsForScope(cwd, outputTypesDir, scopeDir, sharedDir) {
|
|
165
|
-
const poDirs = this.getPageObjectsDirsForScope(scopeDir, sharedDir);
|
|
166
|
-
const actionsDirs = this.getEntityDirsForScope("actions", scopeDir, sharedDir);
|
|
167
|
-
const stepsDirs = this.getEntityDirsForScope("steps", scopeDir, sharedDir);
|
|
168
|
-
const platforms = ["web", "android", "ios", "mobile", "common"];
|
|
169
|
-
const results = {};
|
|
170
|
-
for (const platform of platforms) {
|
|
171
|
-
const hierarchy = PLATFORM_HIERARCHY[platform];
|
|
172
|
-
let content = `// Auto-generated ambient declarations for TestSpectra [${platform.toUpperCase()}]
|
|
173
|
-
`;
|
|
174
|
-
content += `// Managed automatically by TestSpectra Language Service Plugin.
|
|
175
|
-
|
|
176
|
-
`;
|
|
177
|
-
content += `/// <reference types="@wdio/globals/types" />
|
|
178
|
-
`;
|
|
179
|
-
content += `/// <reference types="@wdio/mocha-framework" />
|
|
180
|
-
`;
|
|
181
|
-
content += `/// <reference types="@testspectra/matchers" />
|
|
182
|
-
`;
|
|
183
|
-
content += `/// <reference path="./fixtures.d.ts" />
|
|
184
|
-
|
|
185
|
-
`;
|
|
186
|
-
const declaredPOMs = /* @__PURE__ */ new Set();
|
|
187
|
-
for (const poDir of poDirs) {
|
|
188
|
-
if (!import_fs.default.existsSync(poDir)) continue;
|
|
189
|
-
const poEntries = import_fs.default.readdirSync(poDir, { withFileTypes: true });
|
|
190
|
-
for (const entry of poEntries) {
|
|
191
|
-
if (entry.name.startsWith(".")) continue;
|
|
192
|
-
if (entry.isDirectory()) {
|
|
193
|
-
const className = entry.name;
|
|
194
|
-
if (declaredPOMs.has(className)) continue;
|
|
195
|
-
const classFolder = import_path.default.join(poDir, className);
|
|
196
|
-
let matchedFile = null;
|
|
197
|
-
for (const stem of hierarchy) {
|
|
198
|
-
const candidates = [
|
|
199
|
-
import_path.default.join(classFolder, `${stem}.ts`),
|
|
200
|
-
import_path.default.join(classFolder, `${stem}.page.ts`),
|
|
201
|
-
import_path.default.join(classFolder, `${stem}.po.ts`),
|
|
202
|
-
import_path.default.join(classFolder, "index.ts"),
|
|
203
|
-
import_path.default.join(classFolder, "common.ts")
|
|
204
|
-
];
|
|
205
|
-
for (const cand of candidates) {
|
|
206
|
-
if (import_fs.default.existsSync(cand)) {
|
|
207
|
-
matchedFile = import_path.default.relative(outputTypesDir, cand).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
208
|
-
if (!matchedFile.startsWith(".")) matchedFile = `./${matchedFile}`;
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
if (matchedFile) break;
|
|
213
|
-
}
|
|
214
|
-
if (matchedFile) {
|
|
215
|
-
content += `declare const ${className}: (typeof import('${matchedFile}') extends { default: infer T } ? T : typeof import('${matchedFile}'));
|
|
216
|
-
`;
|
|
217
|
-
declaredPOMs.add(className);
|
|
218
|
-
}
|
|
219
|
-
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
220
|
-
const parts = entry.name.split(".");
|
|
221
|
-
const className = parts[0];
|
|
222
|
-
if (declaredPOMs.has(className)) continue;
|
|
223
|
-
let isMatch = false;
|
|
224
|
-
if (parts.length === 2) {
|
|
225
|
-
isMatch = true;
|
|
226
|
-
} else if (parts.length > 2) {
|
|
227
|
-
const stem = parts[1];
|
|
228
|
-
isMatch = hierarchy.includes(stem);
|
|
229
|
-
}
|
|
230
|
-
if (isMatch) {
|
|
231
|
-
let rel = import_path.default.relative(outputTypesDir, import_path.default.join(poDir, entry.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
232
|
-
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
233
|
-
content += `declare const ${className}: (typeof import('${rel}') extends { default: infer T } ? T : typeof import('${rel}'));
|
|
234
|
-
`;
|
|
235
|
-
declaredPOMs.add(className);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
content += `interface TestSpectraCustomActions {
|
|
241
|
-
`;
|
|
242
|
-
const declaredActions = /* @__PURE__ */ new Set();
|
|
243
|
-
for (const actionsDir of actionsDirs) {
|
|
244
|
-
if (!import_fs.default.existsSync(actionsDir)) continue;
|
|
245
|
-
const actionEntries = import_fs.default.readdirSync(actionsDir, { withFileTypes: true });
|
|
246
|
-
for (const entry of actionEntries) {
|
|
247
|
-
if (entry.name.startsWith(".")) continue;
|
|
248
|
-
if (entry.isDirectory()) {
|
|
249
|
-
const actionName = entry.name;
|
|
250
|
-
if (declaredActions.has(actionName)) continue;
|
|
251
|
-
const actionFolder = import_path.default.join(actionsDir, actionName);
|
|
252
|
-
let matchedFile = null;
|
|
253
|
-
for (const stem of hierarchy) {
|
|
254
|
-
const cand1 = import_path.default.join(actionFolder, `${stem}.action.ts`);
|
|
255
|
-
const cand2 = import_path.default.join(actionFolder, `${stem}.ts`);
|
|
256
|
-
if (import_fs.default.existsSync(cand1)) {
|
|
257
|
-
matchedFile = import_path.default.relative(outputTypesDir, cand1).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
258
|
-
break;
|
|
259
|
-
} else if (import_fs.default.existsSync(cand2)) {
|
|
260
|
-
matchedFile = import_path.default.relative(outputTypesDir, cand2).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
if (matchedFile) {
|
|
265
|
-
if (!matchedFile.startsWith(".")) matchedFile = `./${matchedFile}`;
|
|
266
|
-
content += ` ${actionName}: (typeof import('${matchedFile}') extends { default: infer T } ? T : typeof import('${matchedFile}'));
|
|
267
|
-
`;
|
|
268
|
-
declaredActions.add(actionName);
|
|
269
|
-
}
|
|
270
|
-
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
271
|
-
const parts = entry.name.split(".");
|
|
272
|
-
const stem = parts.length > 2 ? parts[parts.length - 2] : parts[0];
|
|
273
|
-
const actionName = parts[0];
|
|
274
|
-
if (hierarchy.includes(stem) || hierarchy.includes(parts[1])) {
|
|
275
|
-
if (declaredActions.has(actionName)) continue;
|
|
276
|
-
let rel = import_path.default.relative(outputTypesDir, import_path.default.join(actionsDir, entry.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
277
|
-
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
278
|
-
content += ` ${actionName}: (typeof import('${rel}') extends { default: infer T } ? T : typeof import('${rel}'));
|
|
279
|
-
`;
|
|
280
|
-
declaredActions.add(actionName);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
content += `}
|
|
286
|
-
`;
|
|
287
|
-
content += `type TestSpectraActions = import('@testspectra/matchers').SpectraStatic & TestSpectraCustomActions;
|
|
288
|
-
`;
|
|
289
|
-
content += `declare const Spectra: TestSpectraActions;
|
|
290
|
-
|
|
291
|
-
`;
|
|
292
|
-
content += `interface TestSpectraSteps {
|
|
293
|
-
`;
|
|
294
|
-
const declaredSteps = /* @__PURE__ */ new Set();
|
|
295
|
-
for (const stepsDir of stepsDirs) {
|
|
296
|
-
if (!import_fs.default.existsSync(stepsDir)) continue;
|
|
297
|
-
const stepEntries = import_fs.default.readdirSync(stepsDir, { withFileTypes: true });
|
|
298
|
-
for (const entry of stepEntries) {
|
|
299
|
-
if (entry.name.startsWith(".")) continue;
|
|
300
|
-
if (entry.isDirectory()) {
|
|
301
|
-
const stepName = entry.name;
|
|
302
|
-
if (declaredSteps.has(stepName)) continue;
|
|
303
|
-
const stepFolder = import_path.default.join(stepsDir, stepName);
|
|
304
|
-
let matchedFile = null;
|
|
305
|
-
for (const stem of hierarchy) {
|
|
306
|
-
const cand1 = import_path.default.join(stepFolder, `${stem}.step.ts`);
|
|
307
|
-
const cand2 = import_path.default.join(stepFolder, `${stem}.ts`);
|
|
308
|
-
if (import_fs.default.existsSync(cand1)) {
|
|
309
|
-
matchedFile = import_path.default.relative(outputTypesDir, cand1).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
310
|
-
break;
|
|
311
|
-
} else if (import_fs.default.existsSync(cand2)) {
|
|
312
|
-
matchedFile = import_path.default.relative(outputTypesDir, cand2).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (matchedFile) {
|
|
317
|
-
if (!matchedFile.startsWith(".")) matchedFile = `./${matchedFile}`;
|
|
318
|
-
content += ` ${stepName}: (typeof import('${matchedFile}') extends { default: infer T } ? T : typeof import('${matchedFile}'));
|
|
319
|
-
`;
|
|
320
|
-
declaredSteps.add(stepName);
|
|
321
|
-
}
|
|
322
|
-
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
323
|
-
const parts = entry.name.split(".");
|
|
324
|
-
const stem = parts.length > 2 ? parts[parts.length - 2] : parts[0];
|
|
325
|
-
const stepName = parts[0];
|
|
326
|
-
if (hierarchy.includes(stem) || hierarchy.includes(parts[1])) {
|
|
327
|
-
if (declaredSteps.has(stepName)) continue;
|
|
328
|
-
let rel = import_path.default.relative(outputTypesDir, import_path.default.join(stepsDir, entry.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
329
|
-
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
330
|
-
content += ` ${stepName}: (typeof import('${rel}') extends { default: infer T } ? T : typeof import('${rel}'));
|
|
331
|
-
`;
|
|
332
|
-
declaredSteps.add(stepName);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
content += `}
|
|
338
|
-
`;
|
|
339
|
-
content += `declare const Step: TestSpectraSteps;
|
|
340
|
-
|
|
341
|
-
`;
|
|
342
|
-
results[platform] = content;
|
|
343
|
-
}
|
|
344
|
-
return results;
|
|
345
|
-
}
|
|
346
|
-
static generateFixturesDeclarationForScope(scopeDir, sharedDir) {
|
|
347
|
-
const fixturesDirs = this.getEntityDirsForScope("fixtures", scopeDir, sharedDir);
|
|
348
|
-
let content = `// Auto-generated ambient fixture declarations for TestSpectra
|
|
349
|
-
`;
|
|
350
|
-
content += `// Managed automatically by TestSpectra Language Service Plugin.
|
|
351
|
-
|
|
352
|
-
`;
|
|
353
|
-
content += `interface TestSpectraFixtures {
|
|
354
|
-
`;
|
|
355
|
-
const declaredFixtures = /* @__PURE__ */ new Set();
|
|
356
|
-
function scanFixtureDir(dir) {
|
|
357
|
-
if (!import_fs.default.existsSync(dir)) return;
|
|
358
|
-
try {
|
|
359
|
-
const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
360
|
-
for (const entry of entries) {
|
|
361
|
-
if (entry.name.startsWith(".")) continue;
|
|
362
|
-
if (entry.isDirectory()) {
|
|
363
|
-
scanFixtureDir(import_path.default.join(dir, entry.name));
|
|
364
|
-
} else if (entry.isFile()) {
|
|
365
|
-
const parsed = import_path.default.parse(entry.name);
|
|
366
|
-
const varName = parsed.name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
367
|
-
if (declaredFixtures.has(varName)) continue;
|
|
368
|
-
content += ` readonly ${varName}: string;
|
|
369
|
-
`;
|
|
370
|
-
declaredFixtures.add(varName);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
} catch {
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
for (const fixturesDir of fixturesDirs) {
|
|
377
|
-
scanFixtureDir(fixturesDir);
|
|
378
|
-
}
|
|
379
|
-
content += `}
|
|
380
|
-
`;
|
|
381
|
-
content += `declare const Fixture: TestSpectraFixtures;
|
|
382
|
-
`;
|
|
383
|
-
return content;
|
|
384
|
-
}
|
|
385
|
-
static writeDeclarationFiles(cwd) {
|
|
386
|
-
const rootTypesDir = import_path.default.join(cwd, ".testspectra", "types");
|
|
387
|
-
if (!import_fs.default.existsSync(rootTypesDir)) {
|
|
388
|
-
import_fs.default.mkdirSync(rootTypesDir, { recursive: true });
|
|
389
|
-
}
|
|
390
|
-
const scopes = this.getEntityScopes(cwd);
|
|
391
|
-
const sharedScope = scopes.find((s) => s.isShared);
|
|
392
|
-
const rootFixtures = this.generateFixturesDeclarationForScope(cwd);
|
|
393
|
-
import_fs.default.writeFileSync(import_path.default.join(rootTypesDir, "fixtures.d.ts"), rootFixtures, "utf-8");
|
|
394
|
-
const rootDeclarations = this.generateDeclarationsForScope(cwd, rootTypesDir, cwd);
|
|
395
|
-
for (const [platform, content] of Object.entries(rootDeclarations)) {
|
|
396
|
-
import_fs.default.writeFileSync(import_path.default.join(rootTypesDir, `${platform}.d.ts`), content, "utf-8");
|
|
397
|
-
}
|
|
398
|
-
if (sharedScope) {
|
|
399
|
-
const sharedTypesDir = import_path.default.join(rootTypesDir, "shared");
|
|
400
|
-
if (!import_fs.default.existsSync(sharedTypesDir)) import_fs.default.mkdirSync(sharedTypesDir, { recursive: true });
|
|
401
|
-
const sharedFixtures = this.generateFixturesDeclarationForScope(sharedScope.dir);
|
|
402
|
-
import_fs.default.writeFileSync(import_path.default.join(sharedTypesDir, "fixtures.d.ts"), sharedFixtures, "utf-8");
|
|
403
|
-
const sharedDeclarations = this.generateDeclarationsForScope(cwd, sharedTypesDir, sharedScope.dir);
|
|
404
|
-
for (const [platform, content] of Object.entries(sharedDeclarations)) {
|
|
405
|
-
import_fs.default.writeFileSync(import_path.default.join(sharedTypesDir, `${platform}.d.ts`), content, "utf-8");
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
const featureScopes = scopes.filter((s) => !s.isShared);
|
|
409
|
-
for (const feature of featureScopes) {
|
|
410
|
-
const featureTypesDir = import_path.default.join(rootTypesDir, "features", feature.name);
|
|
411
|
-
if (!import_fs.default.existsSync(featureTypesDir)) import_fs.default.mkdirSync(featureTypesDir, { recursive: true });
|
|
412
|
-
const featureFixtures = this.generateFixturesDeclarationForScope(feature.dir, sharedScope?.dir);
|
|
413
|
-
import_fs.default.writeFileSync(import_path.default.join(featureTypesDir, "fixtures.d.ts"), featureFixtures, "utf-8");
|
|
414
|
-
const featureDeclarations = this.generateDeclarationsForScope(
|
|
415
|
-
cwd,
|
|
416
|
-
featureTypesDir,
|
|
417
|
-
feature.dir,
|
|
418
|
-
sharedScope?.dir
|
|
419
|
-
);
|
|
420
|
-
for (const [platform, content] of Object.entries(featureDeclarations)) {
|
|
421
|
-
import_fs.default.writeFileSync(import_path.default.join(featureTypesDir, `${platform}.d.ts`), content, "utf-8");
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
const universalPath = import_path.default.join(rootTypesDir, "index.d.ts");
|
|
425
|
-
import_fs.default.writeFileSync(universalPath, `/// <reference path="./common.d.ts" />
|
|
426
|
-
`, "utf-8");
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
// src/plugin.ts
|
|
431
|
-
function findWorkspaceRoot(startDir) {
|
|
432
|
-
let cur = import_path2.default.resolve(startDir);
|
|
433
|
-
while (cur !== import_path2.default.dirname(cur)) {
|
|
434
|
-
if (import_fs2.default.existsSync(import_path2.default.join(cur, "spectra.config.ts")) || import_fs2.default.existsSync(import_path2.default.join(cur, ".testspectra")) || import_fs2.default.existsSync(import_path2.default.join(cur, "pnpm-workspace.yaml")) || import_fs2.default.existsSync(import_path2.default.join(cur, "nx.json"))) {
|
|
435
|
-
return cur;
|
|
436
|
-
}
|
|
437
|
-
cur = import_path2.default.dirname(cur);
|
|
438
|
-
}
|
|
439
|
-
return startDir;
|
|
440
|
-
}
|
|
441
|
-
function appendLog(workspaceRoot, message) {
|
|
442
|
-
try {
|
|
443
|
-
const logDir = import_path2.default.join(workspaceRoot, ".testspectra", "logs");
|
|
444
|
-
if (!import_fs2.default.existsSync(logDir)) import_fs2.default.mkdirSync(logDir, { recursive: true });
|
|
445
|
-
const logFile = import_path2.default.join(logDir, "plugin.log");
|
|
446
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
447
|
-
import_fs2.default.appendFileSync(logFile, `[${timestamp}] ${message}
|
|
448
|
-
`, "utf-8");
|
|
449
|
-
} catch {
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
function init(modules) {
|
|
453
|
-
const tsModule = modules.typescript;
|
|
454
|
-
function create(info) {
|
|
455
|
-
const project = info.project;
|
|
456
|
-
const configPath = typeof project.getConfigFilePath === "function" ? project.getConfigFilePath() : "";
|
|
457
|
-
const projectDir = configPath ? import_path2.default.dirname(configPath) : project.getCurrentDirectory();
|
|
458
|
-
const workspaceRoot = findWorkspaceRoot(projectDir);
|
|
459
|
-
const log = (msg) => {
|
|
460
|
-
try {
|
|
461
|
-
info.project.projectService.logger.info(`[TestSpectra TS Plugin] ${msg}`);
|
|
462
|
-
} catch {
|
|
463
|
-
}
|
|
464
|
-
appendLog(workspaceRoot, msg);
|
|
465
|
-
};
|
|
466
|
-
log(`Plugin initialized on project: ${projectDir} (resolved root: ${workspaceRoot})`);
|
|
467
|
-
try {
|
|
468
|
-
TypeGenerator.writeDeclarationFiles(workspaceRoot);
|
|
469
|
-
if (typeof project.markAsDirty === "function") {
|
|
470
|
-
project.markAsDirty();
|
|
471
|
-
}
|
|
472
|
-
log(`Generated ambient declarations on startup`);
|
|
473
|
-
} catch (err) {
|
|
474
|
-
log(`Failed initial type generation: ${err?.message}`);
|
|
475
|
-
}
|
|
476
|
-
let debounceTimer = null;
|
|
477
|
-
const triggerRegeneration = (reason, sync = false) => {
|
|
478
|
-
const doRegen = () => {
|
|
479
|
-
try {
|
|
480
|
-
TypeGenerator.writeDeclarationFiles(workspaceRoot);
|
|
481
|
-
if (typeof project.markAsDirty === "function") {
|
|
482
|
-
project.markAsDirty();
|
|
483
|
-
}
|
|
484
|
-
log(`Regenerated ambient declarations (${reason})`);
|
|
485
|
-
} catch (err) {
|
|
486
|
-
log(`Error during regeneration: ${err?.message}`);
|
|
487
|
-
}
|
|
488
|
-
};
|
|
489
|
-
if (sync) {
|
|
490
|
-
doRegen();
|
|
491
|
-
} else {
|
|
492
|
-
if (debounceTimer) clearTimeout(debounceTimer);
|
|
493
|
-
debounceTimer = setTimeout(doRegen, 80);
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
try {
|
|
497
|
-
if (import_fs2.default.existsSync(workspaceRoot)) {
|
|
498
|
-
const watcher = import_fs2.default.watch(workspaceRoot, { recursive: true }, (eventType, filename) => {
|
|
499
|
-
if (!filename) return;
|
|
500
|
-
const fn = filename.toString();
|
|
501
|
-
if (fn.includes(".testspectra") || fn.includes("node_modules") || fn.includes(".git") || fn.includes("dist") || fn.includes(".nx")) {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
if (fn.includes("fixtures") || fn.includes("page-objects") || fn.includes("pageobjects") || fn.includes("actions") || fn.includes("steps") || fn.includes("hooks") || fn.includes("spectra.config")) {
|
|
505
|
-
log(`Detected file change [${eventType}]: ${fn}`);
|
|
506
|
-
triggerRegeneration(`fs.watch '${eventType}' on ${fn}`);
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
watcher.on("error", () => {
|
|
510
|
-
});
|
|
511
|
-
log(`Attached recursive fs.watch on ${workspaceRoot}`);
|
|
512
|
-
}
|
|
513
|
-
} catch (err) {
|
|
514
|
-
log(`Note: Recursive fs.watch not supported or failed: ${err?.message}`);
|
|
515
|
-
}
|
|
516
|
-
if (!info.languageService) {
|
|
517
|
-
return /* @__PURE__ */ Object.create(null);
|
|
518
|
-
}
|
|
519
|
-
const proxy = /* @__PURE__ */ Object.create(null);
|
|
520
|
-
for (const k of Object.keys(info.languageService)) {
|
|
521
|
-
const x = info.languageService[k];
|
|
522
|
-
proxy[k] = (...args) => x.apply(info.languageService, args);
|
|
523
|
-
}
|
|
524
|
-
const originalGetCompletions = info.languageService.getCompletionsAtPosition;
|
|
525
|
-
proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
|
|
526
|
-
const ext = import_path2.default.extname(fileName);
|
|
527
|
-
if (ext === ".ts" || ext === ".tsx" || ext === ".js" || ext === ".mjs") {
|
|
528
|
-
triggerRegeneration(`completions at ${import_path2.default.basename(fileName)}`, false);
|
|
529
|
-
}
|
|
530
|
-
return originalGetCompletions.apply(info.languageService, [
|
|
531
|
-
fileName,
|
|
532
|
-
position,
|
|
533
|
-
options,
|
|
534
|
-
formattingSettings
|
|
535
|
-
]);
|
|
536
|
-
};
|
|
537
|
-
const originalGetQuickInfo = info.languageService.getQuickInfoAtPosition;
|
|
538
|
-
proxy.getQuickInfoAtPosition = (fileName, position) => {
|
|
539
|
-
return originalGetQuickInfo.apply(info.languageService, [fileName, position]);
|
|
540
|
-
};
|
|
541
|
-
return proxy;
|
|
542
|
-
}
|
|
543
|
-
function getExternalFiles(project) {
|
|
544
|
-
try {
|
|
545
|
-
let collectDts2 = function(dir) {
|
|
546
|
-
if (!import_fs2.default.existsSync(dir)) return;
|
|
547
|
-
const entries = import_fs2.default.readdirSync(dir, { withFileTypes: true });
|
|
548
|
-
for (const entry of entries) {
|
|
549
|
-
const fullPath = import_path2.default.join(dir, entry.name);
|
|
550
|
-
if (entry.isDirectory()) {
|
|
551
|
-
collectDts2(fullPath);
|
|
552
|
-
} else if (entry.isFile() && entry.name.endsWith(".d.ts")) {
|
|
553
|
-
files.push(fullPath);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
var collectDts = collectDts2;
|
|
558
|
-
const workspaceRoot = findWorkspaceRoot(project.getCurrentDirectory());
|
|
559
|
-
const typesDir = import_path2.default.join(workspaceRoot, ".testspectra", "types");
|
|
560
|
-
const files = [];
|
|
561
|
-
collectDts2(typesDir);
|
|
562
|
-
return files;
|
|
563
|
-
} catch {
|
|
564
|
-
return [];
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return { create, getExternalFiles };
|
|
568
|
-
}
|
|
569
|
-
init.TypeGenerator = TypeGenerator;
|
|
570
|
-
var plugin_default = init;
|
|
571
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
572
|
-
0 && (module.exports = {
|
|
573
|
-
init
|
|
574
|
-
});
|
|
575
|
-
module.exports = init; module.exports.default = init; module.exports.TypeGenerator = init.TypeGenerator;
|
package/dist/plugin.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type ts from "typescript";
|
|
2
|
-
/**
|
|
3
|
-
* TypeScript Language Service Plugin Factory for TestSpectra.
|
|
4
|
-
* Runs silently inside TSServer (VS Code, Cursor, WebStorm, Neovim, etc.).
|
|
5
|
-
*
|
|
6
|
-
* It generates and refreshes `.testspectra/types/` ambient declarations
|
|
7
|
-
* automatically in the background whenever the project is opened or files change.
|
|
8
|
-
*/
|
|
9
|
-
declare function init(modules: {
|
|
10
|
-
typescript: typeof ts;
|
|
11
|
-
}): {
|
|
12
|
-
create: (info: ts.server.PluginCreateInfo) => any;
|
|
13
|
-
getExternalFiles: (project: ts.server.Project) => string[];
|
|
14
|
-
};
|
|
15
|
-
export default init;
|
|
16
|
-
export { init };
|