@nbakka/mcp-appium 2.0.53 ā 2.0.55
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 +218 -14
- package/package.json +1 -1
package/lib/server.js
CHANGED
|
@@ -580,11 +580,11 @@ tool(
|
|
|
580
580
|
|
|
581
581
|
|
|
582
582
|
// ----------------------
|
|
583
|
-
// TOOL
|
|
583
|
+
// FIXED TOOL: Generate Manual Test Cases from PDF + JIRA
|
|
584
584
|
// ----------------------
|
|
585
585
|
tool(
|
|
586
586
|
"upload_pdf_to_openai",
|
|
587
|
-
"
|
|
587
|
+
"Generate manual test cases by analyzing PDF design with JIRA requirements",
|
|
588
588
|
{
|
|
589
589
|
jiraSummary: zod_1.z.string().describe("Jira issue summary"),
|
|
590
590
|
jiraDescription: zod_1.z.string().describe("Jira issue description"),
|
|
@@ -601,28 +601,232 @@ tool(
|
|
|
601
601
|
|
|
602
602
|
const client = new OpenAI({ apiKey: openaiKey });
|
|
603
603
|
|
|
604
|
-
//
|
|
605
|
-
|
|
604
|
+
// Validate file exists
|
|
605
|
+
try {
|
|
606
|
+
await fs.access(pdfPath);
|
|
607
|
+
} catch (error) {
|
|
608
|
+
throw new Error(`PDF file not found at path: ${pdfPath}`);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const stats = await fs.stat(pdfPath);
|
|
612
|
+
const fileName = path.basename(pdfPath);
|
|
613
|
+
|
|
614
|
+
console.log(`š Processing ${fileName} for test case generation...`);
|
|
606
615
|
|
|
607
|
-
//
|
|
616
|
+
// Use the require() fs for createReadStream (CommonJS style)
|
|
617
|
+
const fsSync = require('fs');
|
|
618
|
+
|
|
619
|
+
// Upload PDF to OpenAI
|
|
608
620
|
const fileUpload = await client.files.create({
|
|
609
|
-
file:
|
|
621
|
+
file: fsSync.createReadStream(pdfPath), // Use fsSync.createReadStream
|
|
610
622
|
purpose: "assistants"
|
|
611
623
|
});
|
|
612
624
|
|
|
613
|
-
|
|
614
|
-
|
|
625
|
+
console.log(`ā
PDF uploaded: ${fileUpload.id}`);
|
|
626
|
+
|
|
627
|
+
// Create specialized assistant for test case generation
|
|
628
|
+
const assistant = await client.beta.assistants.create({
|
|
629
|
+
name: "Manual Test Case Generator",
|
|
630
|
+
instructions: `You are an expert QA engineer specializing in creating comprehensive manual test cases.
|
|
631
|
+
You analyze design documents and requirements to generate detailed, actionable test cases that cover:
|
|
632
|
+
- Functional testing scenarios
|
|
633
|
+
- UI/UX validation tests
|
|
634
|
+
- Edge cases and negative scenarios
|
|
635
|
+
- Cross-browser/device compatibility tests
|
|
636
|
+
- Accessibility testing scenarios`,
|
|
637
|
+
model: "gpt-4o",
|
|
638
|
+
tools: [{ type: "file_search" }],
|
|
639
|
+
tool_resources: {
|
|
640
|
+
file_search: {
|
|
641
|
+
vector_stores: [{
|
|
642
|
+
file_ids: [fileUpload.id]
|
|
643
|
+
}]
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
// Create comprehensive test case generation prompt
|
|
649
|
+
const testCasePrompt = `
|
|
650
|
+
**JIRA REQUIREMENTS:**
|
|
651
|
+
**Summary:** ${jiraSummary}
|
|
652
|
+
**Description:** ${jiraDescription}
|
|
653
|
+
|
|
654
|
+
**TASK:** Generate comprehensive manual test cases based on the attached PDF design and above JIRA requirements.
|
|
655
|
+
|
|
656
|
+
**OUTPUT FORMAT REQUIRED:**
|
|
657
|
+
Please structure your response as follows:
|
|
658
|
+
|
|
659
|
+
## MANUAL TEST CASES
|
|
660
|
+
|
|
661
|
+
### 1. FUNCTIONAL TEST CASES
|
|
662
|
+
**TC-F-001: [Test Case Title]**
|
|
663
|
+
- **Objective:** What this test validates
|
|
664
|
+
- **Preconditions:** Setup required before testing
|
|
665
|
+
- **Test Steps:**
|
|
666
|
+
1. Step 1 action
|
|
667
|
+
2. Step 2 action
|
|
668
|
+
3. Step 3 action
|
|
669
|
+
- **Expected Result:** What should happen
|
|
670
|
+
- **Priority:** High/Medium/Low
|
|
671
|
+
|
|
672
|
+
### 2. UI/UX TEST CASES
|
|
673
|
+
**TC-UI-001: [Test Case Title]**
|
|
674
|
+
[Same format as above]
|
|
675
|
+
|
|
676
|
+
### 3. EDGE CASE & NEGATIVE TEST CASES
|
|
677
|
+
**TC-E-001: [Test Case Title]**
|
|
678
|
+
[Same format as above]
|
|
679
|
+
|
|
680
|
+
### 4. COMPATIBILITY TEST CASES
|
|
681
|
+
**TC-C-001: [Test Case Title]**
|
|
682
|
+
[Same format as above]
|
|
683
|
+
|
|
684
|
+
### 5. ACCESSIBILITY TEST CASES
|
|
685
|
+
**TC-A-001: [Test Case Title]**
|
|
686
|
+
[Same format as above]
|
|
687
|
+
|
|
688
|
+
**IMPORTANT GUIDELINES:**
|
|
689
|
+
1. Create 15-20 test cases total covering all aspects
|
|
690
|
+
2. Reference specific UI elements from the PDF design
|
|
691
|
+
3. Include both positive and negative test scenarios
|
|
692
|
+
4. Consider different user roles if applicable
|
|
693
|
+
5. Include performance and usability aspects
|
|
694
|
+
6. Make test steps specific and actionable
|
|
695
|
+
7. Consider mobile/responsive design if shown in PDF
|
|
696
|
+
8. Include data validation test cases
|
|
697
|
+
9. Cover error handling scenarios
|
|
698
|
+
10. Include integration testing if multiple components interact
|
|
699
|
+
|
|
700
|
+
Generate detailed test cases now based on the PDF design and JIRA requirements.
|
|
701
|
+
`;
|
|
702
|
+
|
|
703
|
+
// Create thread and run analysis
|
|
704
|
+
const thread = await client.beta.threads.create({
|
|
705
|
+
messages: [
|
|
706
|
+
{
|
|
707
|
+
role: "user",
|
|
708
|
+
content: testCasePrompt
|
|
709
|
+
}
|
|
710
|
+
]
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
console.log(`š Generating test cases...`);
|
|
714
|
+
|
|
715
|
+
const run = await client.beta.threads.runs.create(thread.id, {
|
|
716
|
+
assistant_id: assistant.id,
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
// Wait for completion with progress tracking
|
|
720
|
+
let runStatus = await client.beta.threads.runs.retrieve(thread.id, run.id);
|
|
721
|
+
let attempts = 0;
|
|
722
|
+
const maxAttempts = 60;
|
|
723
|
+
|
|
724
|
+
while (runStatus.status !== 'completed' && attempts < maxAttempts) {
|
|
725
|
+
if (runStatus.status === 'failed') {
|
|
726
|
+
throw new Error(`Test case generation failed: ${runStatus.last_error?.message}`);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
if (attempts % 5 === 0) {
|
|
730
|
+
console.log(`ā³ Still generating... (${attempts}s elapsed)`);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
734
|
+
runStatus = await client.beta.threads.runs.retrieve(thread.id, run.id);
|
|
735
|
+
attempts++;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (runStatus.status !== 'completed') {
|
|
739
|
+
throw new Error('Test case generation timed out after 60 seconds');
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Get the generated test cases
|
|
743
|
+
const messages = await client.beta.threads.messages.list(thread.id);
|
|
744
|
+
const testCases = messages.data
|
|
745
|
+
.filter(msg => msg.role === 'assistant')
|
|
746
|
+
.map(msg => msg.content[0]?.text?.value)
|
|
747
|
+
.join('\n\n');
|
|
748
|
+
|
|
749
|
+
// Parse test case count
|
|
750
|
+
const testCaseCount = (testCases.match(/\*\*TC-/g) || []).length;
|
|
751
|
+
|
|
752
|
+
// Clean up assistant
|
|
753
|
+
try {
|
|
754
|
+
await client.beta.assistants.del(assistant.id);
|
|
755
|
+
} catch (cleanupError) {
|
|
756
|
+
console.warn('ā ļø Assistant cleanup failed:', cleanupError.message);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Save test cases to file
|
|
760
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
761
|
+
const outputFileName = `test_cases_${timestamp.substring(0, 19)}.md`;
|
|
762
|
+
const outputPath = path.join(path.dirname(pdfPath), outputFileName);
|
|
763
|
+
|
|
764
|
+
const fileContent = `# Manual Test Cases
|
|
765
|
+
Generated on: ${new Date().toLocaleString()}
|
|
766
|
+
|
|
767
|
+
## Source Information
|
|
768
|
+
- **JIRA Summary:** ${jiraSummary}
|
|
769
|
+
- **JIRA Description:** ${jiraDescription}
|
|
770
|
+
- **Design File:** ${fileName}
|
|
771
|
+
- **Total Test Cases:** ${testCaseCount}
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
${testCases}
|
|
776
|
+
|
|
777
|
+
---
|
|
778
|
+
|
|
779
|
+
## Test Execution Notes
|
|
780
|
+
- Execute test cases in the order listed
|
|
781
|
+
- Log defects with screenshots when issues found
|
|
782
|
+
- Update test results in your test management tool
|
|
783
|
+
- Verify on multiple browsers/devices for compatibility tests
|
|
784
|
+
`;
|
|
785
|
+
|
|
786
|
+
await fs.writeFile(outputPath, fileContent, 'utf-8');
|
|
787
|
+
|
|
788
|
+
console.log(`ā
Test cases generated and saved!`);
|
|
789
|
+
|
|
790
|
+
// CRITICAL: Return only a STRING, not an object
|
|
791
|
+
// The MCP wrapper will handle the proper formatting
|
|
792
|
+
return `ā
Successfully generated ${testCaseCount} manual test cases!
|
|
793
|
+
|
|
794
|
+
š Test cases saved to: ${outputFileName}
|
|
795
|
+
š Full path: ${outputPath}
|
|
796
|
+
|
|
797
|
+
š Generation Summary:
|
|
798
|
+
- Total Test Cases: ${testCaseCount}
|
|
799
|
+
- Categories: Functional, UI/UX, Edge Cases, Compatibility, Accessibility
|
|
800
|
+
- Source File: ${fileName} (${(stats.size / 1024).toFixed(2)} KB)
|
|
801
|
+
- Processing Time: ${attempts} seconds
|
|
802
|
+
- Model Used: gpt-4o
|
|
803
|
+
|
|
804
|
+
šÆ Test Case Preview:
|
|
805
|
+
${testCases.substring(0, 1000)}...
|
|
806
|
+
|
|
807
|
+
[Complete test cases saved to markdown file for easy reference and sharing]`;
|
|
615
808
|
|
|
616
|
-
return {
|
|
617
|
-
message: "ā
PDF uploaded to OpenAI successfully!",
|
|
618
|
-
fileId: fileUpload.id,
|
|
619
|
-
promptUsed: prompt
|
|
620
|
-
};
|
|
621
809
|
} catch (err) {
|
|
622
|
-
|
|
810
|
+
console.error("ā Test Case Generation Error:", err);
|
|
811
|
+
|
|
812
|
+
// Return only error string, not object
|
|
813
|
+
let errorMessage = `ā Failed to generate test cases: ${err.message}`;
|
|
814
|
+
|
|
815
|
+
if (err.message?.includes('quota')) {
|
|
816
|
+
errorMessage += "\n\nš” Troubleshooting: OpenAI quota exceeded. Check your billing at platform.openai.com";
|
|
817
|
+
} else if (err.message?.includes('timeout')) {
|
|
818
|
+
errorMessage += "\n\nš” Troubleshooting: Generation took too long. Try with a smaller PDF file.";
|
|
819
|
+
} else if (err.message?.includes('file')) {
|
|
820
|
+
errorMessage += "\n\nš” Troubleshooting: PDF processing error. Check file format and accessibility.";
|
|
821
|
+
} else if (err.message?.includes('API key')) {
|
|
822
|
+
errorMessage += "\n\nš” Troubleshooting: Invalid OpenAI API key. Check ~/Desktop/openai.json file.";
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
return errorMessage;
|
|
623
826
|
}
|
|
624
827
|
}
|
|
625
828
|
);
|
|
829
|
+
|
|
626
830
|
return server;
|
|
627
831
|
};
|
|
628
832
|
|