@syn7xx/testops-mcp-server 0.1.2 → 0.1.5
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/CHANGELOG.md +55 -0
- package/README.md +147 -89
- package/dist/args.d.ts +2 -3
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +57 -19
- package/dist/args.js.map +1 -1
- package/dist/domain/project/service.d.ts.map +1 -1
- package/dist/domain/project/service.js +1 -1
- package/dist/domain/project/service.js.map +1 -1
- package/dist/domain/project/types.d.ts.map +1 -1
- package/dist/domain/test-case/service.d.ts +13 -1
- package/dist/domain/test-case/service.d.ts.map +1 -1
- package/dist/domain/test-case/service.js +22 -6
- package/dist/domain/test-case/service.js.map +1 -1
- package/dist/domain/test-case/types.d.ts +17 -0
- package/dist/domain/test-case/types.d.ts.map +1 -1
- package/dist/domain/test-plan/service.d.ts.map +1 -1
- package/dist/domain/test-plan/service.js +1 -1
- package/dist/domain/test-plan/service.js.map +1 -1
- package/dist/domain/test-plan/types.d.ts.map +1 -1
- package/dist/presentation/project/tools.d.ts +2 -1
- package/dist/presentation/project/tools.d.ts.map +1 -1
- package/dist/presentation/project/tools.js +30 -8
- package/dist/presentation/project/tools.js.map +1 -1
- package/dist/presentation/test-case/tools.d.ts +2 -1
- package/dist/presentation/test-case/tools.d.ts.map +1 -1
- package/dist/presentation/test-case/tools.js +138 -32
- package/dist/presentation/test-case/tools.js.map +1 -1
- package/dist/presentation/test-plan/tools.d.ts +2 -1
- package/dist/presentation/test-plan/tools.d.ts.map +1 -1
- package/dist/presentation/test-plan/tools.js +17 -5
- package/dist/presentation/test-plan/tools.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +8 -5
- package/dist/server.js.map +1 -1
- package/dist/shared/api.d.ts +2 -4
- package/dist/shared/api.d.ts.map +1 -1
- package/dist/shared/api.js +34 -31
- package/dist/shared/api.js.map +1 -1
- package/dist/shared/pagination.d.ts.map +1 -1
- package/dist/shared/pagination.js.map +1 -1
- package/dist/shared/result.d.ts.map +1 -1
- package/dist/shared/result.js +7 -4
- package/dist/shared/result.js.map +1 -1
- package/package.json +18 -4
- package/dist/services/config.d.ts +0 -43
- package/dist/services/config.d.ts.map +0 -1
- package/dist/services/config.js +0 -99
- package/dist/services/config.js.map +0 -1
- package/dist/services/index.d.ts +0 -8
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -8
- package/dist/services/index.js.map +0 -1
- package/dist/services/project.d.ts +0 -17
- package/dist/services/project.d.ts.map +0 -1
- package/dist/services/project.js +0 -27
- package/dist/services/project.js.map +0 -1
- package/dist/services/test-case.d.ts +0 -59
- package/dist/services/test-case.d.ts.map +0 -1
- package/dist/services/test-case.js +0 -138
- package/dist/services/test-case.js.map +0 -1
- package/dist/services/test-plan.d.ts +0 -20
- package/dist/services/test-plan.d.ts.map +0 -1
- package/dist/services/test-plan.js +0 -18
- package/dist/services/test-plan.js.map +0 -1
- package/dist/services/testops-client.d.ts +0 -96
- package/dist/services/testops-client.d.ts.map +0 -1
- package/dist/services/testops-client.js +0 -392
- package/dist/services/testops-client.js.map +0 -1
- package/dist/services/testops-types.d.ts +0 -62
- package/dist/services/testops-types.d.ts.map +0 -1
- package/dist/services/testops-types.js +0 -3
- package/dist/services/testops-types.js.map +0 -1
- package/dist/tools/index.d.ts +0 -8
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -8
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/project.d.ts +0 -5
- package/dist/tools/project.d.ts.map +0 -1
- package/dist/tools/project.js +0 -62
- package/dist/tools/project.js.map +0 -1
- package/dist/tools/test-case.d.ts +0 -5
- package/dist/tools/test-case.d.ts.map +0 -1
- package/dist/tools/test-case.js +0 -185
- package/dist/tools/test-case.js.map +0 -1
- package/dist/tools/test-plan.d.ts +0 -5
- package/dist/tools/test-plan.d.ts.map +0 -1
- package/dist/tools/test-plan.js +0 -57
- package/dist/tools/test-plan.js.map +0 -1
- package/dist/tools/testops.d.ts +0 -6
- package/dist/tools/testops.d.ts.map +0 -1
- package/dist/tools/testops.js +0 -302
- package/dist/tools/testops.js.map +0 -1
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TestOps Test Case Service
|
|
3
|
-
*/
|
|
4
|
-
import { testopsGet, testopsPost, testopsPatch } from './config.js';
|
|
5
|
-
/**
|
|
6
|
-
* Loads scenario step bodies for a test case.
|
|
7
|
-
*/
|
|
8
|
-
async function getTestOpsTestCaseSteps(testCaseId) {
|
|
9
|
-
const data = await testopsGet(`/api/testcase/${testCaseId}/step`);
|
|
10
|
-
if (data?.scenarioSteps && data.root?.children) {
|
|
11
|
-
const steps = [];
|
|
12
|
-
for (const stepId of data.root.children) {
|
|
13
|
-
const step = data.scenarioSteps[stepId];
|
|
14
|
-
if (step?.body) {
|
|
15
|
-
steps.push({ body: step.body });
|
|
16
|
-
const { expectedResultId } = step;
|
|
17
|
-
if (expectedResultId && data.scenarioSteps[expectedResultId]) {
|
|
18
|
-
const expectedNode = data.scenarioSteps[expectedResultId];
|
|
19
|
-
const expectedChildren = Array.isArray(expectedNode.children)
|
|
20
|
-
? expectedNode.children
|
|
21
|
-
: [];
|
|
22
|
-
for (const childId of expectedChildren) {
|
|
23
|
-
const child = data.scenarioSteps[childId];
|
|
24
|
-
if (child?.body) {
|
|
25
|
-
steps.push({ body: child.body });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return steps;
|
|
32
|
-
}
|
|
33
|
-
return [];
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Loads custom field values for a test case.
|
|
37
|
-
*/
|
|
38
|
-
async function getTestOpsCustomFields(testCaseId) {
|
|
39
|
-
const data = await testopsGet(`/api/testcase/${testCaseId}/cfv`);
|
|
40
|
-
return Array.isArray(data) ? data : [];
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Returns test case metadata plus flattened steps and custom fields when available.
|
|
44
|
-
*/
|
|
45
|
-
export async function getTestOpsTestCaseDetail(testCaseId) {
|
|
46
|
-
const detail = await testopsGet(`/api/testcase/${testCaseId}`);
|
|
47
|
-
try {
|
|
48
|
-
const [steps, customFields] = await Promise.all([
|
|
49
|
-
getTestOpsTestCaseSteps(testCaseId),
|
|
50
|
-
getTestOpsCustomFields(testCaseId),
|
|
51
|
-
]);
|
|
52
|
-
const stepsArray = steps.map(({ body }) => body);
|
|
53
|
-
const customFieldsObject = customFields.reduce((acc, field) => {
|
|
54
|
-
acc[field.customField.name] = field.name;
|
|
55
|
-
return acc;
|
|
56
|
-
}, {});
|
|
57
|
-
return {
|
|
58
|
-
id: detail.id,
|
|
59
|
-
name: detail.name?.trim() || '',
|
|
60
|
-
steps: stepsArray,
|
|
61
|
-
customFields: customFieldsObject,
|
|
62
|
-
tags: (detail.tags || []).map((t) => t.name),
|
|
63
|
-
owner: detail.createdBy || '',
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
console.warn(`Could not load extra fields for test case ${testCaseId}: ${error}`);
|
|
68
|
-
}
|
|
69
|
-
return {
|
|
70
|
-
id: detail.id,
|
|
71
|
-
name: detail.name?.trim() || '',
|
|
72
|
-
steps: [],
|
|
73
|
-
customFields: {},
|
|
74
|
-
tags: (detail.tags || []).map((t) => t.name),
|
|
75
|
-
owner: detail.createdBy || '',
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Fetches scenario (steps + expected results) for a test case.
|
|
80
|
-
*/
|
|
81
|
-
export async function getTestOpsTestCaseScenario(testCaseId) {
|
|
82
|
-
return testopsGet(`/api/testcase/${testCaseId}/step`);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Updates a step (including expected result) for a test case.
|
|
86
|
-
*/
|
|
87
|
-
export async function patchTestOpsScenarioStep(testCaseId, stepId, stepData) {
|
|
88
|
-
const patchData = {};
|
|
89
|
-
if (stepData.body !== undefined)
|
|
90
|
-
patchData.body = stepData.body;
|
|
91
|
-
if (stepData.expectedResult !== undefined)
|
|
92
|
-
patchData.expectedResult = stepData.expectedResult;
|
|
93
|
-
return testopsPatch(`/api/testcase/step/${stepId}`, patchData, { withExpectedResult: true });
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Sets the entire scenario (all steps) for a test case.
|
|
97
|
-
*/
|
|
98
|
-
export async function setTestOpsTestCaseScenario(testCaseId, steps) {
|
|
99
|
-
const scenarioData = {
|
|
100
|
-
steps: steps.map((step) => ({
|
|
101
|
-
action: step.action,
|
|
102
|
-
expectedResult: step.expectedResult || '',
|
|
103
|
-
})),
|
|
104
|
-
};
|
|
105
|
-
return testopsPost(`/api/testcase/${testCaseId}/scenario`, scenarioData);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Fetches custom field values for a test case.
|
|
109
|
-
*/
|
|
110
|
-
export async function getTestOpsTestCaseCustomFields(testCaseId) {
|
|
111
|
-
return testopsGet(`/api/testcase/${testCaseId}/cfv`);
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Updates custom field values for a test case.
|
|
115
|
-
*/
|
|
116
|
-
export async function updateTestOpsTestCaseCustomFields(testCaseId, customFields) {
|
|
117
|
-
await testopsPatch(`/api/testcase/${testCaseId}/cfv`, customFields);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Searches test cases using AQL (Advanced Query Language).
|
|
121
|
-
*/
|
|
122
|
-
export async function searchTestCasesByAQL(projectId, rql, options) {
|
|
123
|
-
const data = await testopsGet('/api/testcase/__search', {
|
|
124
|
-
projectId,
|
|
125
|
-
rql,
|
|
126
|
-
deleted: options?.deleted,
|
|
127
|
-
page: options?.page,
|
|
128
|
-
size: options?.size,
|
|
129
|
-
sort: options?.sort,
|
|
130
|
-
});
|
|
131
|
-
return {
|
|
132
|
-
testCases: data.content || [],
|
|
133
|
-
total: data.totalElements || 0,
|
|
134
|
-
page: data.number || 0,
|
|
135
|
-
size: data.size || 0,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
//# sourceMappingURL=test-case.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-case.js","sourceRoot":"","sources":["../../src/services/test-case.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TestOps Test Plan Service
|
|
3
|
-
*/
|
|
4
|
-
import { TestOpsTestPlan } from './testops-types.js';
|
|
5
|
-
/**
|
|
6
|
-
* Fetches a test plan by ID.
|
|
7
|
-
*/
|
|
8
|
-
export declare function getTestOpsTestPlan(testPlanId: number): Promise<TestOpsTestPlan>;
|
|
9
|
-
/**
|
|
10
|
-
* Fetches test cases from a test plan.
|
|
11
|
-
*/
|
|
12
|
-
export declare function getTestOpsTestPlanTestCases(testPlanId: number, options?: {
|
|
13
|
-
page?: number;
|
|
14
|
-
size?: number;
|
|
15
|
-
sort?: string;
|
|
16
|
-
}): Promise<{
|
|
17
|
-
id: number;
|
|
18
|
-
name: string;
|
|
19
|
-
}[]>;
|
|
20
|
-
//# sourceMappingURL=test-plan.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-plan.d.ts","sourceRoot":"","sources":["../../src/services/test-plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAuB,MAAM,oBAAoB,CAAC;AAE1E;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAErF;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC7C,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACN,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB,GACF,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAMzC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TestOps Test Plan Service
|
|
3
|
-
*/
|
|
4
|
-
import { testopsGet } from './config.js';
|
|
5
|
-
/**
|
|
6
|
-
* Fetches a test plan by ID.
|
|
7
|
-
*/
|
|
8
|
-
export async function getTestOpsTestPlan(testPlanId) {
|
|
9
|
-
return testopsGet(`/api/testplan/${testPlanId}`);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Fetches test cases from a test plan.
|
|
13
|
-
*/
|
|
14
|
-
export async function getTestOpsTestPlanTestCases(testPlanId, options) {
|
|
15
|
-
const data = await testopsGet(`/api/testplan/${testPlanId}/tree/leaf`, { page: options?.page ?? 0, size: options?.size ?? 50, sort: options?.sort ?? 'name,ASC' });
|
|
16
|
-
return data.content || [];
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=test-plan.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-plan.js","sourceRoot":"","sources":["../../src/services/test-plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IACvD,OAAO,UAAU,CAAkB,iBAAiB,UAAU,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC7C,UAAkB,EAClB,OAIC;IAED,MAAM,IAAI,GAAG,MAAM,UAAU,CACzB,iBAAiB,UAAU,YAAY,EACvC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,CAC7F,CAAC;IACF,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { TestOpsProject, TestOpsTestPlan, TestOpsTestCase, TestOpsNormalizedScenario, TestOpsCustomFieldWithValues } from './testops-types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Sets the TestOps base URL and API token (from MCP process args).
|
|
4
|
-
*/
|
|
5
|
-
export declare function configureTestOpsClient(options: {
|
|
6
|
-
baseUrl: string;
|
|
7
|
-
token: string;
|
|
8
|
-
}): void;
|
|
9
|
-
/**
|
|
10
|
-
* Exchanges the API token for a JWT used on subsequent requests.
|
|
11
|
-
*/
|
|
12
|
-
export declare function getJwtToken(): Promise<string>;
|
|
13
|
-
/**
|
|
14
|
-
* Lists projects visible to the authenticated user.
|
|
15
|
-
*/
|
|
16
|
-
export declare function getTestOpsProjects(): Promise<TestOpsProject[]>;
|
|
17
|
-
/**
|
|
18
|
-
* Finds a project by exact name, then by substring match.
|
|
19
|
-
*/
|
|
20
|
-
export declare function getTestOpsProjectByName(projectName: string): Promise<TestOpsProject | null>;
|
|
21
|
-
/**
|
|
22
|
-
* Fetches a test plan by ID.
|
|
23
|
-
*/
|
|
24
|
-
export declare function getTestOpsTestPlan(testPlanId: number): Promise<TestOpsTestPlan>;
|
|
25
|
-
/**
|
|
26
|
-
* Returns leaf nodes of the test plan tree (typically test case references).
|
|
27
|
-
*/
|
|
28
|
-
export declare function getTestOpsTestPlanLeaves(testPlanId: number): Promise<{
|
|
29
|
-
id: number;
|
|
30
|
-
}[]>;
|
|
31
|
-
/**
|
|
32
|
-
* Returns test case metadata plus flattened steps and custom fields when available.
|
|
33
|
-
*/
|
|
34
|
-
export declare function getTestOpsTestCaseDetail(testCaseId: number): Promise<{
|
|
35
|
-
id: any;
|
|
36
|
-
name: any;
|
|
37
|
-
steps: string[];
|
|
38
|
-
customFields: Record<string, string>;
|
|
39
|
-
tags: any;
|
|
40
|
-
owner: any;
|
|
41
|
-
}>;
|
|
42
|
-
/**
|
|
43
|
-
* Fetches scenario (steps + expected results) for a test case.
|
|
44
|
-
*/
|
|
45
|
-
export declare function getTestOpsTestCaseScenario(testCaseId: number): Promise<TestOpsNormalizedScenario>;
|
|
46
|
-
/**
|
|
47
|
-
* Updates a step (including expected result) for a test case.
|
|
48
|
-
*/
|
|
49
|
-
export declare function patchTestOpsScenarioStep(testCaseId: number, stepId: number, stepData: {
|
|
50
|
-
body?: string;
|
|
51
|
-
expectedResult?: string;
|
|
52
|
-
}): Promise<TestOpsNormalizedScenario>;
|
|
53
|
-
/**
|
|
54
|
-
* Sets the entire scenario (all steps) for a test case.
|
|
55
|
-
*/
|
|
56
|
-
export declare function setTestOpsTestCaseScenario(testCaseId: number, steps: Array<{
|
|
57
|
-
action: string;
|
|
58
|
-
expectedResult?: string;
|
|
59
|
-
}>): Promise<TestOpsNormalizedScenario>;
|
|
60
|
-
/**
|
|
61
|
-
* Fetches custom field values for a test case.
|
|
62
|
-
*/
|
|
63
|
-
export declare function getTestOpsTestCaseCustomFields(testCaseId: number): Promise<TestOpsCustomFieldWithValues[]>;
|
|
64
|
-
/**
|
|
65
|
-
* Updates custom field values for a test case.
|
|
66
|
-
*/
|
|
67
|
-
export declare function updateTestOpsTestCaseCustomFields(testCaseId: number, customFields: Array<{
|
|
68
|
-
customFieldId: number;
|
|
69
|
-
valueIds: number[];
|
|
70
|
-
}>): Promise<void>;
|
|
71
|
-
/**
|
|
72
|
-
* Fetches test case IDs from a test plan.
|
|
73
|
-
*/
|
|
74
|
-
export declare function getTestOpsTestPlanTestCases(testPlanId: number, options?: {
|
|
75
|
-
page?: number;
|
|
76
|
-
size?: number;
|
|
77
|
-
sort?: string;
|
|
78
|
-
}): Promise<{
|
|
79
|
-
id: number;
|
|
80
|
-
name: string;
|
|
81
|
-
}[]>;
|
|
82
|
-
/**
|
|
83
|
-
* Searches test cases using AQL (Advanced Query Language).
|
|
84
|
-
*/
|
|
85
|
-
export declare function searchTestCasesByAQL(projectId: number, rql: string, options?: {
|
|
86
|
-
deleted?: boolean;
|
|
87
|
-
page?: number;
|
|
88
|
-
size?: number;
|
|
89
|
-
sort?: string;
|
|
90
|
-
}): Promise<{
|
|
91
|
-
testCases: TestOpsTestCase[];
|
|
92
|
-
total: number;
|
|
93
|
-
page: number;
|
|
94
|
-
size: number;
|
|
95
|
-
}>;
|
|
96
|
-
//# sourceMappingURL=testops-client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"testops-client.d.ts","sourceRoot":"","sources":["../../src/services/testops-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
let baseUrl = '';
|
|
2
|
-
let apiToken = '';
|
|
3
|
-
/**
|
|
4
|
-
* Sets the TestOps base URL and API token (from MCP process args).
|
|
5
|
-
*/
|
|
6
|
-
export function configureTestOpsClient(options) {
|
|
7
|
-
baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
8
|
-
apiToken = options.token;
|
|
9
|
-
}
|
|
10
|
-
function requireClientConfig() {
|
|
11
|
-
if (!baseUrl || !apiToken) {
|
|
12
|
-
throw new Error('TestOps client is not configured: pass --url and --token when starting the server');
|
|
13
|
-
}
|
|
14
|
-
return { baseUrl, token: apiToken };
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Exchanges the API token for a JWT used on subsequent requests.
|
|
18
|
-
*/
|
|
19
|
-
export async function getJwtToken() {
|
|
20
|
-
const { baseUrl: root, token: userToken } = requireClientConfig();
|
|
21
|
-
const response = await fetch(`${root}/api/uaa/oauth/token`, {
|
|
22
|
-
method: 'POST',
|
|
23
|
-
headers: {
|
|
24
|
-
Accept: 'application/json',
|
|
25
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
26
|
-
},
|
|
27
|
-
body: new URLSearchParams({
|
|
28
|
-
grant_type: 'apitoken',
|
|
29
|
-
scope: 'openid',
|
|
30
|
-
token: userToken,
|
|
31
|
-
}),
|
|
32
|
-
});
|
|
33
|
-
if (!response.ok) {
|
|
34
|
-
throw new Error(`Failed to obtain JWT: ${response.status} ${response.statusText}`);
|
|
35
|
-
}
|
|
36
|
-
const data = await response.json();
|
|
37
|
-
return data.access_token;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Lists projects visible to the authenticated user.
|
|
41
|
-
*/
|
|
42
|
-
export async function getTestOpsProjects() {
|
|
43
|
-
const { baseUrl: root } = requireClientConfig();
|
|
44
|
-
const jwtToken = await getJwtToken();
|
|
45
|
-
const response = await fetch(`${root}/api/project?size=1000`, {
|
|
46
|
-
method: 'GET',
|
|
47
|
-
headers: {
|
|
48
|
-
Accept: 'application/json',
|
|
49
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
if (!response.ok) {
|
|
53
|
-
throw new Error(`Failed to list projects: ${response.status} ${response.statusText}`);
|
|
54
|
-
}
|
|
55
|
-
const data = await response.json();
|
|
56
|
-
return data.content || [];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Finds a project by exact name, then by substring match.
|
|
60
|
-
*/
|
|
61
|
-
export async function getTestOpsProjectByName(projectName) {
|
|
62
|
-
const allProjects = await getTestOpsProjects();
|
|
63
|
-
const exactMatch = allProjects.find((project) => project.name.toLowerCase() === projectName.toLowerCase());
|
|
64
|
-
if (exactMatch) {
|
|
65
|
-
return exactMatch;
|
|
66
|
-
}
|
|
67
|
-
const partialMatch = allProjects.find((project) => project.name.toLowerCase().includes(projectName.toLowerCase()));
|
|
68
|
-
return partialMatch || null;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Fetches a test plan by ID.
|
|
72
|
-
*/
|
|
73
|
-
export async function getTestOpsTestPlan(testPlanId) {
|
|
74
|
-
const { baseUrl: root } = requireClientConfig();
|
|
75
|
-
const jwtToken = await getJwtToken();
|
|
76
|
-
const response = await fetch(`${root}/api/testplan/${testPlanId}`, {
|
|
77
|
-
method: 'GET',
|
|
78
|
-
headers: {
|
|
79
|
-
Accept: 'application/json',
|
|
80
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
if (!response.ok) {
|
|
84
|
-
throw new Error(`Failed to fetch test plan: ${response.status} ${response.statusText}`);
|
|
85
|
-
}
|
|
86
|
-
const data = await response.json();
|
|
87
|
-
return data;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Returns leaf nodes of the test plan tree (typically test case references).
|
|
91
|
-
*/
|
|
92
|
-
export async function getTestOpsTestPlanLeaves(testPlanId) {
|
|
93
|
-
const { baseUrl: root } = requireClientConfig();
|
|
94
|
-
const jwtToken = await getJwtToken();
|
|
95
|
-
const response = await fetch(`${root}/api/testplan/${testPlanId}/tree/leaf?page=0&size=1000&sort=name%2CASC`, {
|
|
96
|
-
method: 'GET',
|
|
97
|
-
headers: {
|
|
98
|
-
Accept: 'application/json',
|
|
99
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
|
-
if (!response.ok) {
|
|
103
|
-
throw new Error(`Failed to fetch test plan leaves: ${response.status} ${response.statusText}`);
|
|
104
|
-
}
|
|
105
|
-
const data = await response.json();
|
|
106
|
-
return data.content || [];
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Loads scenario step bodies for a test case.
|
|
110
|
-
*/
|
|
111
|
-
async function getTestOpsTestCaseSteps(testCaseId) {
|
|
112
|
-
const { baseUrl: root } = requireClientConfig();
|
|
113
|
-
const jwtToken = await getJwtToken();
|
|
114
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}/step`, {
|
|
115
|
-
method: 'GET',
|
|
116
|
-
headers: {
|
|
117
|
-
Accept: 'application/json',
|
|
118
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
if (!response.ok) {
|
|
122
|
-
throw new Error(`Failed to fetch steps for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
123
|
-
}
|
|
124
|
-
const data = await response.json();
|
|
125
|
-
if (data?.scenarioSteps && data.root?.children) {
|
|
126
|
-
const steps = [];
|
|
127
|
-
for (const stepId of data.root.children) {
|
|
128
|
-
const step = data.scenarioSteps[stepId];
|
|
129
|
-
if (step?.body) {
|
|
130
|
-
steps.push({ body: step.body });
|
|
131
|
-
const { expectedResultId } = step;
|
|
132
|
-
if (expectedResultId && data.scenarioSteps[expectedResultId]) {
|
|
133
|
-
const expectedNode = data.scenarioSteps[expectedResultId];
|
|
134
|
-
const expectedChildren = Array.isArray(expectedNode.children)
|
|
135
|
-
? expectedNode.children
|
|
136
|
-
: [];
|
|
137
|
-
for (const childId of expectedChildren) {
|
|
138
|
-
const child = data.scenarioSteps[childId];
|
|
139
|
-
if (child?.body) {
|
|
140
|
-
steps.push({ body: child.body });
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return steps;
|
|
147
|
-
}
|
|
148
|
-
return [];
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Loads custom field values for a test case.
|
|
152
|
-
*/
|
|
153
|
-
async function getTestOpsCustomFields(testCaseId) {
|
|
154
|
-
const { baseUrl: root } = requireClientConfig();
|
|
155
|
-
const jwtToken = await getJwtToken();
|
|
156
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}/cfv`, {
|
|
157
|
-
method: 'GET',
|
|
158
|
-
headers: {
|
|
159
|
-
Accept: 'application/json',
|
|
160
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
if (!response.ok) {
|
|
164
|
-
throw new Error(`Failed to fetch custom fields for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
165
|
-
}
|
|
166
|
-
const data = await response.json();
|
|
167
|
-
return Array.isArray(data) ? data : [];
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Returns test case metadata plus flattened steps and custom fields when available.
|
|
171
|
-
*/
|
|
172
|
-
export async function getTestOpsTestCaseDetail(testCaseId) {
|
|
173
|
-
const { baseUrl: root } = requireClientConfig();
|
|
174
|
-
const jwtToken = await getJwtToken();
|
|
175
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}`, {
|
|
176
|
-
method: 'GET',
|
|
177
|
-
headers: {
|
|
178
|
-
Accept: 'application/json',
|
|
179
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
if (!response.ok) {
|
|
183
|
-
throw new Error(`Failed to fetch test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
184
|
-
}
|
|
185
|
-
const detail = await response.json();
|
|
186
|
-
try {
|
|
187
|
-
const [steps, customFields] = await Promise.all([
|
|
188
|
-
getTestOpsTestCaseSteps(testCaseId),
|
|
189
|
-
getTestOpsCustomFields(testCaseId),
|
|
190
|
-
]);
|
|
191
|
-
const stepsArray = steps.map(({ body }) => body);
|
|
192
|
-
const customFieldsObject = customFields.reduce((acc, field) => {
|
|
193
|
-
acc[field.customField.name] = field.name;
|
|
194
|
-
return acc;
|
|
195
|
-
}, {});
|
|
196
|
-
return {
|
|
197
|
-
id: detail.id,
|
|
198
|
-
name: detail.name?.trim() || '',
|
|
199
|
-
steps: stepsArray,
|
|
200
|
-
customFields: customFieldsObject,
|
|
201
|
-
tags: (detail.tags || []).map((t) => t.name),
|
|
202
|
-
owner: detail.createdBy || '',
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
catch (error) {
|
|
206
|
-
console.warn(`Could not load extra fields for test case ${testCaseId}: ${error}`);
|
|
207
|
-
}
|
|
208
|
-
return {
|
|
209
|
-
id: detail.id,
|
|
210
|
-
name: detail.name?.trim() || '',
|
|
211
|
-
steps: [],
|
|
212
|
-
customFields: {},
|
|
213
|
-
tags: (detail.tags || []).map((t) => t.name),
|
|
214
|
-
owner: detail.createdBy || '',
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Fetches scenario (steps + expected results) for a test case.
|
|
219
|
-
*/
|
|
220
|
-
export async function getTestOpsTestCaseScenario(testCaseId) {
|
|
221
|
-
const { baseUrl: root } = requireClientConfig();
|
|
222
|
-
const jwtToken = await getJwtToken();
|
|
223
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}/step`, {
|
|
224
|
-
method: 'GET',
|
|
225
|
-
headers: {
|
|
226
|
-
Accept: 'application/json',
|
|
227
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
if (!response.ok) {
|
|
231
|
-
throw new Error(`Failed to fetch scenario for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
232
|
-
}
|
|
233
|
-
const data = await response.json();
|
|
234
|
-
return data;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Updates a step (including expected result) for a test case.
|
|
238
|
-
*/
|
|
239
|
-
export async function patchTestOpsScenarioStep(testCaseId, stepId, stepData) {
|
|
240
|
-
const { baseUrl: root } = requireClientConfig();
|
|
241
|
-
const jwtToken = await getJwtToken();
|
|
242
|
-
const patchData = {};
|
|
243
|
-
if (stepData.body !== undefined) {
|
|
244
|
-
patchData.body = stepData.body;
|
|
245
|
-
}
|
|
246
|
-
if (stepData.expectedResult !== undefined) {
|
|
247
|
-
patchData.expectedResult = stepData.expectedResult;
|
|
248
|
-
}
|
|
249
|
-
const response = await fetch(`${root}/api/testcase/step/${stepId}?withExpectedResult=true`, {
|
|
250
|
-
method: 'PATCH',
|
|
251
|
-
headers: {
|
|
252
|
-
Accept: 'application/json',
|
|
253
|
-
'Content-Type': 'application/json',
|
|
254
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
255
|
-
},
|
|
256
|
-
body: JSON.stringify(patchData),
|
|
257
|
-
});
|
|
258
|
-
if (!response.ok) {
|
|
259
|
-
throw new Error(`Failed to patch step ${stepId} for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
260
|
-
}
|
|
261
|
-
const data = await response.json();
|
|
262
|
-
return data;
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Sets the entire scenario (all steps) for a test case.
|
|
266
|
-
*/
|
|
267
|
-
export async function setTestOpsTestCaseScenario(testCaseId, steps) {
|
|
268
|
-
const { baseUrl: root } = requireClientConfig();
|
|
269
|
-
const jwtToken = await getJwtToken();
|
|
270
|
-
const scenarioData = {
|
|
271
|
-
steps: steps.map((step) => ({
|
|
272
|
-
action: step.action,
|
|
273
|
-
expectedResult: step.expectedResult || '',
|
|
274
|
-
})),
|
|
275
|
-
};
|
|
276
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}/scenario`, {
|
|
277
|
-
method: 'POST',
|
|
278
|
-
headers: {
|
|
279
|
-
Accept: 'application/json',
|
|
280
|
-
'Content-Type': 'application/json',
|
|
281
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
282
|
-
},
|
|
283
|
-
body: JSON.stringify(scenarioData),
|
|
284
|
-
});
|
|
285
|
-
if (!response.ok) {
|
|
286
|
-
throw new Error(`Failed to set scenario for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
287
|
-
}
|
|
288
|
-
const data = await response.json();
|
|
289
|
-
return data;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Fetches custom field values for a test case.
|
|
293
|
-
*/
|
|
294
|
-
export async function getTestOpsTestCaseCustomFields(testCaseId) {
|
|
295
|
-
const { baseUrl: root } = requireClientConfig();
|
|
296
|
-
const jwtToken = await getJwtToken();
|
|
297
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}/cfv`, {
|
|
298
|
-
method: 'GET',
|
|
299
|
-
headers: {
|
|
300
|
-
Accept: 'application/json',
|
|
301
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
302
|
-
},
|
|
303
|
-
});
|
|
304
|
-
if (!response.ok) {
|
|
305
|
-
throw new Error(`Failed to fetch custom fields for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
306
|
-
}
|
|
307
|
-
const data = await response.json();
|
|
308
|
-
return data;
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Updates custom field values for a test case.
|
|
312
|
-
*/
|
|
313
|
-
export async function updateTestOpsTestCaseCustomFields(testCaseId, customFields) {
|
|
314
|
-
const { baseUrl: root } = requireClientConfig();
|
|
315
|
-
const jwtToken = await getJwtToken();
|
|
316
|
-
const response = await fetch(`${root}/api/testcase/${testCaseId}/cfv`, {
|
|
317
|
-
method: 'PATCH',
|
|
318
|
-
headers: {
|
|
319
|
-
'Content-Type': 'application/json',
|
|
320
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
321
|
-
},
|
|
322
|
-
body: JSON.stringify(customFields),
|
|
323
|
-
});
|
|
324
|
-
if (!response.ok) {
|
|
325
|
-
throw new Error(`Failed to update custom fields for test case ${testCaseId}: ${response.status} ${response.statusText}`);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Fetches test case IDs from a test plan.
|
|
330
|
-
*/
|
|
331
|
-
export async function getTestOpsTestPlanTestCases(testPlanId, options) {
|
|
332
|
-
const { baseUrl: root } = requireClientConfig();
|
|
333
|
-
const jwtToken = await getJwtToken();
|
|
334
|
-
const params = new URLSearchParams();
|
|
335
|
-
params.set('page', String(options?.page ?? 0));
|
|
336
|
-
params.set('size', String(options?.size ?? 10));
|
|
337
|
-
if (options?.sort) {
|
|
338
|
-
params.set('sort', options.sort);
|
|
339
|
-
}
|
|
340
|
-
const response = await fetch(`${root}/api/testplan/${testPlanId}/tree/leaf?${params}`, {
|
|
341
|
-
method: 'GET',
|
|
342
|
-
headers: {
|
|
343
|
-
Accept: 'application/json',
|
|
344
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
345
|
-
},
|
|
346
|
-
});
|
|
347
|
-
if (!response.ok) {
|
|
348
|
-
throw new Error(`Failed to fetch test cases from test plan ${testPlanId}: ${response.status} ${response.statusText}`);
|
|
349
|
-
}
|
|
350
|
-
const data = (await response.json());
|
|
351
|
-
return data.content || [];
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Searches test cases using AQL (Advanced Query Language).
|
|
355
|
-
*/
|
|
356
|
-
export async function searchTestCasesByAQL(projectId, rql, options) {
|
|
357
|
-
const { baseUrl: root } = requireClientConfig();
|
|
358
|
-
const jwtToken = await getJwtToken();
|
|
359
|
-
const params = new URLSearchParams();
|
|
360
|
-
params.set('projectId', String(projectId));
|
|
361
|
-
params.set('rql', rql);
|
|
362
|
-
if (options?.deleted !== undefined) {
|
|
363
|
-
params.set('deleted', String(options.deleted));
|
|
364
|
-
}
|
|
365
|
-
if (options?.page !== undefined) {
|
|
366
|
-
params.set('page', String(options.page));
|
|
367
|
-
}
|
|
368
|
-
if (options?.size !== undefined) {
|
|
369
|
-
params.set('size', String(options.size));
|
|
370
|
-
}
|
|
371
|
-
if (options?.sort) {
|
|
372
|
-
params.set('sort', options.sort);
|
|
373
|
-
}
|
|
374
|
-
const response = await fetch(`${root}/api/testcase/__search?${params}`, {
|
|
375
|
-
method: 'GET',
|
|
376
|
-
headers: {
|
|
377
|
-
Accept: 'application/json',
|
|
378
|
-
Authorization: `Bearer ${jwtToken}`,
|
|
379
|
-
},
|
|
380
|
-
});
|
|
381
|
-
if (!response.ok) {
|
|
382
|
-
throw new Error(`Failed to search test cases: ${response.status} ${response.statusText}`);
|
|
383
|
-
}
|
|
384
|
-
const data = (await response.json());
|
|
385
|
-
return {
|
|
386
|
-
testCases: data.content || [],
|
|
387
|
-
total: data.totalElements || 0,
|
|
388
|
-
page: data.number || 0,
|
|
389
|
-
size: data.size || 0,
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
//# sourceMappingURL=testops-client.js.map
|