upload-test-manual
Version:
CLI tool untuk mengolah file CSV dan upload ke ReportPortal
164 lines (150 loc) • 5.09 kB
JavaScript
const axios = require('axios');
const { buildDescription, buildAttributes } = require('./csvParser');
const startLaunch = async (rpConfig) => {
try {
const response = await axios.post(
`${rpConfig.endpoint}/${rpConfig.project}/launch`,
{
name: rpConfig.launchName,
start_time: new Date().toISOString(),
tags: rpConfig.launchTags || [],
attributes: buildAttributes({}, rpConfig.attributes),
mode: rpConfig.mode || 'DEFAULT',
description: rpConfig.description || 'CSV Import'
},
{
headers: {
Authorization: `bearer ${rpConfig.token}`,
'Content-Type': 'application/json'
},
timeout: rpConfig.timeout || 30000
}
);
console.log(`🚀 Launch started: ${rpConfig.launchName} (ID: ${response.data.id})`);
return response.data.id;
} catch (error) {
throw new Error(`Failed to start launch: ${error.response?.data?.message || error.message}`);
}
};
const finishLaunch = async (launchId, rpConfig) => {
try {
await axios.put(
`${rpConfig.endpoint}/${rpConfig.project}/launch/${launchId}/finish`,
{
end_time: new Date().toISOString(),
status: rpConfig.launchStatus || 'PASSED'
},
{
headers: {
Authorization: `bearer ${rpConfig.token}`,
'Content-Type': 'application/json'
}
}
);
console.log(`🏁 Launch finished: ${launchId}`);
} catch (error) {
throw new Error(`Failed to finish launch: ${error.response?.data?.message || error.message}`);
}
};
const createTestItem = async (launchId, testData, rpConfig, fieldMappings = {}) => {
try {
const mappings = {
nameField: 'Title',
testCaseIdField: 'Test Case ID',
descriptionFields: {},
attributeFields: {},
tagsField: 'Tags',
statusField: 'Status',
typeField: 'Type',
...fieldMappings
};
const testCaseId = testData[mappings.testCaseIdField] ||
`AUTO-${Math.random().toString(36).substr(2, 8)}`;
const requestData = {
launch_id: launchId,
name: String(testData[mappings.nameField] || 'Unnamed Test').substring(0, 256),
start_time: new Date().toISOString(),
type: testData[mappings.typeField] || 'STEP',
tags: testData[mappings.tagsField]?.split(',').map(tag => tag.trim()).filter(Boolean) || [],
status: mapStatus(testData[mappings.statusField]),
description: buildDescription(testData, mappings.descriptionFields),
attributes: [
...buildAttributes(testData, mappings.attributeFields),
{ key: 'test_case_id', value: testCaseId } // Fallback for RP v4
],
testCaseId: testCaseId,
has_stats: true
};
console.log('Creating test item with data:', JSON.stringify(requestData, null, 2));
const response = await axios.post(
`${rpConfig.endpoint}/${rpConfig.project}/item`,
requestData,
{
headers: {
Authorization: `bearer ${rpConfig.token}`,
'Content-Type': 'application/json'
},
timeout: rpConfig.timeout || 30000
}
);
return response.data.id;
} catch (error) {
console.error('Failed to create test item:', error.response?.data || error.message);
return null;
}
};
const finishTestItem = async (itemId, testData, rpConfig, fieldMappings = {}) => {
if (!itemId) return;
try {
const mappings = {
statusField: 'Status',
defectField: 'Defect',
commentField: 'Comment',
issueTypeField: 'IssueType',
...fieldMappings
};
const status = mapStatus(testData[mappings.statusField]);
const requestData = {
end_time: new Date().toISOString(),
status: status
};
if (status === 'FAILED') {
requestData.issue = {
issue_type: testData[mappings.issueTypeField] || 'pb001',
comment: [
testData[mappings.defectField] && `Defect: ${testData[mappings.defectField]}`,
testData[mappings.commentField] && `Comment: ${testData[mappings.commentField]}`
].filter(Boolean).join(' | ') || 'No additional information'
};
}
await axios.put(
`${rpConfig.endpoint}/${rpConfig.project}/item/${itemId}`,
requestData,
{
headers: {
Authorization: `bearer ${rpConfig.token}`,
'Content-Type': 'application/json'
}
}
);
} catch (error) {
console.error(`Failed to finish test item ${itemId}:`, error.response?.data || error.message);
}
};
const mapStatus = (status) => {
const statusMap = {
'Passed': 'PASSED',
'Failed': 'FAILED',
'Skipped': 'SKIPPED',
'Pending': 'PENDING',
'Blocked': 'INTERRUPTED'
};
return statusMap[String(status || '').trim()] || 'FAILED';
};
module.exports = {
startLaunch,
finishLaunch,
createTestItem,
finishTestItem,
mapStatus
};