UNPKG

@testlio/cli

Version:

Official Testlio platform command-line interface

196 lines (155 loc) 7.64 kB
#!/usr/bin/env node const fs = require('fs'); const axios = require('axios'); const Joi = require('joi'); const FormData = require('form-data'); require('dotenv').config(); const FAILURE = 1; const SUCCESS = 0; const ONE_MB_IN_BYTES = 1024 ** 2; const DEVICE_RESULT_PACKAGE_MAX_FILE_SIZE_MB = 500 * ONE_MB_IN_BYTES; const printHelp = () => { console.log(`Parse Run Results Utility Usage: testlio parse-run-results [options] Options: --deviceResultId ID of the specific device result you want to submit results, if you don't know the deviceResult Id you can use find-device-result command or else you can pass automatedDeviceId/automatedBrowserId. (Mutually exclusive with --automatedDeviceId and --automatedBrowserId; provide only one of these options.) --automatedDeviceId ID of the automated device for which you want to submit results. (Mutually exclusive with --deviceResultId and --automatedBrowserId; provide only one of these options.) --automatedBrowserId ID of the automated browser for which you want to submit results. (Mutually exclusive with --deviceResultId and --automatedDeviceId; provide only one of these options.) --browserVersion REQUIRED. In case your device is browser, please pass on the exact browser version on which the tests were executed(e.g., 116.0.5845.110) --externalSource Optional. Specifies the external source URL or identifier where the test execution took place. --path REQUIRED. Specifies the local path to the zip package containing Allure results. --projectConfig [path] Specifies the path to the project configuration file. (Optional; default is 'project-config.json') Note: You must provide exactly one of the following: --deviceResultId, --automatedDeviceId, or --automatedBrowserId. The --path option is mandatory and should point to a valid zip package containing Allure results. The --browserVersion is mandatory in case your device is browser. Please pass on exact browser version on which the test were executed. `); }; const setAuthorizationToken = (token) => { axios.defaults.headers.common.Authorization = `Bearer ${token}`; }; const setBaseUri = (baseURI) => { axios.defaults.baseURL = baseURI; }; const getDeviceResultId = async (resultCollectionGuid, resultGuid, automatedId, idType) => { const result = await axios.get(`/result/v1/collections/${resultCollectionGuid}/results/${resultGuid}`); return result.data.deviceResults.find((deviceResult) => deviceResult[idType] === automatedId)?.id; }; const parseRunResults = async (path, resultCollectionGuid, deviceResultId) => { const { size } = fs.statSync(path); if (size > DEVICE_RESULT_PACKAGE_MAX_FILE_SIZE_MB) { throw new Error( `Uploading ${path} failed: max. file size ${DEVICE_RESULT_PACKAGE_MAX_FILE_SIZE_MB / ONE_MB_IN_BYTES}MB` ); } const form = new FormData(); form.append('file', fs.createReadStream(path), { filename: 'Customer Artifacts.zip', contentType: 'application/zip', knownLength: size }); return axios.post(`/result/v1/collections/${resultCollectionGuid}/device-results/${deviceResultId}/parse`, form, { headers: { ...form.getHeaders(), 'Content-Length': form.getLengthSync() }, maxContentLength: Infinity, maxBodyLength: Infinity }); }; const parseRunResultsSchema = Joi.object({ deviceResultId: Joi.string(), automatedDeviceId: Joi.string().label( 'Pass on the automatedDeviceId against which the results should be submitted' ), automatedBrowserId: Joi.string().label( 'Pass on the automatedBrowserId against which the results should be submitted' ), path: Joi.string().required().label('Path to zip package containing Allure results'), projectConfig: Joi.string().default('project-config.json'), browserVersion: Joi.any(), externalSource: Joi.string().optional().description('External source of the test results') }).xor('deviceResultId', 'automatedDeviceId', 'automatedBrowserId'); module.exports = async (params) => { if (params.h || params.help) { printHelp(); return; } const validatedParams = Joi.attempt(params, parseRunResultsSchema); if (validatedParams.automatedBrowserId && validatedParams.browserVersion === undefined) { console.log( `Please provide --browserVersion it is mandatory in case your device is browser. Please pass on exact browser version on which the test were executed.` ); return FAILURE; } if (!fs.existsSync(validatedParams.projectConfig)) { console.log(`File "${validatedParams.projectConfig}" not found!`); return FAILURE; } try { const projectConfigData = JSON.parse(fs.readFileSync(validatedParams.projectConfig).toString()); if (!process.env.RUN_API_TOKEN) { console.log('Please provide RUN API TOKEN'); return FAILURE; } if (!process.env.RESULT_ID) { console.log('For results parsing, RESULT_ID must be provided'); return FAILURE; } if (!fs.existsSync(params.path)) { console.log( `File "${params.path}" not found! Please provide a valid path to zip package containing Allure results` ); return FAILURE; } setBaseUri(projectConfigData.baseURI); setAuthorizationToken(process.env.RUN_API_TOKEN); const deviceResultId = validatedParams.deviceResultId || (await getDeviceResultId( projectConfigData.resultCollectionGuid, process.env.RESULT_ID, validatedParams.automatedDeviceId, 'automatedDevice' )) || (await getDeviceResultId( projectConfigData.resultCollectionGuid, process.env.RESULT_ID, validatedParams.automatedBrowserId, 'automatedBrowser' )); if (!deviceResultId) { console.log('Device result id not found, cannot parse results'); return FAILURE; } const response = await parseRunResults( validatedParams.path, projectConfigData.resultCollectionGuid, deviceResultId ); const metadata = []; if (validatedParams.browserVersion) { metadata.push({ key: 'browserVersion', value: `${validatedParams.browserVersion}` }); } if (validatedParams.externalSource) { metadata.push({ key: 'externalSource', value: `${validatedParams.externalSource}` }); } if (metadata.length > 0) { await axios.post( `/result/v1/collections/${projectConfigData.resultCollectionGuid}/device-results/${deviceResultId}/metadata`, { metadata } ); } if (response.data.deviceResultId === deviceResultId) { console.log('Results file uploaded successfully'); return SUCCESS; } console.log('Something went wrong while uploading results file'); return FAILURE; } catch (e) { console.log('Something went wrong while parsing run results', e); return FAILURE; } };