@testspectra/cli 1.0.28 → 1.0.29

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 (46) hide show
  1. package/dist/commands/add.js +4 -6
  2. package/dist/commands/init.js +13 -18
  3. package/dist/types/generator.js +73 -71
  4. package/package.json +1 -1
  5. package/templates/default/tsconfig.json +1 -15
  6. package/templates/{nx/modules/auth/e2e/tsconfig.json → default/tsconfig.spectra.json} +7 -8
  7. package/templates/nx/modules/auth/e2e/project.json +3 -4
  8. package/templates/nx/modules/catalog/e2e/project.json +3 -4
  9. package/templates/nx/package.json +1 -1
  10. package/templates/nx/shared/testing/page-objects/NavigationBar/common.ts +2 -2
  11. package/templates/nx/tsconfig.json +1 -3
  12. package/templates/nx/tsconfig.spectra.android.json +36 -0
  13. package/templates/nx/tsconfig.spectra.ios.json +36 -0
  14. package/templates/nx/{modules/catalog/e2e/tsconfig.json → tsconfig.spectra.json} +7 -8
  15. package/templates/nx/tsconfig.spectra.web.json +42 -0
  16. package/templates/nx/modules/auth/e2e/.testspectra/types/android.d.ts +0 -82
  17. package/templates/nx/modules/auth/e2e/.testspectra/types/common.d.ts +0 -80
  18. package/templates/nx/modules/auth/e2e/.testspectra/types/fixtures.d.ts +0 -10
  19. package/templates/nx/modules/auth/e2e/.testspectra/types/index.d.ts +0 -1
  20. package/templates/nx/modules/auth/e2e/.testspectra/types/ios.d.ts +0 -82
  21. package/templates/nx/modules/auth/e2e/.testspectra/types/mobile.d.ts +0 -82
  22. package/templates/nx/modules/auth/e2e/.testspectra/types/web.d.ts +0 -82
  23. package/templates/nx/modules/auth/e2e/tsconfig.android.json +0 -39
  24. package/templates/nx/modules/auth/e2e/tsconfig.android.tsbuildinfo +0 -1
  25. package/templates/nx/modules/auth/e2e/tsconfig.ios.json +0 -39
  26. package/templates/nx/modules/auth/e2e/tsconfig.ios.tsbuildinfo +0 -1
  27. package/templates/nx/modules/auth/e2e/tsconfig.web.json +0 -45
  28. package/templates/nx/modules/auth/e2e/tsconfig.web.tsbuildinfo +0 -1
  29. package/templates/nx/modules/catalog/e2e/.testspectra/types/android.d.ts +0 -82
  30. package/templates/nx/modules/catalog/e2e/.testspectra/types/common.d.ts +0 -80
  31. package/templates/nx/modules/catalog/e2e/.testspectra/types/fixtures.d.ts +0 -10
  32. package/templates/nx/modules/catalog/e2e/.testspectra/types/index.d.ts +0 -1
  33. package/templates/nx/modules/catalog/e2e/.testspectra/types/ios.d.ts +0 -82
  34. package/templates/nx/modules/catalog/e2e/.testspectra/types/mobile.d.ts +0 -82
  35. package/templates/nx/modules/catalog/e2e/.testspectra/types/web.d.ts +0 -82
  36. package/templates/nx/modules/catalog/e2e/tsconfig.android.json +0 -39
  37. package/templates/nx/modules/catalog/e2e/tsconfig.android.tsbuildinfo +0 -1
  38. package/templates/nx/modules/catalog/e2e/tsconfig.ios.json +0 -39
  39. package/templates/nx/modules/catalog/e2e/tsconfig.ios.tsbuildinfo +0 -1
  40. package/templates/nx/modules/catalog/e2e/tsconfig.web.json +0 -45
  41. package/templates/nx/modules/catalog/e2e/tsconfig.web.tsbuildinfo +0 -1
  42. package/templates/nx/shared/testing/tsconfig.json +0 -18
  43. package/templates/nx/shared/testing/tsconfig.tsbuildinfo +0 -1
  44. /package/templates/default/{tsconfig.android.json → tsconfig.spectra.android.json} +0 -0
  45. /package/templates/default/{tsconfig.ios.json → tsconfig.spectra.ios.json} +0 -0
  46. /package/templates/default/{tsconfig.web.json → tsconfig.spectra.web.json} +0 -0
