@testspectra/cli 1.2.1 → 1.2.3

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.
@@ -12,8 +12,9 @@ export class TsConfigGenerator {
12
12
  return {
13
13
  compilerOptions: {
14
14
  target: 'ES2022',
15
- module: 'NodeNext',
16
- moduleResolution: 'NodeNext',
15
+ module: 'ESNext',
16
+ moduleResolution: 'bundler',
17
+ moduleDetection: 'force',
17
18
  skipLibCheck: true,
18
19
  strict: true,
19
20
  composite: true,
@@ -30,8 +31,18 @@ export class TsConfigGenerator {
30
31
  }
31
32
  static getStemExcludes(prefix, stems) {
32
33
  const excludes = [];
34
+ // Platform-stem isolation applies to test ENTITIES (Page Objects, Steps, Actions, Hooks,
35
+ // Specs) — NOT to application/library source under `src/`. Shared runtime infrastructure may
36
+ // legitimately import every platform's implementation (e.g. a finder factory that selects a
37
+ // web/mobile class per runtime platform); excluding `src/**/*.mobile.ts` from the web project
38
+ // would raise TS6307 on those imports. Entity stems appear both as `<stem>.ts` (directory
39
+ // style, e.g. `page-objects/LoginPage/web.ts`) and `<name>.<stem>.ts` (suffix style).
40
+ const entityDirs = ['page-objects', 'pageobjects', 'support', 'global-hooks', 'steps', 'actions', 'hooks'];
33
41
  for (const stem of stems) {
34
- excludes.push(`${prefix}/**/page-objects/**/${stem}.ts`, `${prefix}/**/support/**/${stem}.*`, `${prefix}/**/global-hooks/**/${stem}.*`, `${prefix}/**/specs/**/hooks/**/${stem}.*`, `${prefix}/**/specs/**/${stem}.test.ts`, `${prefix}/**/${stem}.ts`, `${prefix}/**/${stem}.*`, `${prefix}/**/${stem}.*.ts`, `${prefix}/**/*.${stem}.ts`, `${prefix}/**/*.${stem}.*`, `${prefix}/**/*.${stem}.*.ts`);
42
+ for (const dir of entityDirs) {
43
+ excludes.push(`${prefix}/**/${dir}/**/${stem}.ts`, `${prefix}/**/${dir}/**/${stem}.*`, `${prefix}/**/${dir}/**/*.${stem}.ts`, `${prefix}/**/${dir}/**/*.${stem}.*`);
44
+ }
45
+ excludes.push(`${prefix}/**/specs/**/${stem}.test.ts`, `${prefix}/**/specs/**/*.${stem}.test.ts`, `${prefix}/**/specs/**/${stem}.*`, `${prefix}/**/specs/**/*.${stem}.*`);
35
46
  }
36
47
  return excludes;
37
48
  }
@@ -39,8 +50,9 @@ export class TsConfigGenerator {
39
50
  return {
40
51
  compilerOptions: {
41
52
  target: 'ES2022',
42
- module: 'NodeNext',
43
- moduleResolution: 'NodeNext',
53
+ module: 'ESNext',
54
+ moduleResolution: 'bundler',
55
+ moduleDetection: 'force',
44
56
  jsx: 'react-jsx',
45
57
  composite: true,
46
58
  noEmit: true,
@@ -80,8 +92,9 @@ export class TsConfigGenerator {
80
92
  return {
81
93
  compilerOptions: {
82
94
  target: 'ES2022',
83
- module: 'NodeNext',
84
- moduleResolution: 'NodeNext',
95
+ module: 'ESNext',
96
+ moduleResolution: 'bundler',
97
+ moduleDetection: 'force',
85
98
  jsx: 'react-jsx',
86
99
  composite: true,
87
100
  noEmit: true,
@@ -121,8 +134,9 @@ export class TsConfigGenerator {
121
134
  return {
122
135
  compilerOptions: {
123
136
  target: 'ES2022',
124
- module: 'NodeNext',
125
- moduleResolution: 'NodeNext',
137
+ module: 'ESNext',
138
+ moduleResolution: 'bundler',
139
+ moduleDetection: 'force',
126
140
  jsx: 'react-jsx',
127
141
  composite: true,
128
142
  noEmit: true,
@@ -162,8 +176,9 @@ export class TsConfigGenerator {
162
176
  return {
163
177
  compilerOptions: {
164
178
  target: 'ES2022',
165
- module: 'NodeNext',
166
- moduleResolution: 'NodeNext',
179
+ module: 'ESNext',
180
+ moduleResolution: 'bundler',
181
+ moduleDetection: 'force',
167
182
  jsx: 'react-jsx',
168
183
  composite: true,
169
184
  noEmit: true,
@@ -203,8 +218,9 @@ export class TsConfigGenerator {
203
218
  return {
204
219
  compilerOptions: {
205
220
  target: 'ES2022',
206
- module: 'NodeNext',
207
- moduleResolution: 'NodeNext',
221
+ module: 'ESNext',
222
+ moduleResolution: 'bundler',
223
+ moduleDetection: 'force',
208
224
  jsx: 'react-jsx',
209
225
  composite: true,
210
226
  noEmit: true,
@@ -276,8 +292,9 @@ export class TsConfigGenerator {
276
292
  return {
277
293
  compilerOptions: {
278
294
  target: 'ES2022',
279
- module: 'NodeNext',
280
- moduleResolution: 'NodeNext',
295
+ module: 'ESNext',
296
+ moduleResolution: 'bundler',
297
+ moduleDetection: 'force',
281
298
  jsx: 'react-jsx',
282
299
  composite: true,
283
300
  noEmit: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testspectra/cli",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "TestSpectra Cross-Platform Test Runner CLI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,10 +25,10 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@clack/prompts": "^1.7.0",
28
- "@testspectra/matchers": "^1.2.1",
29
- "@testspectra/react": "^1.2.1",
30
- "@testspectra/reporter": "^1.2.1",
31
- "@testspectra/skills": "^1.2.1",
28
+ "@testspectra/matchers": "^1.2.3",
29
+ "@testspectra/react": "^1.2.3",
30
+ "@testspectra/reporter": "^1.2.3",
31
+ "@testspectra/skills": "^1.2.3",
32
32
  "chalk": "^5.3.0",
33
33
  "commander": "^12.1.0",
34
34
  "cross-spawn": "^7.0.6",
@@ -39,9 +39,9 @@
39
39
  "zod": "^3.23.8"
40
40
  },
41
41
  "optionalDependencies": {
42
- "@testspectra/cli-darwin-arm64": "1.2.1",
43
- "@testspectra/cli-linux-x64": "1.2.1",
44
- "@testspectra/cli-win32-x64": "1.2.1"
42
+ "@testspectra/cli-darwin-arm64": "1.2.3",
43
+ "@testspectra/cli-linux-x64": "1.2.3",
44
+ "@testspectra/cli-win32-x64": "1.2.3"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/cross-spawn": "^6.0.6",
@@ -17,9 +17,9 @@
17
17
  "postinstall": "spectra sync-types"
18
18
  },
19
19
  "devDependencies": {
20
- "@testspectra/cli": "^1.2.1",
21
- "@testspectra/matchers": "^1.2.1",
22
- "@testspectra/plugin-demo": "^1.2.1",
20
+ "@testspectra/cli": "^1.2.3",
21
+ "@testspectra/matchers": "^1.2.3",
22
+ "@testspectra/plugin-demo": "^1.2.3",
23
23
  "@types/node": "^20.14.0",
24
24
  "@wdio/cli": "^9.2.8",
25
25
  "@wdio/local-runner": "^9.2.8",
@@ -12,8 +12,8 @@
12
12
  "postinstall": "spectra sync-types"
13
13
  },
14
14
  "devDependencies": {
15
- "@testspectra/cli": "^1.2.1",
16
- "@testspectra/matchers": "^1.2.1",
15
+ "@testspectra/cli": "^1.2.3",
16
+ "@testspectra/matchers": "^1.2.3",
17
17
  "@types/node": "^20.14.0",
18
18
  "@wdio/cli": "^9.2.8",
19
19
  "@wdio/local-runner": "^9.2.8",
@@ -24,6 +24,6 @@
24
24
  "nx": "^20.8.4",
25
25
  "typescript": "^5.4.5",
26
26
  "webdriverio": "^9.2.8",
27
- "@testspectra/plugin-demo": "^1.2.1"
27
+ "@testspectra/plugin-demo": "^1.2.3"
28
28
  }
29
29
  }
@@ -14,9 +14,9 @@
14
14
  "postinstall": "spectra sync-types"
15
15
  },
16
16
  "devDependencies": {
17
- "@testspectra/cli": "^1.2.1",
18
- "@testspectra/matchers": "^1.2.1",
19
- "@testspectra/react": "^1.2.1",
17
+ "@testspectra/cli": "^1.2.3",
18
+ "@testspectra/matchers": "^1.2.3",
19
+ "@testspectra/react": "^1.2.3",
20
20
  "@types/node": "^20.14.0",
21
21
  "@types/react": "^18.3.3",
22
22
  "@types/react-dom": "^18.3.0",
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: TC-0010
3
+ title: Verify scoped child lookup within badge root
4
+ priority: High
5
+ caseType: Positive
6
+ status: automated
7
+ coverage:
8
+ web: automated
9
+ ---
10
+
11
+ # TC-0010: Scoped Child Lookup Within Badge Root
12
+
13
+ Verify that `Spectra.get('~badge').get('~badge-label')` resolves the child element scoped to the
14
+ badge root (not page-wide), and that the collection form `Spectra.get('~badge').getAll('~badge-label')`
15
+ finds the same scoped descendants.
16
+
17
+ ## Test Steps
18
+
19
+ 1. Mount `<Badge label="Scoped Badge" dot />`.
20
+ 2. Verify `Spectra.get('~badge').get('~badge-label')` resolves to the scoped label with the expected text.
21
+ 3. Verify `Spectra.get('~badge').getAll('~badge-label')` finds exactly one scoped label.
@@ -0,0 +1,9 @@
1
+ import { Badge } from '../../../src/components/Badge/Badge.js';
2
+ import { withProviders } from '../../../src/test-utils.js';
3
+
4
+ it('Verify scoped child lookup within badge root', async () => {
5
+ await Spectra.mount(withProviders(<Badge label="Scoped Badge" dot />));
6
+
7
+ await Spectra.get('~badge').get('~badge-label').shouldHaveText('Scoped Badge');
8
+ await Spectra.get('~badge').getAll('~badge-label').shouldHaveLength(1);
9
+ });
@@ -1,5 +1,5 @@
1
1
  ---
2
- id: TC-0006
2
+ id: TC-0011
3
3
  title: Verify button bounds and parent element access
4
4
  priority: Medium
5
5
  caseType: Positive
@@ -0,0 +1,29 @@
1
+ import { Button } from '../../../src/components/Button/Button.js';
2
+ import { withProviders } from '../../../src/test-utils.js';
3
+
4
+ it('Verify button bounds and parent element access', async () => {
5
+ await Spectra.mount(
6
+ withProviders(
7
+ <div>
8
+ <Button label="Bounds Test" />
9
+ </div>,
10
+ ),
11
+ );
12
+
13
+ const button = Spectra.get('~button');
14
+
15
+ // getBounds returns position + size
16
+ const bounds = await button.getBounds();
17
+ if (!(bounds.width > 0) || !(bounds.height > 0)) {
18
+ throw new Error(`Expected positive button bounds, got ${JSON.stringify(bounds)}`);
19
+ }
20
+
21
+ // parent() navigates up the DOM tree
22
+ await button.parent().shouldBeVisible();
23
+
24
+ // closest() finds the matching ancestor
25
+ const wrapper = await button.closest('div');
26
+ if (!wrapper) {
27
+ throw new Error('Expected button.closest("div") to resolve an ancestor');
28
+ }
29
+ });
@@ -1,5 +1,5 @@
1
1
  ---
2
- id: TC-0007
2
+ id: TC-0012
3
3
  title: Verify button wait states and element removal detection
4
4
  priority: Medium
5
5
  caseType: Positive
@@ -2,17 +2,22 @@ import { Button } from '../../../src/components/Button/Button.js';
2
2
  import { withProviders } from '../../../src/test-utils.js';
3
3
 
4
4
  it('Verify button wait states and element removal detection', async () => {
5
- await Spectra.mount(withProviders(
6
- <div><Button label="Wait Test" /></div>,
7
- ));
5
+ await Spectra.mount(
6
+ withProviders(
7
+ <div>
8
+ <Button label="Wait Test" />
9
+ </div>,
10
+ ),
11
+ );
8
12
 
9
13
  const button = Spectra.get('~button');
10
14
 
11
15
  // waitForClickable — button should be clickable
12
16
  const clickable = await button.waitForClickable({ timeout: 3000 });
13
- expect(clickable).toBe(true);
17
+ if (!clickable) {
18
+ throw new Error('Expected button to become clickable within timeout');
19
+ }
14
20
 
15
- // waitForUndisplayed on hidden element
16
- // waitForElementRemoved would need a dynamically removed element — skip for static mount
21
+ // Static mount stays visible; removal waits are covered by integration tests.
17
22
  await button.shouldBeVisible();
18
23
  });
@@ -7,9 +7,12 @@ it('Verify input bounds and closest ancestor', async () => {
7
7
  const input = Spectra.get('input');
8
8
 
9
9
  const bounds = await input.getBounds();
10
- expect(bounds.width).toBeGreaterThan(0);
11
- expect(bounds.height).toBeGreaterThan(0);
10
+ if (!(bounds.width > 0) || !(bounds.height > 0)) {
11
+ throw new Error(`Expected positive input bounds, got ${JSON.stringify(bounds)}`);
12
+ }
12
13
 
13
14
  const closest = await input.closest('div');
14
- expect(closest).not.toBeNull();
15
+ if (!closest) {
16
+ throw new Error('Expected input.closest("div") to resolve an ancestor');
17
+ }
15
18
  });
@@ -1,5 +1,5 @@
1
1
  ---
2
- id: TC-0001
2
+ id: TC-0013
3
3
  title: Verify intercepted user list renders mocked users
4
4
  priority: Critical
5
5
  caseType: Positive
@@ -1,25 +0,0 @@
1
- import { Button } from '../../../src/components/Button/Button.js';
2
- import { withProviders } from '../../../src/test-utils.js';
3
-
4
- it('Verify button bounds and parent element access', async () => {
5
- await Spectra.mount(withProviders(
6
- <div><Button label="Bounds Test" /></div>,
7
- ));
8
-
9
- const button = Spectra.get('~button');
10
-
11
- // getBounds returns position + size
12
- const bounds = await button.getBounds();
13
- expect(bounds.width).toBeGreaterThan(0);
14
- expect(bounds.height).toBeGreaterThan(0);
15
- expect(typeof bounds.x).toBe('number');
16
- expect(typeof bounds.y).toBe('number');
17
-
18
- // parent() navigates up the DOM tree
19
- const parent = button.parent();
20
- await parent.shouldBeVisible();
21
-
22
- // closest() finds matching ancestor
23
- const wrapper = await button.closest('div');
24
- expect(wrapper).not.toBeNull();
25
- });