@testspectra/cli 1.0.7 → 1.0.10

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.
Files changed (66) hide show
  1. package/dist/commands/init.js +58 -398
  2. package/dist/commands/run.js +18 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/package.json +8 -1
  6. package/templates/default/actions/applyDiscount/mobile.action.ts +6 -0
  7. package/templates/default/actions/applyDiscount/web.action.ts +6 -0
  8. package/templates/default/actions/verifyOtp/mobile.action.ts +6 -0
  9. package/templates/default/actions/verifyOtp/web.action.ts +6 -0
  10. package/templates/default/fixtures/couponCode.json +1 -0
  11. package/templates/default/fixtures/searchQuery.json +1 -0
  12. package/templates/default/fixtures/userData.json +1 -0
  13. package/templates/default/global-hooks/before.web.hook.ts +4 -0
  14. package/templates/default/package.json +18 -0
  15. package/templates/default/page-objects/LoginPage/mobile.ts +32 -0
  16. package/templates/default/page-objects/LoginPage/web.ts +32 -0
  17. package/templates/default/page-objects/ProductPage/mobile.ts +39 -0
  18. package/templates/default/page-objects/ProductPage/web.ts +38 -0
  19. package/templates/default/page-objects/SettingsPage/common.ts +26 -0
  20. package/templates/default/spectra.config.ts +61 -0
  21. package/templates/default/steps/loginUser/mobile.step.ts +4 -0
  22. package/templates/default/steps/loginUser/web.step.ts +4 -0
  23. package/templates/default/steps/searchProduct/mobile.step.ts +5 -0
  24. package/templates/default/steps/searchProduct/web.step.ts +5 -0
  25. package/templates/default/suites/Auth/TC-AUTH-01/android.test.ts +6 -0
  26. package/templates/default/suites/Auth/TC-AUTH-01/ios.test.ts +6 -0
  27. package/templates/default/suites/Auth/TC-AUTH-01/web.test.ts +13 -0
  28. package/templates/default/suites/Auth/TC-AUTH-02/android.test.ts +5 -0
  29. package/templates/default/suites/Auth/TC-AUTH-02/web.test.ts +5 -0
  30. package/templates/default/suites/Auth/hooks/before.android.hook.ts +3 -0
  31. package/templates/default/suites/Auth/hooks/before.ios.hook.ts +3 -0
  32. package/templates/default/suites/Auth/hooks/before.web.hook.ts +3 -0
  33. package/templates/default/suites/Product/TC-PROD-01/mobile.test.ts +8 -0
  34. package/templates/default/suites/Product/TC-PROD-01/web.test.ts +8 -0
  35. package/templates/default/suites/Product/TC-PROD-02/mobile.test.ts +6 -0
  36. package/templates/default/suites/Product/TC-PROD-02/web.test.ts +6 -0
  37. package/templates/default/suites/Product/hooks/before.web.hook.ts +3 -0
  38. package/templates/default/suites/Settings/TC-SET-01/common.test.ts +8 -0
  39. package/templates/default/tsconfig.android.json +39 -0
  40. package/templates/default/tsconfig.ios.json +39 -0
  41. package/templates/default/tsconfig.json +20 -0
  42. package/templates/default/tsconfig.web.json +45 -0
  43. package/CLI_IMPLEMENTATION_PLAN.md +0 -369
  44. package/src/commands/devices.ts +0 -41
  45. package/src/commands/doctor.ts +0 -57
  46. package/src/commands/init.ts +0 -470
  47. package/src/commands/run.ts +0 -102
  48. package/src/config/loader.ts +0 -82
  49. package/src/config/schema.ts +0 -489
  50. package/src/index.ts +0 -56
  51. package/src/plugin.ts +0 -81
  52. package/src/runner/bridge.ts +0 -146
  53. package/src/runner/reporter.ts +0 -64
  54. package/src/step/index.ts +0 -6
  55. package/src/step/matchers.ts +0 -131
  56. package/src/step/proto.ts +0 -163
  57. package/src/step/runner/collection.ts +0 -73
  58. package/src/step/runner/single.ts +0 -166
  59. package/src/step/spectra.ts +0 -185
  60. package/src/step/types.ts +0 -113
  61. package/src/types/generator.ts +0 -240
  62. package/src/types/webdriverio.d.ts +0 -46
  63. package/testspectra-cli-1.0.5.tgz +0 -0
  64. package/testspectra-cli-1.0.6.tgz +0 -0
  65. package/testspectra-cli-1.0.7.tgz +0 -0
  66. package/tsconfig.json +0 -17
