@nbakka/mcp-appium 2.0.80 → 2.0.82

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,38 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Test Case Review & Approval</title>
5
+ <link rel="stylesheet" href="/styles.css">
6
+ </head>
7
+ <body>
8
+ <div class="container">
9
+ <h1>Review Test Cases</h1>
10
+
11
+ <!-- New Test Cases Section -->
12
+ <div class="section" id="new-testcases-section">
13
+ <h2>New Test Cases</h2>
14
+ <div id="new-testcases"></div>
15
+ </div>
16
+
17
+ <!-- Modified Test Cases Section -->
18
+ <div class="section" id="modified-testcases-section">
19
+ <h2>Modified Test Cases</h2>
20
+ <div id="modified-testcases"></div>
21
+ </div>
22
+
23
+ <!-- Test Cases to Remove Section -->
24
+ <div class="section" id="remove-testcases-section">
25
+ <h2>Test Cases to Remove</h2>
26
+ <div id="remove-testcases"></div>
27
+ </div>
28
+
29
+ <div class="button-container">
30
+ <button id="approve-btn" onclick="approveTestCases()">✓ Approve Test Cases</button>
31
+ <button id="cancel-btn" onclick="cancelReview()">✗ Cancel Review</button>
32
+ <div id="status" class="status"></div>
33
+ </div>
34
+ </div>
35
+
36
+ <script src="/script.js"></script>
37
+ </body>
38
+ </html>
@@ -0,0 +1,176 @@
1
+ let sessionId = '';
2
+ let testCasesData = {};
3
+
4
+ function initializeTestCases(data) {
5
+ sessionId = data.sessionId;
6
+ testCasesData = data.testCases;
7
+
8
+ renderNewTestCases();
9
+ renderModifiedTestCases();
10
+ renderRemoveTestCases();
11
+
12
+ // Hide empty sections
13
+ toggleSectionVisibility();
14
+ }
15
+
16
+ function renderNewTestCases() {
17
+ const container = document.getElementById('new-testcases');
18
+ const newCases = testCasesData.new || [];
19
+
20
+ if (newCases.length === 0) {
21
+ container.innerHTML = '<p class="no-cases">No new test cases</p>';
22
+ return;
23
+ }
24
+
25
+ container.innerHTML = newCases.map((testCase, index) => `
26
+ <div class="test-case new" data-index="${index}" data-type="new">
27
+ <div class="test-case-header">
28
+ <span class="test-type new">New</span>
29
+ <button class="remove-btn" onclick="removeTestCase('new', ${index})">Remove</button>
30
+ </div>
31
+ <div class="test-description">
32
+ <textarea onchange="updateTestCase('new', ${index}, this.value)">${testCase}</textarea>
33
+ </div>
34
+ </div>
35
+ `).join('');
36
+ }
37
+
38
+ function renderModifiedTestCases() {
39
+ const container = document.getElementById('modified-testcases');
40
+ const modifiedCases = testCasesData.modify || [];
41
+
42
+ if (modifiedCases.length === 0) {
43
+ container.innerHTML = '<p class="no-cases">No modified test cases</p>';
44
+ return;
45
+ }
46
+
47
+ container.innerHTML = modifiedCases.map((testCase, index) => `
48
+ <div class="test-case modify" data-index="${index}" data-type="modify">
49
+ <div class="test-case-header">
50
+ <span class="test-id">${testCase.id}</span>
51
+ <div>
52
+ <span class="test-type modify">Modify</span>
53
+ <button class="remove-btn" onclick="removeTestCase('modify', ${index})">Remove</button>
54
+ </div>
55
+ </div>
56
+ <div class="before-after">
57
+ <div class="before-content">
58
+ <h4>Before (Original)</h4>
59
+ <div>${testCase.original}</div>
60
+ </div>
61
+ <div class="after-content">
62
+ <h4>After (Modified)</h4>
63
+ <textarea onchange="updateModifiedTestCase(${index}, this.value)">${testCase.modified}</textarea>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ `).join('');
68
+ }
69
+
70
+ function renderRemoveTestCases() {
71
+ const container = document.getElementById('remove-testcases');
72
+ const removeCases = testCasesData.remove || [];
73
+
74
+ if (removeCases.length === 0) {
75
+ container.innerHTML = '<p class="no-cases">No test cases to remove</p>';
76
+ return;
77
+ }
78
+
79
+ container.innerHTML = removeCases.map((testCase, index) => `
80
+ <div class="test-case remove" data-index="${index}" data-type="remove">
81
+ <div class="test-case-header">
82
+ <span class="test-id">${testCase.id}</span>
83
+ <span class="test-type">Remove</span>
84
+ </div>
85
+ <div class="test-description">
86
+ <div>${testCase.description}</div>
87
+ </div>
88
+ </div>
89
+ `).join('');
90
+ }
91
+
92
+ function removeTestCase(type, index) {
93
+ if (confirm('Are you sure you want to remove this test case?')) {
94
+ testCasesData[type].splice(index, 1);
95
+
96
+ if (type === 'new') renderNewTestCases();
97
+ else if (type === 'modify') renderModifiedTestCases();
98
+
99
+ toggleSectionVisibility();
100
+ }
101
+ }
102
+
103
+ function updateTestCase(type, index, value) {
104
+ testCasesData[type][index] = value;
105
+ }
106
+
107
+ function updateModifiedTestCase(index, value) {
108
+ testCasesData.modify[index].modified = value;
109
+ }
110
+
111
+ function toggleSectionVisibility() {
112
+ const newSection = document.getElementById('new-testcases-section');
113
+ const modifySection = document.getElementById('modified-testcases-section');
114
+ const removeSection = document.getElementById('remove-testcases-section');
115
+
116
+ newSection.classList.toggle('hidden', !testCasesData.new || testCasesData.new.length === 0);
117
+ modifySection.classList.toggle('hidden', !testCasesData.modify || testCasesData.modify.length === 0);
118
+ removeSection.classList.toggle('hidden', !testCasesData.remove || testCasesData.remove.length === 0);
119
+ }
120
+
121
+ function approveTestCases() {
122
+ const approveBtn = document.getElementById('approve-btn');
123
+ const cancelBtn = document.getElementById('cancel-btn');
124
+ const status = document.getElementById('status');
125
+
126
+ approveBtn.disabled = true;
127
+ cancelBtn.disabled = true;
128
+ approveBtn.innerHTML = 'Processing...';
129
+ approveBtn.style.background = '#6c757d';
130
+
131
+ status.style.display = 'block';
132
+ status.className = 'status success';
133
+ status.innerHTML = 'Test cases approved! Processing...';
134
+
135
+ fetch(`/approve/${sessionId}`, {
136
+ method: 'POST',
137
+ headers: {
138
+ 'Content-Type': 'application/json',
139
+ },
140
+ body: JSON.stringify(testCasesData)
141
+ })
142
+ .then(response => response.text())
143
+ .then(data => {
144
+ status.innerHTML = data + ' You can close this window.';
145
+ setTimeout(() => {
146
+ window.close();
147
+ }, 3000);
148
+ })
149
+ .catch(error => {
150
+ status.className = 'status error';
151
+ status.innerHTML = 'Error: ' + error.message;
152
+ approveBtn.disabled = false;
153
+ cancelBtn.disabled = false;
154
+ });
155
+ }
156
+
157
+ function cancelReview() {
158
+ if (confirm('Are you sure you want to cancel the review? All changes will be lost.')) {
159
+ fetch(`/cancel/${sessionId}`, { method: 'POST' })
160
+ .then(() => {
161
+ window.close();
162
+ });
163
+ }
164
+ }
165
+
166
+ // Load initial data when page loads
167
+ window.addEventListener('DOMContentLoaded', function() {
168
+ fetch('/api/testcases')
169
+ .then(response => response.json())
170
+ .then(data => {
171
+ initializeTestCases(data);
172
+ })
173
+ .catch(error => {
174
+ console.error('Error loading test cases:', error);
175
+ });
176
+ });
@@ -0,0 +1,244 @@
1
+ body {
2
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
3
+ margin: 0;
4
+ padding: 20px;
5
+ background-color: #f8f9fa;
6
+ line-height: 1.6;
7
+ }
8
+
9
+ .container {
10
+ max-width: 1400px;
11
+ margin: 0 auto;
12
+ background: white;
13
+ padding: 30px;
14
+ border-radius: 12px;
15
+ box-shadow: 0 4px 20px rgba(0,0,0,0.1);
16
+ }
17
+
18
+ h1 {
19
+ color: #2c3e50;
20
+ text-align: center;
21
+ border-bottom: 3px solid #3498db;
22
+ padding-bottom: 15px;
23
+ margin-bottom: 30px;
24
+ }
25
+
26
+ h2 {
27
+ color: #34495e;
28
+ border-left: 4px solid #3498db;
29
+ padding-left: 15px;
30
+ margin-top: 30px;
31
+ }
32
+
33
+ .section {
34
+ margin-bottom: 40px;
35
+ padding: 20px;
36
+ border: 1px solid #e9ecef;
37
+ border-radius: 8px;
38
+ background: #fdfdfd;
39
+ }
40
+
41
+ .test-case {
42
+ margin: 15px 0;
43
+ padding: 20px;
44
+ border: 1px solid #dee2e6;
45
+ border-radius: 8px;
46
+ background: white;
47
+ position: relative;
48
+ }
49
+
50
+ .test-case.new {
51
+ border-left: 4px solid #28a745;
52
+ }
53
+
54
+ .test-case.modify {
55
+ border-left: 4px solid #ffc107;
56
+ }
57
+
58
+ .test-case.remove {
59
+ border-left: 4px solid #dc3545;
60
+ background: #fff5f5;
61
+ }
62
+
63
+ .test-case-header {
64
+ display: flex;
65
+ justify-content: space-between;
66
+ align-items: center;
67
+ margin-bottom: 15px;
68
+ }
69
+
70
+ .test-id {
71
+ font-weight: bold;
72
+ color: #3498db;
73
+ font-size: 14px;
74
+ background: #ecf0f1;
75
+ padding: 4px 8px;
76
+ border-radius: 4px;
77
+ }
78
+
79
+ .test-type {
80
+ padding: 4px 12px;
81
+ border-radius: 20px;
82
+ font-size: 12px;
83
+ font-weight: bold;
84
+ text-transform: uppercase;
85
+ }
86
+
87
+ .test-type.new {
88
+ background: #d4edda;
89
+ color: #155724;
90
+ }
91
+
92
+ .test-type.modify {
93
+ background: #fff3cd;
94
+ color: #856404;
95
+ }
96
+
97
+ .remove-btn {
98
+ background: #dc3545;
99
+ color: white;
100
+ border: none;
101
+ padding: 6px 12px;
102
+ border-radius: 4px;
103
+ cursor: pointer;
104
+ font-size: 12px;
105
+ }
106
+
107
+ .remove-btn:hover {
108
+ background: #c82333;
109
+ }
110
+
111
+ .test-description {
112
+ margin: 10px 0;
113
+ }
114
+
115
+ .test-description textarea {
116
+ width: 100%;
117
+ min-height: 60px;
118
+ padding: 10px;
119
+ border: 1px solid #ced4da;
120
+ border-radius: 4px;
121
+ font-family: inherit;
122
+ resize: vertical;
123
+ }
124
+
125
+ .test-description textarea:focus {
126
+ outline: none;
127
+ border-color: #3498db;
128
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
129
+ }
130
+
131
+ .before-after {
132
+ display: grid;
133
+ grid-template-columns: 1fr 1fr;
134
+ gap: 15px;
135
+ margin-top: 15px;
136
+ }
137
+
138
+ .before-content, .after-content {
139
+ padding: 10px;
140
+ border-radius: 4px;
141
+ }
142
+
143
+ .before-content {
144
+ background: #f8f9fa;
145
+ border: 1px solid #dee2e6;
146
+ }
147
+
148
+ .after-content {
149
+ background: #fff;
150
+ border: 1px solid #ced4da;
151
+ }
152
+
153
+ .before-content h4, .after-content h4 {
154
+ margin: 0 0 8px 0;
155
+ font-size: 14px;
156
+ color: #495057;
157
+ }
158
+
159
+ .after-content textarea {
160
+ width: 100%;
161
+ min-height: 50px;
162
+ border: 1px solid #ced4da;
163
+ border-radius: 4px;
164
+ padding: 8px;
165
+ font-family: inherit;
166
+ }
167
+
168
+ .button-container {
169
+ text-align: center;
170
+ margin-top: 40px;
171
+ padding-top: 30px;
172
+ border-top: 2px solid #e9ecef;
173
+ }
174
+
175
+ button {
176
+ padding: 15px 30px;
177
+ margin: 0 10px;
178
+ border: none;
179
+ border-radius: 6px;
180
+ cursor: pointer;
181
+ font-size: 16px;
182
+ font-weight: bold;
183
+ transition: all 0.3s ease;
184
+ }
185
+
186
+ #approve-btn {
187
+ background: #28a745;
188
+ color: white;
189
+ }
190
+
191
+ #approve-btn:hover {
192
+ background: #218838;
193
+ transform: translateY(-1px);
194
+ }
195
+
196
+ #cancel-btn {
197
+ background: #6c757d;
198
+ color: white;
199
+ }
200
+
201
+ #cancel-btn:hover {
202
+ background: #5a6268;
203
+ }
204
+
205
+ .status {
206
+ text-align: center;
207
+ margin-top: 20px;
208
+ font-weight: bold;
209
+ display: none;
210
+ padding: 15px;
211
+ border-radius: 6px;
212
+ }
213
+
214
+ .status.success {
215
+ background: #d4edda;
216
+ color: #155724;
217
+ border: 1px solid #c3e6cb;
218
+ }
219
+
220
+ .status.error {
221
+ background: #f8d7da;
222
+ color: #721c24;
223
+ border: 1px solid #f5c6cb;
224
+ }
225
+
226
+ .hidden {
227
+ display: none !important;
228
+ }
229
+
230
+ @media (max-width: 768px) {
231
+ .before-after {
232
+ grid-template-columns: 1fr;
233
+ }
234
+
235
+ .container {
236
+ padding: 15px;
237
+ }
238
+
239
+ button {
240
+ display: block;
241
+ width: 100%;
242
+ margin: 5px 0;
243
+ }
244
+ }
package/lib/server.js CHANGED
@@ -799,23 +799,48 @@ let approvalSessions = new Map();
799
799
 
