xray-mcp 1.0.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.
@@ -0,0 +1,759 @@
1
+ import axios from 'axios';
2
+ export class XrayClient {
3
+ config;
4
+ client;
5
+ graphqlClient;
6
+ accessToken = null;
7
+ tokenExpiry = 0;
8
+ constructor(config) {
9
+ this.config = {
10
+ ...config,
11
+ baseUrl: config.baseUrl || 'https://xray.cloud.getxray.app/api/v2'
12
+ };
13
+ this.client = axios.create({
14
+ baseURL: this.config.baseUrl,
15
+ headers: {
16
+ 'Content-Type': 'application/json'
17
+ }
18
+ });
19
+ this.graphqlClient = axios.create({
20
+ baseURL: this.config.baseUrl,
21
+ headers: {
22
+ 'Content-Type': 'application/json'
23
+ }
24
+ });
25
+ }
26
+ /**
27
+ * Authenticate with Xray Cloud API and get access token
28
+ */
29
+ async authenticate() {
30
+ // Check if we have a valid token
31
+ if (this.accessToken && Date.now() < this.tokenExpiry) {
32
+ return this.accessToken;
33
+ }
34
+ try {
35
+ const response = await axios.post('https://xray.cloud.getxray.app/api/v1/authenticate', {
36
+ client_id: this.config.clientId,
37
+ client_secret: this.config.clientSecret
38
+ }, {
39
+ headers: {
40
+ 'Content-Type': 'application/json'
41
+ }
42
+ });
43
+ this.accessToken = response.data;
44
+ // Set expiry to 23 hours from now (tokens are valid for 24 hours)
45
+ this.tokenExpiry = Date.now() + (23 * 60 * 60 * 1000);
46
+ if (!this.accessToken) {
47
+ throw new Error('Authentication failed: No access token received');
48
+ }
49
+ return this.accessToken;
50
+ }
51
+ catch (error) {
52
+ if (axios.isAxiosError(error)) {
53
+ throw new Error(`Authentication failed: ${error.response?.data || error.message}`);
54
+ }
55
+ throw new Error(`Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
56
+ }
57
+ }
58
+ /**
59
+ * Make an authenticated request to the Xray API
60
+ */
61
+ async request(method, url, data) {
62
+ const token = await this.authenticate();
63
+ try {
64
+ const response = await this.client.request({
65
+ method,
66
+ url,
67
+ data,
68
+ headers: {
69
+ Authorization: `Bearer ${token}`
70
+ }
71
+ });
72
+ return response.data;
73
+ }
74
+ catch (error) {
75
+ if (axios.isAxiosError(error)) {
76
+ throw new Error(`API request failed: ${error.response?.data?.error || error.message}`);
77
+ }
78
+ throw new Error(`API request failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
79
+ }
80
+ }
81
+ /**
82
+ * Make a GraphQL query to Xray API
83
+ */
84
+ async graphqlRequest(query, variables) {
85
+ const token = await this.authenticate();
86
+ try {
87
+ const response = await this.graphqlClient.post('/graphql', {
88
+ query,
89
+ variables
90
+ }, {
91
+ headers: {
92
+ Authorization: `Bearer ${token}`
93
+ }
94
+ });
95
+ if (response.data.errors && response.data.errors.length > 0) {
96
+ throw new Error(`GraphQL errors: ${JSON.stringify(response.data.errors)}`);
97
+ }
98
+ return response.data.data;
99
+ }
100
+ catch (error) {
101
+ if (axios.isAxiosError(error)) {
102
+ const errorDetails = error.response?.data
103
+ ? JSON.stringify(error.response.data)
104
+ : error.message;
105
+ throw new Error(`GraphQL request failed (${error.response?.status}): ${errorDetails}`);
106
+ }
107
+ throw new Error(`GraphQL request failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
108
+ }
109
+ }
110
+ /**
111
+ * Create a new test case using GraphQL mutation
112
+ */
113
+ async createTestCase(testCase) {
114
+ const mutation = `
115
+ mutation CreateTest($jira: JSON!, $testType: UpdateTestTypeInput, $unstructured: String) {
116
+ createTest(jira: $jira, testType: $testType, unstructured: $unstructured) {
117
+ test {
118
+ issueId
119
+ jira(fields: ["key"])
120
+ }
121
+ warnings
122
+ }
123
+ }
124
+ `;
125
+ const jiraFields = {
126
+ fields: {
127
+ project: {
128
+ key: testCase.projectKey
129
+ },
130
+ summary: testCase.summary,
131
+ issuetype: {
132
+ name: 'Test'
133
+ }
134
+ }
135
+ };
136
+ if (testCase.description) {
137
+ jiraFields.fields.description = testCase.description;
138
+ }
139
+ if (testCase.labels && testCase.labels.length > 0) {
140
+ jiraFields.fields.labels = testCase.labels;
141
+ }
142
+ if (testCase.priority) {
143
+ jiraFields.fields.priority = { name: testCase.priority };
144
+ }
145
+ const variables = {
146
+ jira: jiraFields,
147
+ unstructured: testCase.description || ''
148
+ };
149
+ if (testCase.testType) {
150
+ variables.testType = {
151
+ name: testCase.testType
152
+ };
153
+ }
154
+ const result = await this.graphqlRequest(mutation, variables);
155
+ return {
156
+ id: result.createTest.test.issueId,
157
+ key: result.createTest.test.jira.key,
158
+ self: `https://your-jira-instance.atlassian.net/browse/${result.createTest.test.jira.key}`
159
+ };
160
+ }
161
+ /**
162
+ * Get a test case by key using GraphQL
163
+ */
164
+ async getTestCase(testKey) {
165
+ const query = `
166
+ query GetTest($jql: String!, $limit: Int!) {
167
+ getTests(jql: $jql, limit: $limit) {
168
+ total
169
+ results {
170
+ issueId
171
+ projectId
172
+ jira(fields: ["key", "summary", "description", "priority", "status", "labels"])
173
+ testType {
174
+ name
175
+ kind
176
+ }
177
+ steps {
178
+ id
179
+ action
180
+ data
181
+ result
182
+ }
183
+ gherkin
184
+ unstructured
185
+ }
186
+ }
187
+ }
188
+ `;
189
+ const variables = {
190
+ jql: `key = '${testKey}'`,
191
+ limit: 1
192
+ };
193
+ const result = await this.graphqlRequest(query, variables);
194
+ if (result.getTests.total === 0) {
195
+ throw new Error(`Test case ${testKey} not found`);
196
+ }
197
+ return result.getTests.results[0];
198
+ }
199
+ /**
200
+ * Update a test case
201
+ * Note: Xray GraphQL API has specific mutations for test definition updates
202
+ * (updateUnstructuredTestDefinition, updateGherkinTestDefinition, etc.)
203
+ * For general Jira field updates (summary, description, labels), use Jira REST API directly
204
+ */
205
+ async updateTestCase(testKey, updates) {
206
+ throw new Error('Direct test case update is not supported via Xray GraphQL API. ' +
207
+ 'Use Jira REST API to update standard fields (summary, description, labels, priority). ' +
208
+ 'Use specific Xray mutations for test definition updates: ' +
209
+ 'updateUnstructuredTestDefinition, updateGherkinTestDefinition, updateTestType, etc.');
210
+ }
211
+ /**
212
+ * Delete a test case using GraphQL mutation
213
+ * First retrieves the issueId from the test key, then deletes it
214
+ */
215
+ async deleteTestCase(testKey) {
216
+ // First, get the issueId from the test key
217
+ const test = await this.getTestCase(testKey);
218
+ const mutation = `
219
+ mutation DeleteTest($issueId: String!) {
220
+ deleteTest(issueId: $issueId)
221
+ }
222
+ `;
223
+ const variables = {
224
+ issueId: test.issueId
225
+ };
226
+ await this.graphqlRequest(mutation, variables);
227
+ }
228
+ /**
229
+ * Get test cases for a project using GraphQL
230
+ */
231
+ async getTestCasesByProject(projectKey, maxResults = 50) {
232
+ const jql = `project = '${projectKey}'`;
233
+ return this.searchTestCases(jql, maxResults);
234
+ }
235
+ /**
236
+ * Search test cases using JQL and GraphQL
237
+ */
238
+ async searchTestCases(jql, maxResults = 50) {
239
+ const query = `
240
+ query SearchTests($jql: String!, $limit: Int!) {
241
+ getTests(jql: $jql, limit: $limit) {
242
+ total
243
+ start
244
+ limit
245
+ results {
246
+ issueId
247
+ projectId
248
+ jira(fields: ["key", "summary", "description", "priority", "status", "labels"])
249
+ testType {
250
+ name
251
+ kind
252
+ }
253
+ }
254
+ }
255
+ }
256
+ `;
257
+ const variables = {
258
+ jql,
259
+ limit: maxResults
260
+ };
261
+ const result = await this.graphqlRequest(query, variables);
262
+ return result.getTests;
263
+ }
264
+ // ========================================
265
+ // Test Execution Methods
266
+ // ========================================
267
+ /**
268
+ * Create a new test execution using GraphQL mutation
269
+ */
270
+ async createTestExecution(testExecution) {
271
+ const mutation = `
272
+ mutation CreateTestExecution($jira: JSON!, $testIssueIds: [String], $testEnvironments: [String]) {
273
+ createTestExecution(jira: $jira, testIssueIds: $testIssueIds, testEnvironments: $testEnvironments) {
274
+ testExecution {
275
+ issueId
276
+ jira(fields: ["key", "summary"])
277
+ testRuns(limit: 100) {
278
+ results {
279
+ id
280
+ status {
281
+ name
282
+ description
283
+ }
284
+ test {
285
+ issueId
286
+ jira(fields: ["key", "summary"])
287
+ }
288
+ }
289
+ }
290
+ }
291
+ warnings
292
+ }
293
+ }
294
+ `;
295
+ const jiraFields = {
296
+ fields: {
297
+ project: {
298
+ key: testExecution.projectKey
299
+ },
300
+ summary: testExecution.summary,
301
+ issuetype: {
302
+ name: 'Test Execution'
303
+ }
304
+ }
305
+ };
306
+ if (testExecution.description) {
307
+ jiraFields.fields.description = testExecution.description;
308
+ }
309
+ const variables = {
310
+ jira: jiraFields
311
+ };
312
+ if (testExecution.testIssueIds && testExecution.testIssueIds.length > 0) {
313
+ variables.testIssueIds = testExecution.testIssueIds;
314
+ }
315
+ if (testExecution.testEnvironments && testExecution.testEnvironments.length > 0) {
316
+ variables.testEnvironments = testExecution.testEnvironments;
317
+ }
318
+ const result = await this.graphqlRequest(mutation, variables);
319
+ return {
320
+ issueId: result.createTestExecution.testExecution.issueId,
321
+ key: result.createTestExecution.testExecution.jira.key,
322
+ testRuns: result.createTestExecution.testExecution.testRuns.results
323
+ };
324
+ }
325
+ /**
326
+ * Get a test execution by key using GraphQL
327
+ */
328
+ async getTestExecution(testExecutionKey) {
329
+ const query = `
330
+ query GetTestExecution($jql: String!, $limit: Int!) {
331
+ getTestExecutions(jql: $jql, limit: $limit) {
332
+ total
333
+ results {
334
+ issueId
335
+ projectId
336
+ jira(fields: ["key", "summary", "description", "status"])
337
+ testRuns(limit: 100) {
338
+ results {
339
+ id
340
+ status {
341
+ name
342
+ description
343
+ }
344
+ test {
345
+ issueId
346
+ jira(fields: ["key", "summary"])
347
+ }
348
+ startedOn
349
+ finishedOn
350
+ executedBy
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ `;
357
+ const variables = {
358
+ jql: `key = '${testExecutionKey}'`,
359
+ limit: 1
360
+ };
361
+ const result = await this.graphqlRequest(query, variables);
362
+ if (result.getTestExecutions.total === 0) {
363
+ throw new Error(`Test execution ${testExecutionKey} not found`);
364
+ }
365
+ return result.getTestExecutions.results[0];
366
+ }
367
+ /**
368
+ * Get test executions for a project using GraphQL
369
+ */
370
+ async getTestExecutionsByProject(projectKey, maxResults = 50) {
371
+ const jql = `project = '${projectKey}'`;
372
+ return this.searchTestExecutions(jql, maxResults);
373
+ }
374
+ /**
375
+ * Search test executions using JQL and GraphQL
376
+ */
377
+ async searchTestExecutions(jql, maxResults = 50) {
378
+ const query = `
379
+ query SearchTestExecutions($jql: String!, $limit: Int!) {
380
+ getTestExecutions(jql: $jql, limit: $limit) {
381
+ total
382
+ start
383
+ limit
384
+ results {
385
+ issueId
386
+ projectId
387
+ jira(fields: ["key", "summary", "description", "status", "created", "updated"])
388
+ testRuns(limit: 100) {
389
+ total
390
+ results {
391
+ id
392
+ status {
393
+ name
394
+ description
395
+ }
396
+ test {
397
+ issueId
398
+ jira(fields: ["key", "summary"])
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
404
+ }
405
+ `;
406
+ const variables = {
407
+ jql,
408
+ limit: maxResults
409
+ };
410
+ const result = await this.graphqlRequest(query, variables);
411
+ return result.getTestExecutions;
412
+ }
413
+ /**
414
+ * Update the status of a test run using GraphQL mutation
415
+ */
416
+ async updateTestRunStatus(testRunId, status) {
417
+ const mutation = `
418
+ mutation UpdateTestRunStatus($id: String!, $status: String!) {
419
+ updateTestRunStatus(id: $id, status: $status)
420
+ }
421
+ `;
422
+ const variables = {
423
+ id: testRunId,
424
+ status
425
+ };
426
+ const result = await this.graphqlRequest(mutation, variables);
427
+ return result.updateTestRunStatus;
428
+ }
429
+ // ========================================
430
+ // Test Plan Methods
431
+ // ========================================
432
+ /**
433
+ * Create a new test plan using GraphQL mutation
434
+ */
435
+ async createTestPlan(testPlan) {
436
+ const mutation = `
437
+ mutation CreateTestPlan($jira: JSON!, $testIssueIds: [String]) {
438
+ createTestPlan(jira: $jira, testIssueIds: $testIssueIds) {
439
+ testPlan {
440
+ issueId
441
+ jira(fields: ["key", "summary"])
442
+ tests(limit: 100) {
443
+ results {
444
+ issueId
445
+ jira(fields: ["key", "summary"])
446
+ }
447
+ }
448
+ }
449
+ warnings
450
+ }
451
+ }
452
+ `;
453
+ const jiraFields = {
454
+ fields: {
455
+ project: {
456
+ key: testPlan.projectKey
457
+ },
458
+ summary: testPlan.summary,
459
+ issuetype: {
460
+ name: 'Test Plan'
461
+ }
462
+ }
463
+ };
464
+ if (testPlan.description) {
465
+ jiraFields.fields.description = testPlan.description;
466
+ }
467
+ const variables = {
468
+ jira: jiraFields
469
+ };
470
+ if (testPlan.testIssueIds && testPlan.testIssueIds.length > 0) {
471
+ variables.testIssueIds = testPlan.testIssueIds;
472
+ }
473
+ const result = await this.graphqlRequest(mutation, variables);
474
+ return {
475
+ issueId: result.createTestPlan.testPlan.issueId,
476
+ key: result.createTestPlan.testPlan.jira.key,
477
+ tests: result.createTestPlan.testPlan.tests?.results || []
478
+ };
479
+ }
480
+ /**
481
+ * Get a test plan by key using GraphQL
482
+ */
483
+ async getTestPlan(testPlanKey) {
484
+ const query = `
485
+ query GetTestPlan($jql: String!, $limit: Int!) {
486
+ getTestPlans(jql: $jql, limit: $limit) {
487
+ total
488
+ results {
489
+ issueId
490
+ projectId
491
+ jira(fields: ["key", "summary", "description", "status"])
492
+ tests(limit: 100) {
493
+ total
494
+ results {
495
+ issueId
496
+ jira(fields: ["key", "summary", "status"])
497
+ testType {
498
+ name
499
+ kind
500
+ }
501
+ }
502
+ }
503
+ }
504
+ }
505
+ }
506
+ `;
507
+ const variables = {
508
+ jql: `key = '${testPlanKey}'`,
509
+ limit: 1
510
+ };
511
+ const result = await this.graphqlRequest(query, variables);
512
+ if (result.getTestPlans.total === 0) {
513
+ throw new Error(`Test plan ${testPlanKey} not found`);
514
+ }
515
+ return result.getTestPlans.results[0];
516
+ }
517
+ /**
518
+ * Search test plans using JQL and GraphQL
519
+ */
520
+ async searchTestPlans(jql, maxResults = 50) {
521
+ const query = `
522
+ query SearchTestPlans($jql: String!, $limit: Int!) {
523
+ getTestPlans(jql: $jql, limit: $limit) {
524
+ total
525
+ start
526
+ limit
527
+ results {
528
+ issueId
529
+ projectId
530
+ jira(fields: ["key", "summary", "description", "status", "created", "updated"])
531
+ tests(limit: 10) {
532
+ total
533
+ results {
534
+ issueId
535
+ jira(fields: ["key", "summary"])
536
+ }
537
+ }
538
+ }
539
+ }
540
+ }
541
+ `;
542
+ const variables = {
543
+ jql,
544
+ limit: maxResults
545
+ };
546
+ const result = await this.graphqlRequest(query, variables);
547
+ return result.getTestPlans;
548
+ }
549
+ /**
550
+ * Get test plans for a project using GraphQL
551
+ */
552
+ async getTestPlansByProject(projectKey, maxResults = 50) {
553
+ const jql = `project = '${projectKey}'`;
554
+ return this.searchTestPlans(jql, maxResults);
555
+ }
556
+ /**
557
+ * Add tests to a test plan using GraphQL mutation
558
+ */
559
+ async addTestsToTestPlan(testPlanIssueId, testIssueIds) {
560
+ const mutation = `
561
+ mutation AddTestsToTestPlan($issueId: String!, $testIssueIds: [String]!) {
562
+ addTestsToTestPlan(issueId: $issueId, testIssueIds: $testIssueIds) {
563
+ addedTests
564
+ warning
565
+ }
566
+ }
567
+ `;
568
+ const variables = {
569
+ issueId: testPlanIssueId,
570
+ testIssueIds
571
+ };
572
+ const result = await this.graphqlRequest(mutation, variables);
573
+ return result.addTestsToTestPlan;
574
+ }
575
+ /**
576
+ * Remove tests from a test plan using GraphQL mutation
577
+ */
578
+ async removeTestsFromTestPlan(testPlanIssueId, testIssueIds) {
579
+ const mutation = `
580
+ mutation RemoveTestsFromTestPlan($issueId: String!, $testIssueIds: [String]!) {
581
+ removeTestsFromTestPlan(issueId: $issueId, testIssueIds: $testIssueIds) {
582
+ removedTests
583
+ warning
584
+ }
585
+ }
586
+ `;
587
+ const variables = {
588
+ issueId: testPlanIssueId,
589
+ testIssueIds
590
+ };
591
+ const result = await this.graphqlRequest(mutation, variables);
592
+ return result.removeTestsFromTestPlan;
593
+ }
594
+ // ========================================
595
+ // Test Set Methods
596
+ // ========================================
597
+ /**
598
+ * Create a new test set using GraphQL mutation
599
+ */
600
+ async createTestSet(testSet) {
601
+ const mutation = `
602
+ mutation CreateTestSet($jira: JSON!, $testIssueIds: [String]) {
603
+ createTestSet(jira: $jira, testIssueIds: $testIssueIds) {
604
+ testSet {
605
+ issueId
606
+ jira(fields: ["key", "summary"])
607
+ tests(limit: 100) {
608
+ results {
609
+ issueId
610
+ jira(fields: ["key", "summary"])
611
+ }
612
+ }
613
+ }
614
+ warnings
615
+ }
616
+ }
617
+ `;
618
+ const jiraFields = {
619
+ fields: {
620
+ project: {
621
+ key: testSet.projectKey
622
+ },
623
+ summary: testSet.summary,
624
+ issuetype: {
625
+ name: 'Test Set'
626
+ }
627
+ }
628
+ };
629
+ if (testSet.description) {
630
+ jiraFields.fields.description = testSet.description;
631
+ }
632
+ const variables = {
633
+ jira: jiraFields
634
+ };
635
+ if (testSet.testIssueIds && testSet.testIssueIds.length > 0) {
636
+ variables.testIssueIds = testSet.testIssueIds;
637
+ }
638
+ const result = await this.graphqlRequest(mutation, variables);
639
+ return {
640
+ issueId: result.createTestSet.testSet.issueId,
641
+ key: result.createTestSet.testSet.jira.key,
642
+ tests: result.createTestSet.testSet.tests?.results || []
643
+ };
644
+ }
645
+ /**
646
+ * Get a test set by key using GraphQL
647
+ */
648
+ async getTestSet(testSetKey) {
649
+ const query = `
650
+ query GetTestSet($jql: String!, $limit: Int!) {
651
+ getTestSets(jql: $jql, limit: $limit) {
652
+ total
653
+ results {
654
+ issueId
655
+ projectId
656
+ jira(fields: ["key", "summary", "description", "status"])
657
+ tests(limit: 100) {
658
+ total
659
+ results {
660
+ issueId
661
+ jira(fields: ["key", "summary", "status"])
662
+ testType {
663
+ name
664
+ kind
665
+ }
666
+ }
667
+ }
668
+ }
669
+ }
670
+ }
671
+ `;
672
+ const variables = {
673
+ jql: `key = '${testSetKey}'`,
674
+ limit: 1
675
+ };
676
+ const result = await this.graphqlRequest(query, variables);
677
+ if (result.getTestSets.total === 0) {
678
+ throw new Error(`Test set ${testSetKey} not found`);
679
+ }
680
+ return result.getTestSets.results[0];
681
+ }
682
+ /**
683
+ * Search test sets using JQL and GraphQL
684
+ */
685
+ async searchTestSets(jql, maxResults = 50) {
686
+ const query = `
687
+ query SearchTestSets($jql: String!, $limit: Int!) {
688
+ getTestSets(jql: $jql, limit: $limit) {
689
+ total
690
+ start
691
+ limit
692
+ results {
693
+ issueId
694
+ projectId
695
+ jira(fields: ["key", "summary", "description", "status", "created", "updated"])
696
+ tests(limit: 10) {
697
+ total
698
+ results {
699
+ issueId
700
+ jira(fields: ["key", "summary"])
701
+ }
702
+ }
703
+ }
704
+ }
705
+ }
706
+ `;
707
+ const variables = {
708
+ jql,
709
+ limit: maxResults
710
+ };
711
+ const result = await this.graphqlRequest(query, variables);
712
+ return result.getTestSets;
713
+ }
714
+ /**
715
+ * Get test sets for a project using GraphQL
716
+ */
717
+ async getTestSetsByProject(projectKey, maxResults = 50) {
718
+ const jql = `project = '${projectKey}'`;
719
+ return this.searchTestSets(jql, maxResults);
720
+ }
721
+ /**
722
+ * Add tests to a test set using GraphQL mutation
723
+ */
724
+ async addTestsToTestSet(testSetIssueId, testIssueIds) {
725
+ const mutation = `
726
+ mutation AddTestsToTestSet($issueId: String!, $testIssueIds: [String]!) {
727
+ addTestsToTestSet(issueId: $issueId, testIssueIds: $testIssueIds) {
728
+ addedTests
729
+ warning
730
+ }
731
+ }
732
+ `;
733
+ const variables = {
734
+ issueId: testSetIssueId,
735
+ testIssueIds
736
+ };
737
+ const result = await this.graphqlRequest(mutation, variables);
738
+ return result.addTestsToTestSet;
739
+ }
740
+ /**
741
+ * Remove tests from a test set using GraphQL mutation
742
+ */
743
+ async removeTestsFromTestSet(testSetIssueId, testIssueIds) {
744
+ const mutation = `
745
+ mutation RemoveTestsFromTestSet($issueId: String!, $testIssueIds: [String]!) {
746
+ removeTestsFromTestSet(issueId: $issueId, testIssueIds: $testIssueIds) {
747
+ removedTests
748
+ warning
749
+ }
750
+ }
751
+ `;
752
+ const variables = {
753
+ issueId: testSetIssueId,
754
+ testIssueIds
755
+ };
756
+ const result = await this.graphqlRequest(mutation, variables);
757
+ return result.removeTestsFromTestSet;
758
+ }
759
+ }