@@ -1,369 +0,0 @@
1
- # TestSpectra CLI (`@testspectra/cli`) Implementation Plan
2
-
3
- ## 1. Overview
4
- The TestSpectra CLI provides a zero-config, command-line interface for running Web and Mobile (Android/iOS) test suites using the shared Rust core runner (`core/test-runner` and `core/device-manager`).
5
-
6
- The CLI configuration strictly adheres to the backend `ProjectConfig` and `ConfigData` schema (`backend/src/models/project_config.rs` and `src/services/project-config-service.ts`).
7
-
8
- ---
9
-
10
- ## 2. Architecture
11
-
12
- ```
13
- ┌─────────────────────────────────┐
14
- │ TypeScript CLI (`cli/`) │
15
- │ (commander / inquirer / ora) │
16
- └────────────────┬────────────────┘
17
-
18
- ┌────────────────┴────────────────┐
19
- ▼ ▼
20
- Local Execution Remote Execution
21
- ┌─────────────────────────────┐ ┌─────────────────────────────┐
22
- │ NAPI-RS / Subprocess Bridge │ │ HTTP REST API Client │
23
- │ to core/test-runner (Rust) │ │ to Backend API Server │
24
- └──────────────┬──────────────┘ └──────────────┬──────────────┘
25
- │ │
26
- ▼ ▼
27
- ┌───────────────────────┐ ┌───────────────────────┐
28
- │ core/test-runner │ │ Backend API │
29
- │ (Rust Engine) │ │ (PostgreSQL + Engine) │
30
- └───────────────────────┘ └───────────────────────┘
31
- ```
32
-
33
- ---
34
-
35
- ## 3. Package & File Structure
36
-
37
- ```
38
- testspectra-source/
39
- └── cli/
40
- ├── README.md
41
- ├── CLI_IMPLEMENTATION_PLAN.md <-- This Plan
42
- ├── package.json
43
- ├── tsconfig.json
44
- ├── bin/
45
- │ └── testspectra.js
46
- └── src/
47
- ├── index.ts # Main entrypoint & Commander setup
48
- ├── config/
49
- │ ├── schema.ts # Exact ConfigData & ProjectConfig TypeScript types
50
- │ └── loader.ts # Config resolution (file vs remote vs CLI flags)
51
- ├── commands/
52
- │ ├── init.ts # Generate default testspectra.config.json
53
- │ ├── run.ts # Execute test cases/suites
54
- │ ├── devices.ts # List connected Android/iOS/Web devices
55
- │ └── doctor.ts # System diagnostic check (ADB, Appium, Java, Browsers)
56
- ├── runner/
57
- │ ├── bridge.ts # Interface to Rust core runner binary/NAPI
58
- │ └── reporter.ts # Spec, JSON, & JUnit XML reporters
59
- └── api/
60
- └── client.ts # REST client for sync with backend project config
61
- ```
62
-
63
- ---
64
-
65
- ## 4. Configuration Schema (`cli/src/config/schema.ts`)
66
-
67
- Matches `backend/src/models/project_config.rs` and `src/services/project-config-service.ts`:
68
-
69
- ```typescript
70
- export interface WebConfig {
71
- baseUrl: string;
72
- maxConcurrentSessions: string;
73
- headlessMode: boolean;
74
- implicitWait: string;
75
- pageLoadTimeout: string;
76
- scriptTimeout: string;
77
- parallelizationMode: "testcase" | "suite";
78
- }
79
-
80
- export interface AndroidConfig {
81
- appiumServer: string;
82
- platformName: string;
83
- platformVersion: string;
84
- deviceName: string;
85
- automationName: string;
86
- appPackage: string;
87
- appActivity: string;
88
- autoGrantPermissions: boolean;
89
- noReset: boolean;
90
- implicitWait: string;
91
- parallelizationMode: "testcase" | "suite";
92
- }
93
-
94
- export interface IosConfig {
95
- appiumServer: string;
96
- platformName: string;
97
- platformVersion: string;
98
- deviceName: string;
99
- automationName: string;
100
- bundleId: string;
101
- udid: string;
102
- xcodeOrgId: string;
103
- xcodeSigningId: string;
104
- autoAcceptAlerts: boolean;
105
- noReset: boolean;
106
- implicitWait: string;
107
- parallelizationMode: "testcase" | "suite";
108
- }
109
-
110
- export interface ConfigData {
111
- webConfig: WebConfig;
112
- browsers: Array<{
113
- id: string;
114
- type: string;
115
- mobileEmulation: boolean;
116
- deviceName?: string;
117
- width?: string;
118
- height?: string;
119
- }>;
120
- androidConfig: AndroidConfig;
121
- iosConfig: IosConfig;
122
- loadConfig: {
123
- virtualUsers: string;
124
- duration: string;
125
- };
126
- loadStages: Array<{
127
- id: string;
128
- duration: string;
129
- targetVUs: string;
130
- }>;
131
- thresholds: Array<{
132
- id: string;
133
- metricType: string;
134
- maxValue: string;
135
- }>;
136
- executionConfig?: {
137
- networkMonitoringEnabled: boolean;
138
- fastResponseTime: string;
139
- normalResponseTime: string;
140
- monitoredDomains?: Array<{ domain: string; enabled: boolean }>;
141
- environmentVariables?: Array<{ key: string; value: string }>;
142
- };
143
- }
144
-
145
- export interface ProjectConfig {
146
- project_id: string;
147
- config_data: ConfigData;
148
- updated_at?: string;
149
- }
150
- ```
151
-
152
- ---
153
-
154
- ## 5. Key CLI Commands & Features
155
-
156
- | Command | Arguments / Flags | Description |
157
- |---|---|---|
158
- | `testspectra init` | `--force` | Generate default `testspectra.config.json` adhering to `ConfigData`. |
159
- | `testspectra doctor` | `--fix` | Diagnostic check for ADB, Appium, Chrome, Java, Node. |
160
- | `testspectra devices` | `--target <android\|ios\|web>` | List connected devices & available browsers. |
161
- | `testspectra run` | `<path>` `--target <target>` `--remote` `--project-id <id>` | Run test cases/suites via local config or remote backend config. |
162
-
163
- ---
164
-
165
- ## 6. Execution Flow & Driver Management
166
-
167
- 1. **Base Directory Resolution (`app_data_path`):**
168
- - CLI sets `RunnerContext.app_data_path` to `./.testspectra` inside the target project root (overridable via `--workdir`).
169
- - Driver cache automatically lands in `./.testspectra/driver_cache`.
170
- - Desktop Tauri app uses OS AppSupport (`~/Library/Application Support/...`), while CLI isolates everything inside project `.testspectra`.
171
-
172
- 2. **Initialization:** CLI resolves config via local `testspectra.config.json` or fetches `ProjectConfig` from backend.
173
- 3. **Environment Validation:** Verifies Appium / ADB readiness using `core/device-manager`.
174
- 4. **Execution & Driver Auto-Recovery:**
175
- - Pass resolved `ConfigData` JSON + test files payload into `core/test-runner` Rust engine via NAPI bridge or subprocess IPC stream.
176
- - `core/test-runner` automatically monitors for Chromedriver download failures, wipes `./.testspectra/driver_cache`, and retries once transparently.
177
- 5. **Reporting:** Stream real-time logs and output JUnit / Spec formatted result.
178
-
179
- ---
180
-
181
- ## 7. Refactoring Plan: Moving Shared Core Features from `src-tauri` to `core/`
182
-
183
- To avoid code duplication and support CLI/Server environments natively, the following features will be refactored from `src-tauri` into the shared `core` workspace:
184
-
185
- ### A. ADB Wireless & Pairing (`src-tauri/src/adb.rs` → `core/device-manager`)
186
- - **Current State:** High-level device discovery and auto-reconnection loop (`get_adb_devices_impl`) live in `src-tauri/src/adb.rs` while primitive ADB calls live in `core/device-manager`.
187
- - **Target Architecture:**
188
- - Move stateful device tracking & background auto-reconnection into `core/device-manager::android`.
189
- - Provide headless Rust/C-API/NAPI methods (`get_adb_devices`, `pair_adb_device`, `start_qr_pairing`) accessible to both Tauri app and `testspectra devices pair` CLI command.
190
-
191
- ### B. Dependency Check & Installer (`src-tauri/src/dependencies.rs` → `core/test-runner`)
192
- - **Current State:** `src-tauri/src/dependencies.rs` wraps `testspectra_core_runner::dependency` with Tauri `AppHandle` events for emitting install logs.
193
- - **Target Architecture:**
194
- - Decouple log emission using a generic callback/channel pattern (`fn(log: DependencyLog)`).
195
- - Move full dependency resolution & auto-installer (`install_missing_dependencies`) into `core/test-runner::dependency`.
196
- - Tauri UI subscribes via channel; CLI `testspectra doctor --fix` renders progress directly to terminal stdout/stderr via `ora` spinner / progress bar.
197
-
198
- ---
199
-
200
- ## 8. Multi-Platform Hierarchy & Ambient Type Resolution
201
-
202
- TestSpectra scripts are organized natively by **Entity Folders** supporting multi-platform hierarchy resolution (as defined in `docs/features/v1.3-MULTI_PLATFORM_AUTOMATION.md`):
203
-
204
- ### A. Resolution Hierarchy (Highest to Lowest Priority)
205
- | Target Context / Spec | Hierarchy Chain |
206
- | :--- | :--- |
207
- | **Web Context (`web.test.ts`)** | `*.web.ts` &rarr; `*.common.ts` (or `*.ts` fallback) |
208
- | **iOS Context (`ios.test.ts`)** | `*.ios.ts` &rarr; `*.mobile.ts` &rarr; `*.common.ts` |
209
- | **Android Context (`android.test.ts`)** | `*.android.ts` &rarr; `*.mobile.ts` &rarr; `*.common.ts` |
210
- | **Mobile Context (`mobile.test.ts`)** | `*.mobile.ts` &rarr; `*.common.ts` |
211
- | **Common Context (`common.test.ts`)** | `*.common.ts` (Strict base only) |
212
-
213
- ### B. Ambient Global Resolution in Specs (Zero Manual Imports)
214
- TestSpectra execution preparer (`core/test-runner`) and the CLI Type Generator (`cli::TypeGenerator`) synthesize global ambient declarations (`.testspectra/types/{web,android,ios,mobile,common}.d.ts`) so specs never need manual imports for Page Objects, Actions, Steps, or Fixtures:
215
- - **`LoginPage.open()`** &rarr; Ambiently declared via `declare const LoginPage: typeof import('../page-objects/LoginPage/web.js').default;`
216
- - **`Spectra.actionName()`** &rarr; Ambiently declared per platform from `actions/`.
217
- - **`Step.stepName()`** &rarr; Ambiently declared per platform from `steps/`.
218
- - **`Fixture.fixtureName`** &rarr; Ambiently declared from `fixtures/` assets.
219
- - **`browser.intercept()`** &rarr; Ambiently declared on `WebdriverIO.Browser`.
220
-
221
- No custom VS Code language server plugin or extension is required. Standard TypeScript compiler (`tsc`) and standard IDEs (VS Code, Cursor, WebStorm) handle everything natively via the platform tsconfigs.
222
-
223
- ## 9. Standard TestSpectra Multi-Platform Project Structure & Platform-Isolated TSConfigs
224
-
225
- To ensure 100% accurate TypeScript type resolution without collisions across platform signatures (e.g. `login(u,p)` on Web vs `login(u,p,captcha)` on Mobile), TestSpectra uses **Platform-Isolated TSConfigs**:
226
-
227
- ```text
228
- my-test-project/
229
- ├── tsconfig.json # Solution root pointing to platform tsconfigs
230
- ├── tsconfig.web.json # Web TS context (web specs + web.d.ts + common.d.ts)
231
- ├── tsconfig.android.json # Android TS context (android specs + android.d.ts + mobile.d.ts + common.d.ts)
232
- ├── tsconfig.ios.json # iOS TS context (ios specs + ios.d.ts + mobile.d.ts + common.d.ts)
233
- ├── spectra.config.ts # Matching backend ConfigData schema (typed with defineConfig)
234
- ├── .testspectra/ # Local TestSpectra runtime & types (ignored in git)
235
- │ ├── types/
236
- │ │ ├── web.d.ts # Generated ambient types for web
237
- │ │ ├── android.d.ts # Generated ambient types for android
238
- │ │ ├── ios.d.ts # Generated ambient types for ios
239
- │ │ └── common.d.ts # Generated ambient types for common
240
- │ └── driver_cache/ # Managed Chromedriver / Appium cache
241
-
242
- ├── specs/ # Entity folder per Test Case
243
- │ └── TC-LOGIN-01/
244
- │ ├── web.test.ts # Web implementation (zero-import single it block)
245
- │ ├── android.test.ts # Android implementation
246
- │ └── ios.test.ts # iOS implementation
247
-
248
- ├── page-objects/ # Entity folder per Page Object
249
- │ └── LoginPage/
250
- │ ├── web.ts # Web Page Object implementation
251
- │ └── mobile.ts # Shared mobile Page Object implementation
252
-
253
- ├── actions/ # Entity folder per Action
254
- │ └── verifyOtp/
255
- │ ├── web.action.ts
256
- │ └── mobile.action.ts
257
-
258
- ├── steps/ # Entity folder per Step
259
- │ └── loginUser/
260
- │ ├── web.step.ts
261
- │ └── mobile.step.ts
262
-
263
- ├── fixtures/ # Test assets (JSON, PNG, CSV)
264
- │ └── userData.json
265
-
266
- └── hooks/ # Per-suite lifecycle hooks
267
- └── default/
268
- ├── before.web.hook.ts
269
- ├── before.android.hook.ts
270
- └── before.ios.hook.ts
271
- ```
272
-
273
- ### Complete Scaffolding on `spectra init`
274
- Running `spectra init` automatically scaffolds:
275
- 1. `spectra.config.ts` using `defineConfig`.
276
- 2. Root `tsconfig.json` & platform-isolated `tsconfig.web.json`, `tsconfig.android.json`, `tsconfig.ios.json`.
277
- 3. Complete boilerplate templates for **Page Objects**, **Specs**, **Actions**, **Steps**, **Fixtures**, and **Suite Hooks**.
278
- 4. `.gitignore` ensuring `.testspectra/`, `dist/`, and `node_modules/` are not committed.
279
- 5. All scaffolded templates pass TypeScript checking with **0 errors**.
280
-
281
- 3. Updates TypeScript triple-slash references if necessary.
282
-
283
- ### B. Dependencies Location & Isolation (`node_modules`)
284
- - CLI isolates WebdriverIO & Appium dependencies into `./.testspectra/node_modules` (or uses root `node_modules` if a `package.json` is present).
285
- - Ensures user test projects don't need a manually managed `package.json` unless desired.
286
-
287
- ---
288
-
289
- ## 11. Custom Browser Commands & Fixture-Integrated Interceptor (`browser.intercept`)
290
-
291
- TestSpectra extends WebdriverIO's `browser` object with runtime custom commands bundled directly in `core/test-runner` execution preparer (keeping user `wdio.conf.ts` completely clean).
292
-
293
- ### A. Feature Capabilities
294
- - **`browser.intercept(path, method, fixture?, options?)`**: Strongly-typed API mock interceptor.
295
- - **Fixture Object Integration:** Accepts `Fixture.sampleJson` asset references directly, auto-loading and parsing files from `fixtures/`.
296
- - **Dynamic `mock.respondWith()`**: Allows updating mock responses on the fly within individual test steps.
297
-
298
- ### B. Type Declarations (`cli/src/types/webdriverio.d.ts`)
299
- ```typescript
300
- declare global {
301
- namespace WebdriverIO {
302
- export interface InterceptFixtureOptions {
303
- statusCode?: number;
304
- headers?: Record<string, string>;
305
- }
306
-
307
- export interface InterceptFixtureObject<TData = unknown> {
308
- statusCode?: number;
309
- body: TData;
310
- headers?: Record<string, string>;
311
- }
312
-
313
- export type InterceptInput<TData = unknown> =
314
- | InterceptFixtureObject<TData>
315
- | TData
316
- | string;
317
-
318
- interface Mock {
319
- /**
320
- * Dynamically set or change the fixture response for this mock instance.
321
- * Supports Fixture paths, `{ statusCode, body, headers }` objects, or raw payloads.
322
- */
323
- respondWith<TData = unknown>(
324
- fixture: InterceptInput<TData>,
325
- options?: InterceptFixtureOptions,
326
- ): Promise<void>;
327
- }
328
-
329
- interface Browser {
330
- /**
331
- * Clean & strongly-typed API interceptor for WebdriverIO.
332
- * Automatically resolves relative path against browser.options.baseUrl.
333
- * Integrated directly with TestSpectra Fixtures.
334
- */
335
- intercept<TData = unknown>(
336
- path: string,
337
- method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
338
- fixture?: InterceptInput<TData>,
339
- options?: InterceptFixtureOptions,
340
- ): Promise<Mock>;
341
- }
342
- }
343
- }
344
- ```
345
-
346
- ### C. Usage Example in Test Files
347
- ```typescript
348
- test('intercept user API using TestSpectra Fixtures', async () => {
349
- // Pass Fixture asset directly
350
- await browser.intercept('/api/users', 'GET', Fixture.usersListJson);
351
-
352
- // Pass Fixture object with custom status code
353
- await browser.intercept('/api/login', 'POST', {
354
- statusCode: 401,
355
- body: { error: 'Invalid credentials' }
356
- });
357
-
358
- // Dynamic response update
359
- const userMock = await browser.intercept('/api/profile', 'GET');
360
- await userMock.respondWith(Fixture.adminProfileJson, { statusCode: 200 });
361
- });
362
- ```
363
-
364
- ---
365
-
366
- ### C. Test Output & Reports (Real-Time Stdout + Local JSON Export)
367
- For local CLI runs, test execution provides real-time feedback and JSON persistence:
368
- - **Terminal Stdout:** Real-time colored stdout stream of step `TestLog` entries.
369
- - **Local JSON Output:** Saves complete `TestRunResult` payload (`status`, `duration`, `logs`, CDP `networkResources`) to `./.testspectra/reports/result.json` (or custom path via `--output <path>`).
@@ -1,41 +0,0 @@
1
- import { execSync } from "child_process";
2
-
3
- export async function devicesCommand(options: { target?: "android" | "ios" | "web" | "all" }) {
4
- const target = options.target || "all";
5
- console.log(`\x1b[36m[TestSpectra Devices]\x1b[0m Listing connected test targets (scope: ${target})...\n`);
6
-
7
- if (target === "all" || target === "android") {
8
- console.log("\x1b[1mAndroid Devices (ADB):\x1b[0m");
9
- try {
10
- const adbOutput = execSync("adb devices -l", { stdio: "pipe" }).toString();
11
- const lines = adbOutput.split("\n").slice(1);
12
- let found = false;
13
- for (const line of lines) {
14
- if (line.trim()) {
15
- found = true;
16
- console.log(` \x1b[32m•\x1b[0m ${line.trim()}`);
17
- }
18
- }
19
- if (!found) {
20
- console.log(" \x1b[90mNo Android devices/emulators connected via ADB.\x1b[0m");
21
- }
22
- } catch {
23
- console.log(" \x1b[31mADB command failed or platform-tools not in PATH.\x1b[0m");
24
- }
25
- }
26
-
27
- if (target === "all" || target === "web") {
28
- console.log("\n\x1b[1mWeb Browsers:\x1b[0m");
29
- try {
30
- const chromeVer = execSync(
31
- process.platform === "darwin"
32
- ? '"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version'
33
- : "google-chrome --version",
34
- { stdio: "pipe" }
35
- ).toString().trim();
36
- console.log(` \x1b[32m•\x1b[0m Chrome: ${chromeVer}`);
37
- } catch {
38
- console.log(" \x1b[90m• Chrome: Not installed\x1b[0m");
39
- }
40
- }
41
- }
@@ -1,57 +0,0 @@
1
- import { execSync } from "child_process";
2
-
3
- export async function doctorCommand(options: { fix?: boolean }) {
4
- console.log("\x1b[36m[TestSpectra Doctor]\x1b[0m Checking development and runtime dependencies...\n");
5
-
6
- const checks = [
7
- {
8
- name: "Node.js",
9
- command: "node -v",
10
- required: true,
11
- },
12
- {
13
- name: "Bun",
14
- command: "bun -v",
15
- required: false,
16
- },
17
- {
18
- name: "ADB (Android Debug Bridge)",
19
- command: "adb version",
20
- required: false,
21
- },
22
- {
23
- name: "Java JDK",
24
- command: "java -version",
25
- required: false,
26
- },
27
- {
28
- name: "Google Chrome",
29
- command: process.platform === "darwin"
30
- ? '"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version'
31
- : "google-chrome --version",
32
- required: false,
33
- },
34
- ];
35
-
36
- let missingCount = 0;
37
-
38
- for (const check of checks) {
39
- try {
40
- const out = execSync(check.command, { stdio: "pipe" }).toString().trim();
41
- const firstLine = out.split("\n")[0];
42
- console.log(` \x1b[32m✓\x1b[0m ${check.name.padEnd(30)} \x1b[90m(${firstLine})\x1b[0m`);
43
- } catch {
44
- console.log(` \x1b[31m✗\x1b[0m ${check.name.padEnd(30)} \x1b[31m(Not found)\x1b[0m`);
45
- if (check.required) {
46
- missingCount++;
47
- }
48
- }
49
- }
50
-
51
- console.log("\n------------------------------------------------------------");
52
- if (missingCount === 0) {
53
- console.log("\x1b[32m[Doctor]\x1b[0m System ready for local test execution!");
54
- } else {
55
- console.log(`\x1b[33m[Doctor]\x1b[0m Found ${missingCount} missing required dependencies.`);
56
- }
57
- }