zephyr-scale-mcp-server 0.2.4 → 0.2.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/build/tool-handlers.js +53 -10
- package/package.json +1 -1
- package/src/tool-handlers.ts +54 -10
package/build/tool-handlers.js
CHANGED
|
@@ -125,27 +125,70 @@ export class ZephyrToolHandlers {
|
|
|
125
125
|
// First, get the existing test case data
|
|
126
126
|
const getResponse = await this.axiosInstance.get(`${this.jiraConfig.apiEndpoints.testcase}/${test_case_key}`);
|
|
127
127
|
const testCaseData = getResponse.data;
|
|
128
|
-
//
|
|
129
|
-
const
|
|
130
|
-
|
|
128
|
+
// Convert incoming BDD markdown (fallback to raw content if conversion returns empty)
|
|
129
|
+
const converted = convertToGherkin(bdd_content);
|
|
130
|
+
const finalText = converted && converted.trim().length > 0 ? converted : bdd_content;
|
|
131
|
+
// Build a payload aligned with Zephyr Scale Server's update schema.
|
|
132
|
+
// Only include fields that exist to avoid accidental nulling; required fields must be present.
|
|
133
|
+
const payload = {};
|
|
134
|
+
// Required base fields (schema requires these on Server/Data Center). If missing, throw.
|
|
135
|
+
const requiredFields = [
|
|
136
|
+
['projectKey', testCaseData.projectKey],
|
|
137
|
+
['name', testCaseData.name],
|
|
138
|
+
['status', testCaseData.status],
|
|
139
|
+
['priority', testCaseData.priority]
|
|
140
|
+
];
|
|
141
|
+
for (const [field, value] of requiredFields) {
|
|
142
|
+
if (value === undefined || value === null || value === '') {
|
|
143
|
+
throw new McpError(ErrorCode.InternalError, `Existing test case is missing required field '${field}' needed for update.`);
|
|
144
|
+
}
|
|
145
|
+
payload[field] = value;
|
|
146
|
+
}
|
|
147
|
+
// Optional simple scalar/string fields
|
|
148
|
+
const optionalScalarFields = [
|
|
149
|
+
'objective',
|
|
150
|
+
'precondition',
|
|
151
|
+
'folder',
|
|
152
|
+
'component',
|
|
153
|
+
'owner',
|
|
154
|
+
'estimatedTime'
|
|
155
|
+
];
|
|
156
|
+
for (const field of optionalScalarFields) {
|
|
157
|
+
if (testCaseData[field] !== undefined)
|
|
158
|
+
payload[field] = testCaseData[field];
|
|
159
|
+
}
|
|
160
|
+
// Arrays / objects
|
|
161
|
+
if (Array.isArray(testCaseData.labels))
|
|
162
|
+
payload.labels = testCaseData.labels;
|
|
163
|
+
if (testCaseData.customFields)
|
|
164
|
+
payload.customFields = testCaseData.customFields;
|
|
165
|
+
if (testCaseData.parameters)
|
|
166
|
+
payload.parameters = testCaseData.parameters;
|
|
167
|
+
// issueLinks preferred; map deprecated issueKey if present and issueLinks absent
|
|
168
|
+
if (Array.isArray(testCaseData.issueLinks)) {
|
|
169
|
+
payload.issueLinks = testCaseData.issueLinks;
|
|
170
|
+
}
|
|
171
|
+
else if (testCaseData.issueKey) {
|
|
172
|
+
payload.issueLinks = [testCaseData.issueKey];
|
|
173
|
+
}
|
|
174
|
+
// Build testScript. Force type to BDD when performing a BDD update.
|
|
175
|
+
payload.testScript = {
|
|
176
|
+
type: 'BDD',
|
|
177
|
+
text: finalText
|
|
131
178
|
};
|
|
132
|
-
//
|
|
133
|
-
payload.testScript.text = convertToGherkin(bdd_content);
|
|
134
|
-
// Update the test case
|
|
179
|
+
// PUT update
|
|
135
180
|
const updateResponse = await this.axiosInstance.put(`${this.jiraConfig.apiEndpoints.testcase}/${test_case_key}`, payload);
|
|
136
181
|
if (updateResponse.status === 200) {
|
|
137
182
|
return {
|
|
138
183
|
content: [
|
|
139
184
|
{
|
|
140
185
|
type: 'text',
|
|
141
|
-
text: `✅ Updated ${test_case_key} with BDD content successfully`,
|
|
186
|
+
text: `✅ Updated ${test_case_key} with BDD content successfully\nPayload summary: ${JSON.stringify({ textLength: finalText.length, projectKey: payload.projectKey, preservedLabels: payload.labels?.length || 0 }, null, 2)}`,
|
|
142
187
|
},
|
|
143
188
|
],
|
|
144
189
|
};
|
|
145
190
|
}
|
|
146
|
-
|
|
147
|
-
throw new Error(`Failed to update ${test_case_key}: ${updateResponse.status}`);
|
|
148
|
-
}
|
|
191
|
+
throw new Error(`Failed to update ${test_case_key}: ${updateResponse.status}`);
|
|
149
192
|
}
|
|
150
193
|
catch (error) {
|
|
151
194
|
throw new McpError(ErrorCode.InternalError, `Failed to update test case BDD: ${error instanceof Error ? error.message : String(error)}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zephyr-scale-mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for Zephyr Scale test case management with comprehensive STEP_BY_STEP, PLAIN_TEXT, and BDD support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./build/index.js",
|
package/src/tool-handlers.ts
CHANGED
|
@@ -141,16 +141,60 @@ export class ZephyrToolHandlers {
|
|
|
141
141
|
// First, get the existing test case data
|
|
142
142
|
const getResponse = await this.axiosInstance.get(`${this.jiraConfig.apiEndpoints.testcase}/${test_case_key}`);
|
|
143
143
|
const testCaseData = getResponse.data;
|
|
144
|
+
// Convert incoming BDD markdown (fallback to raw content if conversion returns empty)
|
|
145
|
+
const converted = convertToGherkin(bdd_content);
|
|
146
|
+
const finalText = converted && converted.trim().length > 0 ? converted : bdd_content;
|
|
147
|
+
|
|
148
|
+
// Build a payload aligned with Zephyr Scale Server's update schema.
|
|
149
|
+
// Only include fields that exist to avoid accidental nulling; required fields must be present.
|
|
150
|
+
const payload: any = {};
|
|
151
|
+
|
|
152
|
+
// Required base fields (schema requires these on Server/Data Center). If missing, throw.
|
|
153
|
+
const requiredFields: Array<[string, any]> = [
|
|
154
|
+
['projectKey', testCaseData.projectKey],
|
|
155
|
+
['name', testCaseData.name],
|
|
156
|
+
['status', testCaseData.status],
|
|
157
|
+
['priority', testCaseData.priority]
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
for (const [field, value] of requiredFields) {
|
|
161
|
+
if (value === undefined || value === null || value === '') {
|
|
162
|
+
throw new McpError(ErrorCode.InternalError, `Existing test case is missing required field '${field}' needed for update.`);
|
|
163
|
+
}
|
|
164
|
+
payload[field] = value;
|
|
165
|
+
}
|
|
144
166
|
|
|
145
|
-
//
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
167
|
+
// Optional simple scalar/string fields
|
|
168
|
+
const optionalScalarFields = [
|
|
169
|
+
'objective',
|
|
170
|
+
'precondition',
|
|
171
|
+
'folder',
|
|
172
|
+
'component',
|
|
173
|
+
'owner',
|
|
174
|
+
'estimatedTime'
|
|
175
|
+
];
|
|
176
|
+
for (const field of optionalScalarFields) {
|
|
177
|
+
if (testCaseData[field] !== undefined) payload[field] = testCaseData[field];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Arrays / objects
|
|
181
|
+
if (Array.isArray(testCaseData.labels)) payload.labels = testCaseData.labels;
|
|
182
|
+
if (testCaseData.customFields) payload.customFields = testCaseData.customFields;
|
|
183
|
+
if (testCaseData.parameters) payload.parameters = testCaseData.parameters;
|
|
184
|
+
// issueLinks preferred; map deprecated issueKey if present and issueLinks absent
|
|
185
|
+
if (Array.isArray(testCaseData.issueLinks)) {
|
|
186
|
+
payload.issueLinks = testCaseData.issueLinks;
|
|
187
|
+
} else if (testCaseData.issueKey) {
|
|
188
|
+
payload.issueLinks = [testCaseData.issueKey];
|
|
189
|
+
}
|
|
149
190
|
|
|
150
|
-
//
|
|
151
|
-
payload.testScript
|
|
191
|
+
// Build testScript. Force type to BDD when performing a BDD update.
|
|
192
|
+
payload.testScript = {
|
|
193
|
+
type: 'BDD',
|
|
194
|
+
text: finalText
|
|
195
|
+
};
|
|
152
196
|
|
|
153
|
-
//
|
|
197
|
+
// PUT update
|
|
154
198
|
const updateResponse = await this.axiosInstance.put(`${this.jiraConfig.apiEndpoints.testcase}/${test_case_key}`, payload);
|
|
155
199
|
|
|
156
200
|
if (updateResponse.status === 200) {
|
|
@@ -158,13 +202,13 @@ export class ZephyrToolHandlers {
|
|
|
158
202
|
content: [
|
|
159
203
|
{
|
|
160
204
|
type: 'text',
|
|
161
|
-
text: `✅ Updated ${test_case_key} with BDD content successfully`,
|
|
205
|
+
text: `✅ Updated ${test_case_key} with BDD content successfully\nPayload summary: ${JSON.stringify({ textLength: finalText.length, projectKey: payload.projectKey, preservedLabels: payload.labels?.length || 0 }, null, 2)}`,
|
|
162
206
|
},
|
|
163
207
|
],
|
|
164
208
|
};
|
|
165
|
-
} else {
|
|
166
|
-
throw new Error(`Failed to update ${test_case_key}: ${updateResponse.status}`);
|
|
167
209
|
}
|
|
210
|
+
|
|
211
|
+
throw new Error(`Failed to update ${test_case_key}: ${updateResponse.status}`);
|
|
168
212
|
} catch (error) {
|
|
169
213
|
throw new McpError(
|
|
170
214
|
ErrorCode.InternalError,
|