@syn7xx/testops-mcp-server 0.1.0

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 (134) hide show
  1. package/README.md +177 -0
  2. package/dist/args.d.ts +10 -0
  3. package/dist/args.d.ts.map +1 -0
  4. package/dist/args.js +26 -0
  5. package/dist/args.js.map +1 -0
  6. package/dist/domain/index.d.ts +4 -0
  7. package/dist/domain/index.d.ts.map +1 -0
  8. package/dist/domain/index.js +4 -0
  9. package/dist/domain/index.js.map +1 -0
  10. package/dist/domain/project/index.d.ts +3 -0
  11. package/dist/domain/project/index.d.ts.map +1 -0
  12. package/dist/domain/project/index.js +3 -0
  13. package/dist/domain/project/index.js.map +1 -0
  14. package/dist/domain/project/service.d.ts +23 -0
  15. package/dist/domain/project/service.d.ts.map +1 -0
  16. package/dist/domain/project/service.js +51 -0
  17. package/dist/domain/project/service.js.map +1 -0
  18. package/dist/domain/project/types.d.ts +12 -0
  19. package/dist/domain/project/types.d.ts.map +1 -0
  20. package/dist/domain/project/types.js +5 -0
  21. package/dist/domain/project/types.js.map +1 -0
  22. package/dist/domain/test-case/index.d.ts +3 -0
  23. package/dist/domain/test-case/index.d.ts.map +1 -0
  24. package/dist/domain/test-case/index.js +3 -0
  25. package/dist/domain/test-case/index.js.map +1 -0
  26. package/dist/domain/test-case/service.d.ts +69 -0
  27. package/dist/domain/test-case/service.d.ts.map +1 -0
  28. package/dist/domain/test-case/service.js +141 -0
  29. package/dist/domain/test-case/service.js.map +1 -0
  30. package/dist/domain/test-case/types.d.ts +51 -0
  31. package/dist/domain/test-case/types.d.ts.map +1 -0
  32. package/dist/domain/test-case/types.js +5 -0
  33. package/dist/domain/test-case/types.js.map +1 -0
  34. package/dist/domain/test-plan/index.d.ts +3 -0
  35. package/dist/domain/test-plan/index.d.ts.map +1 -0
  36. package/dist/domain/test-plan/index.js +3 -0
  37. package/dist/domain/test-plan/index.js.map +1 -0
  38. package/dist/domain/test-plan/service.d.ts +33 -0
  39. package/dist/domain/test-plan/service.d.ts.map +1 -0
  40. package/dist/domain/test-plan/service.js +40 -0
  41. package/dist/domain/test-plan/service.js.map +1 -0
  42. package/dist/domain/test-plan/types.d.ts +18 -0
  43. package/dist/domain/test-plan/types.d.ts.map +1 -0
  44. package/dist/domain/test-plan/types.js +5 -0
  45. package/dist/domain/test-plan/types.js.map +1 -0
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +10 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/presentation/index.d.ts +4 -0
  51. package/dist/presentation/index.d.ts.map +1 -0
  52. package/dist/presentation/index.js +4 -0
  53. package/dist/presentation/index.js.map +1 -0
  54. package/dist/presentation/project/tools.d.ts +2 -0
  55. package/dist/presentation/project/tools.d.ts.map +1 -0
  56. package/dist/presentation/project/tools.js +61 -0
  57. package/dist/presentation/project/tools.js.map +1 -0
  58. package/dist/presentation/test-case/tools.d.ts +2 -0
  59. package/dist/presentation/test-case/tools.d.ts.map +1 -0
  60. package/dist/presentation/test-case/tools.js +139 -0
  61. package/dist/presentation/test-case/tools.js.map +1 -0
  62. package/dist/presentation/test-plan/tools.d.ts +2 -0
  63. package/dist/presentation/test-plan/tools.d.ts.map +1 -0
  64. package/dist/presentation/test-plan/tools.js +46 -0
  65. package/dist/presentation/test-plan/tools.js.map +1 -0
  66. package/dist/server.d.ts +4 -0
  67. package/dist/server.d.ts.map +1 -0
  68. package/dist/server.js +32 -0
  69. package/dist/server.js.map +1 -0
  70. package/dist/services/config.d.ts +43 -0
  71. package/dist/services/config.d.ts.map +1 -0
  72. package/dist/services/config.js +99 -0
  73. package/dist/services/config.js.map +1 -0
  74. package/dist/services/index.d.ts +8 -0
  75. package/dist/services/index.d.ts.map +1 -0
  76. package/dist/services/index.js +8 -0
  77. package/dist/services/index.js.map +1 -0
  78. package/dist/services/project.d.ts +17 -0
  79. package/dist/services/project.d.ts.map +1 -0
  80. package/dist/services/project.js +27 -0
  81. package/dist/services/project.js.map +1 -0
  82. package/dist/services/test-case.d.ts +59 -0
  83. package/dist/services/test-case.d.ts.map +1 -0
  84. package/dist/services/test-case.js +138 -0
  85. package/dist/services/test-case.js.map +1 -0
  86. package/dist/services/test-plan.d.ts +20 -0
  87. package/dist/services/test-plan.d.ts.map +1 -0
  88. package/dist/services/test-plan.js +18 -0
  89. package/dist/services/test-plan.js.map +1 -0
  90. package/dist/services/testops-client.d.ts +96 -0
  91. package/dist/services/testops-client.d.ts.map +1 -0
  92. package/dist/services/testops-client.js +392 -0
  93. package/dist/services/testops-client.js.map +1 -0
  94. package/dist/services/testops-types.d.ts +62 -0
  95. package/dist/services/testops-types.d.ts.map +1 -0
  96. package/dist/services/testops-types.js +3 -0
  97. package/dist/services/testops-types.js.map +1 -0
  98. package/dist/shared/api.d.ts +39 -0
  99. package/dist/shared/api.d.ts.map +1 -0
  100. package/dist/shared/api.js +94 -0
  101. package/dist/shared/api.js.map +1 -0
  102. package/dist/shared/index.d.ts +4 -0
  103. package/dist/shared/index.d.ts.map +1 -0
  104. package/dist/shared/index.js +4 -0
  105. package/dist/shared/index.js.map +1 -0
  106. package/dist/shared/pagination.d.ts +37 -0
  107. package/dist/shared/pagination.d.ts.map +1 -0
  108. package/dist/shared/pagination.js +40 -0
  109. package/dist/shared/pagination.js.map +1 -0
  110. package/dist/shared/result.d.ts +39 -0
  111. package/dist/shared/result.d.ts.map +1 -0
  112. package/dist/shared/result.js +34 -0
  113. package/dist/shared/result.js.map +1 -0
  114. package/dist/tools/index.d.ts +8 -0
  115. package/dist/tools/index.d.ts.map +1 -0
  116. package/dist/tools/index.js +8 -0
  117. package/dist/tools/index.js.map +1 -0
  118. package/dist/tools/project.d.ts +5 -0
  119. package/dist/tools/project.d.ts.map +1 -0
  120. package/dist/tools/project.js +62 -0
  121. package/dist/tools/project.js.map +1 -0
  122. package/dist/tools/test-case.d.ts +5 -0
  123. package/dist/tools/test-case.d.ts.map +1 -0
  124. package/dist/tools/test-case.js +185 -0
  125. package/dist/tools/test-case.js.map +1 -0
  126. package/dist/tools/test-plan.d.ts +5 -0
  127. package/dist/tools/test-plan.d.ts.map +1 -0
  128. package/dist/tools/test-plan.js +57 -0
  129. package/dist/tools/test-plan.js.map +1 -0
  130. package/dist/tools/testops.d.ts +6 -0
  131. package/dist/tools/testops.d.ts.map +1 -0
  132. package/dist/tools/testops.js +302 -0
  133. package/dist/tools/testops.js.map +1 -0
  134. package/package.json +50 -0
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # TestOps MCP Server
2
+
3
+ Model Context Protocol server for TestOps 5.25
4
+
5
+ Package: `@syn7xx/testops-mcp-server`
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @syn7xx/testops-mcp-server
11
+ ```
12
+
13
+ Or use directly via npx:
14
+
15
+ ```bash
16
+ npx @syn7xx/testops-mcp-server --url <testops-url> --token <api-token>
17
+ ```
18
+
19
+ ## Build
20
+
21
+ ```bash
22
+ npm run build
23
+ ```
24
+
25
+ ## Run
26
+
27
+ ```bash
28
+ npm start -- --url <testops-url> --token <api-token>
29
+ ```
30
+
31
+ Or with npx (if not installed globally):
32
+
33
+ ```bash
34
+ npx @syn7xx/testops-mcp-server --url <testops-url> --token <api-token>
35
+ ```
36
+
37
+ ## Tools
38
+
39
+ ### Project
40
+ | Tool | Description |
41
+ |------|-------------|
42
+ | `project_list` | List projects with pagination |
43
+ | `project_find_by_name` | Find project by exact or partial name match |
44
+ | `project_get_by_id` | Get project by ID |
45
+
46
+ ### Test Plan
47
+ | Tool | Description |
48
+ |------|-------------|
49
+ | `testplan_get` | Get test plan by ID |
50
+ | `testplan_get_test_cases` | Get test cases from test plan with pagination |
51
+
52
+ ### Test Case
53
+ | Tool | Description |
54
+ |------|-------------|
55
+ | `testcase_get` | Get test case by ID |
56
+ | `testcase_get_detail` | Get test case with steps and custom fields |
57
+ | `testcase_get_scenario` | Get scenario (steps and expected results) |
58
+ | `testcase_update_step` | Update a step in scenario |
59
+ | `testcase_set_scenario` | Replace all steps in scenario |
60
+ | `testcase_get_custom_fields` | Get custom field values |
61
+ | `testcase_update_custom_fields` | Update custom field values |
62
+ | `testcase_search_by_aql` | Search test cases using AQL |
63
+
64
+ ## Project Structure
65
+
66
+ ```
67
+ src/
68
+ ├── shared/ # Utilities (Result, pagination, API client)
69
+ ├── domain/ # Business logic (project, test-plan, test-case)
70
+ ├── presentation/ # MCP tools
71
+ ├── index.ts # Entry point
72
+ └── server.ts # MCP server configuration
73
+ ```
74
+
75
+ <details>
76
+ <summary><b>Configuration in AI Editors</b> (click to expand)</summary>
77
+
78
+ Use `@syn7xx/testops-mcp-server` package:
79
+
80
+ ```bash
81
+ npm install -g @syn7xx/testops-mcp-server
82
+ ```
83
+
84
+ ### Cursor
85
+
86
+ Add to `~/.cursor/mcp.json` or project `.cursor/mcp.json`:
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "testops": {
92
+ "command": "npx",
93
+ "args": ["@syn7xx/testops-mcp-server", "--url", "https://your-testops.com", "--token", "your-token"]
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ ### Windsurf (Codeium)
100
+
101
+ Add to `~/.config/windsurf/mcp.json` or project `.windsurf/mcp.json`:
102
+
103
+ ```json
104
+ {
105
+ "mcpServers": {
106
+ "testops": {
107
+ "command": "npx",
108
+ "args": ["@syn7xx/testops-mcp-server", "--url", "https://your-testops.com", "--token", "your-token"]
109
+ }
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### Kilo Code
115
+
116
+ Add to `~/.kilocode/mcp.json` or project `.kilocode/mcp.json`:
117
+
118
+ ```json
119
+ {
120
+ "mcpServers": {
121
+ "testops": {
122
+ "command": "npx",
123
+ "args": ["@syn7xx/testops-mcp-server", "--url", "https://your-testops.com", "--token", "your-token"]
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ ### OpenCode
130
+
131
+ Add to `~/.opencode/mcp.json` or project `.opencode/mcp.json`:
132
+
133
+ ```json
134
+ {
135
+ "mcpServers": {
136
+ "testops": {
137
+ "command": "npx",
138
+ "args": ["@syn7xx/testops-mcp-server", "--url", "https://your-testops.com", "--token", "your-token"]
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### Claude Desktop
145
+
146
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
147
+
148
+ ```json
149
+ {
150
+ "mcpServers": {
151
+ "testops": {
152
+ "command": "npx",
153
+ "args": ["@syn7xx/testops-mcp-server", "--url", "https://your-testops.com", "--token", "your-token"]
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ ### Zed
160
+
161
+ Add to `~/.config/zed/mcp.json`:
162
+
163
+ ```json
164
+ {
165
+ "mcpServers": {
166
+ "testops": {
167
+ "command": "npx",
168
+ "args": ["@syn7xx/testops-mcp-server", "--url", "https://your-testops.com", "--token", "your-token"]
169
+ }
170
+ }
171
+ }
172
+ ```
173
+ </details>
174
+
175
+ ## License
176
+
177
+ MIT
package/dist/args.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export type TestOpsServerArgs = {
2
+ url: string;
3
+ token: string;
4
+ };
5
+ /**
6
+ * Parse process args: --url <base> --token <apitoken>
7
+ * Base URL is stored without a trailing slash.
8
+ */
9
+ export declare function parseTestOpsServerArgs(argv: string[]): TestOpsServerArgs;
10
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAwBxE"}
package/dist/args.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Parse process args: --url <base> --token <apitoken>
3
+ * Base URL is stored without a trailing slash.
4
+ */
5
+ export function parseTestOpsServerArgs(argv) {
6
+ const raw = argv.slice(2);
7
+ let url;
8
+ let token;
9
+ for (let i = 0; i < raw.length; i++) {
10
+ if (raw[i] === '--url' && raw[i + 1] !== undefined) {
11
+ url = raw[++i];
12
+ }
13
+ else if (raw[i] === '--token' && raw[i + 1] !== undefined) {
14
+ token = raw[++i];
15
+ }
16
+ }
17
+ if (!url?.trim() || !token?.trim()) {
18
+ console.error('Required: --url <TESTOPS_BASE_URL> --token <API_TOKEN>');
19
+ process.exit(1);
20
+ }
21
+ return {
22
+ url: url.replace(/\/+$/, ''),
23
+ token: token.trim(),
24
+ };
25
+ }
26
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAc;IACnD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,GAAuB,CAAC;IAC5B,IAAI,KAAyB,CAAC;IAE9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACnD,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACjB,CAAC;aAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5D,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CACX,wDAAwD,CACzD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC5B,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './project/index.js';
2
+ export * from './test-plan/index.js';
3
+ export * from './test-case/index.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './project/index.js';
2
+ export * from './test-plan/index.js';
3
+ export * from './test-case/index.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './service.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/project/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './service.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/project/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { Result } from '../../shared/result.js';
2
+ import { PageParams, type Paginated } from '../../shared/pagination.js';
3
+ import type { Project } from './types.js';
4
+ /**
5
+ * Find all projects with pagination
6
+ * @param params - Pagination parameters (page, size, sort)
7
+ * @returns Paginated list of projects
8
+ */
9
+ export declare const findProjects: (params?: PageParams) => Promise<Result<Paginated<Project>, Error>>;
10
+ /**
11
+ * Find a project by name using suggest API
12
+ * Tries exact match first, then partial match
13
+ * @param name - Project name to search
14
+ * @returns Project if found, null otherwise
15
+ */
16
+ export declare const findProjectByName: (name: string) => Promise<Result<Project | null, Error>>;
17
+ /**
18
+ * Get a single project by ID
19
+ * @param id - Project ID
20
+ * @returns Project details
21
+ */
22
+ export declare const getProjectById: (id: number) => Promise<Result<Project, Error>>;
23
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/domain/project/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAO,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAwC,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC9G,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,YAAY,CAAC;AAS7D;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAU,SAAS,UAAU,KAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAiBjG,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,EAAE,KAAK,CAAC,CAsB3F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAU,IAAI,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAG/E,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { apiGet } from '../../shared/api.js';
2
+ import { map } from '../../shared/result.js';
3
+ import { normalizePageParams, createPaginated } from '../../shared/pagination.js';
4
+ /**
5
+ * Find all projects with pagination
6
+ * @param params - Pagination parameters (page, size, sort)
7
+ * @returns Paginated list of projects
8
+ */
9
+ export const findProjects = async (params) => {
10
+ const { page, size, sort } = normalizePageParams(params);
11
+ const response = await apiGet('/api/project', {
12
+ page,
13
+ size,
14
+ sort,
15
+ });
16
+ return map(response, (data) => createPaginated(data.content ?? [], data.number ?? page, data.size ?? size, data.totalElements));
17
+ };
18
+ /**
19
+ * Find a project by name using suggest API
20
+ * Tries exact match first, then partial match
21
+ * @param name - Project name to search
22
+ * @returns Project if found, null otherwise
23
+ */
24
+ export const findProjectByName = async (name) => {
25
+ const response = await apiGet('/api/project/suggest', {
26
+ query: name,
27
+ size: 10,
28
+ });
29
+ return map(response, (data) => {
30
+ const suggestions = data.content ?? [];
31
+ if (!suggestions.length)
32
+ return null;
33
+ // Exact match
34
+ const exact = suggestions.find((s) => s.name.toLowerCase() === name.toLowerCase());
35
+ if (exact)
36
+ return { id: exact.id, name: exact.name };
37
+ // Partial match
38
+ const partial = suggestions.find((s) => s.name.toLowerCase().includes(name.toLowerCase()));
39
+ return partial ? { id: partial.id, name: partial.name } : null;
40
+ });
41
+ };
42
+ /**
43
+ * Get a single project by ID
44
+ * @param id - Project ID
45
+ * @returns Project details
46
+ */
47
+ export const getProjectById = async (id) => {
48
+ const response = await apiGet(`/api/project/${id}`);
49
+ return map(response, (project) => project);
50
+ };
51
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/domain/project/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAU,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAc,mBAAmB,EAAE,eAAe,EAAkB,MAAM,4BAA4B,CAAC;AAU9G;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,MAAmB,EAA8C,EAAE;IAClG,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAwB,cAAc,EAAE;QACjE,IAAI;QACJ,IAAI;QACJ,IAAI;KACP,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAC1B,eAAe,CACX,IAAI,CAAC,OAAO,IAAI,EAAE,EAClB,IAAI,CAAC,MAAM,IAAI,IAAI,EACnB,IAAI,CAAC,IAAI,IAAI,IAAI,EACjB,IAAI,CAAC,aAAa,CACrB,CACJ,CAAC;AACN,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,IAAY,EAA0C,EAAE;IAC5F,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAkC,sBAAsB,EAAE;QACnF,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,EAAE;KACX,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAErC,cAAc;QACd,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CACrD,CAAC;QACF,IAAI,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QAErD,gBAAgB;QAChB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACnC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CACpD,CAAC;QACF,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,EAAU,EAAmC,EAAE;IAChF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAU,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC7D,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;AAC/C,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Project Domain - Types
3
+ */
4
+ export interface Project {
5
+ id: number;
6
+ name: string;
7
+ }
8
+ export interface ProjectSuggestion {
9
+ id: number;
10
+ name: string;
11
+ }
12
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/domain/project/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Project Domain - Types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/project/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './service.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/test-case/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './service.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/test-case/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { Result } from '../../shared/result.js';
2
+ import { PageParams } from '../../shared/pagination.js';
3
+ import type { TestCase, TestCaseDetail, NormalizedScenario, CustomFieldWithValues, TestCaseSearchResult } from './types.js';
4
+ /**
5
+ * Get a test case by ID
6
+ * @param id - Test case ID
7
+ * @returns Basic test case info
8
+ */
9
+ export declare const getTestCase: (id: number) => Promise<Result<TestCase, Error>>;
10
+ /**
11
+ * Get detailed test case with steps and custom fields
12
+ * Fetches additional data in parallel for performance
13
+ * @param id - Test case ID
14
+ * @returns Full test case details
15
+ */
16
+ export declare const getTestCaseDetail: (id: number) => Promise<Result<TestCaseDetail, Error>>;
17
+ /**
18
+ * Get scenario (steps and expected results) for a test case
19
+ * @param testCaseId - Test case ID
20
+ * @returns Normalized scenario structure
21
+ */
22
+ export declare const getTestCaseScenario: (testCaseId: number) => Promise<Result<NormalizedScenario, Error>>;
23
+ /**
24
+ * Update a single step in the scenario
25
+ * @param testCaseId - Test case ID
26
+ * @param stepId - Step ID to update
27
+ * @param data - Step data (body and/or expectedResult)
28
+ * @returns Updated scenario
29
+ */
30
+ export declare const updateScenarioStep: (testCaseId: number, stepId: number, data: {
31
+ body?: string;
32
+ expectedResult?: string;
33
+ }) => Promise<Result<NormalizedScenario, Error>>;
34
+ /**
35
+ * Replace entire scenario with new steps
36
+ * @param testCaseId - Test case ID
37
+ * @param steps - Array of steps with actions and expected results
38
+ * @returns Updated scenario
39
+ */
40
+ export declare const setTestCaseScenario: (testCaseId: number, steps: Array<{
41
+ action: string;
42
+ expectedResult?: string;
43
+ }>) => Promise<Result<NormalizedScenario, Error>>;
44
+ /**
45
+ * Get custom field values for a test case
46
+ * @param testCaseId - Test case ID
47
+ * @returns Custom fields with their values
48
+ */
49
+ export declare const getTestCaseCustomFields: (testCaseId: number) => Promise<Result<CustomFieldWithValues[], Error>>;
50
+ /**
51
+ * Update custom field values for a test case
52
+ * @param testCaseId - Test case ID
53
+ * @param fields - Array of custom field updates (fieldId + valueIds)
54
+ */
55
+ export declare const updateTestCaseCustomFields: (testCaseId: number, fields: Array<{
56
+ customFieldId: number;
57
+ valueIds: number[];
58
+ }>) => Promise<Result<void, Error>>;
59
+ /**
60
+ * Search test cases using AQL (Advanced Query Language)
61
+ * @param projectId - Project ID
62
+ * @param rql - AQL query string
63
+ * @param params - Pagination and options
64
+ * @returns Search results with pagination info
65
+ */
66
+ export declare const searchTestCasesByAQL: (projectId: number, rql: string, params?: PageParams & {
67
+ deleted?: boolean;
68
+ }) => Promise<Result<TestCaseSearchResult, Error>>;
69
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/domain/test-case/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAA2B,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAuC,MAAM,4BAA4B,CAAC;AAC7F,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAS5H;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAU,IAAI,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAE7E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAU,IAAI,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,CAmCzF,CAAC;AAoBF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC5B,YAAY,MAAM,KACnB,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAE3C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC3B,YAAY,MAAM,EAClB,QAAQ,MAAM,EACd,MAAM;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,KACjD,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAU3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC5B,YAAY,MAAM,EAClB,OAAO,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,KAC1D,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAY3C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAChC,YAAY,MAAM,KACnB,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,EAAE,KAAK,CAAC,CAEhD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GACnC,YAAY,MAAM,EAClB,QAAQ,KAAK,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,KAC7D,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAG7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC7B,WAAW,MAAM,EACjB,KAAK,MAAM,EACX,SAAS,UAAU,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,KAC5C,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAqB7C,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { apiGet, apiPatch, apiPost } from '../../shared/api.js';
2
+ import { map, isSuccess, success } from '../../shared/result.js';
3
+ import { normalizePageParams } from '../../shared/pagination.js';
4
+ /**
5
+ * Get a test case by ID
6
+ * @param id - Test case ID
7
+ * @returns Basic test case info
8
+ */
9
+ export const getTestCase = async (id) => {
10
+ return apiGet(`/api/testcase/${id}`);
11
+ };
12
+ /**
13
+ * Get detailed test case with steps and custom fields
14
+ * Fetches additional data in parallel for performance
15
+ * @param id - Test case ID
16
+ * @returns Full test case details
17
+ */
18
+ export const getTestCaseDetail = async (id) => {
19
+ const testCaseResult = await apiGet(`/api/testcase/${id}`);
20
+ if (!isSuccess(testCaseResult)) {
21
+ return testCaseResult;
22
+ }
23
+ const testCase = testCaseResult.value;
24
+ // Fetch additional data in parallel
25
+ const [scenarioResult, cfResult] = await Promise.all([
26
+ getTestCaseScenario(id),
27
+ getTestCaseCustomFields(id),
28
+ ]);
29
+ const steps = isSuccess(scenarioResult)
30
+ ? extractStepsFromScenario(scenarioResult.value)
31
+ : [];
32
+ const customFields = isSuccess(cfResult)
33
+ ? cfResult.value.reduce((acc, cf) => {
34
+ if (cf.values.length > 0) {
35
+ acc[cf.customField.name] = cf.values[0].name;
36
+ }
37
+ return acc;
38
+ }, {})
39
+ : {};
40
+ return success({
41
+ ...testCase,
42
+ steps,
43
+ customFields,
44
+ tags: testCase.tags?.map((t) => t.name) ?? [],
45
+ owner: testCase.createdBy ?? '',
46
+ });
47
+ };
48
+ /** Extract step bodies from normalized scenario */
49
+ const extractStepsFromScenario = (scenario) => {
50
+ const steps = [];
51
+ if (!scenario.scenarioSteps || !scenario.root?.children) {
52
+ return steps;
53
+ }
54
+ for (const stepId of scenario.root.children) {
55
+ const step = scenario.scenarioSteps[stepId];
56
+ if (step?.body) {
57
+ steps.push(step.body);
58
+ }
59
+ }
60
+ return steps;
61
+ };
62
+ /**
63
+ * Get scenario (steps and expected results) for a test case
64
+ * @param testCaseId - Test case ID
65
+ * @returns Normalized scenario structure
66
+ */
67
+ export const getTestCaseScenario = async (testCaseId) => {
68
+ return apiGet(`/api/testcase/${testCaseId}/step`);
69
+ };
70
+ /**
71
+ * Update a single step in the scenario
72
+ * @param testCaseId - Test case ID
73
+ * @param stepId - Step ID to update
74
+ * @param data - Step data (body and/or expectedResult)
75
+ * @returns Updated scenario
76
+ */
77
+ export const updateScenarioStep = async (testCaseId, stepId, data) => {
78
+ const body = {};
79
+ if (data.body !== undefined)
80
+ body.body = data.body;
81
+ if (data.expectedResult !== undefined)
82
+ body.expectedResult = data.expectedResult;
83
+ return apiPatch(`/api/testcase/step/${stepId}`, body, { withExpectedResult: true });
84
+ };
85
+ /**
86
+ * Replace entire scenario with new steps
87
+ * @param testCaseId - Test case ID
88
+ * @param steps - Array of steps with actions and expected results
89
+ * @returns Updated scenario
90
+ */
91
+ export const setTestCaseScenario = async (testCaseId, steps) => {
92
+ const scenarioData = {
93
+ steps: steps.map((s) => ({
94
+ action: s.action,
95
+ expectedResult: s.expectedResult ?? '',
96
+ })),
97
+ };
98
+ return apiPost(`/api/testcase/${testCaseId}/scenario`, scenarioData);
99
+ };
100
+ /**
101
+ * Get custom field values for a test case
102
+ * @param testCaseId - Test case ID
103
+ * @returns Custom fields with their values
104
+ */
105
+ export const getTestCaseCustomFields = async (testCaseId) => {
106
+ return apiGet(`/api/testcase/${testCaseId}/cfv`);
107
+ };
108
+ /**
109
+ * Update custom field values for a test case
110
+ * @param testCaseId - Test case ID
111
+ * @param fields - Array of custom field updates (fieldId + valueIds)
112
+ */
113
+ export const updateTestCaseCustomFields = async (testCaseId, fields) => {
114
+ const result = await apiPatch(`/api/testcase/${testCaseId}/cfv`, fields);
115
+ return map(result, () => undefined);
116
+ };
117
+ /**
118
+ * Search test cases using AQL (Advanced Query Language)
119
+ * @param projectId - Project ID
120
+ * @param rql - AQL query string
121
+ * @param params - Pagination and options
122
+ * @returns Search results with pagination info
123
+ */
124
+ export const searchTestCasesByAQL = async (projectId, rql, params) => {
125
+ const { page, size, sort } = normalizePageParams(params);
126
+ const response = await apiGet('/api/testcase/__search', {
127
+ projectId,
128
+ rql,
129
+ deleted: params?.deleted,
130
+ page,
131
+ size,
132
+ sort,
133
+ });
134
+ return map(response, (data) => ({
135
+ testCases: data.content ?? [],
136
+ total: data.totalElements ?? 0,
137
+ page: data.number ?? page,
138
+ size: data.size ?? size,
139
+ }));
140
+ };
141
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/domain/test-case/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * TestCase Domain - Types
3
+ */
4
+ export interface TestCase {
5
+ id: number;
6
+ name: string;
7
+ description?: string;
8
+ createdBy?: string;
9
+ tags?: Array<{
10
+ name: string;
11
+ }>;
12
+ }
13
+ export interface TestCaseDetail {
14
+ id: number;
15
+ name: string;
16
+ description?: string;
17
+ createdBy?: string;
18
+ steps: string[];
19
+ customFields: Record<string, string>;
20
+ tags: string[];
21
+ owner: string;
22
+ }
23
+ export interface ScenarioStep {
24
+ id: number;
25
+ body?: string;
26
+ children?: number[];
27
+ expectedResultId?: number;
28
+ }
29
+ export interface NormalizedScenario {
30
+ scenarioSteps: Record<number, ScenarioStep>;
31
+ root: {
32
+ children: number[];
33
+ };
34
+ }
35
+ export interface CustomFieldWithValues {
36
+ customField: {
37
+ id: number;
38
+ name: string;
39
+ };
40
+ values: Array<{
41
+ id: number;
42
+ name: string;
43
+ }>;
44
+ }
45
+ export interface TestCaseSearchResult {
46
+ testCases: TestCase[];
47
+ total: number;
48
+ page: number;
49
+ size: number;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map