@nbakka/mcp-appium 3.0.10 → 3.0.12
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/lib/server.js +170 -26
- package/lib/testcases-generation-context.txt +2 -1
- package/package.json +1 -1
package/lib/server.js
CHANGED
|
@@ -837,22 +837,46 @@ tool(
|
|
|
837
837
|
|
|
838
838
|
// Process test cases - handle the specific format properly
|
|
839
839
|
const processedTestCases = testCases.map((testCase, index) => {
|
|
840
|
-
// Each testCase is an array like ["title", "description", "status", "originalCase"]
|
|
841
840
|
if (Array.isArray(testCase)) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
841
|
+
const arrayLength = testCase.length;
|
|
842
|
+
|
|
843
|
+
if (arrayLength === 4) {
|
|
844
|
+
// Modify case: ["original title", "new description", "Modify", "SCRUM-TC-1"]
|
|
845
|
+
return {
|
|
846
|
+
originalTitle: testCase[0] || `Test Case ${index + 1}`,
|
|
847
|
+
newDescription: testCase[1] || '',
|
|
848
|
+
status: testCase[2] || 'Modify',
|
|
849
|
+
testId: testCase[3] || '',
|
|
850
|
+
index: index
|
|
851
|
+
};
|
|
852
|
+
} else if (arrayLength === 3) {
|
|
853
|
+
// Remove case: ["title", "Remove", "SCRUM-TC-2"]
|
|
854
|
+
return {
|
|
855
|
+
title: testCase[0] || `Test Case ${index + 1}`,
|
|
856
|
+
status: testCase[1] || 'Remove',
|
|
857
|
+
testId: testCase[2] || '',
|
|
858
|
+
index: index
|
|
859
|
+
};
|
|
860
|
+
} else if (arrayLength === 2) {
|
|
861
|
+
// New case: ["title", "New"]
|
|
862
|
+
return {
|
|
863
|
+
title: testCase[0] || `Test Case ${index + 1}`,
|
|
864
|
+
status: testCase[1] || 'New',
|
|
865
|
+
index: index
|
|
866
|
+
};
|
|
867
|
+
} else {
|
|
868
|
+
// Fallback for unexpected format
|
|
869
|
+
return {
|
|
870
|
+
title: testCase[0] || `Test Case ${index + 1}`,
|
|
871
|
+
status: 'New',
|
|
872
|
+
index: index
|
|
873
|
+
};
|
|
874
|
+
}
|
|
849
875
|
} else {
|
|
850
|
-
// Fallback for
|
|
876
|
+
// Fallback for non-array format
|
|
851
877
|
return {
|
|
852
878
|
title: String(testCase) || `Test Case ${index + 1}`,
|
|
853
|
-
description: '',
|
|
854
879
|
status: 'New',
|
|
855
|
-
originalCase: '',
|
|
856
880
|
index: index
|
|
857
881
|
};
|
|
858
882
|
}
|
|
@@ -864,12 +888,12 @@ tool(
|
|
|
864
888
|
|
|
865
889
|
if (status === 'modify') {
|
|
866
890
|
// For modify cases, show original → changed format
|
|
867
|
-
return
|
|
891
|
+
return `Original: ${testCase.originalTitle}\nChanged to: ${testCase.newDescription}`;
|
|
868
892
|
} else if (status === 'remove') {
|
|
869
|
-
// For remove cases,
|
|
893
|
+
// For remove cases, show the title
|
|
870
894
|
return testCase.title;
|
|
871
895
|
} else {
|
|
872
|
-
// For new cases,
|
|
896
|
+
// For new cases, show the title
|
|
873
897
|
return testCase.title;
|
|
874
898
|
}
|
|
875
899
|
};
|
|
@@ -1176,10 +1200,10 @@ tool(
|
|
|
1176
1200
|
|
|
1177
1201
|
// Create proper label and test ID display for modify/remove cases
|
|
1178
1202
|
let labelAndIdDisplay = '';
|
|
1179
|
-
if (testCase.status.toLowerCase() === 'modify' && testCase.
|
|
1180
|
-
labelAndIdDisplay = `<div style="margin-bottom: 8px; font-weight: 600; color: #856404; font-size: 13px;">Modify - ${testCase.
|
|
1181
|
-
} else if (testCase.status.toLowerCase() === 'remove' && testCase.
|
|
1182
|
-
labelAndIdDisplay = `<div style="margin-bottom: 8px; font-weight: 600; color: #721c24; font-size: 13px;">Remove - ${testCase.
|
|
1203
|
+
if (testCase.status.toLowerCase() === 'modify' && testCase.testId) {
|
|
1204
|
+
labelAndIdDisplay = `<div style="margin-bottom: 8px; font-weight: 600; color: #856404; font-size: 13px;">Modify - ${testCase.testId}</div>`;
|
|
1205
|
+
} else if (testCase.status.toLowerCase() === 'remove' && testCase.testId) {
|
|
1206
|
+
labelAndIdDisplay = `<div style="margin-bottom: 8px; font-weight: 600; color: #721c24; font-size: 13px;">Remove - ${testCase.testId}</div>`;
|
|
1183
1207
|
}
|
|
1184
1208
|
|
|
1185
1209
|
return `
|
|
@@ -1245,7 +1269,9 @@ tool(
|
|
|
1245
1269
|
const status = originalTestCase.status.toLowerCase();
|
|
1246
1270
|
|
|
1247
1271
|
if (status === 'modify') {
|
|
1248
|
-
resetValue =
|
|
1272
|
+
resetValue = 'Original: ' + originalTestCase.originalTitle + '\\nChanged to: ' + originalTestCase.newDescription;
|
|
1273
|
+
} else if (status === 'remove') {
|
|
1274
|
+
resetValue = originalTestCase.title;
|
|
1249
1275
|
} else {
|
|
1250
1276
|
resetValue = originalTestCase.title;
|
|
1251
1277
|
}
|
|
@@ -1275,13 +1301,32 @@ tool(
|
|
|
1275
1301
|
const textarea = el.querySelector('textarea');
|
|
1276
1302
|
const originalTestCase = testCases[index];
|
|
1277
1303
|
|
|
1278
|
-
// Create the updated test case array
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1304
|
+
// Create the updated test case array based on the original format
|
|
1305
|
+
let updatedCase;
|
|
1306
|
+
const status = originalTestCase.status.toLowerCase();
|
|
1307
|
+
|
|
1308
|
+
if (status === 'modify') {
|
|
1309
|
+
// For modify: [updatedContent, newDescription, "Modify", testId]
|
|
1310
|
+
updatedCase = [
|
|
1311
|
+
textarea.value.trim(),
|
|
1312
|
+
originalTestCase.newDescription,
|
|
1313
|
+
originalTestCase.status,
|
|
1314
|
+
originalTestCase.testId
|
|
1315
|
+
];
|
|
1316
|
+
} else if (status === 'remove') {
|
|
1317
|
+
// For remove: [updatedContent, "Remove", testId]
|
|
1318
|
+
updatedCase = [
|
|
1319
|
+
textarea.value.trim(),
|
|
1320
|
+
originalTestCase.status,
|
|
1321
|
+
originalTestCase.testId
|
|
1322
|
+
];
|
|
1323
|
+
} else {
|
|
1324
|
+
// For new: [updatedContent, "New"]
|
|
1325
|
+
updatedCase = [
|
|
1326
|
+
textarea.value.trim(),
|
|
1327
|
+
originalTestCase.status
|
|
1328
|
+
];
|
|
1329
|
+
}
|
|
1285
1330
|
|
|
1286
1331
|
updatedTestCases.push(updatedCase);
|
|
1287
1332
|
}
|
|
@@ -1523,6 +1568,105 @@ tool(
|
|
|
1523
1568
|
}
|
|
1524
1569
|
);
|
|
1525
1570
|
|
|
1571
|
+
tool(
|
|
1572
|
+
"update_testcases_to_tcms",
|
|
1573
|
+
"Create new test cases in TCMS from approved test cases. Only processes test cases with 'New' status, ignores Modify and Remove cases since APIs are not available.",
|
|
1574
|
+
{
|
|
1575
|
+
testCases: zod_1.z.array(zod_1.z.array(zod_1.z.string())).describe("Array of test case arrays from approved test cases")
|
|
1576
|
+
},
|
|
1577
|
+
async ({ testCases }) => {
|
|
1578
|
+
try {
|
|
1579
|
+
// Load AIO token from Desktop/aio.json
|
|
1580
|
+
const aioConfigPath = path.join(os.homedir(), "Desktop", "aio.json");
|
|
1581
|
+
const configContent = await fs.readFile(aioConfigPath, "utf-8");
|
|
1582
|
+
const { token } = JSON.parse(configContent);
|
|
1583
|
+
|
|
1584
|
+
if (!token) throw new Error("AIO token missing in aio.json");
|
|
1585
|
+
|
|
1586
|
+
// Filter test cases to extract only "New" test cases
|
|
1587
|
+
const newTestCases = [];
|
|
1588
|
+
|
|
1589
|
+
for (const testCase of testCases) {
|
|
1590
|
+
if (Array.isArray(testCase) && testCase.length >= 2) {
|
|
1591
|
+
// Check if the last element or second-to-last element is "New"
|
|
1592
|
+
const status = testCase.length === 2 ? testCase[1] : testCase[testCase.length - 2];
|
|
1593
|
+
|
|
1594
|
+
if (status && status.toLowerCase() === 'new') {
|
|
1595
|
+
const title = testCase[0]; // First element is always the title
|
|
1596
|
+
if (title && title.trim().length > 0) {
|
|
1597
|
+
newTestCases.push(title.trim());
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
if (newTestCases.length === 0) {
|
|
1604
|
+
return "No new test cases found to create in TCMS. Only test cases marked as '(New)' are processed.";
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// Hard-coded values as requested
|
|
1608
|
+
const projectKey = "SCRUM";
|
|
1609
|
+
const folderId = 1;
|
|
1610
|
+
const ownerId = "712020:37085ff2-5a05-47eb-8977-50a485355755";
|
|
1611
|
+
|
|
1612
|
+
// Create test cases in TCMS one by one
|
|
1613
|
+
for (let i = 0; i < newTestCases.length; i++) {
|
|
1614
|
+
const title = newTestCases[i];
|
|
1615
|
+
|
|
1616
|
+
try {
|
|
1617
|
+
const requestBody = {
|
|
1618
|
+
title: title,
|
|
1619
|
+
ownedByID: ownerId,
|
|
1620
|
+
folder: {
|
|
1621
|
+
ID: folderId
|
|
1622
|
+
},
|
|
1623
|
+
status: {
|
|
1624
|
+
name: "Published",
|
|
1625
|
+
description: "The test is ready for execution",
|
|
1626
|
+
ID: 1
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
(0, logger_1.trace)(`Creating test case ${i + 1}/${newTestCases.length}: ${title}`);
|
|
1631
|
+
|
|
1632
|
+
const response = await axios.post(
|
|
1633
|
+
`https://tcms.aiojiraapps.com/aio-tcms/api/v1/project/${projectKey}/testcase`,
|
|
1634
|
+
requestBody,
|
|
1635
|
+
{
|
|
1636
|
+
headers: {
|
|
1637
|
+
"accept": "application/json;charset=utf-8",
|
|
1638
|
+
"Authorization": `AioAuth ${token}`,
|
|
1639
|
+
"Content-Type": "application/json"
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
);
|
|
1643
|
+
|
|
1644
|
+
if (response.status === 200 || response.status === 201) {
|
|
1645
|
+
const testCaseKey = response.data.key || `${projectKey}-TC-${response.data.ID}`;
|
|
1646
|
+
(0, logger_1.trace)(`Successfully created test case: ${testCaseKey} - ${title}`);
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
// Add a small delay between requests to avoid rate limiting
|
|
1650
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
1651
|
+
|
|
1652
|
+
} catch (error) {
|
|
1653
|
+
(0, logger_1.trace)(`Failed to create test case: ${title} - ${error.message}`);
|
|
1654
|
+
throw new Error(`Failed to create test case "${title}": ${error.message}`);
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
return "All test cases have been updated to TCMS";
|
|
1659
|
+
|
|
1660
|
+
} catch (error) {
|
|
1661
|
+
console.error('TCMS update error:', error);
|
|
1662
|
+
if (error.response) {
|
|
1663
|
+
return `❌ TCMS API Error: ${error.response.status} - ${error.response.data?.message || error.response.statusText}`;
|
|
1664
|
+
}
|
|
1665
|
+
return `❌ Error updating test cases to TCMS: ${error.message}`;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
);
|
|
1669
|
+
|
|
1526
1670
|
return server;
|
|
1527
1671
|
};
|
|
1528
1672
|
|
|
@@ -16,9 +16,10 @@ should contains before test case from tcms and after testcase that is generated,
|
|
|
16
16
|
existing in TCMS and if change is to be done to it should be marked as Modify
|
|
17
17
|
"SCRUM-TC-2" - id of existing test case in TCMS, only for Remove and Modify test cases
|
|
18
18
|
if any new test case is to be created then don't mention any id against it
|
|
19
|
-
for review_testcases
|
|
19
|
+
for review_testcases and update_testcases_to_tcms tool data should be in this format, strictly follow this format espcially for Modify test cases
|
|
20
20
|
{"testCases":[["Verify that brochure section is visible under overview tab","Verify brochure section is removed from property tour tab","Modify","SCRUM-TC-1"],
|
|
21
21
|
["Verify similar properties section is visible under over tab in pdp section","Remove","SCRUM-TC-2"],
|
|
22
22
|
["Verify Project Brochure section appears above the 'Explore on map' section in Overview tab","New"]]}
|
|
23
23
|
|
|
24
|
+
for update_testcases_to_tcms tool, send only test cases approved by user
|
|
24
25
|
NOTE: keep polling continously for 10 times max till the test cases are approved by user
|