@nbakka/mcp-appium 2.0.69 → 2.0.70

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 CHANGED
@@ -509,13 +509,13 @@ function extractFileAndNodeId(url) {
509
509
  }
510
510
 
511
511
  // ----------------------
512
- // TOOL 1: Export Figma to PDF
512
+ // TOOL 1: Export Figma to PNG
513
513
  // ----------------------
514
514
  tool(
515
- "mobile_export_figma_pdf",
516
- "Export Figma file as PDF",
515
+ "mobile_export_figma_png",
516
+ "Export Figma file as PNG",
517
517
  {
518
- figmaUrl: zod_1.z.string().describe("The Figma file URL to export as PDF")
518
+ figmaUrl: zod_1.z.string().describe("The Figma file URL to export as PNG")
519
519
  },
520
520
  async ({ figmaUrl }) => {
521
521
  try {
@@ -552,24 +552,22 @@ tool(
552
552
  throw new Error("No frames found in Figma file");
553
553
  }
554
554
 
555
- // Request PDF export
555
+ // Request PNG export with higher scale for better quality
556
556
  const exportResponse = await axios.get(
557
557
  `https://api.figma.com/v1/images/${fileId}`,
558
558
  {
559
559
  headers: { "X-Figma-Token": figmaToken },
560
- params: { ids: idsToExport.join(","), format: "pdf" }
560
+ params: {
561
+ ids: idsToExport.join(","),
562
+ format: "png",
563
+ scale: "2" // 2x scale for better quality
564
+ }
561
565
  }
562
566
  );
563
567
 
564
- const pdfUrl = Object.values(exportResponse.data.images)[0];
565
- if (!pdfUrl) throw new Error("No PDF export URL returned from Figma");
566
-
567
- // Download PDF
568
- const pdfResponse = await axios.get(pdfUrl, { responseType: "arraybuffer" });
569
-
570
568
  const exportPath = path.join(os.homedir(), "Desktop", "figma");
571
569
 
572
- // Clear the folder before creating new PDF
570
+ // Clear the folder before creating new PNGs
573
571
  try {
574
572
  // Check if folder exists
575
573
  await fs.access(exportPath);
@@ -588,19 +586,35 @@ tool(
588
586
  await fs.mkdir(exportPath, { recursive: true });
589
587
 
590
588
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, -5);
591
- const pdfPath = path.join(exportPath, `figma-export-${timestamp}.pdf`);
592
- await fs.writeFile(pdfPath, pdfResponse.data);
593
589
 
594
- return `✅ PDF Export Complete: ${pdfPath}`;
590
+ // Download all PNG images
591
+ const downloadPromises = Object.entries(exportResponse.data.images).map(
592
+ async ([nodeId, pngUrl], index) => {
593
+ if (!pngUrl) throw new Error(`No PNG export URL returned for node ${nodeId}`);
594
+
595
+ const pngResponse = await axios.get(pngUrl, { responseType: "arraybuffer" });
596
+ const filename = idsToExport.length > 1
597
+ ? `figma-export-${timestamp}-${index + 1}.png`
598
+ : `figma-export-${timestamp}.png`;
599
+ const pngPath = path.join(exportPath, filename);
600
+
601
+ await fs.writeFile(pngPath, pngResponse.data);
602
+ return pngPath;
603
+ }
604
+ );
605
+
606
+ const savedPaths = await Promise.all(downloadPromises);
607
+
608
+ return `✅ PNG Export Complete: ${savedPaths.length} file(s) saved to ${exportPath}`;
595
609
  } catch (err) {
596
- return `❌ Error exporting Figma PDF: ${err.message}`;
610
+ return `❌ Error exporting Figma PNG: ${err.message}`;
597
611
  }
598
612
  }
599
613
  );
600
614
 
601
615
  tool(
602
- "upload_pdf_to_openai",
603
- "Generate manual test cases by analyzing PDF design with JIRA requirements",
616
+ "generate_testcases_from_ticket_data",
617
+ "Generate manual test cases by analyzing PNG design with JIRA requirements",
604
618
  {
605
619
  jiraSummary: zod_1.z.string().describe("Jira issue summary"),
606
620
  jiraDescription: zod_1.z.string().describe("Jira issue description")
@@ -612,41 +626,66 @@ tool(
612
626
  const configContent = await fs.readFile(openaiConfigPath, "utf-8");
613
627
  const { apiKey } = JSON.parse(configContent);
614
628
 
629
+ // Load test case generation guidelines
630
+ const guidelinesPath = path.join(__dirname, 'testcases-generation-context.txt');
631
+ const guidelines = await fs.readFile(guidelinesPath, "utf-8");
632
+
615
633
  const figmaDir = path.join(os.homedir(), "Desktop", "figma");
616
634
  const files = await fs.readdir(figmaDir);
617
- const pdfFiles = files.filter(file => file.toLowerCase().endsWith('.pdf'));
635
+ const pngFiles = files.filter(file => file.toLowerCase().endsWith('.png'));
618
636
 
619
- if (pdfFiles.length === 0) throw new Error("No PDF files found in figma folder");
637
+ if (pngFiles.length === 0) throw new Error("No PNG files found in figma folder");
620
638
 
621
- const latestPdf = pdfFiles.sort((a, b) => b.localeCompare(a))[0];
622
- const pdfPath = path.join(figmaDir, latestPdf);
639
+ // Get the latest PNG file
640
+ const latestPng = pngFiles.sort((a, b) => b.localeCompare(a))[0];
641
+ const pngPath = path.join(figmaDir, latestPng);
623
642
 
624
643
  const client = new OpenAI({ apiKey });
625
644
 
626
- const file = await client.files.create({
627
- file: fsSync.createReadStream(pdfPath),
628
- purpose: "user_data",
629
- });
645
+ // Convert PNG to base64 for vision API
646
+ const pngBuffer = await fs.readFile(pngPath);
647
+ const base64Image = pngBuffer.toString('base64');
630
648
 
631
649
  const completion = await client.chat.completions.create({
632
- model: "gpt-5",
650
+ model: "gpt-5", // Use vision model for image analysis
633
651
  messages: [{
634
652
  role: "user",
635
- content: [{
636
- type: "file",
637
- file: { file_id: file.id }
638
- }, {
639
- type: "text",
640
- text: `For the attached pdf, OCR the page return a JSON with text, bounding boxes. Line-level boxes, Normalized [0–1] coordinates, origin top-left, Include readingOrder and no confidence, Keep all occurrences as they appear NOTE: Dont ask anymore questions, just give me output. I wont be able to answer`
641
- }]
642
- }]
653
+ content: [
654
+ {
655
+ type: "text",
656
+ text: `Generate comprehensive manual test cases based on the following:
657
+
658
+ JIRA Summary: ${jiraSummary}
659
+
660
+ JIRA Description: ${jiraDescription}
661
+
662
+ Test Case Generation Guidelines:
663
+ ${guidelines}
664
+
665
+ Please analyze the provided Figma design (PNG image) and create detailed manual test cases that cover all the functionality described in the JIRA requirements. Focus on UI/UX changes, user interactions, navigation flows, and edge cases.`
666
+ },
667
+ {
668
+ type: "image_url",
669
+ image_url: {
670
+ url: `data:image/png;base64,${base64Image}`,
671
+ detail: "high"
672
+ }
673
+ }
674
+ ]
675
+ }],
676
+ max_tokens: 10000
643
677
  });
644
678
 
645
679
  const testCases = completion.choices[0].message.content;
646
680
 
647
- return testCases;
681
+ // Save the generated test cases to a file for reference
682
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, -5);
683
+ const testCasesPath = path.join(figmaDir, `test-cases-${timestamp}.txt`);
684
+ await fs.writeFile(testCasesPath, testCases);
685
+
686
+ return `✅ Test cases generated successfully!\n\nSaved to: ${testCasesPath}\n\n${testCases}`;
648
687
  } catch (err) {
649
- return `Error: ${err.message}`;
688
+ return `❌ Error generating test cases: ${err.message}`;
650
689
  }
651
690
  }
652
691
  );
@@ -0,0 +1,11 @@
1
+ generate test cases using jira summary, description and figma image,
2
+ don't take any extra user input,
3
+ final output should be test in following format
4
+ "Verify pay on credit banner exits on PDP", "Existing"
5
+ "Verify overview tab on PDP", "New"
6
+ "Verify financial services are displayed under financial tab", "Remove"
7
+ "Verify xyz is moved to sja ", "Modify"
8
+ here existing means the test case is already present in the repo
9
+ new means the test case is not present in the repo and needs to be added
10
+ remove means the test case is present in the repo but is not required and needs to be removed
11
+ modify means the test case is present in the repo but needs some modification
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nbakka/mcp-appium",
3
- "version": "2.0.69",
3
+ "version": "2.0.70",
4
4
  "description": "Appium MCP",
5
5
  "engines": {
6
6
  "node": ">=18"