From 13af79ac93394df5249245df5146e42451ca4dab Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Wed, 29 Nov 2023 11:25:29 +0530 Subject: [PATCH 1/8] update: stability improvements --- bin/commands/runs.js | 8 +++++++- bin/helpers/utils.js | 24 ++++++++++++++++++++++++ bin/testObservability/helper/helper.js | 9 ++++++++- bin/testObservability/reporter/index.js | 12 ++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/bin/commands/runs.js b/bin/commands/runs.js index e198d291..a25e1fad 100644 --- a/bin/commands/runs.js +++ b/bin/commands/runs.js @@ -111,7 +111,10 @@ module.exports = function run(args, rawArgs) { /* Send build start to Observability */ - if(isTestObservabilitySession) await launchTestSession(bsConfig, bsConfigPath); + if(isTestObservabilitySession) { + await launchTestSession(bsConfig, bsConfigPath); + utils.setO11yProcessHooks(null, bsConfig, args, null, buildReportData); + } // accept the system env list from bsconf and set it utils.setSystemEnvs(bsConfig); @@ -264,6 +267,9 @@ module.exports = function run(args, rawArgs) { markBlockEnd('createBuild'); markBlockEnd('total'); utils.setProcessHooks(data.build_id, bsConfig, bs_local, args, buildReportData); + if(isTestObservabilitySession) { + utils.setO11yProcessHooks(data.build_id, bsConfig, bs_local, args, buildReportData); + } let message = `${data.message}! ${Constants.userMessages.BUILD_CREATED} with build id: ${data.build_id}`; let dashboardLink = `${Constants.userMessages.VISIT_DASHBOARD} ${data.dashboard_url}`; buildReportData = { 'build_id': data.build_id, 'parallels': userSpecifiedParallels, ...buildReportData } diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index 7c608280..6b63dd3f 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -1451,8 +1451,24 @@ exports.setProcessHooks = (buildId, bsConfig, bsLocal, args, buildReportData) => process.on('SIGTERM', processExitHandler.bind(this, bindData)); process.on('SIGBREAK', processExitHandler.bind(this, bindData)); process.on('uncaughtException', processExitHandler.bind(this, bindData)); + process.on('beforeExit', processO11yExitHandler.bind(this, bindData)); } +exports.setO11yProcessHooks = (() => { + let bindData = {}; + let handlerAdded = false; + return (buildId, bsConfig, bsLocal, args, buildReportData) => { + bindData.buildId = buildId; + bindData.bsConfig = bsConfig; + bindData.bsLocal = bsLocal; + bindData.args = args; + bindData.buildReportData = buildReportData; + if (handlerAdded) return; + handlerAdded = true; + process.on('beforeExit', processO11yExitHandler.bind(this, bindData)); + } +})() + async function processExitHandler(exitData){ logger.warn(Constants.userMessages.PROCESS_KILL_MESSAGE); await this.stopBrowserStackBuild(exitData.bsConfig, exitData.args, exitData.buildId, null, exitData.buildReportData); @@ -1461,6 +1477,14 @@ async function processExitHandler(exitData){ process.exit(0); } +async function processO11yExitHandler(exitData){ + if (!exitData.buildId && args.async) { + await printBuildLink(false); + } else { + await printBuildLink(true); + } +} + exports.fetchZipSize = (fileName) => { try { let stats = fs.statSync(fileName) diff --git a/bin/testObservability/helper/helper.js b/bin/testObservability/helper/helper.js index 2588095d..56525fe7 100644 --- a/bin/testObservability/helper/helper.js +++ b/bin/testObservability/helper/helper.js @@ -64,8 +64,11 @@ const supportFileCleanup = () => { }); } +exports.buildStopped = false; + exports.printBuildLink = async (shouldStopSession, exitCode = null) => { - if(!this.isTestObservabilitySession()) return; + if(!this.isTestObservabilitySession() || exports.buildStopped) return; + exports.buildStopped = true; try { if(shouldStopSession) { supportFileCleanup(); @@ -472,6 +475,10 @@ const RequestQueueHandler = require('./requestQueueHandler'); exports.requestQueueHandler = new RequestQueueHandler(); exports.uploadEventData = async (eventData, run=0) => { + exports.debug("I aminside upload event data") + exports.debug(JSON.stringify(eventData)) + consoleHolder.log("I aminside upload event data") + consoleHolder.log(JSON.stringify(eventData)) const log_tag = { ['TestRunStarted']: 'Test_Start_Upload', ['TestRunFinished']: 'Test_End_Upload', diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 7c194b14..25fba340 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -93,6 +93,7 @@ class MyReporter { delete this.runStatusMarkedHash[hook.hookAnalyticsId]; hook.hookAnalyticsId = uuidv4(); } + console.log("At hook begin ", hook.hookAnalyticsId + hook.fullTitle()) hook.hook_started_at = (new Date()).toISOString(); hook.started_at = (new Date()).toISOString(); this.current_hook = hook; @@ -101,7 +102,9 @@ class MyReporter { }) .on(EVENT_HOOK_END, async (hook) => { + console.log("At hook end ", this.current_hook.hookAnalyticsId, hook.fullTitle()) if(this.testObservability == true) { + // console.log("At hook end bool", this.runStatusMarkedHash[hook.hookAnalyticsId]) if(!this.runStatusMarkedHash[hook.hookAnalyticsId]) { if(!hook.hookAnalyticsId) { /* Hook objects don't maintain uuids in Cypress-Mocha */ @@ -110,6 +113,7 @@ class MyReporter { } else { this.runStatusMarkedHash[hook.hookAnalyticsId] = true; } + console.log("Sending hook finished ", hook.hookAnalyticsId); await this.sendTestRunEvent(hook,undefined,false,"HookRunFinished"); } } @@ -143,21 +147,27 @@ class MyReporter { .on(EVENT_TEST_PENDING, async (test) => { if(this.testObservability == true) { + test.isSkipped = true; if(!test.testAnalyticsId) test.testAnalyticsId = uuidv4(); if(!this.runStatusMarkedHash[test.testAnalyticsId]) { this.runStatusMarkedHash[test.testAnalyticsId] = true; + consoleHolder.log("Inside event for event_test_pending " + test.state); await this.sendTestRunEvent(test,undefined,false,"TestRunSkipped"); } } }) .on(EVENT_TEST_BEGIN, async (test) => { + consoleHolder.log("Inside event for event_test_begin " + test.state + " " + test.isSkipped); + if (test.isSkipped) return; if(this.testObservability == true) { await this.testStarted(test); } }) .on(EVENT_TEST_END, async (test) => { + consoleHolder.log("Inside event for event_test_end " + test.state + " " + test.isSkipped); + if (test.isSkipped) return; if(this.testObservability == true) { if(!this.runStatusMarkedHash[test.testAnalyticsId]) { if(test.testAnalyticsId) this.runStatusMarkedHash[test.testAnalyticsId] = true; @@ -253,6 +263,8 @@ class MyReporter { } sendTestRunEvent = async (test, err = undefined, customFinished=false, eventType = "TestRunFinished") => { + debug("Sending test run event for " + eventType); + consoleHolder.log("Sending test run event for " + eventType) try { if(test.body && test.body.match(/browserstack internal helper hook/)) return; let failureArgs = []; From f4b0aa9b0e782dffa3e6f23405182b8a2d24933d Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Wed, 29 Nov 2023 11:27:50 +0530 Subject: [PATCH 2/8] remove: exit hook from setprocesshooks --- bin/helpers/utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index 6b63dd3f..fac79ef1 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -1451,7 +1451,6 @@ exports.setProcessHooks = (buildId, bsConfig, bsLocal, args, buildReportData) => process.on('SIGTERM', processExitHandler.bind(this, bindData)); process.on('SIGBREAK', processExitHandler.bind(this, bindData)); process.on('uncaughtException', processExitHandler.bind(this, bindData)); - process.on('beforeExit', processO11yExitHandler.bind(this, bindData)); } exports.setO11yProcessHooks = (() => { From 13970b5ac3c55ab2397e0b42dd259893946dfc0f Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Thu, 30 Nov 2023 14:43:24 +0530 Subject: [PATCH 3/8] fix: hook finish --- bin/helpers/utils.js | 2 +- bin/testObservability/reporter/index.js | 31 +++++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index fac79ef1..650bc0b2 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -1477,7 +1477,7 @@ async function processExitHandler(exitData){ } async function processO11yExitHandler(exitData){ - if (!exitData.buildId && args.async) { + if (exitData.buildId && exitData.args && exitData.args.async) { await printBuildLink(false); } else { await printBuildLink(true); diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 25fba340..84e1869f 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -71,6 +71,7 @@ class MyReporter { this._paths = new PathHelper({ cwd: process.cwd() }, this._testEnv.location_prefix); this.currentTestSteps = []; this.currentTestCucumberSteps = []; + this.hooksStarted = {}; this.beforeHooks = []; this.platformDetailsMap = {}; this.runStatusMarkedHash = {}; @@ -93,7 +94,6 @@ class MyReporter { delete this.runStatusMarkedHash[hook.hookAnalyticsId]; hook.hookAnalyticsId = uuidv4(); } - console.log("At hook begin ", hook.hookAnalyticsId + hook.fullTitle()) hook.hook_started_at = (new Date()).toISOString(); hook.started_at = (new Date()).toISOString(); this.current_hook = hook; @@ -102,7 +102,6 @@ class MyReporter { }) .on(EVENT_HOOK_END, async (hook) => { - console.log("At hook end ", this.current_hook.hookAnalyticsId, hook.fullTitle()) if(this.testObservability == true) { // console.log("At hook end bool", this.runStatusMarkedHash[hook.hookAnalyticsId]) if(!this.runStatusMarkedHash[hook.hookAnalyticsId]) { @@ -114,6 +113,8 @@ class MyReporter { this.runStatusMarkedHash[hook.hookAnalyticsId] = true; } console.log("Sending hook finished ", hook.hookAnalyticsId); + // Remove hooks added at hook start + delete this.hooksStarted[hook.hookAnalyticsId]; await this.sendTestRunEvent(hook,undefined,false,"HookRunFinished"); } } @@ -151,14 +152,12 @@ class MyReporter { if(!test.testAnalyticsId) test.testAnalyticsId = uuidv4(); if(!this.runStatusMarkedHash[test.testAnalyticsId]) { this.runStatusMarkedHash[test.testAnalyticsId] = true; - consoleHolder.log("Inside event for event_test_pending " + test.state); await this.sendTestRunEvent(test,undefined,false,"TestRunSkipped"); } } }) .on(EVENT_TEST_BEGIN, async (test) => { - consoleHolder.log("Inside event for event_test_begin " + test.state + " " + test.isSkipped); if (test.isSkipped) return; if(this.testObservability == true) { await this.testStarted(test); @@ -166,7 +165,6 @@ class MyReporter { }) .on(EVENT_TEST_END, async (test) => { - consoleHolder.log("Inside event for event_test_end " + test.state + " " + test.isSkipped); if (test.isSkipped) return; if(this.testObservability == true) { if(!this.runStatusMarkedHash[test.testAnalyticsId]) { @@ -263,8 +261,6 @@ class MyReporter { } sendTestRunEvent = async (test, err = undefined, customFinished=false, eventType = "TestRunFinished") => { - debug("Sending test run event for " + eventType); - consoleHolder.log("Sending test run event for " + eventType) try { if(test.body && test.body.match(/browserstack internal helper hook/)) return; let failureArgs = []; @@ -447,6 +443,27 @@ class MyReporter { }; await uploadEventData(buildUpdateData); } + + // Add started hooks to the hash + if(eventType === 'HookRunStarted' && ['BEFORE_EACH', 'AFTER_EACH', 'BEFORE_ALL'].includes(testData['hook_type'])) { + this.hooksStarted[testData.uuid] = uploadData; + } + + // Send pending hook finsihed events for hook starts + if (eventType === 'TestRunFinished') { + Object.values(this.hooksStarted).forEach(async hookData => { + hookData['hook_run'].finished_at = hookData['hook_run'].started_at; + hookData['hook_run'].duration = 0; + hookData['hook_run'].result = uploadData['test_run'].result; + hookData['hook_run'].failure = uploadData['test_run'].failure; + hookData['hook_run'].failure_type = uploadData['test_run'].failure_type; + hookData['hook_run'].failure_reason = uploadData['test_run'].failure_reason; + hookData['hook_run'].failure_reason_expanded = uploadData['test_run'].failure_reason_expanded; + hookData['hook_run'].failure_backtrace = uploadData['test_run'].failure_backtrace; + await uploadEventData(hookData); + }) + this.hooksStarted = {}; + } } catch(error) { debug(`Exception in populating test data for event ${eventType} with error : ${error}`, true, error); } From 023a85f7fa34f5da789999730d919c260b2560b7 Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Thu, 30 Nov 2023 14:45:31 +0530 Subject: [PATCH 4/8] chore: remove logs --- bin/testObservability/helper/helper.js | 4 ---- bin/testObservability/reporter/index.js | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/bin/testObservability/helper/helper.js b/bin/testObservability/helper/helper.js index 56525fe7..33e6cfd9 100644 --- a/bin/testObservability/helper/helper.js +++ b/bin/testObservability/helper/helper.js @@ -475,10 +475,6 @@ const RequestQueueHandler = require('./requestQueueHandler'); exports.requestQueueHandler = new RequestQueueHandler(); exports.uploadEventData = async (eventData, run=0) => { - exports.debug("I aminside upload event data") - exports.debug(JSON.stringify(eventData)) - consoleHolder.log("I aminside upload event data") - consoleHolder.log(JSON.stringify(eventData)) const log_tag = { ['TestRunStarted']: 'Test_Start_Upload', ['TestRunFinished']: 'Test_End_Upload', diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 84e1869f..4b88fdd8 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -103,7 +103,6 @@ class MyReporter { .on(EVENT_HOOK_END, async (hook) => { if(this.testObservability == true) { - // console.log("At hook end bool", this.runStatusMarkedHash[hook.hookAnalyticsId]) if(!this.runStatusMarkedHash[hook.hookAnalyticsId]) { if(!hook.hookAnalyticsId) { /* Hook objects don't maintain uuids in Cypress-Mocha */ @@ -112,7 +111,7 @@ class MyReporter { } else { this.runStatusMarkedHash[hook.hookAnalyticsId] = true; } - console.log("Sending hook finished ", hook.hookAnalyticsId); + // Remove hooks added at hook start delete this.hooksStarted[hook.hookAnalyticsId]; await this.sendTestRunEvent(hook,undefined,false,"HookRunFinished"); From 82b1c50104e69e2470e593051016645f54a86853 Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Thu, 30 Nov 2023 15:49:49 +0530 Subject: [PATCH 5/8] fix: beforeall duration --- bin/testObservability/reporter/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 4b88fdd8..59ed71e6 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -147,7 +147,6 @@ class MyReporter { .on(EVENT_TEST_PENDING, async (test) => { if(this.testObservability == true) { - test.isSkipped = true; if(!test.testAnalyticsId) test.testAnalyticsId = uuidv4(); if(!this.runStatusMarkedHash[test.testAnalyticsId]) { this.runStatusMarkedHash[test.testAnalyticsId] = true; @@ -451,14 +450,20 @@ class MyReporter { // Send pending hook finsihed events for hook starts if (eventType === 'TestRunFinished') { Object.values(this.hooksStarted).forEach(async hookData => { - hookData['hook_run'].finished_at = hookData['hook_run'].started_at; - hookData['hook_run'].duration = 0; + hookData['event_type'] = 'HookRunFinished'; hookData['hook_run'].result = uploadData['test_run'].result; hookData['hook_run'].failure = uploadData['test_run'].failure; hookData['hook_run'].failure_type = uploadData['test_run'].failure_type; hookData['hook_run'].failure_reason = uploadData['test_run'].failure_reason; hookData['hook_run'].failure_reason_expanded = uploadData['test_run'].failure_reason_expanded; hookData['hook_run'].failure_backtrace = uploadData['test_run'].failure_backtrace; + if (hookData['hook_run']['hook_type'] === 'BEFORE_ALL') { + hookData['hook_run'].finished_at = uploadData['test_run'].finished_at; + hookData['hook_run'].duration_in_ms = new Date(hookData['hook_run'].finished_at).getTime() - new Date(hookData['hook_run'].started_at).getTime(); + } else { + hookData['hook_run'].finished_at = hookData['hook_run'].started_at; + hookData['hook_run'].duration_in_ms = 0; + } await uploadEventData(hookData); }) this.hooksStarted = {}; From e96802c09c21c05085af42b510b99c3dfd025b5b Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Thu, 30 Nov 2023 21:12:06 +0530 Subject: [PATCH 6/8] chore: comments --- bin/helpers/utils.js | 2 +- bin/testObservability/reporter/index.js | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index 650bc0b2..a679bae3 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -1477,7 +1477,7 @@ async function processExitHandler(exitData){ } async function processO11yExitHandler(exitData){ - if (exitData.buildId && exitData.args && exitData.args.async) { + if (exitData.buildId) { await printBuildLink(false); } else { await printBuildLink(true); diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 59ed71e6..5dc108e6 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -451,12 +451,17 @@ class MyReporter { if (eventType === 'TestRunFinished') { Object.values(this.hooksStarted).forEach(async hookData => { hookData['event_type'] = 'HookRunFinished'; - hookData['hook_run'].result = uploadData['test_run'].result; - hookData['hook_run'].failure = uploadData['test_run'].failure; - hookData['hook_run'].failure_type = uploadData['test_run'].failure_type; - hookData['hook_run'].failure_reason = uploadData['test_run'].failure_reason; - hookData['hook_run'].failure_reason_expanded = uploadData['test_run'].failure_reason_expanded; - hookData['hook_run'].failure_backtrace = uploadData['test_run'].failure_backtrace; + hookData['hook_run'] = { + ...hookData['hook_run'], + result: uploadData['test_run'].result, + failure: uploadData['test_run'].failure, + failure_type: uploadData['test_run'].failure_type, + failure_reason: uploadData['test_run'].failure_reason, + failure_reason_expanded: uploadData['test_run'].failure_reason_expanded, + failure_backtrace: uploadData['test_run'].failure_backtrace + + } + if (hookData['hook_run']['hook_type'] === 'BEFORE_ALL') { hookData['hook_run'].finished_at = uploadData['test_run'].finished_at; hookData['hook_run'].duration_in_ms = new Date(hookData['hook_run'].finished_at).getTime() - new Date(hookData['hook_run'].started_at).getTime(); @@ -464,6 +469,7 @@ class MyReporter { hookData['hook_run'].finished_at = hookData['hook_run'].started_at; hookData['hook_run'].duration_in_ms = 0; } + console.log(hookData); await uploadEventData(hookData); }) this.hooksStarted = {}; From 4f5c41869f4ec5433ace3aec5114309cdf6f1469 Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Fri, 1 Dec 2023 10:31:37 +0530 Subject: [PATCH 7/8] chore: remove logs --- bin/testObservability/reporter/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/testObservability/reporter/index.js b/bin/testObservability/reporter/index.js index 5dc108e6..a460b8b6 100644 --- a/bin/testObservability/reporter/index.js +++ b/bin/testObservability/reporter/index.js @@ -469,7 +469,6 @@ class MyReporter { hookData['hook_run'].finished_at = hookData['hook_run'].started_at; hookData['hook_run'].duration_in_ms = 0; } - console.log(hookData); await uploadEventData(hookData); }) this.hooksStarted = {}; From 90dfac5639fe7d1180c173bb885e47cc0a979193 Mon Sep 17 00:00:00 2001 From: 07souravkunda Date: Wed, 6 Dec 2023 13:17:00 +0530 Subject: [PATCH 8/8] add: unit tests --- bin/helpers/utils.js | 20 +++++----- test/unit/bin/helpers/utils.js | 69 +++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index a679bae3..a7758ba0 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -22,7 +22,7 @@ const usageReporting = require("./usageReporting"), config = require("../helpers/config"), pkg = require('../../package.json'), transports = require('./logger').transports, - { findGitConfig, printBuildLink, isTestObservabilitySession, isBrowserstackInfra, shouldReRunObservabilityTests } = require('../testObservability/helper/helper'), + o11yHelpers = require('../testObservability/helper/helper'), { OBSERVABILITY_ENV_VARS, TEST_OBSERVABILITY_REPORTER } = require('../testObservability/helper/constants'); const request = require('request'); @@ -480,7 +480,7 @@ 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(isBrowserstackInfra() && isTestObservabilitySession() && shouldReRunObservabilityTests()) { + if(o11yHelpers.isBrowserstackInfra() && o11yHelpers.isTestObservabilitySession() && o11yHelpers.shouldReRunObservabilityTests()) { bsConfig.run_settings.specs = process.env.BROWSERSTACK_RERUN_TESTS; return; } @@ -580,8 +580,8 @@ exports.setSystemEnvs = (bsConfig) => { envKeys[key] = process.env[key]; }); - let gitConfigPath = findGitConfig(process.cwd()); - if(!isBrowserstackInfra()) process.env.OBSERVABILITY_GIT_CONFIG_PATH_LOCAL = gitConfigPath; + let gitConfigPath = o11yHelpers.findGitConfig(process.cwd()); + if(!o11yHelpers.isBrowserstackInfra()) process.env.OBSERVABILITY_GIT_CONFIG_PATH_LOCAL = gitConfigPath; if(gitConfigPath) { const relativePathFromGitConfig = path.relative(gitConfigPath, process.cwd()); envKeys["OBSERVABILITY_GIT_CONFIG_PATH"] = relativePathFromGitConfig ? relativePathFromGitConfig : 'DEFAULT'; @@ -1184,8 +1184,8 @@ exports.handleSyncExit = (exitCode, dashboard_url) => { syncCliLogger.info(Constants.userMessages.BUILD_REPORT_MESSAGE); syncCliLogger.info(dashboard_url); } - if(isTestObservabilitySession()) { - printBuildLink(true, exitCode); + if(o11yHelpers.isTestObservabilitySession()) { + o11yHelpers.printBuildLink(true, exitCode); } else { process.exit(exitCode); } @@ -1288,7 +1288,7 @@ exports.setConfig = (bsConfig, args) => { // blindly send other passed configs with run_settings and handle at backend exports.setOtherConfigs = (bsConfig, args) => { - if(isTestObservabilitySession() && process.env.BS_TESTOPS_JWT) { + if(o11yHelpers.isTestObservabilitySession() && process.env.BS_TESTOPS_JWT) { bsConfig["run_settings"]["reporter"] = TEST_OBSERVABILITY_REPORTER; return; } @@ -1472,15 +1472,15 @@ async function processExitHandler(exitData){ logger.warn(Constants.userMessages.PROCESS_KILL_MESSAGE); await this.stopBrowserStackBuild(exitData.bsConfig, exitData.args, exitData.buildId, null, exitData.buildReportData); await this.stopLocalBinary(exitData.bsConfig, exitData.bsLocalInstance, exitData.args, null, exitData.buildReportData); - await printBuildLink(true); + await o11yHelpers.printBuildLink(true); process.exit(0); } async function processO11yExitHandler(exitData){ if (exitData.buildId) { - await printBuildLink(false); + await o11yHelpers.printBuildLink(false); } else { - await printBuildLink(true); + await o11yHelpers.printBuildLink(true); } } diff --git a/test/unit/bin/helpers/utils.js b/test/unit/bin/helpers/utils.js index f2751d76..13dfb66b 100644 --- a/test/unit/bin/helpers/utils.js +++ b/test/unit/bin/helpers/utils.js @@ -21,7 +21,8 @@ const utils = require('../../../../bin/helpers/utils'), fileHelpers = require('../../../../bin/helpers/fileHelpers'), testObjects = require('../../support/fixtures/testObjects'), syncLogger = require('../../../../bin/helpers/logger').syncCliLogger, - Contants = require('../../../../bin/helpers/constants'); + Contants = require('../../../../bin/helpers/constants'), + o11yHelpers = require('../../../../bin/testObservability/helper/helper'); const browserstack = require('browserstack-local'); const { CYPRESS_V10_AND_ABOVE_TYPE, CYPRESS_V9_AND_OLDER_TYPE } = require('../../../../bin/helpers/constants'); const { winstonLogger, syncCliLogger } = require('../../../../bin/helpers/logger'); @@ -3396,6 +3397,72 @@ describe('utils', () => { }); }); + describe('setO11yProcessHooks', () => { + it('should handle multiple calls', (done) => { + let buildId = null; + let bsConfig = testObjects.sampleBsConfig; + let bsLocalStub = sinon.stub(); + let args= {}; + + let printBuildLinkStub = sinon.stub(o11yHelpers, 'printBuildLink').returns(Promise.resolve(true)); + let processOnSpy = sinon.spy(process, 'on'); + + utils.setO11yProcessHooks(buildId, bsConfig, bsLocalStub, args); + sinon.assert.calledOnce(processOnSpy); + processOnSpy.restore(); + processOnSpy = sinon.spy(process, 'on'); + utils.setO11yProcessHooks('build_id', bsConfig, bsLocalStub, args); + sinon.assert.notCalled(processOnSpy); + processOnSpy.restore(); + process.on('beforeExit', () => { + sinon.assert.calledOnce(printBuildLinkStub); + sinon.assert.calledWith(printBuildLinkStub, false); + done(); + }); + process.emit('beforeExit'); + printBuildLinkStub.restore(); + sinon.stub.restore(); + }); + + it('should handle "beforeExit" event, with build id', (done) => { + let buildId = 'build_id'; + let bsConfig = testObjects.sampleBsConfig; + let bsLocalStub = sinon.stub(); + let args= {}; + + let printBuildLinkStub = sinon.stub(o11yHelpers, 'printBuildLink').returns(Promise.resolve(true)); + + utils.setO11yProcessHooks(buildId, bsConfig, bsLocalStub, args); + process.on('beforeExit', () => { + sinon.assert.calledOnce(printBuildLinkStub); + sinon.assert.calledWith(printBuildLinkStub, false); + done(); + }); + process.emit('beforeExit'); + printBuildLinkStub.restore(); + sinon.stub.restore(); + }); + + it('should handle "beforeExit" event, without build id', (done) => { + let buildId = null; + let bsConfig = testObjects.sampleBsConfig; + let bsLocalStub = sinon.stub(); + let args= {}; + + let printBuildLinkStub = sinon.stub(o11yHelpers, 'printBuildLink').returns(Promise.resolve(true)); + + utils.setO11yProcessHooks(buildId, bsConfig, bsLocalStub, args); + process.on('beforeExit', () => { + sinon.assert.calledOnce(printBuildLinkStub); + sinon.assert.calledWith(printBuildLinkStub, true); + done(); + }); + process.emit('beforeExit'); + printBuildLinkStub.restore(); + sinon.stub.restore(); + }); + }); + describe('fetchZipSize', () => { it('should return size in bytes if file is present', () => { sinon.stub(fs, 'statSync').returns({size: 123});