@@ -311,24 +311,22 @@ export async function addCommand(moduleNameArg, options = {}) {
311
311
  const localConfig = path.join(targetE2eDir, "spectra.config.ts");
312
312
  if (fs.existsSync(localConfig))
313
313
  fs.unlinkSync(localConfig);
314
- // Update Root Solution tsconfig.json references
314
+ // Ensure Root Solution tsconfig.json references tsconfig.spectra.json
315
315
  const rootTsConfigPath = path.join(rootDir, "tsconfig.json");
316
316
  if (fs.existsSync(rootTsConfigPath)) {
317
317
  try {
318
318
  const rootTsConfig = JSON.parse(fs.readFileSync(rootTsConfigPath, "utf-8"));
319
319
  if (!rootTsConfig.references)
320
320
  rootTsConfig.references = [];
321
- const relRef = `./${path.relative(rootDir, targetE2eDir).replace(/\\/g, "/")}`;
322
- if (!rootTsConfig.references.some((r) => r.path === relRef)) {
323
- rootTsConfig.references.push({ path: relRef });
321
+ if (!rootTsConfig.references.some((r) => r.path === "./tsconfig.spectra.json")) {
322
+ rootTsConfig.references.push({ path: "./tsconfig.spectra.json" });
324
323
  fs.writeFileSync(rootTsConfigPath, JSON.stringify(rootTsConfig, null, 2), "utf-8");
325
324
  }
326
325
  }
327
326
  catch { }
328
327
  }
329
- // Generate Ambient Types for root and new module
328
+ // Generate Ambient Types for root workspace
330
329
  TypeGenerator.writeDeclarationFiles(rootDir);
331
- TypeGenerator.writeDeclarationFiles(targetE2eDir);
332
330
  s.stop(`Module ${e2eProjectName} added successfully!`);
333
331
  p.log.success(chalk.green(`Directory: ./${path.relative(rootDir, targetE2eDir)}`));
334
332
  p.log.success(chalk.green(`Nx Target: ${e2eProjectName}:e2e`));
@@ -385,36 +385,28 @@ export async function initCommand(options = {}) {
385
385
  // 5. Ensure pnpm-workspace.yaml includes shared library (feature modules are already part of existing workspace globs)
386
386
  const pnpmWorkspaceFilePath = path.join(cwd, "pnpm-workspace.yaml");
387
387
  ensurePnpmWorkspaceIncludes(pnpmWorkspaceFilePath, sharedTestingRelPath);
388
- // 6. Update Root Solution tsconfig.json references
388
+ // 6. Update Root Solution tsconfig.json to reference tsconfig.spectra.json
389
389
  const rootTsConfigPath = path.join(cwd, "tsconfig.json");
390
- const references = [];
391
- for (const e2eDir of featureE2eDirs) {
392
- references.push({ path: `./${path.relative(cwd, e2eDir).replace(/\\/g, "/")}` });
393
- }
394
- references.push({ path: `./${sharedTestingRelPath.replace(/\\/g, "/")}` });
395
390
  let rootTsConfig = { files: [], references: [] };
396
391
  if (fs.existsSync(rootTsConfigPath)) {
397
392
  try {
398
393
  rootTsConfig = JSON.parse(fs.readFileSync(rootTsConfigPath, "utf-8"));
399
394
  if (!rootTsConfig.references)
400
395
  rootTsConfig.references = [];
401
- for (const ref of references) {
402
- if (!rootTsConfig.references.some((r) => r.path === ref.path)) {
403
- rootTsConfig.references.push(ref);
404
- }
396
+ if (!rootTsConfig.references.some((r) => r.path === "./tsconfig.spectra.json")) {
397
+ rootTsConfig.references.push({ path: "./tsconfig.spectra.json" });
405
398
  }
406
399
  }
407
- catch { }
400
+ catch {
401
+ rootTsConfig = { files: [], references: [{ path: "./tsconfig.spectra.json" }] };
402
+ }
408
403
  }
409
404
  else {
410
- rootTsConfig = { files: [], references };
405
+ rootTsConfig = { files: [], references: [{ path: "./tsconfig.spectra.json" }] };
411
406
  }
412
407
  fs.writeFileSync(rootTsConfigPath, JSON.stringify(rootTsConfig, null, 2), "utf-8");
413
- // 7. Generate Ambient Types for Shared + All E2E Feature Directories
408
+ // 7. Generate Ambient Types in ROOT only
414
409
  TypeGenerator.writeDeclarationFiles(cwd);
415
- for (const e2eDir of featureE2eDirs) {
416
- TypeGenerator.writeDeclarationFiles(e2eDir);
417
- }
418
410
  const sharedPoLine = `${sharedTestingRelPath}/page-objects`.padEnd(28, " ");
419
411
  const sharedStepsLine = `${sharedTestingRelPath}/steps`.padEnd(28, " ");
420
412
  const sharedActLine = `${sharedTestingRelPath}/actions`.padEnd(28, " ");
@@ -430,6 +422,10 @@ This workspace uses TestSpectra's **"Centralized Configuration, Distributed Impl
430
422
  ### Centralized Root Elements
431
423
  - \`./spectra.config.ts\`: Single source of truth for runtime configurations (Base URL, Appium devices, browser targets, timeouts).
432
424
  - \`./.testspectra/\`: Centralized app data folder containing driver caches (ChromeDriver, GeckoDriver, Appium), execution logs, and universal ambient types (\`.testspectra/types/\`).
425
+ - \`./tsconfig.spectra.json\`: Solution TypeScript entry point equipped with TestSpectra language service plugin.
426
+ - \`./tsconfig.spectra.web.json\`: Strongly-typed composite configuration for Web platform tests.
427
+ - \`./tsconfig.spectra.android.json\`: Strongly-typed composite configuration for Android platform tests.
428
+ - \`./tsconfig.spectra.ios.json\`: Strongly-typed composite configuration for iOS platform tests.
433
429
  - \`./nx.json\`: Nx target defaults with execution caching and inputs.
434
430
  - \`./pnpm-workspace.yaml\`: Monorepo package glob definitions.
435
431
  - \`./tsconfig.json\`: Solution-style TypeScript orchestrator linking all distributed E2E projects and shared libraries.
@@ -449,8 +445,7 @@ ${featureE2eDirs.map((d) => {
449
445
  return `- \`./${rel}\` (**${name}**, Nx Project: \`${e2eName}\`):
450
446
  - \`specs/\`: Feature test cases (\`specs/<SuiteName>/<CaseId>/\` with \`web.test.ts\`, \`android.test.ts\`, \`ios.test.ts\`).
451
447
  - \`page-objects/\`: Feature-specific Page Objects (e.g. \`LoginPage\`, \`ProductPage\`).
452
- - \`project.json\`: Nx targets (\`e2e\`, \`type-check\`) supporting configurations (\`--configuration=android\`, \`--configuration=ios\`, \`--configuration=headless\`).
453
- - \`tsconfig.json\`: Solution TypeScript config reference.`;
448
+ - \`project.json\`: Nx targets (\`e2e\`, \`type-check\`) supporting configurations (\`--configuration=android\`, \`--configuration=ios\`, \`--configuration=headless\`).`;
454
449
  }).join("\n")}
455
450
 
456
451
  ---
@@ -10,91 +10,72 @@ const PLATFORM_HIERARCHY = {
10
10
  export class TypeGenerator {
11
11
  static getPageObjectsDirs(cwd) {
12
12
  const dirs = [];
13
- const p1 = path.join(cwd, "page-objects");
14
- const p2 = path.join(cwd, "pageobjects");
15
- if (fs.existsSync(p1))
16
- dirs.push(p1);
17
- else if (fs.existsSync(p2))
18
- dirs.push(p2);
19
- // Look for shared directories in monorepo root
20
- let cur = cwd;
21
- while (cur !== path.dirname(cur)) {
22
- const candidates = [
23
- path.join(cur, "shared/testing/page-objects"),
24
- path.join(cur, "shared/page-objects"),
25
- path.join(cur, "packages/core/testing/page-objects"),
26
- path.join(cur, "packages/shared/testing/page-objects"),
27
- path.join(cur, "packages/testing/page-objects"),
28
- path.join(cur, "core/testing/page-objects"),
29
- ];
30
- for (const cand of candidates) {
31
- if (fs.existsSync(cand) && !dirs.includes(cand))
32
- dirs.push(cand);
13
+ function scanDir(dir, maxDepth) {
14
+ if (maxDepth <= 0 || !fs.existsSync(dir))
15
+ return;
16
+ const base = path.basename(dir);
17
+ if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra")
18
+ return;
19
+ if (base === "page-objects" || base === "pageobjects") {
20
+ if (!dirs.includes(dir))
21
+ dirs.push(dir);
22
+ return;
33
23
  }
34
- // Also dynamically check tsconfig.json references if in root
35
- const rootTsConfig = path.join(cur, "tsconfig.json");
36
- if (fs.existsSync(rootTsConfig)) {
37
- try {
38
- const parsed = JSON.parse(fs.readFileSync(rootTsConfig, "utf-8"));
39
- if (Array.isArray(parsed.references)) {
40
- for (const ref of parsed.references) {
41
- if (ref.path) {
42
- const poPath1 = path.resolve(cur, ref.path, "page-objects");
43
- const poPath2 = path.resolve(cur, ref.path, "pageobjects");
44
- if (fs.existsSync(poPath1) && !dirs.includes(poPath1))
45
- dirs.push(poPath1);
46
- if (fs.existsSync(poPath2) && !dirs.includes(poPath2))
47
- dirs.push(poPath2);
48
- }
49
- }
24
+ try {
25
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
26
+ for (const entry of entries) {
27
+ if (entry.isDirectory()) {
28
+ scanDir(path.join(dir, entry.name), maxDepth - 1);
50
29
  }
51
30
  }
52
- catch { }
53
31
  }
54
- if (fs.existsSync(path.join(cur, "pnpm-workspace.yaml")) || fs.existsSync(path.join(cur, "nx.json")))
32
+ catch { }
33
+ }
34
+ // 1. Scan from cwd downwards (finds all feature page-objects and shared page-objects)
35
+ scanDir(cwd, 6);
36
+ // 2. Also look upwards to monorepo root if called from a subfolder
37
+ let cur = cwd;
38
+ while (cur !== path.dirname(cur)) {
39
+ if (fs.existsSync(path.join(cur, "pnpm-workspace.yaml")) || fs.existsSync(path.join(cur, "nx.json")) || fs.existsSync(path.join(cur, "spectra.config.ts"))) {
40
+ scanDir(cur, 6);
55
41
  break;
42
+ }
56
43
  cur = path.dirname(cur);
57
44
  }
58
45
  return dirs;
59
46
  }
60
47
  static getEntityDirs(cwd, entityType) {
61
48
  const dirs = [];
62
- const local = path.join(cwd, entityType);
63
- if (fs.existsSync(local))
64
- dirs.push(local);
65
- let cur = cwd;
66
- while (cur !== path.dirname(cur)) {
67
- const candidates = [
68
- path.join(cur, "shared/testing", entityType),
69
- path.join(cur, "shared", entityType),
70
- path.join(cur, "packages/core/testing", entityType),
71
- path.join(cur, "packages/shared/testing", entityType),
72
- path.join(cur, "packages/testing", entityType),
73
- path.join(cur, "core/testing", entityType),
74
- ];
75
- for (const cand of candidates) {
76
- if (fs.existsSync(cand) && !dirs.includes(cand))
77
- dirs.push(cand);
49
+ function scanDir(dir, maxDepth) {
50
+ if (maxDepth <= 0 || !fs.existsSync(dir))
51
+ return;
52
+ const base = path.basename(dir);
53
+ if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra")
54
+ return;
55
+ if (base === entityType) {
56
+ if (!dirs.includes(dir))
57
+ dirs.push(dir);
58
+ return;
78
59
  }
79
- // Also dynamically check tsconfig.json references
80
- const rootTsConfig = path.join(cur, "tsconfig.json");
81
- if (fs.existsSync(rootTsConfig)) {
82
- try {
83
- const parsed = JSON.parse(fs.readFileSync(rootTsConfig, "utf-8"));
84
- if (Array.isArray(parsed.references)) {
85
- for (const ref of parsed.references) {
86
- if (ref.path) {
87
- const entPath = path.resolve(cur, ref.path, entityType);
88
- if (fs.existsSync(entPath) && !dirs.includes(entPath))
89
- dirs.push(entPath);
90
- }
91
- }
60
+ try {
61
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
62
+ for (const entry of entries) {
63
+ if (entry.isDirectory()) {
64
+ scanDir(path.join(dir, entry.name), maxDepth - 1);
92
65
  }
93
66
  }
94
- catch { }
95
67
  }
96
- if (fs.existsSync(path.join(cur, "pnpm-workspace.yaml")) || fs.existsSync(path.join(cur, "nx.json")))
68
+ catch { }
69
+ }
70
+ // 1. Scan from cwd downwards
71
+ scanDir(cwd, 6);
72
+ // 2. Look upwards to monorepo root if called from a subfolder
73
+ let cur = cwd;
74
+ while (cur !== path.dirname(cur)) {
75
+ if (fs.existsSync(path.join(cur, "pnpm-workspace.yaml")) || fs.existsSync(path.join(cur, "nx.json")) || fs.existsSync(path.join(cur, "spectra.config.ts"))) {
76
+ scanDir(cur, 6);
97
77
  break;
78
+ }
98
79
  cur = path.dirname(cur);
99
80
  }
100
81
  return dirs;
@@ -207,8 +188,28 @@ export class TypeGenerator {
207
188
  }
208
189
  }
209
190
  }
210
- // 2. Actions Global Interface (Local + Shared)
211
- content += `\ninterface TestSpectraActions extends Omit<typeof import('@testspectra/cli').Spectra, ''> {\n`;
191
+ // 2. Built-in Spectra Static Methods & Custom Actions
192
+ content += `\ninterface SpectraStaticInstance {\n`;
193
+ content += ` get(target: any): import('@testspectra/matchers').SingleElementRunner;\n`;
194
+ content += ` getAll(selector: string): import('@testspectra/matchers').MultiElementRunner;\n`;
195
+ content += ` navigate(url: string): import('@testspectra/matchers').SingleElementRunner;\n`;
196
+ content += ` back(): import('@testspectra/matchers').SingleElementRunner;\n`;
197
+ content += ` refresh(): import('@testspectra/matchers').SingleElementRunner;\n`;
198
+ content += ` click(target: any, textOrOptions?: string | import('@testspectra/matchers').ClickOptions): import('@testspectra/matchers').SingleElementRunner;\n`;
199
+ content += ` doubleClick(target: any, textOrOptions?: string | import('@testspectra/matchers').ClickOptions): import('@testspectra/matchers').SingleElementRunner;\n`;
200
+ content += ` longPress(target: any, options?: import('@testspectra/matchers').LongPressOptions | number): import('@testspectra/matchers').SingleElementRunner;\n`;
201
+ content += ` type(target: any, value: string, options?: import('@testspectra/matchers').TypeOptions): import('@testspectra/matchers').SingleElementRunner;\n`;
202
+ content += ` clear(target: any): import('@testspectra/matchers').SingleElementRunner;\n`;
203
+ content += ` select(target: any, value: string): import('@testspectra/matchers').SingleElementRunner;\n`;
204
+ content += ` hover(target: any): import('@testspectra/matchers').SingleElementRunner;\n`;
205
+ content += ` pressKey(key: import('@testspectra/matchers').KeyOption | string): import('@testspectra/matchers').SingleElementRunner;\n`;
206
+ content += ` dragDrop(sourceTarget: any, destTarget: any): import('@testspectra/matchers').SingleElementRunner;\n`;
207
+ content += ` scroll(options?: import('@testspectra/matchers').ScrollOptions): import('@testspectra/matchers').SingleElementRunner;\n`;
208
+ content += ` swipe(options: import('@testspectra/matchers').SwipeOptions): import('@testspectra/matchers').SingleElementRunner;\n`;
209
+ content += ` wait(durationMs: number): import('@testspectra/matchers').SingleElementRunner;\n`;
210
+ content += ` waitForElement(target: any, timeoutMs?: number): import('@testspectra/matchers').SingleElementRunner;\n`;
211
+ content += `}\n\n`;
212
+ content += `interface TestSpectraCustomActions {\n`;
212
213
  const declaredActions = new Set();
213
214
  for (const actionsDir of actionsDirs) {
214
215
  if (!fs.existsSync(actionsDir))
@@ -259,6 +260,7 @@ export class TypeGenerator {
259
260
  }
260
261
  }
261
262
  content += `}\n`;
263
+ content += `type TestSpectraActions = SpectraStaticInstance & TestSpectraCustomActions;\n`;
262
264
  content += `declare const Spectra: TestSpectraActions;\n\n`;
263
265
  // 3. Shared Steps Global Interface (Local + Shared)
264
266
  content += `interface TestSpectraSteps {\n`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testspectra/cli",
3
- "version": "1.0.28",
3
+ "version": "1.0.29",
4
4
  "description": "TestSpectra Zero-Config Cross-Platform Test Runner CLI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,20 +1,6 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"],
7
- "plugins": [
8
- { "name": "@testspectra/cli" }
9
- ],
10
- "skipLibCheck": true,
11
- "strict": true,
12
- "noEmit": true
13
- },
14
2
  "files": [],
15
3
  "references": [
16
- { "path": "./tsconfig.web.json" },
17
- { "path": "./tsconfig.android.json" },
18
- { "path": "./tsconfig.ios.json" }
4
+ { "path": "./tsconfig.spectra.json" }
19
5
  ]
20
6
  }
@@ -3,18 +3,17 @@
3
3
  "target": "ES2022",
4
4
  "module": "NodeNext",
5
5
  "moduleResolution": "NodeNext",
6
- "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"],
7
- "plugins": [
8
- { "name": "@testspectra/cli" }
9
- ],
10
6
  "skipLibCheck": true,
11
7
  "strict": true,
12
- "noEmit": true
8
+ "noEmit": true,
9
+ "plugins": [
10
+ { "name": "@testspectra/cli" }
11
+ ]
13
12
  },
14
13
  "files": [],
15
14
  "references": [
16
- { "path": "./tsconfig.web.json" },
17
- { "path": "./tsconfig.android.json" },
18
- { "path": "./tsconfig.ios.json" }
15
+ { "path": "./tsconfig.spectra.web.json" },
16
+ { "path": "./tsconfig.spectra.android.json" },
17
+ { "path": "./tsconfig.spectra.ios.json" }
19
18
  ]
20
19
  }
@@ -25,11 +25,10 @@
25
25
  "type-check": {
26
26
  "executor": "nx:run-commands",
27
27
  "options": {
28
- "command": "tsc -b",
29
- "cwd": "modules/auth/e2e"
28
+ "command": "tsc -b tsconfig.spectra.json",
29
+ "cwd": "."
30
30
  }
31
31
  }
32
32
  },
33
- "tags": ["scope:auth", "type:e2e"],
34
- "implicitDependencies": ["@testspectra/feature-auth"]
33
+ "tags": ["scope:auth", "type:e2e"]
35
34
  }
@@ -25,11 +25,10 @@
25
25
  "type-check": {
26
26
  "executor": "nx:run-commands",
27
27
  "options": {
28
- "command": "tsc -b",
29
- "cwd": "modules/catalog/e2e"
28
+ "command": "tsc -b tsconfig.spectra.json",
29
+ "cwd": "."
30
30
  }
31
31
  }
32
32
  },
33
- "tags": ["scope:catalog", "type:e2e"],
34
- "implicitDependencies": ["@testspectra/feature-catalog"]
33
+ "tags": ["scope:catalog", "type:e2e"]
35
34
  }
@@ -6,7 +6,7 @@
6
6
  "scripts": {
7
7
  "e2e": "nx run-many -t e2e",
8
8
  "e2e:affected": "nx affected -t e2e",
9
- "type-check": "tsc -b",
9
+ "type-check": "tsc -b tsconfig.spectra.json",
10
10
  "build": "nx run-many -t build"
11
11
  },
12
12
  "devDependencies": {
@@ -1,9 +1,9 @@
1
1
  export default class NavigationBar {
2
- static get logo() {
2
+ static get logo(): ChainablePromiseElement {
3
3
  return $('header .logo');
4
4
  }
5
5
 
6
- static get profileMenu() {
6
+ static get profileMenu(): ChainablePromiseElement {
7
7
  return $('header .user-profile');
8
8
  }
9
9
 
@@ -1,8 +1,6 @@
1
1
  {
2
2
  "files": [],
3
3
  "references": [
4
- { "path": "./modules/auth/e2e" },
5
- { "path": "./modules/catalog/e2e" },
6
- { "path": "./shared/testing" }
4
+ { "path": "./tsconfig.spectra.json" }
7
5
  ]
8
6
  }
@@ -0,0 +1,36 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "composite": true,
7
+ "noEmit": true,
8
+ "skipLibCheck": true,
9
+ "strict": true,
10
+ "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"]
11
+ },
12
+ "include": [
13
+ ".testspectra/types/android.d.ts",
14
+ ".testspectra/types/fixtures.d.ts",
15
+ "spectra.config.ts",
16
+ "modules/**/e2e/**/*.ts",
17
+ "packages/**/e2e/**/*.ts",
18
+ "shared/testing/**/*.ts"
19
+ ],
20
+ "exclude": [
21
+ "node_modules",
22
+ "dist",
23
+ "**/page-objects/**/web.ts",
24
+ "**/page-objects/**/ios.ts",
25
+ "**/steps/**/web.step.ts",
26
+ "**/steps/**/ios.step.ts",
27
+ "**/actions/**/web.action.ts",
28
+ "**/actions/**/ios.action.ts",
29
+ "**/global-hooks/**/web.hook.ts",
30
+ "**/global-hooks/**/ios.hook.ts",
31
+ "**/specs/**/hooks/**/web.hook.ts",
32
+ "**/specs/**/hooks/**/ios.hook.ts",
33
+ "**/specs/**/web.test.ts",
34
+ "**/specs/**/ios.test.ts"
35
+ ]
36
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "composite": true,
7
+ "noEmit": true,
8
+ "skipLibCheck": true,
9
+ "strict": true,
10
+ "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"]
11
+ },
12
+ "include": [
13
+ ".testspectra/types/ios.d.ts",
14
+ ".testspectra/types/fixtures.d.ts",
15
+ "spectra.config.ts",
16
+ "modules/**/e2e/**/*.ts",
17
+ "packages/**/e2e/**/*.ts",
18
+ "shared/testing/**/*.ts"
19
+ ],
20
+ "exclude": [
21
+ "node_modules",
22
+ "dist",
23
+ "**/page-objects/**/web.ts",
24
+ "**/page-objects/**/android.ts",
25
+ "**/steps/**/web.step.ts",
26
+ "**/steps/**/android.step.ts",
27
+ "**/actions/**/web.action.ts",
28
+ "**/actions/**/android.action.ts",
29
+ "**/global-hooks/**/web.hook.ts",
30
+ "**/global-hooks/**/android.hook.ts",
31
+ "**/specs/**/hooks/**/web.hook.ts",
32
+ "**/specs/**/hooks/**/android.hook.ts",
33
+ "**/specs/**/web.test.ts",
34
+ "**/specs/**/android.test.ts"
35
+ ]
36
+ }
@@ -3,18 +3,17 @@
3
3
  "target": "ES2022",
4
4
  "module": "NodeNext",
5
5
  "moduleResolution": "NodeNext",
6
- "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"],
7
- "plugins": [
8
- { "name": "@testspectra/cli" }
9
- ],
10
6
  "skipLibCheck": true,
