@nbakka/mcp-appium 2.0.67 → 2.0.68

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.
Files changed (2) hide show
  1. package/lib/server.js +132 -26
  2. package/package.json +1 -1
package/lib/server.js CHANGED
@@ -664,12 +664,12 @@ tool(
664
664
  async ({ testCases }) => {
665
665
  try {
666
666
  const express = require('express');
667
- const open = require('open');
668
667
 
669
- return new Promise((resolve, reject) => {
668
+ return new Promise(async (resolve, reject) => {
670
669
  const app = express();
671
670
  const port = 3001;
672
671
  let server;
672
+ let userApproved = false;
673
673
 
674
674
  // Serve a simple HTML page with test cases
675
675
  app.get("/", (req, res) => {
@@ -678,25 +678,122 @@ tool(
678
678
  <head>
679
679
  <title>Test Case Approval</title>
680
680
  <style>
681
- body { font-family: Arial, sans-serif; margin: 20px; }
682
- h1 { color: #333; }
683
- li { margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
684
- button { padding: 10px 20px; background: #007cba; color: white; border: none; border-radius: 5px; cursor: pointer; }
685
- button:hover { background: #005a87; }
681
+ body {
682
+ font-family: Arial, sans-serif;
683
+ margin: 20px;
684
+ background-color: #f5f5f5;
685
+ }
686
+ .container {
687
+ max-width: 1200px;
688
+ margin: 0 auto;
689
+ background: white;
690
+ padding: 20px;
691
+ border-radius: 8px;
692
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
693
+ }
694
+ h1 {
695
+ color: #333;
696
+ text-align: center;
697
+ border-bottom: 2px solid #007cba;
698
+ padding-bottom: 10px;
699
+ }
700
+ .test-case {
701
+ margin: 15px 0;
702
+ padding: 15px;
703
+ border: 1px solid #ddd;
704
+ border-radius: 8px;
705
+ background: #fafafa;
706
+ }
707
+ .test-id {
708
+ font-weight: bold;
709
+ color: #007cba;
710
+ font-size: 16px;
711
+ }
712
+ .test-title {
713
+ font-weight: bold;
714
+ margin: 5px 0;
715
+ color: #333;
716
+ }
717
+ .test-description {
718
+ color: #666;
719
+ line-height: 1.4;
720
+ }
721
+ .button-container {
722
+ text-align: center;
723
+ margin-top: 30px;
724
+ padding-top: 20px;
725
+ border-top: 1px solid #ddd;
726
+ }
727
+ button {
728
+ padding: 15px 30px;
729
+ background: #28a745;
730
+ color: white;
731
+ border: none;
732
+ border-radius: 5px;
733
+ cursor: pointer;
734
+ font-size: 16px;
735
+ font-weight: bold;
736
+ }
737
+ button:hover {
738
+ background: #218838;
739
+ }
740
+ .status {
741
+ text-align: center;
742
+ margin-top: 20px;
743
+ font-weight: bold;
744
+ display: none;
745
+ }
686
746
  </style>
687
747
  </head>
688
748
  <body>
689
- <h1>Review Test Cases</h1>
690
- <ul>
749
+ <div class="container">
750
+ <h1>Review Test Cases</h1>
751
+ <div id="test-cases">
691
752
  `;
692
753
 
693
754
  testCases.forEach(tc => {
694
- html += `<li><strong>${tc.id} - ${tc.title}</strong><p>${tc.description}</p></li>`;
755
+ html += `
756
+ <div class="test-case">
757
+ <div class="test-id">${tc.id}</div>
758
+ <div class="test-title">${tc.title}</div>
759
+ <div class="test-description">${tc.description}</div>
760
+ </div>
761
+ `;
695
762
  });
696
763
 
697
764
  html += `
698
- </ul>
699
- <button onclick="fetch('/approve').then(()=>window.close())">Approve</button>
765
+ </div>
766
+ <div class="button-container">
767
+ <button onclick="approveTestCases()">✓ Approve Test Cases</button>
768
+ <div id="status" class="status"></div>
769
+ </div>
770
+ </div>
771
+
772
+ <script>
773
+ function approveTestCases() {
774
+ document.querySelector('button').disabled = true;
775
+ document.querySelector('button').style.background = '#6c757d';
776
+ document.querySelector('button').innerHTML = 'Processing...';
777
+
778
+ const status = document.getElementById('status');
779
+ status.style.display = 'block';
780
+ status.style.color = '#28a745';
781
+ status.innerHTML = 'Test cases approved! You can close this window.';
782
+
783
+ fetch('/approve')
784
+ .then(response => response.text())
785
+ .then(data => {
786
+ status.innerHTML = data + ' You can close this window.';
787
+ setTimeout(() => {
788
+ window.close();
789
+ }, 2000);
790
+ })
791
+ .catch(error => {
792
+ status.style.color = '#dc3545';
793
+ status.innerHTML = 'Error: ' + error.message;
794
+ });
795
+ }
796
+ </script>
700
797
  </body>
701
798
  </html>
702
799
  `;
@@ -705,21 +802,30 @@ tool(
705
802
 
706
803
  // Approval endpoint
707
804
  app.get("/approve", (req, res) => {
708
- res.send("Approved!");
709
- if (server) {
710
- server.close();
711
- }
712
- resolve("Test cases approved by user");
805
+ userApproved = true;
806
+ res.send("✓ Test cases approved successfully!");
807
+
808
+ // Close server after a short delay
809
+ setTimeout(() => {
810
+ if (server) {
811
+ server.close();
812
+ }
813
+ resolve("✓ Test cases have been approved by the user. Continuing with next operations...");
814
+ }, 1000);
713
815
  });
714
816
 
715
- // Start server and open browser
817
+ // Start server
716
818
  server = app.listen(port, async () => {
819
+ console.log(`Test case review server started on http://localhost:${port}`);
820
+
717
821
  try {
822
+ // Use dynamic import for the open package (ES module)
823
+ const { default: open } = await import('open');
718
824
  await open(`http://localhost:${port}`);
825
+ console.log('Browser opened successfully');
719
826
  } catch (openError) {
720
- console.error('Failed to open browser:', openError);
721
- // Fallback: just provide the URL
722
- resolve(`Test cases review page available at: http://localhost:${port}`);
827
+ console.log('Failed to open browser automatically:', openError.message);
828
+ console.log(`Please manually open: http://localhost:${port}`);
723
829
  }
724
830
  });
725
831
 
@@ -728,17 +834,17 @@ tool(
728
834
  reject(`Server error: ${err.message}`);
729
835
  });
730
836
 
731
- // Timeout after 5 minutes
837
+ // Timeout after 10 minutes if user doesn't approve
732
838
  setTimeout(() => {
733
- if (server) {
839
+ if (!userApproved && server) {
734
840
  server.close();
841
+ reject("⚠️ Review session timed out after 10 minutes. Test cases were not approved.");
735
842
  }
736
- reject("Review session timed out after 5 minutes");
737
- }, 300000);
843
+ }, 600000); // 10 minutes
738
844
  });
739
845
 
740
846
  } catch (err) {
741
- return `Error setting up review interface: ${err.message}`;
847
+ return `❌ Error setting up review interface: ${err.message}`;
742
848
  }
743
849
  }
744
850
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nbakka/mcp-appium",
3
- "version": "2.0.67",
3
+ "version": "2.0.68",
4
4
  "description": "Appium MCP",
5
5
  "engines": {
6
6
  "node": ">=18"