Res: https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.2/axios.min.js // Note this extension is not a product feature of Virtuoso and is not officially supported // Extensions use javascript which may or may not be compatible with systems under test (SUTs) // We welcome you to use this extension or adapt it for your needs //INSTRUCTIONS: /* Example Usage: readAndProcessJourneysData($Token, "Master Data", "PRODUCTION", "149022", "3295200") returning $data */ /* Created By : Suhas. YS Created Date : 22/07/2024 */ const desiredGoalId = Number(goalIdInput); const jobId = Number(jobIdInput); const endpoints = { PRODUCTION: "https://api.virtuoso.qa/api", US: "https://api-us.virtuoso.qa/api", DEVELOPMENT: "https://api-dev.virtuoso.qa/api", APP2: "https://api-app2.virtuoso.qa/api", UK: "https://api-uk.virtuoso.qa/api" }; //const env = "PRODUCTION"; const basicUrl = endpoints[env]; if (!basicUrl) { throw new Error("Invalid environment " + env + ". Please use PRODUCTION, US, DEVELOPMENT, UK or APP2"); } //const basicUrl = 'https://api.virtuoso.qa/api'; //const token = ''; if (!desiredGoalId) { throw new Error('desiredGoalId is missing!'); } if (!/^\d+$/.test(desiredGoalId)) { throw new Error('desiredGoalId must contain only digits!'); } if (!jobId) { throw new Error('jobId is missing!'); } if (!/^\d+$/.test(jobId)) { throw new Error('jobId must contain only digits!'); } if (!basicUrl) { throw new Error('basicUrl is missing!'); } if (!token) { throw new Error('token is missing!'); } if (!desiredJourneyName) { throw new Error('desiredJourneyName is missing!'); } const options = { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; async function sendRequest(url) { try { const response = await axios.get(url, options); return response.data; } catch (error) { console.error('Error in sendRequest:', error.message); throw error; } } async function fetchAndProcessJourneys() { try { // First request to identify the totalCount const latestStatusUrl = `${basicUrl}/testsuites/latest_status?jobId=${jobId}&includeSequencesDetails=true`; const latestStatusResponse = await axios.get(latestStatusUrl, options); let totalCountFound = false; let journeysWithDataDrivenDetails = []; const statusMap = latestStatusResponse.data.map; for (const suiteId in statusMap) { if (statusMap.hasOwnProperty(suiteId)) { const journeyData = statusMap[suiteId]; const journey = journeyData.journey; if (journey) { const goalId = journey.goalId; const journeyTitle = journey.title; console.log(`Processing latest status journey: ${journeyTitle} (Suite ID: ${suiteId}, Goal ID: ${goalId})`); if (journeyTitle === desiredJourneyName && goalId === desiredGoalId) { const sequencesDetails = journeyData.lastExecution.sequencesDetails; if (sequencesDetails && sequencesDetails.totalCount !== undefined) { const totalCount = sequencesDetails.totalCount; console.log(`Total count for journey "${journeyTitle}" with goal ID ${goalId}: ${totalCount}`); totalCountFound = true; journeysWithDataDrivenDetails.push({ suiteId, totalCount }); } else { console.log(`totalCount not found for journey "${journeyTitle}" with goal ID ${goalId}`); } break; } } else { console.log(`Journey data not found for suite ID: ${suiteId}`); } } } if (!totalCountFound) { // Send the first request if totalCount is not found console.log('Sending request to fetch execution details'); const url = `${basicUrl}/testsuites/execution?jobId=${jobId}`; const response = await axios.get(url, options); console.log('API request completed.'); const journeys = response.data.item.journeys; console.log('Journeys retrieved:', JSON.stringify(journeys, null, 2)); const journeyArray = []; for (const journeyId in journeys) { if (journeys.hasOwnProperty(journeyId)) { const journeyData = journeys[journeyId]; const journey = journeyData.journey; if (journey) { const goalId = journey.goalId; const journeyTitle = journey.title; console.log(`Processing journey: ${journeyTitle} (ID: ${journeyId}, Goal ID: ${goalId})`); if (journeyTitle === desiredJourneyName && goalId === desiredGoalId) { console.log(`Found desired journey: ${journeyTitle}`); const journeyObject = { journeyTitle: journeyTitle, goalId: goalId, sideEffects: {}, sequence: null }; const lastExecution = journeyData.lastExecution; const readJourneyId = lastExecution.report.journeyId; if (readJourneyId) { journeyObject.journeyId = readJourneyId; } const sequence = lastExecution.execution.sequence; journeyObject.sequence = sequence; console.log(`Sequence: ${sequence}`); if (lastExecution && lastExecution.report && lastExecution.report.checkpoints) { for (const checkpointId in lastExecution.report.checkpoints) { if (lastExecution.report.checkpoints.hasOwnProperty(checkpointId)) { const checkpoint = lastExecution.report.checkpoints[checkpointId]; if (checkpoint.steps) { for (const stepId in checkpoint.steps) { if (checkpoint.steps.hasOwnProperty(stepId)) { const step = checkpoint.steps[stepId]; console.log(`Processing step: ${stepId}`); if (goalId === desiredGoalId) { const usedData = step.sideEffects ? step.sideEffects.usedData : {}; if (Object.keys(usedData).length > 0) { console.log('Found used data:', JSON.stringify(usedData, null, 2)); Object.assign(journeyObject.sideEffects, usedData); } } } } } } } } // Process libraryCheckpointExecutionReports if (lastExecution.report.libraryCheckpointExecutionReports) { for (const libCheckpointPosition in lastExecution.report.libraryCheckpointExecutionReports) { const libCheckpoint = lastExecution.report.libraryCheckpointExecutionReports[libCheckpointPosition]; if (libCheckpoint.steps) { for (const stepId in libCheckpoint.steps) { if (libCheckpoint.steps.hasOwnProperty(stepId)) { const step = libCheckpoint.steps[stepId]; console.log(`Processing library checkpoint step: ${stepId}`); const usedData = step.sideEffects ? step.sideEffects.usedData : {}; if (Object.keys(usedData).length > 0) { console.log('Found used data in library checkpoint:', usedData); Object.assign(journeyObject.sideEffects, usedData); } } } } } } journeyArray.push(journeyObject); console.log('Journey object added to array:', JSON.stringify(journeyObject, null, 2)); break; } } else { console.log(`Journey data not found for journey ID: ${journeyId}`); } } } console.log(`'Final journey array:', ${JSON.stringify(journeyArray, null, 2)}`); if (journeyArray.length === 0) { throw new Error(`Desired journey "${desiredJourneyName}" not found when validated with goal Id ${desiredGoalId}`); } return (journeyArray); } // If totalCount is found, send additional requests if (totalCountFound) { const requests = []; for (const { suiteId, totalCount } of journeysWithDataDrivenDetails) { for (let i = 1; i <= totalCount; i++) { const sequenceUrl = `${basicUrl}/testsuites/execution?suiteId=${suiteId}&jobId=${jobId}&sequence=${i}&includeJourneyDetails=true&envelope=false`; console.log('Sequence URL:', sequenceUrl); const sequenceResponse = sendRequest(sequenceUrl); requests.push(sequenceResponse); } } const results = await Promise.all(requests); const consolidatedData = results.reduce((acc, result) => { for (let key in result) { if (result.hasOwnProperty(key)) { if (!acc[key]) { acc[key] = []; } acc[key] = acc[key].concat(result[key]); } } return acc; }, {}); console.log('Consolidated Data:', JSON.stringify(consolidatedData, null, 2)); const journeyArray = []; for (const journeyObj of consolidatedData.journeys) { const journeyId = Object.keys(journeyObj)[0]; const journeyData = journeyObj[journeyId]; const journey = journeyData.journey; if (journey && journey.title === desiredJourneyName && journey.goalId === desiredGoalId) { const journeyObject = { journeyTitle: journey.title, goalId: journey.goalId, sideEffects: {}, sequence: journeyData.lastExecution.execution.sequence }; for (const checkpointId in journeyData.lastExecution.report.checkpoints) { if (journeyData.lastExecution.report.checkpoints.hasOwnProperty(checkpointId)) { const checkpoint = journeyData.lastExecution.report.checkpoints[checkpointId]; for (const stepId in checkpoint.steps) { if (checkpoint.steps.hasOwnProperty(stepId)) { const step = checkpoint.steps[stepId]; if (step.sideEffects && step.sideEffects.usedData && Object.keys(step.sideEffects.usedData).length > 0) { journeyObject.sideEffects = step.sideEffects.usedData; } } } } } // Process libraryCheckpointExecutionReports if (journeyData.lastExecution.report.libraryCheckpointExecutionReports) { for (const libCheckpointPosition in journeyData.lastExecution.report.libraryCheckpointExecutionReports) { const libCheckpoint = journeyData.lastExecution.report.libraryCheckpointExecutionReports[libCheckpointPosition]; if (libCheckpoint.steps) { for (const stepId in libCheckpoint.steps) { if (libCheckpoint.steps.hasOwnProperty(stepId)) { const step = libCheckpoint.steps[stepId]; console.log(`Processing library checkpoint step: ${stepId}`); const usedData = step.sideEffects ? step.sideEffects.usedData : {}; if (Object.keys(usedData).length > 0) { console.log('Found used data in library checkpoint:', usedData); Object.assign(journeyObject.sideEffects, usedData); } } } } } } journeyArray.push(journeyObject); } } console.log(`Final journey array:', ${JSON.stringify(journeyArray, null, 2)}`); if (journeyArray.length === 0) { throw new Error(`Desired journey "${desiredJourneyName}" not found when validated with goal Id ${desiredGoalId}`); } return (journeyArray); } } catch (error) { console.error('Error Message:', error.message); throw new Error('Error Message: ' + error.message); } } fetchAndProcessJourneys().then(done).catch(doneError);