cypress-aiotests-reporter
Advanced tools
Comparing version 1.4.2 to 1.5.0
@@ -14,3 +14,3 @@ const { defineConfig } = require("cypress"); | ||
"hosted" : { | ||
"jiraUrl": "https://jira8.aioreports.com", | ||
"jiraUrl": "https://jira.aiojiraapps.com", | ||
"jiraPAT": "", | ||
@@ -26,3 +26,3 @@ "jiraUsername": "", | ||
"folder": ["Cloud","Smoke Test Nightly"], | ||
"tasks": ["NVTES-1"] | ||
"tasks": ["NVTES-1"], | ||
}, | ||
@@ -32,5 +32,9 @@ "addNewRun": false, | ||
"createNewRunForRetries": false, | ||
"addTestBodyToComments": true | ||
"addTestBodyToComments": true, | ||
"parallelBuild":{ | ||
"masterBuild": true, | ||
"waitForSeconds": 10 | ||
} | ||
} | ||
} | ||
}); |
@@ -20,6 +20,6 @@ const { defineConfig } = require("cypress"); | ||
"createNewCycle": false, | ||
"cycleName": "Cypress nightly runs ", | ||
"cycleName": "Cypress nightly runs 4", | ||
"cycleKey": "NVTES-CY-65", | ||
"folder": ["Cloud","Smoke Test Nightly"], | ||
"tasks": ["NVTES-1"] | ||
"tasks": ["NVTES-1"], | ||
}, | ||
@@ -30,5 +30,9 @@ "addNewRun": false, | ||
"addTestBodyToComments": true, | ||
"debugMode": true | ||
"debugMode": true, | ||
"parallelBuild":{ | ||
"masterBuild": true, | ||
"waitForSeconds": 10 | ||
} | ||
} | ||
} | ||
}); |
{ | ||
"name": "cypress-aiotests-reporter", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"description": "Plugin to report cypress results to AIO Tests Jira", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
144
README.md
@@ -108,8 +108,46 @@ [](https://github.com/aiotests/cypress-aiotests-reporter/actions/workflows/main.yml) | ||
"cycleDetails": { | ||
"createNewCycle": true, | ||
"createNewCycle": true, //possible values "true","false","CREATE_IF_ABSENT", true, false | ||
"cycleName": "Cypress first run from plugin", | ||
"cycleKey": "NVTES-CY-2", | ||
"folder": ["Cloud","Smoke Test Nightly"], | ||
"tasks": ["SCRUM-1","SCRUM-2] | ||
"tasks": ["SCRUM-1","SCRUM-2], | ||
"customFields": [ | ||
{ | ||
"name": "Reviewed? [Boolean CF]", | ||
"value": "Yes", | ||
}, | ||
{ | ||
"name": "Set (Single Select CF)", | ||
"value": {"value":"P1"} | ||
}, | ||
{ | ||
"name": "Teams (Multi Select CF)", | ||
"value": [{"value":"TeamAlpha"},{"value":"Zeta"}] | ||
}, | ||
{ | ||
"name": "NumberCF", "value": 0 | ||
}, | ||
{ | ||
"name": "TextValue CF", "value": "This can be a long note", | ||
}, | ||
{ | ||
"name": "Reviewed Date", "value": "2024-08-29T04:38:36.437Z", | ||
}, | ||
{ | ||
"name": "SME [User CF]", "value": "<accountid of user>" | ||
} | ||
], | ||
}, | ||
"runDetails": { | ||
"customFieldsToUpdate": [ | ||
{ | ||
"operationType": "ADD_TO_EXISTING", | ||
"name": "StepOwner", | ||
"value": [{"value": "Val2"},{"value": "Val1"}] | ||
}, | ||
{ | ||
"name": "Env", "value": {"value":"UAT"} | ||
} | ||
] | ||
}, | ||
"addNewRun": true, | ||
@@ -119,3 +157,7 @@ "addAttachmentToFailedCases": true, | ||
"addTestBodyToComments": true, | ||
"debugMode": false | ||
"debugMode": false, | ||
"parallelBuild":{ //optional | ||
"masterBuild": true, | ||
"waitForSeconds": 10 //defaults to 2 seconds | ||
} | ||
} | ||
@@ -149,8 +191,46 @@ } | ||
"cycleDetails": { | ||
"createNewCycle": true, | ||
"createNewCycle": true, //possible values "true","false","CREATE_IF_ABSENT", true, false | ||
"cycleName": "Cypress Nightly Run ", | ||
"cycleKey": "SERV-CY-2", | ||
"folder": ["Server","Smoke Test Nightly"], | ||
"tasks": ["SERV-1","SERV-2] | ||
"tasks": ["SERV-1","SERV-2], | ||
"customFields": [ | ||
{ | ||
"name": "Reviewed? [Boolean CF]", | ||
"value": "Yes", | ||
}, | ||
{ | ||
"name": "Set (Single Select CF)", | ||
"value": {"value":"P1"} | ||
}, | ||
{ | ||
"name": "Teams (Multi Select CF)", | ||
"value": [{"value":"TeamAlpha"},{"value":"Zeta"}] | ||
}, | ||
{ | ||
"name": "NumberCF", "value": 0 | ||
}, | ||
{ | ||
"name": "TextValue CF", "value": "This can be a long note", | ||
}, | ||
{ | ||
"name": "Reviewed Date", "value": "2024-08-29T04:38:36.437Z", | ||
}, | ||
{ | ||
"name": "SME [User CF]", "value": "<accountid of user>" | ||
} | ||
], | ||
}, | ||
"runDetails": { | ||
"customFieldsToUpdate": [ | ||
{ | ||
"operationType": "ADD_TO_EXISTING", | ||
"name": "StepOwner", | ||
"value": [{"value": "Val2"},{"value": "Val1"}] | ||
}, | ||
{ | ||
"name": "Env", "value": {"value":"UAT"} | ||
} | ||
] | ||
}, | ||
"addNewRun": true, | ||
@@ -160,3 +240,7 @@ "addAttachmentToFailedCases": false, | ||
"addTestBodyToComments": true, | ||
"debugMode": false | ||
"debugMode": false, | ||
"parallelBuild":{ //optional | ||
"masterBuild": true, | ||
"waitForSeconds": 10 //defaults to 2 seconds | ||
} | ||
} | ||
@@ -170,18 +254,38 @@ } | ||
| Value | Description | | ||
|-----------------------------|------------------------------------------------------------------------------------------------------| | ||
| enableReporting | Set to true to make the current run update results to AIO Tests. Default false. | | ||
| jiraProjectId | Jira Project key to update results to | | ||
| cycleDetails.createNewCycle | Set to true to create a new cycle for run being reported | | ||
| cycleDetails.cycleName | Works if createNewCycle is true, sets the cycle name of cycle getting created | | ||
| cycleDetails.cycleKey | AIO Tests cycle key that should be updated. Used if createNewCycle is false | | ||
| cycleDetails.folder | Folder hierarchy, where first item in array is parent folder and so on eg.["Parent","Child"] | | ||
| cycleDetails.tasks | List of Jira Issue Keys to attach as Tasks to created cycle, impacts only when creating new cycle | | ||
| addNewRun | Create a new run or update an existing run in the cycle | | ||
| addAttachmentToFailedCases | Set to true to attach screenshots, if available, for failed cases | | ||
| createNewRunForRetries | Set to true if each retry should create a new run | | ||
| addTestBodyToComments | Set to true test script body should be added as a comment in a failed case. Doesn't work above v12.x | | ||
| debugMode | Default false. Set to true to increase verbosity of logs while debugging an issue | | ||
| Value | Description | | ||
|------------------------------------|----------------------------------------------------------------------------------------------------------| | ||
| enableReporting | Set to true to make the current run update results to AIO Tests. Default false. | | ||
| jiraProjectId | Jira Project key to update results to | | ||
| cycleDetails.createNewCycle | Options: [true, false, "CREATE_IF_ABSENT"]. Set to true to create a new cycle for run being reported. | | ||
| cycleDetails.cycleName | Works if createNewCycle is true, sets the cycle name of cycle getting created | | ||
| cycleDetails.cycleKey | AIO Tests cycle key that should be updated. Used if createNewCycle is false | | ||
| cycleDetails.folder | Folder hierarchy, where first item in array is parent folder and so on eg.["Parent","Child"] | | ||
| cycleDetails.tasks | List of Jira Issue Keys to attach as Tasks to created cycle, impacts only when creating new cycle | | ||
| cycleDetails.customFields | List of custom fields that need to be set while creating cycle. Options shown in example. | | ||
| addNewRun | Create a new run or update an existing run in the cycle | | ||
| addAttachmentToFailedCases | Set to true to attach screenshots, if available, for failed cases | | ||
| createNewRunForRetries | Set to true if each retry should create a new run | | ||
| addTestBodyToComments | Set to true test script body should be added as a comment in a failed case. **Doesn't work above v12.x** | | ||
| runDetails.customFieldsToUpdate | List of run level custom fields. Options in example above. | | ||
| customFieldsToUpdate.operationType | Options: ADD_TO_EXISTING, REPLACE_EXISTING, DELETE_EXISTING | | ||
| debugMode | Default false. Set to true to increase verbosity of logs while debugging an issue | | ||
| parallelBuild.masterBuild | Optional. Default true. See below for details on parallelBuild | | ||
| parallelBuild.waitForSeconds | Optional. Default 2 seconds. See below for details on parallelBuild | | ||
#### Create New Cycle options | ||
- createNewCycle = true or "true", uses the **cycleName** and cycleDetails value to generate new cycle | ||
- createNewCycle = false or "false", uses the **cycleKey** value to find an existing cycle and updates the cycle. If cycle is not found, an error is thrown | ||
- createNewCycle = "CREATE_IF_ABSENT" uses the **cycleName** to search for an existing cycle with an exact match. If cycle is found, then the cycle is updated. | ||
If it is not found, then a new cycle is created using **cycleName** and **cycleDetails** | ||
#### Parallel builds | ||
If multiple builds are being triggered in parallel, the parallelBuild setting can be used to specify the masterBuild. | ||
One of the parallel builds can be configured to set **masterBuild as true**. This build should have createNewCycle either set as true or CREATE_IF_ABSENT. | ||
The other builds running in parallel can have masterBuild set to false, which would imply, they would wait for the masterBuild to run the cycle creation code, waiting for | ||
**waitForSeconds** (defaults to 2 seconds), before trying to find the cycle. | ||
If multiple builds are not being run in parallel, the parallelBuild value can be ignored. | ||
# Logging | ||
@@ -188,0 +292,0 @@ |
@@ -7,4 +7,7 @@ const axios = require('axios'); | ||
const rateLimitWaitTime = 60*1000; | ||
const CREATE_IF_ABSENT = "CREATE_IF_ABSENT"; | ||
const createNewCycleOptions = [true, false, "true", "false", CREATE_IF_ABSENT]; | ||
let aioAPIClient = null; | ||
let debugMode = false; | ||
let allCaseKeys = []; | ||
function sleep(ms) { | ||
@@ -62,2 +65,51 @@ return new Promise(resolve => setTimeout(resolve, ms)); | ||
let isAttachmentAPIAvailable = null; | ||
function getCustomFieldValueToUpdate(customFieldsToUpdate) { | ||
let cfUpdates = []; | ||
if(customFieldsToUpdate) { | ||
customFieldsToUpdate.forEach(cf => { | ||
let data = {"customValue":{"name":cf.name, "value": cf.value}}; | ||
if(cf.operationType) { | ||
data["customFieldUpdateOperationType"] = cf.operationType; | ||
} | ||
cfUpdates.push(data); | ||
}) | ||
} | ||
return cfUpdates; | ||
} | ||
const updateRunFields = async function (aioConfig){ | ||
if(allCaseKeys.length === 0){ | ||
aioLogger.debug("No cases to update for bulk update of run custom fields.") | ||
return Promise.resolve(); | ||
} | ||
const cfUpdates = getCustomFieldValueToUpdate(aioConfig.runDetails.customFieldsToUpdate); | ||
if(!cfUpdates.length) { | ||
aioLogger.debug("No custom fields data found.") | ||
return Promise.resolve(); | ||
} | ||
let data = { | ||
"testRunSearchRequest": { | ||
"key": { | ||
"comparisonType": "IN", | ||
"list": allCaseKeys | ||
}}, | ||
"testRunBulkUpdateRequest": {"customFieldValueToUpdate" : cfUpdates} | ||
} | ||
aioLogger.debug("Posting run fields to " + `/project/${aioConfig.jiraProjectId}/testcycle/${aioConfig.cycleDetails.cycleKeyToReportTo}/bulk/testrun`) | ||
return await aioAPIClient | ||
.put(`/project/${aioConfig.jiraProjectId}/testcycle/${aioConfig.cycleDetails.cycleKeyToReportTo}/bulk/testrun`, data) | ||
.then(function (response) { | ||
aioLogger.debug(`Successfully updated run fields.`); | ||
}) | ||
.catch(async err => { | ||
debugLogError(err) | ||
if(err.response) { | ||
aioLogger.error("Error reporting in updating run fields. " + "Status Code - " + err.response.status + " - " + err.response.data); | ||
} else { | ||
aioLogger.error("Error in updating run fields : " + err.code); | ||
} | ||
}) | ||
} | ||
const reportSpecResults = function(config, results) { | ||
@@ -75,2 +127,3 @@ if(!aioAPIClient) { | ||
let caseKeys = [...testData.keys()]; | ||
allCaseKeys.push(...caseKeys); | ||
let passedCaseKeys = []; | ||
@@ -134,3 +187,2 @@ let failedCaseKeys = []; | ||
aioLogger.debug("Posting results to " + `/project/${aioConfig.jiraProjectId}/testcycle/${aioConfig.cycleDetails.cycleKeyToReportTo}/testcase/${caseKey}/testrun?createNewRun=${createNewRun}`) | ||
aioLogger.debug(data) | ||
return aioAPIClient | ||
@@ -148,3 +200,3 @@ .post(`/project/${aioConfig.jiraProjectId}/testcycle/${aioConfig.cycleDetails.cycleKeyToReportTo}/testcase/${caseKey}/testrun?createNewRun=${createNewRun}`, data) | ||
if(err.response) { | ||
if (err.response.status == 429 && trialCounter < 3) { | ||
if (err.response.status === 429 && trialCounter < 3) { | ||
aioLogger.log("Reached AIO rate limits. Pausing..") | ||
@@ -278,9 +330,9 @@ await sleep(rateLimitWaitTime); | ||
const getOrCreateCycle = (aioConfig) => { | ||
const getOrCreateCycle = async (aioConfig) => { | ||
aioLogger.logStartEnd("Determining cycle to update"); | ||
initAPIClient(aioConfig); | ||
if(!aioAPIClient) { | ||
if (!aioAPIClient) { | ||
return Promise.resolve("Please specify valid credentials to connect with AIO Tests."); | ||
} | ||
if(!aioConfig.cycleDetails) { | ||
if (!aioConfig.cycleDetails) { | ||
aioLogger.error("Please specify cycleDetails in config. eg. \"cycleDetails\": {\"cycleKey\":\"AT-CY-11\"}", true); | ||
@@ -290,57 +342,76 @@ return Promise.resolve(); | ||
let aioCycleConfig = aioConfig.cycleDetails; | ||
if(aioCycleConfig.createNewCycle) { | ||
if(!(createNewCycleOptions.includes(aioCycleConfig.createNewCycle))){ | ||
return Promise.resolve( | ||
`Invalid value for createNewCycle "${aioCycleConfig.createNewCycle}". Valid values include ${createNewCycleOptions}.` | ||
); | ||
} | ||
if((!aioCycleConfig.createNewCycle || "false" === aioCycleConfig.createNewCycle) && aioCycleConfig.cycleKey){ | ||
aioCycleConfig["cycleKeyToReportTo"] = aioCycleConfig.cycleKey; | ||
return Promise.resolve(); | ||
} | ||
if(aioCycleConfig.createNewCycle === true || "true" === aioCycleConfig.createNewCycle || aioCycleConfig.createNewCycle === CREATE_IF_ABSENT) { | ||
let cycleTitle = aioCycleConfig.cycleName; | ||
if(!!!cycleTitle){ | ||
return Promise.resolve("createNewCycle is true in config. New cycle name is mandatory.", true) | ||
} else { | ||
aioLogger.log("Creating cycle : " + cycleTitle); | ||
let folderCreationPromise = getOrCreateFolder(aioConfig.jiraProjectId, aioCycleConfig); | ||
return folderCreationPromise.then((folderCreationResponse) => { | ||
aioLogger.debug("Folder task resolved. Creating cycle.") | ||
let createCycleBody = { | ||
title: cycleTitle | ||
let customFields = aioCycleConfig.customFields; | ||
if (!!!cycleTitle) { | ||
return Promise.resolve("createNewCycle is set to " + aioCycleConfig.createNewCycle +" in config. Please set cycleName.") | ||
} | ||
if(aioCycleConfig.createNewCycle === CREATE_IF_ABSENT) { | ||
let results = await findExistingCycleThroughName(aioConfig); | ||
if (results === true) { | ||
aioLogger.debug("Existing cycle found") | ||
//Cycle found and set. | ||
return; | ||
} | ||
if (results !== false) { | ||
//Error while finding cycle. | ||
aioLogger.log(results) | ||
return; | ||
} | ||
} | ||
aioLogger.log("Creating cycle : " + cycleTitle); | ||
let folderCreationPromise = getOrCreateFolder(aioConfig.jiraProjectId, aioCycleConfig); | ||
return folderCreationPromise.then((folderCreationResponse) => { | ||
aioLogger.debug("Folder task resolved. Creating cycle.") | ||
let createCycleBody = { | ||
title: cycleTitle, | ||
customFields: customFields || null | ||
} | ||
if (folderCreationResponse) { | ||
createCycleBody.folder = folderCreationResponse.data; | ||
} | ||
if (aioCycleConfig.tasks && aioCycleConfig.tasks.length > 0 && Array.isArray(aioCycleConfig.tasks)) { | ||
let jiraTasks = aioCycleConfig.tasks.filter(f => f && !!f.trim()); | ||
if (jiraTasks.length > 0) { | ||
createCycleBody.jiraTaskIDs = jiraTasks; | ||
} | ||
if(folderCreationResponse) { | ||
createCycleBody.folder = folderCreationResponse.data; | ||
} | ||
if(aioCycleConfig.tasks && aioCycleConfig.tasks.length > 0 && Array.isArray(aioCycleConfig.tasks)) { | ||
let jiraTasks = aioCycleConfig.tasks.filter(f => f && !!f.trim()); | ||
if(jiraTasks.length > 0) { | ||
createCycleBody.jiraTaskIDs = jiraTasks; | ||
} | ||
aioLogger.debug("Cycle endpoint " + "/project/" + aioConfig.jiraProjectId + "/testcycle/detail"); | ||
return aioAPIClient.post("/project/" + aioConfig.jiraProjectId + "/testcycle/detail", createCycleBody) | ||
.then(function (response) { | ||
aioCycleConfig["cycleKeyToReportTo"] = response.data.key; | ||
aioLogger.log("Cycle created successfully : " + aioCycleConfig.cycleKeyToReportTo) | ||
}) | ||
.catch(function (error) { | ||
debugLogError(error); | ||
if (error.response) { | ||
if (error.response.status === 401 || error.response.status === 403) { | ||
return Promise.resolve("Authorization error. Please check credentials.") | ||
} else { | ||
return Promise.resolve(error.response.status + " : " + error.response.data); | ||
} | ||
} | ||
} | ||
aioLogger.debug("Cycle endpoint " + "/project/"+ aioConfig.jiraProjectId+"/testcycle/detail"); | ||
aioLogger.debug(createCycleBody) | ||
return aioAPIClient.post("/project/"+ aioConfig.jiraProjectId+"/testcycle/detail", createCycleBody) | ||
.then(function (response) { | ||
aioCycleConfig["cycleKeyToReportTo"] = response.data.key; | ||
aioLogger.log("Cycle created successfully : " + aioCycleConfig.cycleKeyToReportTo ) | ||
}) | ||
.catch(function (error) { | ||
debugLogError(error); | ||
if(error.response) { | ||
if (error.response.status === 401 || error.response.status === 403) { | ||
return Promise.resolve("Authorization error. Please check credentials.") | ||
} else { | ||
return Promise.resolve(error.response.status + " : " + error.response.data); | ||
} | ||
} | ||
}); | ||
}).catch((error) => { | ||
debugLogError(error); | ||
if(error.response) { | ||
aioLogger.error(error.response.status + " : " + error.response.data) | ||
} | ||
return Promise.resolve("Error in fetching or creating cycle folder. " + | ||
"Please check format of folder, for eg. [\"Cloud\",\"Release1\"]"); | ||
}) | ||
} | ||
} else { | ||
if(!!!aioCycleConfig.cycleKey) { | ||
return Promise.resolve("createNewCycle is false in config. Please specify a cycle key (eg. AT-CY-11) as \"cycleKey\":\"AT-CY=11\"", true); | ||
} else { | ||
aioCycleConfig["cycleKeyToReportTo"] = aioCycleConfig.cycleKey; | ||
} | ||
return Promise.resolve(); | ||
}); | ||
}).catch((error) => { | ||
debugLogError(error); | ||
if (error.response) { | ||
aioLogger.error(error.response.status + " : " + error.response.data) | ||
} | ||
return Promise.resolve("Error in fetching or creating cycle folder. " + | ||
"Please check format of folder, for eg. [\"Cloud\",\"Release1\"]"); | ||
}) | ||
} | ||
return Promise.resolve("createNewCycle is false in config. Please specify a cycle key (eg. AT-CY-11) as \"cycleKey\":\"AT-CY=11\" or cycle name (eg. NVTES) as \"cycleName\":\"NVTES\" ", true); | ||
} | ||
@@ -350,2 +421,37 @@ | ||
async function findExistingCycleThroughName(aioConfig) { | ||
if (aioConfig.parallelBuild && aioConfig.parallelBuild.masterBuild === false) { | ||
let to = aioConfig.parallelBuild.waitForSeconds? aioConfig.parallelBuild.waitForSeconds: 2; | ||
aioLogger.log(`Waiting for ${to} seconds for master build to finish`) | ||
await new Promise(resolve => setTimeout(resolve, to*1000)); | ||
} | ||
let body = { | ||
"title": { | ||
"comparisonType": "EXACT_MATCH", | ||
"value": aioConfig.cycleDetails.cycleName.trim() | ||
} | ||
} | ||
aioLogger.log("Finding cycle with name : " + aioConfig.cycleDetails.cycleName.trim()) | ||
return aioAPIClient.post(`/project/${aioConfig.jiraProjectId}/testcycle/search`, body) | ||
.then(function (response) { | ||
const items = response?.data?.items; | ||
if (items && items.length > 0) { | ||
aioConfig.cycleDetails["cycleKeyToReportTo"] = items[0]?.key; | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
}) | ||
.catch(function (error) { | ||
debugLogError(error); | ||
if (error.response) { | ||
if (error.response.status === 401 || error.response.status === 403) { | ||
return Promise.resolve("Authorization error. Please check credentials.") | ||
} else { | ||
return Promise.resolve(error.response.status + " : " + error.response.data); | ||
} | ||
} | ||
}); | ||
} | ||
function getAIORunStatus(cypressStatusString) { | ||
@@ -372,2 +478,2 @@ switch(cypressStatusString) { | ||
module.exports = { reportSpecResults, getOrCreateCycle } | ||
module.exports = { reportSpecResults, getOrCreateCycle, updateRunFields } |
@@ -18,8 +18,9 @@ | ||
const registerAIOTestsPlugin = (on, config) => { | ||
on('before:run', () => { | ||
const registerAIOTestsPlugin = async (on, config) => { | ||
on('before:run', async () => { | ||
let aioConfig = getAIOConfig(config, true); | ||
if(aioConfig) { | ||
return reporter.getOrCreateCycle(aioConfig).then((data) => { | ||
if(aioConfig.cycleDetails.cycleKeyToReportTo) { | ||
if (aioConfig) { | ||
try { | ||
const data = await reporter.getOrCreateCycle(aioConfig); | ||
if (aioConfig.cycleDetails.cycleKeyToReportTo) { | ||
aioLogger.log("Reporting results to cycle : " + aioConfig.cycleDetails.cycleKeyToReportTo); | ||
@@ -29,3 +30,5 @@ } else { | ||
} | ||
}) | ||
} catch (err) { | ||
aioLogger.error("An error occurred: " + err.message); | ||
} | ||
} | ||
@@ -42,4 +45,14 @@ }); | ||
}) | ||
on('after:run', async () => { | ||
let aioConfig = getAIOConfig(config); | ||
if(aioConfig && aioConfig.runDetails) { | ||
return reporter.updateRunFields( aioConfig ).then(() => { | ||
aioLogger.logStartEnd("Updating run fields completed."); | ||
}) | ||
} | ||
}); | ||
}; | ||
module.exports = { registerAIOTestsPlugin } |
Sorry, the diff of this file is not supported yet
297145
21
668
306