@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.
- package/README.md +177 -0
- package/dist/args.d.ts +10 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +26 -0
- package/dist/args.js.map +1 -0
- package/dist/domain/index.d.ts +4 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +4 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/project/index.d.ts +3 -0
- package/dist/domain/project/index.d.ts.map +1 -0
- package/dist/domain/project/index.js +3 -0
- package/dist/domain/project/index.js.map +1 -0
- package/dist/domain/project/service.d.ts +23 -0
- package/dist/domain/project/service.d.ts.map +1 -0
- package/dist/domain/project/service.js +51 -0
- package/dist/domain/project/service.js.map +1 -0
- package/dist/domain/project/types.d.ts +12 -0
- package/dist/domain/project/types.d.ts.map +1 -0
- package/dist/domain/project/types.js +5 -0
- package/dist/domain/project/types.js.map +1 -0
- package/dist/domain/test-case/index.d.ts +3 -0
- package/dist/domain/test-case/index.d.ts.map +1 -0
- package/dist/domain/test-case/index.js +3 -0
- package/dist/domain/test-case/index.js.map +1 -0
- package/dist/domain/test-case/service.d.ts +69 -0
- package/dist/domain/test-case/service.d.ts.map +1 -0
- package/dist/domain/test-case/service.js +141 -0
- package/dist/domain/test-case/service.js.map +1 -0
- package/dist/domain/test-case/types.d.ts +51 -0
- package/dist/domain/test-case/types.d.ts.map +1 -0
- package/dist/domain/test-case/types.js +5 -0
- package/dist/domain/test-case/types.js.map +1 -0
- package/dist/domain/test-plan/index.d.ts +3 -0
- package/dist/domain/test-plan/index.d.ts.map +1 -0
- package/dist/domain/test-plan/index.js +3 -0
- package/dist/domain/test-plan/index.js.map +1 -0
- package/dist/domain/test-plan/service.d.ts +33 -0
- package/dist/domain/test-plan/service.d.ts.map +1 -0
- package/dist/domain/test-plan/service.js +40 -0
- package/dist/domain/test-plan/service.js.map +1 -0
- package/dist/domain/test-plan/types.d.ts +18 -0
- package/dist/domain/test-plan/types.d.ts.map +1 -0
- package/dist/domain/test-plan/types.js +5 -0
- package/dist/domain/test-plan/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/index.d.ts +4 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +4 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/project/tools.d.ts +2 -0
- package/dist/presentation/project/tools.d.ts.map +1 -0
- package/dist/presentation/project/tools.js +61 -0
- package/dist/presentation/project/tools.js.map +1 -0
- package/dist/presentation/test-case/tools.d.ts +2 -0
- package/dist/presentation/test-case/tools.d.ts.map +1 -0
- package/dist/presentation/test-case/tools.js +139 -0
- package/dist/presentation/test-case/tools.js.map +1 -0
- package/dist/presentation/test-plan/tools.d.ts +2 -0
- package/dist/presentation/test-plan/tools.d.ts.map +1 -0
- package/dist/presentation/test-plan/tools.js +46 -0
- package/dist/presentation/test-plan/tools.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +32 -0
- package/dist/server.js.map +1 -0
- package/dist/services/config.d.ts +43 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +99 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +8 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/project.d.ts +17 -0
- package/dist/services/project.d.ts.map +1 -0
- package/dist/services/project.js +27 -0
- package/dist/services/project.js.map +1 -0
- package/dist/services/test-case.d.ts +59 -0
- package/dist/services/test-case.d.ts.map +1 -0
- package/dist/services/test-case.js +138 -0
- package/dist/services/test-case.js.map +1 -0
- package/dist/services/test-plan.d.ts +20 -0
- package/dist/services/test-plan.d.ts.map +1 -0
- package/dist/services/test-plan.js +18 -0
- package/dist/services/test-plan.js.map +1 -0
- package/dist/services/testops-client.d.ts +96 -0
- package/dist/services/testops-client.d.ts.map +1 -0
- package/dist/services/testops-client.js +392 -0
- package/dist/services/testops-client.js.map +1 -0
- package/dist/services/testops-types.d.ts +62 -0
- package/dist/services/testops-types.d.ts.map +1 -0
- package/dist/services/testops-types.js +3 -0
- package/dist/services/testops-types.js.map +1 -0
- package/dist/shared/api.d.ts +39 -0
- package/dist/shared/api.d.ts.map +1 -0
- package/dist/shared/api.js +94 -0
- package/dist/shared/api.js.map +1 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/pagination.d.ts +37 -0
- package/dist/shared/pagination.d.ts.map +1 -0
- package/dist/shared/pagination.js +40 -0
- package/dist/shared/pagination.js.map +1 -0
- package/dist/shared/result.d.ts +39 -0
- package/dist/shared/result.d.ts.map +1 -0
- package/dist/shared/result.js +34 -0
- package/dist/shared/result.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/project.d.ts +5 -0
- package/dist/tools/project.d.ts.map +1 -0
- package/dist/tools/project.js +62 -0
- package/dist/tools/project.js.map +1 -0
- package/dist/tools/test-case.d.ts +5 -0
- package/dist/tools/test-case.d.ts.map +1 -0
- package/dist/tools/test-case.js +185 -0
- package/dist/tools/test-case.js.map +1 -0
- package/dist/tools/test-plan.d.ts +5 -0
- package/dist/tools/test-plan.d.ts.map +1 -0
- package/dist/tools/test-plan.js +57 -0
- package/dist/tools/test-plan.js.map +1 -0
- package/dist/tools/testops.d.ts +6 -0
- package/dist/tools/testops.d.ts.map +1 -0
- package/dist/tools/testops.js +302 -0
- package/dist/tools/testops.js.map +1 -0
- 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
|
package/dist/args.js.map
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/project/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -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 @@
|
|
|
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
|