11
7
  "strict": true,
12
- "noEmit": true
8
+ "noEmit": true,
9
+ "plugins": [
10
+ { "name": "@testspectra/cli" }
11
+ ]
13
12
  },
14
13
  "files": [],
15
14
  "references": [
16
- { "path": "./tsconfig.web.json" },
17
- { "path": "./tsconfig.android.json" },
18
- { "path": "./tsconfig.ios.json" }
15
+ { "path": "./tsconfig.spectra.web.json" },
16
+ { "path": "./tsconfig.spectra.android.json" },
17
+ { "path": "./tsconfig.spectra.ios.json" }
19
18
  ]
20
19
  }
@@ -0,0 +1,42 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "composite": true,
7
+ "noEmit": true,
8
+ "skipLibCheck": true,
9
+ "strict": true,
10
+ "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"]
11
+ },
12
+ "include": [
13
+ ".testspectra/types/web.d.ts",
14
+ ".testspectra/types/fixtures.d.ts",
15
+ "spectra.config.ts",
16
+ "modules/**/e2e/**/*.ts",
17
+ "packages/**/e2e/**/*.ts",
18
+ "shared/testing/**/*.ts"
19
+ ],
20
+ "exclude": [
21
+ "node_modules",
22
+ "dist",
23
+ "**/page-objects/**/android.ts",
24
+ "**/page-objects/**/ios.ts",
25
+ "**/page-objects/**/mobile.ts",
26
+ "**/steps/**/android.step.ts",
27
+ "**/steps/**/ios.step.ts",
28
+ "**/steps/**/mobile.step.ts",
29
+ "**/actions/**/android.action.ts",
30
+ "**/actions/**/ios.action.ts",
31
+ "**/actions/**/mobile.action.ts",
32
+ "**/global-hooks/**/android.hook.ts",
33
+ "**/global-hooks/**/ios.hook.ts",
34
+ "**/global-hooks/**/mobile.hook.ts",
35
+ "**/specs/**/hooks/**/android.hook.ts",
36
+ "**/specs/**/hooks/**/ios.hook.ts",
37
+ "**/specs/**/hooks/**/mobile.hook.ts",
38
+ "**/specs/**/android.test.ts",
39
+ "**/specs/**/ios.test.ts",
40
+ "**/specs/**/mobile.test.ts"
41
+ ]
42
+ }
@@ -1,82 +0,0 @@
1
- // Auto-generated ambient declarations for TestSpectra [ANDROID]
2
- // Do not edit manually. Run 'spectra watch' or let the Language Service manage this.
3
-
4
- /// <reference types="@wdio/globals/types" />
5
- /// <reference types="@wdio/mocha-framework" />
6
- /// <reference path="./fixtures.d.ts" />
7
-
8
- declare namespace WebdriverIO {
9
- export interface InterceptFixtureOptions {
10
- statusCode?: number;
11
- headers?: Record<string, string>;
12
- }
13
- export interface InterceptFixtureObject<TData = unknown> {
14
- statusCode?: number;
15
- body: TData;
16
- headers?: Record<string, string>;
17
- }
18
- export type InterceptInput<TData = unknown> = InterceptFixtureObject<TData> | TData | string;
19
- interface Mock {
20
- respondWith<TData = unknown>(fixture: InterceptInput<TData>, options?: InterceptFixtureOptions): Promise<void>;
21
- }
22
- interface Browser {
23
- intercept<TData = unknown>(path: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH', fixture?: InterceptInput<TData>, options?: InterceptFixtureOptions): Promise<Mock>;
24
- shouldHaveUrl(expectedUrl: string): Promise<void>;
25
- shouldContainUrl(expectedUrl: string): Promise<void>;
26
- shouldHaveTitle(expectedTitle: string): Promise<void>;
27
- shouldContainTitle(expectedTitle: string): Promise<void>;
28
- }
29
- interface Element {
30
- shouldBeVisible(): Promise<Element>;
31
- shouldNotBeVisible(): Promise<Element>;
32
- shouldExist(): Promise<Element>;
33
- shouldNotExist(): Promise<Element>;
34
- shouldBeEnabled(): Promise<Element>;
35
- shouldBeDisabled(): Promise<Element>;
36
- shouldBeSelected(): Promise<Element>;
37
- shouldBeChecked(): Promise<Element>;
38
- shouldHaveValue(expectedValue: string): Promise<Element>;
39
- shouldContainValue(expectedValue: string): Promise<Element>;
40
- shouldHaveText(expectedText: string): Promise<Element>;
41
- shouldContainText(expectedText: string): Promise<Element>;
42
- shouldHaveClass(className: string): Promise<Element>;
43
- shouldHaveAttribute(attributeName: string, expectedValue?: string): Promise<Element>;
44
- }
45
- }
46
-
47
- interface Promise<T> {
48
- shouldBeVisible(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
49
- shouldNotBeVisible(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
50
- shouldExist(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
51
- shouldNotExist(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
52
- shouldBeEnabled(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
53
- shouldBeDisabled(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
54
- shouldBeSelected(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
55
- shouldBeChecked(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
56
- shouldHaveValue(this: Promise<WebdriverIO.Element>, expectedValue: string): Promise<WebdriverIO.Element>;
57
- shouldContainValue(this: Promise<WebdriverIO.Element>, expectedValue: string): Promise<WebdriverIO.Element>;
58
- shouldHaveText(this: Promise<WebdriverIO.Element>, expectedText: string): Promise<WebdriverIO.Element>;
59
- shouldContainText(this: Promise<WebdriverIO.Element>, expectedText: string): Promise<WebdriverIO.Element>;
60
- shouldHaveClass(this: Promise<WebdriverIO.Element>, className: string): Promise<WebdriverIO.Element>;
61
- shouldHaveAttribute(this: Promise<WebdriverIO.Element>, attributeName: string, expectedValue?: string): Promise<WebdriverIO.Element>;
62
- }
63
-
64
- declare const LoginPage: typeof import('../../page-objects/LoginPage/mobile.js').default;
65
- declare const ProductPage: typeof import('../../page-objects/ProductPage/mobile.js').default;
66
- declare const SettingsPage: typeof import('../../page-objects/SettingsPage/common.js').default;
67
- declare const NavigationBar: typeof import('../../../../../shared/testing/page-objects/NavigationBar/common.js').default;
68
-
69
- interface TestSpectraActions extends Omit<typeof import('@testspectra/cli').Spectra, ''> {
70
- applyDiscount: (typeof import('../../actions/applyDiscount/mobile.action.js') extends { default: infer T } ? T : typeof import('../../actions/applyDiscount/mobile.action.js'));
71
- verifyOtp: (typeof import('../../actions/verifyOtp/mobile.action.js') extends { default: infer T } ? T : typeof import('../../actions/verifyOtp/mobile.action.js'));
72
- dismissBanner: (typeof import('../../../../../shared/testing/actions/dismissBanner/common.action.js') extends { default: infer T } ? T : typeof import('../../../../../shared/testing/actions/dismissBanner/common.action.js'));
73
- }
74
- declare const Spectra: TestSpectraActions;
75
-
76
- interface TestSpectraSteps {
77
- loginUser: (typeof import('../../steps/loginUser/mobile.step.js') extends { default: infer T } ? T : typeof import('../../steps/loginUser/mobile.step.js'));
78
- searchProduct: (typeof import('../../steps/searchProduct/mobile.step.js') extends { default: infer T } ? T : typeof import('../../steps/searchProduct/mobile.step.js'));
79
- loginAsAdmin: (typeof import('../../../../../shared/testing/steps/loginAsAdmin/common.step.js') extends { default: infer T } ? T : typeof import('../../../../../shared/testing/steps/loginAsAdmin/common.step.js'));
80
- }
81
- declare const Step: TestSpectraSteps;
82
-