@nbakka/mcp-appium 2.0.66 → 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 +157 -19
  2. package/package.json +1 -1
package/lib/server.js CHANGED
@@ -662,31 +662,138 @@ tool(
662
662
  })).describe("Array of test cases to review")
663
663
  },
664
664
  async ({ testCases }) => {
665
- const express = require('express');
666
- const open = require('open');
665
+ try {
666
+ const express = require('express');
667
667
 
668
- return new Promise((resolve, reject) => {
669
- try {
668
+ return new Promise(async (resolve, reject) => {
670
669
  const app = express();
671
670
  const port = 3001;
671
+ let server;
672
+ let userApproved = false;
672
673
 
673
674
  // Serve a simple HTML page with test cases
674
675
  app.get("/", (req, res) => {
675
676
  let html = `
676
677
  <html>
677
- <head><title>Test Case Approval</title></head>
678
+ <head>
679
+ <title>Test Case Approval</title>
680
+ <style>
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
+ }
746
+ </style>
747
+ </head>
678
748
  <body>
679
- <h1>Review Test Cases</h1>
680
- <ul>
749
+ <div class="container">
750
+ <h1>Review Test Cases</h1>
751
+ <div id="test-cases">
681
752
  `;
682
753
 
683
754
  testCases.forEach(tc => {
684
- 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
+ `;
685
762
  });
686
763
 
687
764
  html += `
688
- </ul>
689
- <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>
690
797
  </body>
691
798
  </html>
692
799
  `;
@@ -695,19 +802,50 @@ tool(
695
802
 
696
803
  // Approval endpoint
697
804
  app.get("/approve", (req, res) => {
698
- res.send("Approved!");
699
- server.close();
700
- resolve("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);
701
815
  });
702
816
 
703
- const server = app.listen(port, async () => {
704
- await open(`http://localhost:${port}`);
817
+ // Start server
818
+ server = app.listen(port, async () => {
819
+ console.log(`Test case review server started on http://localhost:${port}`);
820
+
821
+ try {
822
+ // Use dynamic import for the open package (ES module)
823
+ const { default: open } = await import('open');
824
+ await open(`http://localhost:${port}`);
825
+ console.log('Browser opened successfully');
826
+ } catch (openError) {
827
+ console.log('Failed to open browser automatically:', openError.message);
828
+ console.log(`Please manually open: http://localhost:${port}`);
829
+ }
705
830
  });
706
831
 
707
- } catch (err) {
708
- reject(`Error: ${err.message}`);
709
- }
710
- });
832
+ // Handle server errors
833
+ server.on('error', (err) => {
834
+ reject(`Server error: ${err.message}`);
835
+ });
836
+
837
+ // Timeout after 10 minutes if user doesn't approve
838
+ setTimeout(() => {
839
+ if (!userApproved && server) {
840
+ server.close();
841
+ reject("⚠️ Review session timed out after 10 minutes. Test cases were not approved.");
842
+ }
843
+ }, 600000); // 10 minutes
844
+ });
845
+
846
+ } catch (err) {
847
+ return `❌ Error setting up review interface: ${err.message}`;
848
+ }
711
849
  }
712
850
  );
713
851
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nbakka/mcp-appium",
3
- "version": "2.0.66",
3
+ "version": "2.0.68",
4
4
  "description": "Appium MCP",
5
5
  "engines": {
6
6
  "node": ">=18"