fintech-automation-test
Version:
Autonomous Test Automation
229 lines (205 loc) • 6.32 kB
JavaScript
const { I } = inject();
const { event } = require('codeceptjs');
const axios = require('axios');
const fs = require('fs-extra');
const path = require('path');
const config = require('../../../config');
const JIRA_API_URL = config.zapiBaseUrl;
const JIRA_API_KEY = config.zapiBearerToken;
const {
getUserStoryDetails,
} = require('../../main/utils/jiraIntegrationUtils');
const { initializeOpenAI } = require('../../main/utils/openaiUtils');
const aiUtils = require('../../main/utils/AIUtils');
const customDirectory = './src/test/web';
const BASE_TESTS_DIR = customDirectory || './tests'; // Default to './tests' if custom directory is not provided
function sanitizeSummary(summary) {
if (!summary || typeof summary !== 'string') {
return 'No_Summary'; // Fallback value if summary is undefined or not a string
}
let sanitized = summary.replace(/[^a-zA-Z0-9]+/g, '_');
if (sanitized.endsWith('_')) {
sanitized = sanitized.slice(0, -1);
}
return sanitized;
}
async function getTestSteps(testScriptUrl) {
const response = await axios.get(testScriptUrl, {
headers: getJiraHeaders(),
params: {
maxResults: 50,
startAt: 0,
},
});
console.log(response.data);
return response.data.values;
}
function getJiraHeaders() {
return {
Authorization: `Bearer ${JIRA_API_KEY}`,
'Content-Type': 'application/json',
};
}
async function getTestCasesByKey(testCaseKey) {
const response = await axios.get(
`${config.zapiBaseUrl}/testcases/${testCaseKey}`,
{
headers: {
Authorization: `Bearer ${config.zapiBearerToken}`,
'Content-Type': 'application/json',
},
}
);
return response.data;
}
async function getTestCasesByProjectKey() {
try {
console.log(
'Fetching test cases...',
config.zapiBaseUrl,
config.projectKey
);
const response = await axios.get(
`${config.zapiBaseUrl}/testcases?projectKey=${config.projectKey}`,
{
headers: {
Authorization: `Bearer ${config.zapiBearerToken}`,
'Content-Type': 'application/json',
},
params: {
maxResults: 50,
startAt: 0,
},
}
);
console.log(response.data);
return response.data.values;
} catch (error) {
console.error(
'Error fetching test cases:',
error.response ? error.response.data : error.message
);
throw error;
}
}
function extractLinksAndIssues(testCase) {
const links = testCase.links;
if (links && links.issues && Array.isArray(links.issues)) {
return links.issues.map((issue) => ({
issueId: issue.issueId,
target: issue.target,
}));
} else {
console.log('No issues found in links for test case:', testCase.name);
return [];
}
}
function groupTestCasesByUserStory(testCases) {
const grouped = {};
testCases.forEach((testCase) => {
const issuesData = extractLinksAndIssues(testCase);
issuesData.forEach(({ target }) => {
const userStoryId = path.basename(target);
if (!grouped[userStoryId]) {
grouped[userStoryId] = { testCases: [] };
}
grouped[userStoryId].testCases.push(testCase);
});
});
return grouped;
}
function extractUrl(text) {
const urlPattern = /https?:\/\/[^\s]+/; // Regular expression for matching URLs
const match = text.match(urlPattern);
return match ? match[0] : null; // Return the URL if found, otherwise return null
}
async function generateTestCaseTemplates(
apiKey,
model,
groupedTestCases,
customBaseDir,
I
) {
const baseDir = customBaseDir || BASE_TESTS_DIR;
for (const userStoryId in groupedTestCases) {
const userStoryDetails = await getUserStoryDetails(userStoryId);
if (userStoryDetails) {
const { parentKey, userStoryName, userStoryKey } = userStoryDetails;
const parentFolderDir = path.join(
baseDir,
config.projectKey,
parentKey
);
const userStoryDir = path.join(
parentFolderDir.toLowerCase(),
userStoryKey.toLowerCase()
);
fs.ensureDirSync(userStoryDir);
const testFileName = `${sanitizeSummary(userStoryName)}.js`;
const testFilePath = path.join(userStoryDir, testFileName);
let aiGeneratedSteps;
let testFileContent = `\nFeature('${userStoryName}');\n\n`;
fs.appendFileSync(testFilePath, testFileContent);
for (const testCase of groupedTestCases[userStoryId].testCases) {
const testCaseKey = testCase.key;
console.log(
`Generating test case template for ${testCaseKey}_${testCase.name}`
);
testFileContent = `
Scenario('${testCaseKey}_${testCase.name}', async ({ I }) => {
let testCaseId = '${testCaseKey}';\n`;
fs.appendFileSync(testFilePath, testFileContent);
const tcDetails = await getTestCasesByKey(testCaseKey);
const testSteps = await getTestSteps(tcDetails.testScript.self);
let i=0;
for (const [index, step] of testSteps.entries()) {
console.log(`${index + 1}. ${step.inline.description}`);
if (
step.inline.description.toLowerCase().includes('go to')
) {
const extractedUrl = extractUrl(
step.inline.description
);
aiGeneratedSteps =
'\nI.amOnPage("' + extractedUrl + '")\n\n I.wait(5)';
fs.appendFileSync(testFilePath, aiGeneratedSteps);
await I.amOnPage(extractedUrl);
await I.wait(5);
}
try {
await aiUtils.getAICommand(
I,
step.inline.description,
testFilePath,`${index + 1}`
);
} catch (error) {
console.error(
`Error while generating AI command for step: ${step.inline.description}`,
error
);
// Optionally, you can log the error or take other actions here
}
await I.wait(5);
}
fs.appendFileSync(testFilePath, '});\n\n');
}
}
}
}
Feature('Autonomous Script Generation from JIRA');
Scenario(
'Fetch test cases and generate scripts from JIRA using FAT',
async ({ I }) => {
// Execute the complete process
const testCases = await getTestCasesByProjectKey();
const groupedTestCases = groupTestCasesByUserStory(testCases);
await generateTestCaseTemplates(
config.apikeyCode,
'gpt-4o',
groupedTestCases,
customDirectory,
I
);
console.log('Test case generation completed!');
}
);