@testspectra/cli 1.1.8-rc.8 → 1.1.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 (88) hide show
  1. package/README.md +11 -8
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/commands/__tests__/doctor-filter.test.d.ts +1 -0
  4. package/dist/commands/__tests__/doctor-filter.test.js +37 -0
  5. package/dist/commands/__tests__/test-error-streaming.test.d.ts +1 -0
  6. package/dist/commands/__tests__/test-error-streaming.test.js +85 -0
  7. package/dist/commands/__tests__/test-scaffolding.test.d.ts +1 -0
  8. package/dist/commands/__tests__/test-scaffolding.test.js +32 -0
  9. package/dist/commands/__tests__/upgrade.test.d.ts +1 -0
  10. package/dist/commands/__tests__/upgrade.test.js +95 -0
  11. package/dist/commands/add.js +5 -4
  12. package/dist/commands/devices.js +1 -0
  13. package/dist/commands/docs.d.ts +4 -0
  14. package/dist/commands/docs.js +17 -0
  15. package/dist/commands/doctor.d.ts +9 -1
  16. package/dist/commands/doctor.js +17 -3
  17. package/dist/commands/init.js +7 -160
  18. package/dist/commands/install.js +5 -0
  19. package/dist/commands/license.js +1 -0
  20. package/dist/commands/run.d.ts +2 -0
  21. package/dist/commands/run.js +22 -0
  22. package/dist/commands/test.d.ts +13 -0
  23. package/dist/commands/test.js +115 -21
  24. package/dist/commands/upgrade.d.ts +12 -0
  25. package/dist/commands/upgrade.js +197 -0
  26. package/dist/config/schema.d.ts +53 -0
  27. package/dist/config/schema.js +2 -0
  28. package/dist/generator/__tests__/tsconfig-isolation.test.js +2 -1
  29. package/dist/generator/__tests__/type-generator.test.js +38 -0
  30. package/dist/generator/architecture-doc-generator.d.ts +14 -0
  31. package/dist/generator/architecture-doc-generator.js +80 -0
  32. package/dist/generator/index.d.ts +1 -0
  33. package/dist/generator/index.js +1 -0
  34. package/dist/generator/tsconfig-generator.js +1 -1
  35. package/dist/generator/type-generator.d.ts +5 -2
  36. package/dist/generator/type-generator.js +14 -17
  37. package/dist/index.js +59 -16
  38. package/dist/linter/__tests__/shared-lib-boundary.test.js +15 -15
  39. package/dist/linter/discovery.d.ts +3 -3
  40. package/dist/linter/discovery.js +7 -7
  41. package/dist/linter/schemas/spec.schema.d.ts +6 -6
  42. package/dist/runner/bridge.d.ts +1 -1
  43. package/dist/runner/bridge.js +67 -16
  44. package/dist/runner/reporter.d.ts +1 -0
  45. package/dist/runner/reporter.js +12 -6
  46. package/dist/utils/__tests__/dev-server-manager.test.d.ts +1 -0
  47. package/dist/utils/__tests__/dev-server-manager.test.js +72 -0
  48. package/dist/utils/background-update-check.d.ts +1 -0
  49. package/dist/utils/background-update-check.js +43 -0
  50. package/dist/utils/dependency-updates.d.ts +15 -0
  51. package/dist/utils/dependency-updates.js +107 -0
  52. package/dist/utils/dev-server-manager.d.ts +40 -0
  53. package/dist/utils/dev-server-manager.js +257 -0
  54. package/dist/utils/update-notifier.d.ts +2 -0
  55. package/dist/utils/update-notifier.js +67 -0
  56. package/package.json +10 -9
  57. package/templates/default/package.json +2 -2
  58. package/templates/docs/ARCHITECTURE.default.md +26 -0
  59. package/templates/docs/ARCHITECTURE.nx.md +147 -0
  60. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db +0 -0
  61. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-shm +0 -0
  62. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-wal +0 -0
  63. package/templates/nx/.nx/workspace-data/d/daemon.log +947 -0
  64. package/templates/nx/.nx/workspace-data/d/server-process.json +1 -1
  65. package/templates/nx/.nx/workspace-data/file-map.json +172 -186
  66. package/templates/nx/.nx/workspace-data/lockfile.hash +1 -1
  67. package/templates/nx/.nx/workspace-data/nx_files.nxt +0 -0
  68. package/templates/nx/.nx/workspace-data/parsed-lock-file.json +81 -130
  69. package/templates/nx/.nx/workspace-data/project-graph.json +90 -144
  70. package/templates/nx/.nx/workspace-data/source-maps.json +336 -0
  71. package/templates/nx/package.json +3 -3
  72. package/templates/nx/packages/matchers/e2e/project.json +2 -2
  73. package/templates/nx/packages/playground/e2e/project.json +2 -2
  74. package/templates/nx/pnpm-lock.yaml +191 -214
  75. package/templates/nx/shared/testing/project.json +1 -2
  76. package/templates/nx/spectra.config.ts +13 -0
  77. package/templates/react-component/package.json +3 -3
  78. package/templates/react-component/page-objects/BadgeComponent/web.ts +4 -4
  79. package/templates/react-component/page-objects/ButtonComponent/web.ts +3 -3
  80. package/templates/react-component/page-objects/InputComponent/web.ts +1 -1
  81. package/templates/react-component/specs/ButtonComponent/TC-0001-button-rendering-and-click/web.test.tsx +0 -3
  82. package/templates/react-component/specs/ButtonComponent/TC-0004-disabled-button-not-clickable/web.test.tsx +0 -9
  83. package/templates/react-component/specs/ButtonComponent/TC-0005-button-renders-icon/web.test.tsx +1 -1
  84. package/templates/react-component/specs/InputComponent/TC-0003-input-typing-and-clear/web.test.tsx +4 -8
  85. package/templates/react-component/spectra.config.ts +0 -10
  86. package/templates/react-component/src/components/Badge/Badge.tsx +3 -3
  87. package/templates/react-component/src/components/Button/Button.tsx +5 -3
  88. package/templates/react-component/src/components/Input/Input.tsx +2 -3
