@testspectra/cli 1.0.62 → 1.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -32
- package/dist/commands/add.js +4 -4
- package/dist/commands/init.js +8 -8
- package/package.json +2 -2
- package/templates/default/CLAUDE.md +2 -3
- package/templates/default/package.json +1 -1
- package/templates/nx/CLAUDE.md +4 -4
- package/templates/nx/package.json +1 -1
- package/templates/nx/packages/matchers/e2e/project.json +37 -0
- package/templates/nx/packages/playground/e2e/project.json +37 -0
package/README.md
CHANGED
|
@@ -179,35 +179,36 @@ export default defineConfig({
|
|
|
179
179
|
├── tsconfig.android.json # Android platform TypeScript scope
|
|
180
180
|
├── tsconfig.ios.json # iOS platform TypeScript scope
|
|
181
181
|
├── page-objects/ # Page Object Model folders
|
|
182
|
-
│ └──
|
|
182
|
+
│ └── PlaygroundPage/
|
|
183
183
|
│ ├── web.ts
|
|
184
184
|
│ └── mobile.ts
|
|
185
|
-
├──
|
|
186
|
-
│
|
|
187
|
-
│
|
|
188
|
-
│
|
|
189
|
-
|
|
190
|
-
│ └──
|
|
191
|
-
│
|
|
192
|
-
│
|
|
185
|
+
├── support/
|
|
186
|
+
│ ├── actions/ # Reusable atomic actions
|
|
187
|
+
│ │ └── fillCredentials/
|
|
188
|
+
│ │ ├── web.action.ts
|
|
189
|
+
│ │ └── mobile.action.ts
|
|
190
|
+
│ └── steps/ # High-level business flows
|
|
191
|
+
│ └── verifyPlaygroundState/
|
|
192
|
+
│ ├── web.step.ts
|
|
193
|
+
│ └── mobile.step.ts
|
|
193
194
|
├── global-hooks/ # Global lifecycle hooks
|
|
194
|
-
│ └── before
|
|
195
|
+
│ └── before/
|
|
196
|
+
│ └── web.hook.ts
|
|
195
197
|
├── specs/ # Layered zero-import test cases
|
|
196
|
-
│ └──
|
|
197
|
-
│ └── TC-
|
|
198
|
+
│ └── Playground/
|
|
199
|
+
│ └── TC-0001-form-controls/
|
|
198
200
|
│ ├── web.test.ts
|
|
199
|
-
│
|
|
200
|
-
│ └── ios.test.ts
|
|
201
|
+
│ └── mobile.test.ts
|
|
201
202
|
├── fixtures/ # Platform-agnostic test data
|
|
202
|
-
│ └──
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
│ └── playgroundData.json
|
|
204
|
+
├── .testspectra/ # Auto-generated ambient typings & cache
|
|
205
|
+
│ └── types/
|
|
206
|
+
│ ├── fixtures.d.ts
|
|
207
|
+
│ ├── web.d.ts
|
|
208
|
+
│ ├── android.d.ts
|
|
209
|
+
│ ├── ios.d.ts
|
|
210
|
+
│ ├── mobile.d.ts
|
|
211
|
+
│ └── common.d.ts
|
|
211
212
|
```
|
|
212
213
|
|
|
213
214
|
---
|
|
@@ -230,19 +231,19 @@ TestSpectra features an enterprise-grade architecture for large monorepos: **"Ce
|
|
|
230
231
|
┌──────────────────────────────┴──────────────────────────────┐
|
|
231
232
|
▼ ▼
|
|
232
233
|
┌───────────────────────────────┐ ┌───────────────────────────────┐
|
|
233
|
-
│ shared/testing/ (Library) │ │
|
|
234
|
+
│ shared/testing/ (Library) │ │ packages/playground/e2e/ │
|
|
234
235
|
├───────────────────────────────┤ ├───────────────────────────────┤
|
|
235
236
|
│ - Shared Page Objects │ ◄─── Auto-Scanned Globals ──│ - Feature Specs (specs/) │
|
|
236
|
-
│ - Shared Steps (
|
|
237
|
-
│ - Shared Actions (
|
|
238
|
-
│ - Shared Fixtures (
|
|
237
|
+
│ - Shared Steps (verifyState) │ (100% Zero-Import!) │ - Feature Page Objects (POMs) │
|
|
238
|
+
│ - Shared Actions (fillCreds) │ │ - project.json (Nx Target) │
|
|
239
|
+
│ - Shared Fixtures (playData) │ │ - tsconfig.web/android/ios │
|
|
239
240
|
└───────────────────────────────┘ └───────────────────────────────┘
|
|
240
241
|
```
|
|
241
242
|
|
|
242
243
|
### Key Pillars of Monorepo Integration:
|
|
243
244
|
|
|
244
245
|
1. **Interactive Workspace Auto-Discovery (`spectra init`)**:
|
|
245
|
-
- Parses `pnpm-workspace.yaml` (e.g. `packages
|
|
246
|
+
- Parses `pnpm-workspace.yaml` (e.g. `packages/*`, `modules/**`).
|
|
246
247
|
- Scans sub-directories for existing `project.json` or `package.json`.
|
|
247
248
|
- Prompts the user with an interactive multi-select checkbox to choose which features will receive E2E testing.
|
|
248
249
|
- Prompts for customizable E2E folder names (e.g. `e2e`, `test/e2e`) and the shared testing library path (`shared/testing`).
|
|
@@ -253,18 +254,18 @@ TestSpectra features an enterprise-grade architecture for large monorepos: **"Ce
|
|
|
253
254
|
- Driver caches, binaries, and logs reside in `<root>/.testspectra/`, preventing repository clutter across individual feature folders.
|
|
254
255
|
|
|
255
256
|
3. **Global Zero-Import Consumption of Shared Library**:
|
|
256
|
-
- Entities placed inside `shared/testing/page-objects/`, `shared/testing/steps/`, `shared/testing/actions/`, and `shared/testing/fixtures/` are automatically aggregated into ambient declarations.
|
|
257
|
-
- Feature test specs consume shared Page Objects (`
|
|
257
|
+
- Entities placed inside `shared/testing/page-objects/`, `shared/testing/support/steps/`, `shared/testing/support/actions/`, and `shared/testing/fixtures/` are automatically aggregated into ambient declarations.
|
|
258
|
+
- Feature test specs consume shared Page Objects (`PlaygroundPage.open()`), steps (`Step.verifyPlaygroundState()`), actions (`Spectra.fillCredentials()`), and fixtures (`Fixture.playgroundData`) **without a single line of `import` statement**.
|
|
258
259
|
|
|
259
260
|
4. **Nx Target Execution & Affected Caching**:
|
|
260
261
|
- Each feature E2E folder includes an Nx `project.json`:
|
|
261
262
|
```json
|
|
262
263
|
{
|
|
263
|
-
"name": "
|
|
264
|
+
"name": "playground-e2e",
|
|
264
265
|
"targets": {
|
|
265
266
|
"e2e": {
|
|
266
267
|
"executor": "nx:run-commands",
|
|
267
|
-
"options": { "command": "spectra run", "cwd": "
|
|
268
|
+
"options": { "command": "spectra run", "cwd": "packages/playground/e2e" },
|
|
268
269
|
"configurations": {
|
|
269
270
|
"android": { "command": "spectra run --target android" },
|
|
270
271
|
"ios": { "command": "spectra run --target ios" },
|
package/dist/commands/add.js
CHANGED
|
@@ -130,7 +130,7 @@ export async function addCommand(moduleNameArg, options = {}) {
|
|
|
130
130
|
if (!fs.existsSync(templateDir)) {
|
|
131
131
|
templateDir = path.resolve(__dirname, "../../../templates/nx");
|
|
132
132
|
}
|
|
133
|
-
const sampleE2eSrc = path.join(templateDir, "
|
|
133
|
+
const sampleE2eSrc = path.join(templateDir, "packages/playground/e2e");
|
|
134
134
|
if (!fs.existsSync(sampleE2eSrc)) {
|
|
135
135
|
p.cancel(chalk.red(`Template directory not found at: ${sampleE2eSrc}`));
|
|
136
136
|
return;
|
|
@@ -283,9 +283,9 @@ export async function addCommand(moduleNameArg, options = {}) {
|
|
|
283
283
|
const s = p.spinner();
|
|
284
284
|
s.start(`Scaffolding ${e2eProjectName} in ./${path.relative(rootDir, targetE2eDir)}...`);
|
|
285
285
|
copyRecursive(sampleE2eSrc, targetE2eDir, {
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"scope:
|
|
286
|
+
"playground-e2e": e2eProjectName,
|
|
287
|
+
"packages/playground/e2e": path.relative(rootDir, targetE2eDir).replace(/\\/g, "/"),
|
|
288
|
+
"scope:playground": `scope:${featureName}`,
|
|
289
289
|
});
|
|
290
290
|
// Adjust project.json
|
|
291
291
|
const projJsonPath = path.join(targetE2eDir, "project.json");
|
package/dist/commands/init.js
CHANGED
|
@@ -338,7 +338,7 @@ export async function initCommand(options = {}) {
|
|
|
338
338
|
p.log.warn(chalk.yellow("No feature packages found in workspace. You can enter feature names to scaffold."));
|
|
339
339
|
const featureNamesInput = await p.text({
|
|
340
340
|
message: "Enter feature module names (comma-separated), or leave blank to skip:",
|
|
341
|
-
placeholder: "
|
|
341
|
+
placeholder: "playground, matchers, navigation",
|
|
342
342
|
defaultValue: "",
|
|
343
343
|
});
|
|
344
344
|
if (p.isCancel(featureNamesInput)) {
|
|
@@ -350,14 +350,14 @@ export async function initCommand(options = {}) {
|
|
|
350
350
|
// Build relPaths from feature names using a sensible default location
|
|
351
351
|
const featureBaseInput = await p.text({
|
|
352
352
|
message: "Enter base directory for feature modules:",
|
|
353
|
-
placeholder: "packages
|
|
354
|
-
defaultValue: "packages
|
|
353
|
+
placeholder: "packages",
|
|
354
|
+
defaultValue: "packages",
|
|
355
355
|
});
|
|
356
356
|
if (p.isCancel(featureBaseInput)) {
|
|
357
357
|
p.cancel("Setup cancelled.");
|
|
358
358
|
return;
|
|
359
359
|
}
|
|
360
|
-
const featureBase = featureBaseInput.trim() || "packages
|
|
360
|
+
const featureBase = featureBaseInput.trim() || "packages";
|
|
361
361
|
chosenProjects = raw.split(",").map((n) => `${featureBase}/${n.trim()}`).filter(Boolean);
|
|
362
362
|
}
|
|
363
363
|
}
|
|
@@ -467,16 +467,16 @@ export async function initCommand(options = {}) {
|
|
|
467
467
|
copyRecursive(sharedTestingSrc, sharedTestingAbsPath);
|
|
468
468
|
}
|
|
469
469
|
// 4. Distribute E2E Folders to Selected Feature Modules
|
|
470
|
-
const sampleE2eSrc = path.join(templateDir, "
|
|
470
|
+
const sampleE2eSrc = path.join(templateDir, "packages/playground/e2e");
|
|
471
471
|
const featureE2eDirs = [];
|
|
472
472
|
for (const projRel of chosenProjects) {
|
|
473
473
|
const targetE2eDir = path.join(cwd, projRel, e2eFolderName);
|
|
474
474
|
const featureName = path.basename(projRel);
|
|
475
475
|
const e2eProjectName = `${featureName}-${e2eFolderName}`;
|
|
476
476
|
copyRecursive(sampleE2eSrc, targetE2eDir, {
|
|
477
|
-
"
|
|
478
|
-
"
|
|
479
|
-
"scope:
|
|
477
|
+
"playground-e2e": e2eProjectName,
|
|
478
|
+
"packages/playground/e2e": path.relative(cwd, targetE2eDir).replace(/\\/g, "/"),
|
|
479
|
+
"scope:playground": `scope:${featureName}`,
|
|
480
480
|
});
|
|
481
481
|
// Adjust project.json
|
|
482
482
|
const projJsonPath = path.join(targetE2eDir, "project.json");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testspectra/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.63",
|
|
4
4
|
"description": "TestSpectra Zero-Config Cross-Platform Test Runner CLI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@clack/prompts": "^1.7.0",
|
|
32
|
-
"@testspectra/matchers": "^1.0.
|
|
32
|
+
"@testspectra/matchers": "^1.0.63",
|
|
33
33
|
"chalk": "^5.3.0",
|
|
34
34
|
"commander": "^12.1.0",
|
|
35
35
|
"dotenv": "^16.4.5",
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# CLAUDE.md - TestSpectra Framework Conventions
|
|
2
2
|
|
|
3
3
|
## Commands
|
|
4
|
-
- Run all Web tests
|
|
5
|
-
- Run specific spec
|
|
6
|
-
- Run Web tests: `pnpm test`
|
|
4
|
+
- Run all Web tests: `pnpm spectra run -t web`
|
|
5
|
+
- Run specific spec: `pnpm spectra run "specs/Playground/TC-0001-form-controls/web.test.ts" -t web`
|
|
7
6
|
- Run Mobile tests: `pnpm spectra run --target android` or `pnpm spectra run --target ios`
|
|
8
7
|
- Type checking: `pnpm type-check` (or `tsc -b`)
|
|
9
8
|
- Preflight doctor: `pnpm spectra doctor`
|
package/templates/nx/CLAUDE.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# CLAUDE.md - TestSpectra Framework Conventions
|
|
2
2
|
|
|
3
3
|
## Commands
|
|
4
|
-
- Run all Web tests
|
|
5
|
-
- Run specific spec
|
|
6
|
-
- Run
|
|
4
|
+
- Run all Web tests: `pnpm spectra run -t web`
|
|
5
|
+
- Run specific spec: `pnpm spectra run "specs/Playground/TC-0001-form-controls/web.test.ts" -t web`
|
|
6
|
+
- Run Nx monorepo E2E targets: `pnpm nx run-many -t e2e`
|
|
7
7
|
- Run Mobile tests: `pnpm spectra run --target android` or `pnpm spectra run --target ios`
|
|
8
|
-
- Type checking: `pnpm type-check` (or `tsc -b`)
|
|
8
|
+
- Type checking: `pnpm type-check` (or `tsc -b tsconfig.spectra.json`)
|
|
9
9
|
- Preflight doctor: `pnpm spectra doctor`
|
|
10
10
|
- List devices: `pnpm spectra devices`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "matchers-e2e",
|
|
3
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"projectType": "application",
|
|
5
|
+
"sourceRoot": "packages/matchers/e2e",
|
|
6
|
+
"targets": {
|
|
7
|
+
"e2e": {
|
|
8
|
+
"executor": "nx:run-commands",
|
|
9
|
+
"options": {
|
|
10
|
+
"command": "spectra run",
|
|
11
|
+
"cwd": "packages/matchers/e2e"
|
|
12
|
+
},
|
|
13
|
+
"configurations": {
|
|
14
|
+
"android": {
|
|
15
|
+
"command": "spectra run --target android"
|
|
16
|
+
},
|
|
17
|
+
"ios": {
|
|
18
|
+
"command": "spectra run --target ios"
|
|
19
|
+
},
|
|
20
|
+
"headless": {
|
|
21
|
+
"command": "spectra run --headless"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"type-check": {
|
|
26
|
+
"executor": "nx:run-commands",
|
|
27
|
+
"options": {
|
|
28
|
+
"command": "tsc -b",
|
|
29
|
+
"cwd": "."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"tags": [
|
|
34
|
+
"scope:matchers",
|
|
35
|
+
"type:e2e"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "playground-e2e",
|
|
3
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"projectType": "application",
|
|
5
|
+
"sourceRoot": "packages/playground/e2e",
|
|
6
|
+
"targets": {
|
|
7
|
+
"e2e": {
|
|
8
|
+
"executor": "nx:run-commands",
|
|
9
|
+
"options": {
|
|
10
|
+
"command": "spectra run",
|
|
11
|
+
"cwd": "packages/playground/e2e"
|
|
12
|
+
},
|
|
13
|
+
"configurations": {
|
|
14
|
+
"android": {
|
|
15
|
+
"command": "spectra run --target android"
|
|
16
|
+
},
|
|
17
|
+
"ios": {
|
|
18
|
+
"command": "spectra run --target ios"
|
|
19
|
+
},
|
|
20
|
+
"headless": {
|
|
21
|
+
"command": "spectra run --headless"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"type-check": {
|
|
26
|
+
"executor": "nx:run-commands",
|
|
27
|
+
"options": {
|
|
28
|
+
"command": "tsc -b",
|
|
29
|
+
"cwd": "."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"tags": [
|
|
34
|
+
"scope:playground",
|
|
35
|
+
"type:e2e"
|
|
36
|
+
]
|
|
37
|
+
}
|