800
800
  tool(
801
801
  "review_testcases",
802
- "Open JSON test cases in browser for manual approval",
802
+ "Open test cases in browser for manual approval. Accepts test cases in format: [description, type, id?]",
803
803
  {
804
- testCases: zod_1.z.array(zod_1.z.object({
805
- id: zod_1.z.string(),
806
- title: zod_1.z.string(),
807
- description: zod_1.z.string(),
808
- })).describe("Array of test cases to review")
804
+ testCases: zod_1.z.array(zod_1.z.array(zod_1.z.string())).describe("Array of test case arrays: [description, type, id?] where type is 'New', 'Modify', or 'Remove'")
809
805
  },
810
806
  async ({ testCases }) => {
811
807
  try {
812
808
  const express = require('express');
809
+ const path = require('path');
813
810
  const sessionId = Date.now().toString();
814
811
 
812
+ // Parse test cases into categories
813
+ const parsedTestCases = {
814
+ new: [],
815
+ modify: [],
816
+ remove: []
817
+ };
818
+
819
+ testCases.forEach(tc => {
820
+ const [description, type, id] = tc;
821
+ const typeKey = type.toLowerCase();
822
+
823
+ if (typeKey === 'new') {
824
+ parsedTestCases.new.push(description);
825
+ } else if (typeKey === 'modify') {
826
+ parsedTestCases.modify.push({
827
+ id: id || 'N/A',
828
+ original: description,
829
+ modified: description // Default to original, user can edit
830
+ });
831
+ } else if (typeKey === 'remove') {
832
+ parsedTestCases.remove.push({
833
+ id: id || 'N/A',
834
+ description: description
835
+ });
836
+ }
837
+ });
838
+
815
839
  // Initialize session state
816
840
  approvalSessions.set(sessionId, {
817
841
  status: 'pending',
818
- testCases: testCases,
842
+ testCases: parsedTestCases,
843
+ originalTestCases: JSON.parse(JSON.stringify(parsedTestCases)), // Deep copy
819
844
  server: null,
820
845
  startTime: Date.now()
821
846
  });
@@ -823,157 +848,55 @@ tool(
823
848
  const app = express();
824
849
  const port = 3001;
825
850
 
826
- // Serve a simple HTML page with test cases
851
+ // Middleware for JSON parsing
852
+ app.use(express.json());
853
+ app.use(express.static(path.join(__dirname, 'review-ui')));
854
+
855
+ // Main page
827
856
  app.get("/", (req, res) => {
828
- let html = `
829
- <html>
830
- <head>
831
- <title>Test Case Approval</title>
832
- <style>
833
- body {
834
- font-family: Arial, sans-serif;
835
- margin: 20px;
836
- background-color: #f5f5f5;
837
- }
838
- .container {
839
- max-width: 1200px;
840
- margin: 0 auto;
841
- background: white;
842
- padding: 20px;
843
- border-radius: 8px;
844
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
845
- }
846
- h1 {
847
- color: #333;
848
- text-align: center;
849
- border-bottom: 2px solid #007cba;
850
- padding-bottom: 10px;
851
- }
852
- .test-case {
853
- margin: 15px 0;
854
- padding: 15px;
855
- border: 1px solid #ddd;
856
- border-radius: 8px;
857
- background: #fafafa;
858
- }
859
- .test-id {
860
- font-weight: bold;
861
- color: #007cba;
862
- font-size: 16px;
863
- }
864
- .test-title {
865
- font-weight: bold;
866
- margin: 5px 0;
867
- color: #333;
868
- }
869
- .test-description {
870
- color: #666;
871
- line-height: 1.4;
872
- }
873
- .button-container {
874
- text-align: center;
875
- margin-top: 30px;
876
- padding-top: 20px;
877
- border-top: 1px solid #ddd;
878
- }
879
- button {
880
- padding: 15px 30px;
881
- background: #28a745;
882
- color: white;
883
- border: none;
884
- border-radius: 5px;
885
- cursor: pointer;
886
- font-size: 16px;
887
- font-weight: bold;
888
- }
889
- button:hover {
890
- background: #218838;
891
- }
892
- .status {
893
- text-align: center;
894
- margin-top: 20px;
895
- font-weight: bold;
896
- display: none;
897
- }
898
- </style>
899
- </head>
900
- <body>
901
- <div class="container">
902
- <h1>Review Test Cases</h1>
903
- <div id="test-cases">
904
- `;
905
-
906
- testCases.forEach(tc => {
907
- html += `
908
- <div class="test-case">
909
- <div class="test-id">${tc.id}</div>
910
- <div class="test-title">${tc.title}</div>
911
- <div class="test-description">${tc.description}</div>
912
- </div>
913
- `;
914
- });
857
+ res.sendFile(path.join(__dirname, 'review-ui', 'index.html'));
858
+ });
915
859
 
916
- html += `
917
- </div>
918
- <div class="button-container">
919
- <button onclick="approveTestCases()">✓ Approve Test Cases</button>
920
- <div id="status" class="status"></div>
921
- </div>
922
- </div>
923
-
924
- <script>
925
- function approveTestCases() {
926
- document.querySelector('button').disabled = true;
927
- document.querySelector('button').style.background = '#6c757d';
928
- document.querySelector('button').innerHTML = 'Processing...';
929
-
930
- const status = document.getElementById('status');
931
- status.style.display = 'block';
932
- status.style.color = '#28a745';
933
- status.innerHTML = 'Test cases approved! You can close this window.';
934
-
935
- fetch('/approve/${sessionId}')
936
- .then(response => response.text())
937
- .then(data => {
938
- status.innerHTML = data + ' You can close this window.';
939
- setTimeout(() => {
940
- window.close();
941
- }, 2000);
942
- })
943
- .catch(error => {
944
- status.style.color = '#dc3545';
945
- status.innerHTML = 'Error: ' + error.message;
946
- });
947
- }
948
- </script>
949
- </body>
950
- </html>
951
- `;
952
- res.send(html);
860
+ // API to get test cases data
861
+ app.get("/api/testcases", (req, res) => {
862
+ const session = approvalSessions.get(sessionId);
863
+ res.json({
864
+ sessionId: sessionId,
865
+ testCases: session ? session.testCases : {}
866
+ });
953
867
  });
954
868
 
955
869
  // Approval endpoint
956
- app.get(`/approve/${sessionId}`, (req, res) => {
870
+ app.post(`/approve/${sessionId}`, (req, res) => {
957
871
  const session = approvalSessions.get(sessionId);
958
872
  if (session) {
959
873
  session.status = 'approved';
874
+ session.finalTestCases = req.body; // Store the final approved test cases
960
875
  approvalSessions.set(sessionId, session);
961
876
  }
962
877
  res.send("✓ Test cases approved successfully!");
963
878
  });
964
879
 
880
+ // Cancel endpoint
881
+ app.post(`/cancel/${sessionId}`, (req, res) => {
882
+ const session = approvalSessions.get(sessionId);
883
+ if (session) {
884
+ session.status = 'cancelled';
885
+ approvalSessions.set(sessionId, session);
886
+ }
887
+ res.send("Review cancelled");
888
+ });
889
+
965
890
  // Start server
966
891
  const server = app.listen(port, async () => {
967
892
  console.log(`Test case review server started on http://localhost:${port}`);
968
893
 
969
894
  try {
970
- // Use dynamic import for the open package (ES module)
971
895
  const { default: open } = await import('open');
972
896
  await open(`http://localhost:${port}`);
973
897
  console.log('Browser opened successfully');
974
898
  } catch (openError) {
975
899
  console.log('Failed to open browser automatically:', openError.message);
976
- console.log(`Please manually open: http://localhost:${port}`);
977
900
  }
978
901
  });
979
902
 
@@ -1000,7 +923,7 @@ tool(
1000
923
  message: "Test case review interface opened in browser. Use check_approval_status tool to poll for approval.",
1001
924
  testCasesCount: testCases.length,
1002
925
  browserUrl: `http://localhost:${port}`,
1003
- instructions: "Poll every 10 seconds using check_approval_status tool until approved or timeout (5 minutes)"
926
+ instructions: "Poll every 25 seconds using check_approval_status tool until approved or timeout (5 minutes)"
1004
927
  });
1005
928
 
1006
929
  } catch (err) {
@@ -1014,11 +937,14 @@ tool(
1014
937
 
1015
938
  tool(
1016
939
  "check_approval_status",
1017
- "Check the approval status of test cases review session",
940
+ "Check the approval status of test cases review session with 25 second wait",
1018
941
  {
1019
942
  sessionId: zod_1.z.string().describe("The session ID returned from review_testcases tool")
1020
943
  },
1021
944
  async ({ sessionId }) => {
945
+ // Add 25 second hard wait
946
+ await new Promise(resolve => setTimeout(resolve, 25000));
947
+
1022
948
  const session = approvalSessions.get(sessionId);
1023
949
 
1024
950
  if (!session) {
@@ -1036,12 +962,26 @@ tool(
1036
962
  if (session.server) {
1037
963
  session.server.close();
1038
964
  }
965
+
966
+ const approvedTestCases = session.finalTestCases || session.testCases;
1039
967
  approvalSessions.delete(sessionId);
1040
968
 
1041
969
  return JSON.stringify({
1042
970
  status: "approved",
1043
- message: "Test cases have been approved by the user. Continuing with next operations...",
1044
- testCasesCount: session.testCases.length,
971
+ message: "Test cases have been approved by the user.",
972
+ approvedTestCases: approvedTestCases,
973
+ elapsedTime: elapsedTime
974
+ });
975
+ } else if (session.status === 'cancelled') {
976
+ // Clean up session and close server
977
+ if (session.server) {
978
+ session.server.close();
979
+ }
980
+ approvalSessions.delete(sessionId);
981
+
982
+ return JSON.stringify({
983
+ status: "cancelled",
984
+ message: "Review was cancelled by the user.",
1045
985
  elapsedTime: elapsedTime
1046
986
  });
1047
987
  } else if (session.status === 'timeout' || elapsedTime > 300) { // 5 minutes
@@ -1054,20 +994,19 @@ tool(
1054
994
  return JSON.stringify({
1055
995
  status: "timeout",
1056
996
  message: "Review session timed out after 5 minutes. Test cases were not approved.",
1057
- testCasesCount: session.testCases.length,
1058
997
  elapsedTime: elapsedTime
1059
998
  });
1060
999
  } else {
1061
1000
  return JSON.stringify({
1062
1001
  status: "pending",
1063
1002
  message: "Test cases are still pending approval. Continue polling.",
1064
- testCasesCount: session.testCases.length,
1065
1003
  elapsedTime: elapsedTime,
1066
1004
  remainingTime: Math.max(0, 300 - elapsedTime)
1067
1005
  });
1068
1006
  }
1069
1007
  }
1070
1008
  );
1009
+
1071
1010
  return server;
1072
1011
  };
1073
1012
 
@@ -6,9 +6,12 @@ have other features which are not part of the jira ticket,
6
6
  final output should be test in following format
7
7
  "Verify pay on credit banner exits on PDP", "Existing"
8
8
  "Verify overview tab on PDP", "New"
9
- "Verify financial services are displayed under financial tab", "Remove"
10
- "Verify xyz is moved to sja ", "Modify"
11
- here existing means the test case is already present in the repo
12
- new means the test case is not present in the repo and needs to be added
13
- remove means the test case is present in the repo but is not required and needs to be removed
14
- modify means the test case is present in the repo but needs some modification
9
+ "Verify financial services are displayed under financial tab", "Remove", "SCRUM-TC-2"
10
+ "Verify xyz is moved to sja ", "Modify", "SCRUM-TC-2"
11
+ Existing - already exists in TCMS and no changes needed
12
+ New - doesn't exist in TCMS and needs to be created
13
+ Remove - to remove test cases from TCMS because it is no longer valid
14
+ Modify - existing TCMS test case needs to be modified because of changes in the feature, only test cases
15
+ existing in TCMS and if change is to be done to it should be marked as Modify
16
+ "SCRUM-TC-2" - id of existing test case in TCMS, only for Remove and Modify test cases
17
+ if any new test case is to be created then don't mention any id against it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nbakka/mcp-appium",
3
- "version": "2.0.80",
3
+ "version": "2.0.82",
4
4
  "description": "Appium MCP",
5
5
  "engines": {
6
6
  "node": ">=18"