@@ -13,7 +13,6 @@
13
13
  }
14
14
  },
15
15
  "tags": [
16
- "scope:shared",
17
- "type:shared"
16
+ "testspectra:shared"
18
17
  ]
19
18
  }
@@ -3,6 +3,19 @@ import { defineConfig } from "@testspectra/cli";
3
3
  export default defineConfig({
4
4
  webConfig: {
5
5
  baseUrl: "http://localhost:5173",
6
+ hosts: {
7
+ // Named host aliases for microfrontends and multi-entrypoint apps
8
+ // e.g. sso: "https://sso.local:5174", admin: "https://admin.local:5176"
9
+ },
10
+ devServers: [
11
+ // Auto-start and healthcheck local development servers before running tests
12
+ // {
13
+ // name: "app",
14
+ // command: "pnpm dev",
15
+ // url: "http://localhost:5173",
16
+ // reuseExistingServer: true,
17
+ // },
18
+ ],
6
19
  maxConcurrentSessions: "1",
7
20
  headless: true,
8
21
  implicitWait: "5000",
@@ -14,9 +14,9 @@
14
14
  "postinstall": "spectra sync-types"
15
15
  },
16
16
  "devDependencies": {
17
- "@testspectra/cli": "link:../..",
18
- "@testspectra/matchers": "link:../../../tools/matchers",
19
- "@testspectra/react": "link:../../../tools/react",
17
+ "@testspectra/cli": "^1.1.10",
18
+ "@testspectra/matchers": "^1.1.10",
19
+ "@testspectra/react": "^1.1.10",
20
20
  "@types/node": "^20.14.0",
21
21
  "@types/react": "^18.3.3",
22
22
  "@types/react-dom": "^18.3.0",
@@ -1,22 +1,22 @@
1
1
  class BadgeComponent {
2
2
  /** Root badge element */
3
3
  get root() {
4
- return Spectra.get("[data-testid='testspectra-badge']");
4
+ return Spectra.get('~badge');
5
5
  }
6
6
 
7
7
  /** Dot indicator element */
8
8
  get dot() {
9
- return Spectra.get("[data-testid='badge-dot']");
9
+ return Spectra.get('~badge-dot');
10
10
  }
11
11
 
12
12
  /** Badge label text element */
13
13
  get label() {
14
- return Spectra.get("[data-testid='badge-label']");
14
+ return Spectra.get('~badge-label');
15
15
  }
16
16
 
17
17
  /** Lookup badge by severity attribute */
18
18
  bySeverity(severity: 'info' | 'success' | 'warning' | 'danger') {
19
- return Spectra.get(`[data-testid='testspectra-badge'][data-severity='${severity}']`);
19
+ return Spectra.get(`~badge[data-severity='${severity}']`);
20
20
  }
21
21
  }
22
22
 
@@ -1,17 +1,17 @@
1
1
  class ButtonComponent {
2
2
  /** Root button element */
3
3
  get root() {
4
- return Spectra.get("[data-testid='testspectra-button']");
4
+ return Spectra.get('~button');
5
5
  }
6
6
 
7
7
  /** Label element inside button */
8
8
  get label() {
9
- return Spectra.get("[data-testid='button-label']");
9
+ return Spectra.get('~button-label');
10
10
  }
11
11
 
12
12
  /** Optional icon element */
13
13
  get icon() {
14
- return Spectra.get("[data-testid='button-icon']");
14
+ return Spectra.get('~button-icon');
15
15
  }
16
16
 
17
17
  /** Lookup button element by visible text */
@@ -1,7 +1,7 @@
1
1
  class InputComponent {
2
2
  /** Root input element */
3
3
  get root() {
4
- return Spectra.get("[data-testid='testspectra-input']");
4
+ return Spectra.get('~input');
5
5
  }
6
6
 
7
7
  /** Lookup input element by placeholder substring */
@@ -22,7 +22,4 @@ it('Verify button render, text, and click with Spectra DSL', async () => {
22
22
  await ButtonComponent.root.shouldHaveText('Save Changes');
23
23
  await ButtonComponent.root.shouldHaveAttribute('data-variant', 'primary');
24
24
  await ButtonComponent.root.click();
25
-
26
- // Verify callback state
27
- expect(isClicked).toBe(true);
28
25
  });
@@ -1,22 +1,13 @@
1
1
  import { Button } from '../../../src/components/Button/Button.js';
2
2
 
3
3
  it('Verify disabled button cannot be clicked', async () => {
4
- let isClicked = false;
5
-
6
4
  await Spectra.mount(
7
5
  <Button
8
6
  label="Disabled Action"
9
7
  disabled
10
- onClick={() => {
11
- isClicked = true;
12
- }}
13
8
  />,
14
9
  );
15
10
 
16
11
  await ButtonComponent.root.shouldBeVisible();
17
12
  await ButtonComponent.root.shouldBeDisabled();
18
-
19
- // Attempt click - should not fire callback
20
- await ButtonComponent.root.click().catch(() => {});
21
- expect(isClicked).toBe(false);
22
13
  });
@@ -1,7 +1,7 @@
1
1
  import { Button } from '../../../src/components/Button/Button.js';
2
2
 
3
3
  it('Verify button renders optional icon', async () => {
4
- await Spectra.mount(<Button label="Download Report" icon={<span data-testid="button-icon">📥</span>} />);
4
+ await Spectra.mount(<Button label="Download Report" icon={<span aria-label="button-icon">📥</span>} />);
5
5
 
6
6
  await ButtonComponent.icon.shouldBeVisible();
7
7
  await ButtonComponent.icon.shouldHaveText('📥');
@@ -2,15 +2,10 @@ import { Input } from '../../../src/components/Input/Input.js';
2
2
  import { withProviders } from '../../../src/test-utils.js';
3
3
 
4
4
  it('Verify input placeholder and typing interaction', async () => {
5
- let currentVal = '';
6
-
7
5
  await Spectra.mount(
8
6
  withProviders(
9
7
  <Input
10
8
  placeholder="Enter email address"
11
- onChange={(e) => {
12
- currentVal = e.target.value;
13
- }}
14
9
  />,
15
10
  ),
16
11
  );
@@ -19,10 +14,11 @@ it('Verify input placeholder and typing interaction', async () => {
19
14
  await InputComponent.root.shouldBeVisible();
20
15
  await InputComponent.byPlaceholder('email address').shouldBeVisible();
21
16
 
22
- // 2. Type text using Spectra DSL
17
+ // 2. Type text using Spectra DSL and verify value
23
18
  await InputComponent.root.type('test@example.com');
24
19
  await InputComponent.root.shouldHaveValue('test@example.com');
25
20
 
26
- // 3. Verify onChange state
27
- expect(currentVal).toBe('test@example.com');
21
+ // 3. Clear text using Spectra DSL and verify cleared state
22
+ await InputComponent.root.clear();
23
+ await InputComponent.root.shouldHaveValue('');
28
24
  });
@@ -6,22 +6,12 @@ export default defineConfig({
6
6
  maxConcurrentSessions: "4",
7
7
  headless: true,
8
8
  implicitWait: "5000",
9
- pageLoadTimeout: "30000",
10
- scriptTimeout: "30000",
11
9
  parallelizationMode: "testcase",
12
10
  },
13
- browsers: [
14
- {
15
- id: "chrome-desktop",
16
- type: "chrome",
17
- mobileEmulation: false,
18
- },
19
- ],
20
11
  executionConfig: {
21
12
  networkMonitoringEnabled: true,
22
13
  fastResponseTime: "200",
23
14
  normalResponseTime: "1000",
24
15
  monitoredDomains: [],
25
- environmentVariables: [],
26
16
  },
27
17
  });
@@ -29,7 +29,7 @@ export const Badge: React.FC<BadgeProps> = ({
29
29
 
30
30
  return (
31
31
  <span
32
- data-testid="testspectra-badge"
32
+ aria-label="badge"
33
33
  data-severity={severity}
34
34
  style={{
35
35
  display: 'inline-flex',
@@ -45,7 +45,7 @@ export const Badge: React.FC<BadgeProps> = ({
45
45
  >
46
46
  {dot && (
47
47
  <span
48
- data-testid="badge-dot"
48
+ aria-label="badge-dot"
49
49
  style={{
50
50
  width: '6px',
51
51
  height: '6px',
@@ -54,7 +54,7 @@ export const Badge: React.FC<BadgeProps> = ({
54
54
  }}
55
55
  />
56
56
  )}
57
- <span data-testid="badge-label">{label}</span>
57
+ <span aria-label="badge-label">{label}</span>
58
58
  </span>
59
59
  );
60
60
  };
@@ -6,6 +6,7 @@ export interface ButtonProps {
6
6
  disabled?: boolean;
7
7
  onClick?: () => void;
8
8
  icon?: React.ReactNode;
9
+ ariaLabel?: string;
9
10
  }
10
11
 
11
12
  export const Button: React.FC<ButtonProps> = ({
@@ -14,6 +15,7 @@ export const Button: React.FC<ButtonProps> = ({
14
15
  disabled = false,
15
16
  onClick,
16
17
  icon,
18
+ ariaLabel,
17
19
  }) => {
18
20
  const getBackgroundColor = () => {
19
21
  if (disabled) return '#9ca3af';
@@ -31,7 +33,7 @@ export const Button: React.FC<ButtonProps> = ({
31
33
  return (
32
34
  <button
33
35
  type="button"
34
- data-testid="testspectra-button"
36
+ aria-label={ariaLabel || 'button'}
35
37
  data-variant={variant}
36
38
  disabled={disabled}
37
39
  onClick={onClick}
@@ -50,8 +52,8 @@ export const Button: React.FC<ButtonProps> = ({
50
52
  transition: 'background-color 0.2s ease',
51
53
  }}
52
54
  >
53
- {icon && <span data-testid="button-icon">{icon}</span>}
54
- <span>{label}</span>
55
+ {icon && <span aria-label="button-icon">{icon}</span>}
56
+ <span aria-label="button-label">{label}</span>
55
57
  </button>
56
58
  );
57
59
  };
@@ -15,18 +15,17 @@ export const Input: React.FC<InputProps> = ({
15
15
  defaultValue,
16
16
  disabled = false,
17
17
  onChange,
18
- ariaLabel,
18
+ ariaLabel = 'input',
19
19
  }) => {
20
20
  return (
21
21
  <input
22
22
  type="text"
23
- data-testid="testspectra-input"
23
+ aria-label={ariaLabel}
24
24
  placeholder={placeholder}
25
25
  value={value}
26
26
  defaultValue={defaultValue}
27
27
  disabled={disabled}
28
28
  onChange={onChange}
29
- aria-label={ariaLabel}
30
29
  style={{
31
30
  padding: '8px 12px',
32
31
  borderRadius: '6px',