diff --git a/bin/commands/runs.js b/bin/commands/runs.js index 0a439ff6..1e6f4944 100644 --- a/bin/commands/runs.js +++ b/bin/commands/runs.js @@ -40,7 +40,7 @@ const { isTurboScaleSession, getTurboScaleGridDetails, patchCypressConfigFileCon module.exports = function run(args, rawArgs) { - + utils.normalizeTestReportingEnvVars(); markBlockStart('preBuild'); // set debug mode (--cli-debug) utils.setDebugMode(args); @@ -112,7 +112,7 @@ module.exports = function run(args, rawArgs) { // set build tag caps utils.setBuildTags(bsConfig, args); - // Send build start to Observability + // Send build start to TEST REPORTING AND ANALYTICS if(isTestObservabilitySession) { await launchTestSession(bsConfig, bsConfigPath); utils.setO11yProcessHooks(null, bsConfig, args, null, buildReportData); diff --git a/bin/helpers/helper.js b/bin/helpers/helper.js index ecb4e279..b839c76b 100644 --- a/bin/helpers/helper.js +++ b/bin/helpers/helper.js @@ -19,10 +19,11 @@ const { readCypressConfigFile } = require('./readCypressConfigUtil'); const { MAX_GIT_META_DATA_SIZE_IN_BYTES, GIT_META_DATA_TRUNCATED } = require('./constants') const CrashReporter = require('../testObservability/crashReporter'); const HttpsProxyAgent = require('https-proxy-agent'); +const { TEST_REPORTING_ANALYTICS } = require("../testObservability/helper/constants"); exports.debug = (text, shouldReport = false, throwable = null) => { if (process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "true" || process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "1") { - logger.info(`[ OBSERVABILITY ] ${text}`); + logger.info(`[ ${TEST_REPORTING_ANALYTICS} ] ${text}`); } if(shouldReport) { CrashReporter.getInstance().uploadCrashReport(text, throwable ? throwable && throwable.stack : null); diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index caaf992e..cc644c03 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -33,6 +33,7 @@ exports.validateBstackJson = (bsConfigPath) => { try { logger.info(`Reading config from ${bsConfigPath}`); let bsConfig = require(bsConfigPath); + bsConfig = exports.normalizeTestReportingConfig(bsConfig); resolve(bsConfig); } catch (e) { reject( @@ -492,7 +493,6 @@ exports.setNodeVersion = (bsConfig, args) => { // specs can be passed via command line args as a string // command line args takes precedence over config exports.setUserSpecs = (bsConfig, args) => { - if(o11yHelpers.isBrowserstackInfra() && o11yHelpers.isTestObservabilitySession() && o11yHelpers.shouldReRunObservabilityTests()) { bsConfig.run_settings.specs = process.env.BROWSERSTACK_RERUN_TESTS; return; @@ -1499,7 +1499,6 @@ exports.splitStringByCharButIgnoreIfWithinARange = (str, splitChar, leftLimiter, // blindly send other passed configs with run_settings and handle at backend exports.setOtherConfigs = (bsConfig, args) => { - if(o11yHelpers.isTestObservabilitySession() && process.env.BS_TESTOPS_JWT) { bsConfig["run_settings"]["reporter"] = TEST_OBSERVABILITY_REPORTER; return; @@ -1519,7 +1518,15 @@ exports.setOtherConfigs = (bsConfig, args) => { exports.readBsConfigJSON = (bsConfigPath) => { try { fs.accessSync(bsConfigPath, fs.constants.R_OK); - return fs.readFileSync(bsConfigPath, 'utf-8'); + const configContent = fs.readFileSync(bsConfigPath, 'utf-8'); + try { + const bsConfig = JSON.parse(configContent); + const normalizedBsConfig = exports.normalizeTestReportingConfig(bsConfig); + return JSON.stringify(normalizedBsConfig); + } catch (err) { + logger.error(`Error parsing JSON from ${bsConfigPath}:`, err); + return null; + } } catch (err) { return null; } @@ -1804,3 +1811,25 @@ exports.decodeJWTToken = (token) => { return undefined; } } + +exports.normalizeTestReportingEnvVars = () => { + if (!this.isUndefined(process.env.BROWSERSTACK_TEST_REPORTING)){ + process.env.BROWSERSTACK_TEST_OBSERVABILITY = process.env.BROWSERSTACK_TEST_REPORTING; + } + + if (!this.isUndefined(process.env.BROWSERSTACK_TEST_REPORTING_DEBUG)){ + process.env.BROWSERSTACK_OBSERVABILITY_DEBUG = process.env.BROWSERSTACK_TEST_REPORTING_DEBUG; + } +} + +exports.normalizeTestReportingConfig = (bsConfig) => { + if (!this.isUndefined(bsConfig["testReporting"])) { + bsConfig["testObservability"] = bsConfig["testReporting"]; + } + + if (!this.isUndefined(bsConfig["testReportingOptions"])) { + bsConfig["testObservabilityOptions"] = bsConfig["testReportingOptions"]; + } + + return bsConfig; +} diff --git a/bin/testObservability/crashReporter/index.js b/bin/testObservability/crashReporter/index.js index 00ecb6bc..15022ce9 100644 --- a/bin/testObservability/crashReporter/index.js +++ b/bin/testObservability/crashReporter/index.js @@ -7,7 +7,7 @@ const HttpsProxyAgent = require('https-proxy-agent'); const logger = require("../../helpers/logger").winstonLogger; const utils = require('../../helpers/utils'); -const { API_URL, consoleHolder } = require('../helper/constants'); +const { API_URL, consoleHolder, TEST_REPORTING_ANALYTICS } = require('../helper/constants'); /* Below global methods are added here to remove cyclic dependency with helper.js, refactor later */ const httpsKeepAliveAgent = new https.Agent({ @@ -19,7 +19,7 @@ const httpsKeepAliveAgent = new https.Agent({ const debug = (text) => { if (process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "true" || process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "1") { - logger.info(`[ OBSERVABILITY ] ${text}`); + logger.info(`[ ${TEST_REPORTING_ANALYTICS} ] ${text}`); } } diff --git a/bin/testObservability/helper/constants.js b/bin/testObservability/helper/constants.js index dbf5e053..d3013f40 100644 --- a/bin/testObservability/helper/constants.js +++ b/bin/testObservability/helper/constants.js @@ -16,6 +16,7 @@ exports.IPC_EVENTS = { exports.OBSERVABILITY_ENV_VARS = [ "BROWSERSTACK_TEST_OBSERVABILITY", + "BROWSERSTACK_TEST_REPORTING", "BROWSERSTACK_AUTOMATION", "BS_TESTOPS_BUILD_COMPLETED", "BS_TESTOPS_JWT", @@ -23,6 +24,7 @@ exports.OBSERVABILITY_ENV_VARS = [ "BS_TESTOPS_ALLOW_SCREENSHOTS", "OBSERVABILITY_LAUNCH_SDK_VERSION", "BROWSERSTACK_OBSERVABILITY_DEBUG", + "BROWSERSTACK_TEST_REPORTING_DEBUG", "OBS_CRASH_REPORTING_USERNAME", "OBS_CRASH_REPORTING_ACCESS_KEY", "OBS_CRASH_REPORTING_BS_CONFIG_PATH", @@ -34,3 +36,5 @@ exports.TEST_OBSERVABILITY_REPORTER = 'browserstack-cypress-cli/bin/testObservab exports.TEST_OBSERVABILITY_REPORTER_LOCAL = path.join(__dirname, '..', 'reporter'); exports.PENDING_QUEUES_FILE = `pending_queues_${process.pid}.json`; + +exports.TEST_REPORTING_ANALYTICS = 'TEST REPORTING AND ANALYTICS'; diff --git a/bin/testObservability/helper/helper.js b/bin/testObservability/helper/helper.js index 467f090c..cc504bd7 100644 --- a/bin/testObservability/helper/helper.js +++ b/bin/testObservability/helper/helper.js @@ -27,7 +27,7 @@ const GLOBAL_MODULE_PATH = execSync('npm root -g').toString().trim(); const { name, version } = require('../../../package.json'); const { CYPRESS_V10_AND_ABOVE_CONFIG_FILE_EXTENSIONS } = require('../../helpers/constants'); -const { consoleHolder, API_URL, TEST_OBSERVABILITY_REPORTER, TEST_OBSERVABILITY_REPORTER_LOCAL } = require('./constants'); +const { consoleHolder, API_URL, TEST_OBSERVABILITY_REPORTER, TEST_OBSERVABILITY_REPORTER_LOCAL, TEST_REPORTING_ANALYTICS } = require('./constants'); const ALLOWED_MODULES = [ 'cypress/package.json', @@ -43,13 +43,13 @@ exports.pending_test_uploads = { exports.debugOnConsole = (text) => { if ((process.env.BROWSERSTACK_OBSERVABILITY_DEBUG + '') === "true" || (process.env.BROWSERSTACK_OBSERVABILITY_DEBUG + '') === "1") { - consoleHolder.log(`[ OBSERVABILITY ] ${text}`); + consoleHolder.log(`[ ${TEST_REPORTING_ANALYTICS} ] ${text}`); } } exports.debug = (text, shouldReport = false, throwable = null) => { if (process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "true" || process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "1") { - logger.info(`[ OBSERVABILITY ] ${text}`); + logger.info(`[ ${TEST_REPORTING_ANALYTICS} ] ${text}`); } if(shouldReport) { CrashReporter.getInstance().uploadCrashReport(text, throwable ? throwable && throwable.stack : null); @@ -105,7 +105,7 @@ exports.printBuildLink = async (shouldStopSession, exitCode = null) => { && process.env.BS_TESTOPS_BUILD_HASHED_ID != "null" && process.env.BS_TESTOPS_BUILD_HASHED_ID != "undefined") { console.log(); - logger.info(`Visit https://observability.browserstack.com/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID} to view build report, insights, and many more debugging information all at one place!\n`); + logger.info(`Visit https://automation.browserstack.com/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID} to view build report, insights, and many more debugging information all at one place!\n`); } } catch(err) { exports.debug('Build Not Found'); @@ -513,9 +513,9 @@ exports.batchAndPostEvents = async (eventUrl, kind, data) => { } catch(error) { exports.debugOnConsole(`[Request Error] Error in sending request ${util.format(error)}`); if (error.response) { - exports.debug(`EXCEPTION IN ${kind} REQUEST TO TEST OBSERVABILITY : ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`, true, error); + exports.debug(`EXCEPTION IN ${kind} REQUEST TO ${TEST_REPORTING_ANALYTICS} : ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`, true, error); } else { - exports.debug(`EXCEPTION IN ${kind} REQUEST TO TEST OBSERVABILITY : ${error.message || error}`, true, error); + exports.debug(`EXCEPTION IN ${kind} REQUEST TO ${TEST_REPORTING_ANALYTICS} : ${error.message || error}`, true, error); } exports.pending_test_uploads.count = Math.max(0,exports.pending_test_uploads.count - data.length); } @@ -541,7 +541,7 @@ exports.uploadEventData = async (eventData, run=0) => { if (process.env.BS_TESTOPS_BUILD_COMPLETED === "true") { if(process.env.BS_TESTOPS_JWT == "null") { - exports.debug(`EXCEPTION IN ${log_tag} REQUEST TO TEST OBSERVABILITY : missing authentication token`); + exports.debug(`EXCEPTION IN ${log_tag} REQUEST TO ${TEST_REPORTING_ANALYTICS}: missing authentication token`); exports.pending_test_uploads.count = Math.max(0,exports.pending_test_uploads.count-1); return { status: 'error', @@ -586,9 +586,9 @@ exports.uploadEventData = async (eventData, run=0) => { } catch(error) { exports.debugOnConsole(`[Request Error] Error in sending request ${util.format(error)}`); if (error.response) { - exports.debug(`EXCEPTION IN ${event_api_url !== exports.requestQueueHandler.eventUrl ? log_tag : 'Batch-Queue'} REQUEST TO TEST OBSERVABILITY : ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`, true, error); + exports.debug(`EXCEPTION IN ${event_api_url !== exports.requestQueueHandler.eventUrl ? log_tag : 'Batch-Queue'} REQUEST TO ${TEST_REPORTING_ANALYTICS} : ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`, true, error); } else { - exports.debug(`EXCEPTION IN ${event_api_url !== exports.requestQueueHandler.eventUrl ? log_tag : 'Batch-Queue'} REQUEST TO TEST OBSERVABILITY : ${error.message || error}`, true, error); + exports.debug(`EXCEPTION IN ${event_api_url !== exports.requestQueueHandler.eventUrl ? log_tag : 'Batch-Queue'} REQUEST TO ${TEST_REPORTING_ANALYTICS} : ${error.message || error}`, true, error); } exports.pending_test_uploads.count = Math.max(0,exports.pending_test_uploads.count - (event_api_url === 'api/v1/event' ? 1 : data.length)); return { @@ -598,7 +598,7 @@ exports.uploadEventData = async (eventData, run=0) => { } } } else if (run >= 5) { - exports.debug(`EXCEPTION IN ${log_tag} REQUEST TO TEST OBSERVABILITY : Build Start is not completed and ${log_tag} retry runs exceeded`); + exports.debug(`EXCEPTION IN ${log_tag} REQUEST TO ${TEST_REPORTING_ANALYTICS} : Build Start is not completed and ${log_tag} retry runs exceeded`); if(process.env.BS_TESTOPS_JWT != "null") exports.pending_test_uploads.count = Math.max(0,exports.pending_test_uploads.count-1); return { status: 'error', @@ -664,7 +664,7 @@ exports.shouldReRunObservabilityTests = () => { exports.stopBuildUpstream = async () => { if (process.env.BS_TESTOPS_BUILD_COMPLETED === "true") { if(process.env.BS_TESTOPS_JWT == "null" || process.env.BS_TESTOPS_BUILD_HASHED_ID == "null") { - exports.debug('EXCEPTION IN stopBuildUpstream REQUEST TO TEST OBSERVABILITY : Missing authentication token'); + exports.debug(`EXCEPTION IN stopBuildUpstream REQUEST TO ${TEST_REPORTING_ANALYTICS} : Missing authentication token`); return { status: 'error', message: 'Token/buildID is undefined, build creation might have failed' @@ -694,9 +694,9 @@ exports.stopBuildUpstream = async () => { } } catch(error) { if (error.response) { - exports.debug(`EXCEPTION IN stopBuildUpstream REQUEST TO TEST OBSERVABILITY : ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`, true, error); + exports.debug(`EXCEPTION IN stopBuildUpstream REQUEST TO ${TEST_REPORTING_ANALYTICS} : ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`, true, error); } else { - exports.debug(`EXCEPTION IN stopBuildUpstream REQUEST TO TEST OBSERVABILITY : ${error.message || error}`, true, error); + exports.debug(`EXCEPTION IN stopBuildUpstream REQUEST TO ${TEST_REPORTING_ANALYTICS} : ${error.message || error}`, true, error); } return { status: 'error', diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 396ad0e3..5b71c55e 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -12,7 +12,7 @@ const Mocha = requireModule('mocha'); const Runnable = require('mocha/lib/runnable'); // need to handle as this isn't present in older mocha versions const { v4: uuidv4 } = require('uuid'); -const { IPC_EVENTS } = require('../helper/constants'); +const { IPC_EVENTS, TEST_REPORTING_ANALYTICS } = require('../helper/constants'); const { startIPCServer } = require('../plugin/ipcServer'); const HOOK_TYPES_MAP = { @@ -511,7 +511,7 @@ class MyReporter { }); } } catch(error) { - debug(`Exception in uploading log data to Observability with error : ${error}`, true, error); + debug(`Exception in uploading log data to ${TEST_REPORTING_ANALYTICS} with error : ${error}`, true, error); } }