@azure-devops/mcp 2.10.0-nightly.20261012 → 2.10.0-nightly.20261014
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/dist/tools/test-plans.js +55 -18
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/tools/test-plans.js
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
|
+
import { TestOutcome } from "azure-devops-node-api/interfaces/TestInterfaces.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { apiVersion } from "../utils.js";
|
|
6
|
+
const TEST_RESULT_PAGE_SIZE = 1_000;
|
|
7
|
+
const TEST_RESULT_CONCURRENCY = 5;
|
|
8
|
+
const TEST_OUTCOMES = [
|
|
9
|
+
"Unspecified",
|
|
10
|
+
"None",
|
|
11
|
+
"Passed",
|
|
12
|
+
"Failed",
|
|
13
|
+
"Inconclusive",
|
|
14
|
+
"Timeout",
|
|
15
|
+
"Aborted",
|
|
16
|
+
"Blocked",
|
|
17
|
+
"NotExecuted",
|
|
18
|
+
"Warning",
|
|
19
|
+
"Error",
|
|
20
|
+
"NotApplicable",
|
|
21
|
+
"Paused",
|
|
22
|
+
"InProgress",
|
|
23
|
+
"NotImpacted",
|
|
24
|
+
];
|
|
5
25
|
const TEST_PLAN_TOOLS = {
|
|
6
26
|
testplan: "testplan",
|
|
7
27
|
test_results_from_build_id: "testplan_show_test_results_from_build_id",
|
|
@@ -137,33 +157,50 @@ function configureTestPlanTools(server, tokenProvider, connectionProvider, userA
|
|
|
137
157
|
server.tool(TEST_PLAN_TOOLS.test_results_from_build_id, "Gets a list of test results for a given project and build ID. Can filter by test outcome (e.g. Failed, Passed, Aborted). Returns test case titles, error messages, stack traces, and outcomes. Efficiently handles builds with large numbers of test runs.", {
|
|
138
158
|
project: z.string().describe("The unique identifier (ID or name) of the Azure DevOps project."),
|
|
139
159
|
buildid: z.coerce.number().min(1).describe("The ID of the build."),
|
|
140
|
-
outcomes: z.array(z.
|
|
160
|
+
outcomes: z.array(z.enum(TEST_OUTCOMES)).optional().describe("Filter results by test outcome, e.g. ['Failed', 'Passed', 'Aborted']."),
|
|
141
161
|
}, async ({ project, buildid, outcomes }) => {
|
|
142
162
|
try {
|
|
143
163
|
const connection = await connectionProvider();
|
|
144
164
|
const testResultsApi = await connection.getTestResultsApi();
|
|
145
|
-
const
|
|
146
|
-
const
|
|
165
|
+
const buildUri = `vstfs:///Build/Build/${buildid}`;
|
|
166
|
+
const testRuns = [];
|
|
167
|
+
for (let skip = 0;; skip += TEST_RESULT_PAGE_SIZE) {
|
|
168
|
+
const page = await testResultsApi.getTestRuns(project, buildUri, undefined, undefined, undefined, undefined, undefined, skip, TEST_RESULT_PAGE_SIZE);
|
|
169
|
+
testRuns.push(...page);
|
|
170
|
+
if (page.length < TEST_RESULT_PAGE_SIZE) {
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const outcomeFilter = outcomes?.map((outcome) => TestOutcome[outcome]);
|
|
175
|
+
const runsWithIds = testRuns.filter((run) => run.id !== undefined);
|
|
147
176
|
const allResults = [];
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
177
|
+
for (let index = 0; index < runsWithIds.length; index += TEST_RESULT_CONCURRENCY) {
|
|
178
|
+
const batch = runsWithIds.slice(index, index + TEST_RESULT_CONCURRENCY);
|
|
179
|
+
const batchResults = await Promise.all(batch.map(async (run) => {
|
|
180
|
+
const results = [];
|
|
181
|
+
for (let skip = 0;; skip += TEST_RESULT_PAGE_SIZE) {
|
|
182
|
+
const page = await testResultsApi.getTestResults(project, run.id, undefined, skip, TEST_RESULT_PAGE_SIZE, outcomeFilter);
|
|
183
|
+
results.push(...page.map((result) => ({ result, runId: run.id })));
|
|
184
|
+
if (page.length < TEST_RESULT_PAGE_SIZE) {
|
|
185
|
+
break;
|
|
153
186
|
}
|
|
154
187
|
}
|
|
188
|
+
return results;
|
|
189
|
+
}));
|
|
190
|
+
for (const results of batchResults) {
|
|
191
|
+
allResults.push(...results);
|
|
155
192
|
}
|
|
156
193
|
}
|
|
157
|
-
const formattedResults = allResults.map((
|
|
158
|
-
id:
|
|
159
|
-
testCaseTitle:
|
|
160
|
-
outcome:
|
|
161
|
-
errorMessage:
|
|
162
|
-
stackTrace:
|
|
163
|
-
automatedTestName:
|
|
164
|
-
automatedTestStorage:
|
|
165
|
-
durationInMs:
|
|
166
|
-
runId
|
|
194
|
+
const formattedResults = allResults.map(({ result, runId }) => ({
|
|
195
|
+
id: result.id,
|
|
196
|
+
testCaseTitle: result.testCaseTitle,
|
|
197
|
+
outcome: result.outcome,
|
|
198
|
+
errorMessage: result.errorMessage,
|
|
199
|
+
stackTrace: result.stackTrace,
|
|
200
|
+
automatedTestName: result.automatedTestName,
|
|
201
|
+
automatedTestStorage: result.automatedTestStorage,
|
|
202
|
+
durationInMs: result.durationInMs,
|
|
203
|
+
runId,
|
|
167
204
|
}));
|
|
168
205
|
return {
|
|
169
206
|
content: [{ type: "text", text: JSON.stringify(formattedResults, null, 2) }],
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageVersion = "2.10.0-nightly.
|
|
1
|
+
export const packageVersion = "2.10.0-nightly.20261014";
|
package/package.json
CHANGED