Skip to content

Commit ce999af

Browse files
committed
upload crash reports
1 parent 3636135 commit ce999af

File tree

6 files changed

+262
-45
lines changed

6 files changed

+262
-45
lines changed

bin/commands/runs.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ module.exports = function run(args, rawArgs) {
7272
// accept the build name from command line if provided
7373
utils.setBuildName(bsConfig, args);
7474

75+
// set cypress config filename
76+
utils.setCypressConfigFilename(bsConfig, args);
77+
7578
if(isBrowserstackInfra) {
76-
// set cypress config filename
77-
utils.setCypressConfigFilename(bsConfig, args);
78-
7979
// set cypress test suite type
8080
utils.setCypressTestSuiteType(bsConfig);
8181

@@ -98,7 +98,7 @@ module.exports = function run(args, rawArgs) {
9898
/*
9999
Send build start to Observability
100100
*/
101-
if(isTestObservabilitySession) await launchTestSession(bsConfig);
101+
if(isTestObservabilitySession) await launchTestSession(bsConfig, bsConfigPath);
102102

103103
// accept the system env list from bsconf and set it
104104
utils.setSystemEnvs(bsConfig);

bin/helpers/utils.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const usageReporting = require("./usageReporting"),
2121
config = require("../helpers/config"),
2222
pkg = require('../../package.json'),
2323
transports = require('./logger').transports,
24-
{ findGitConfig, printBuildLink, isTestObservabilitySession, isBrowserstackInfra, shouldReRunObservabilityTests } = require('../testObservability/helper/helper');
24+
{ findGitConfig, printBuildLink, isTestObservabilitySession, isBrowserstackInfra, shouldReRunObservabilityTests } = require('../testObservability/helper/helper'),
25+
{ OBSERVABILITY_ENV_VARS } = require('../testObservability/helper/constants');
2526

2627
const request = require('request');
2728

@@ -538,16 +539,18 @@ exports.setSystemEnvs = (bsConfig) => {
538539
});
539540
}
540541

541-
["BROWSERSTACK_TEST_OBSERVABILITY", "BROWSERSTACK_AUTOMATION", "BS_TESTOPS_BUILD_COMPLETED", "BS_TESTOPS_JWT", "BS_TESTOPS_BUILD_HASHED_ID", "BS_TESTOPS_ALLOW_SCREENSHOTS", "OBSERVABILITY_LAUNCH_SDK_VERSION", "BROWSERSTACK_OBSERVABILITY_DEBUG"].forEach(key => {
542-
envKeys[key] = process.env[key];
543-
});
544-
545-
let gitConfigPath = findGitConfig(process.cwd());
546-
if(!isBrowserstackInfra()) process.env.OBSERVABILITY_GIT_CONFIG_PATH_LOCAL = gitConfigPath;
547-
if(gitConfigPath) {
548-
const relativePathFromGitConfig = path.relative(gitConfigPath, process.cwd());
549-
envKeys["OBSERVABILITY_GIT_CONFIG_PATH"] = relativePathFromGitConfig ? relativePathFromGitConfig : 'DEFAULT';
550-
}
542+
try {
543+
OBSERVABILITY_ENV_VARS.forEach(key => {
544+
envKeys[key] = process.env[key];
545+
});
546+
547+
let gitConfigPath = findGitConfig(process.cwd());
548+
if(!isBrowserstackInfra()) process.env.OBSERVABILITY_GIT_CONFIG_PATH_LOCAL = gitConfigPath;
549+
if(gitConfigPath) {
550+
const relativePathFromGitConfig = path.relative(gitConfigPath, process.cwd());
551+
envKeys["OBSERVABILITY_GIT_CONFIG_PATH"] = relativePathFromGitConfig ? relativePathFromGitConfig : 'DEFAULT';
552+
}
553+
} catch(e){}
551554

552555
if (Object.keys(envKeys).length === 0) {
553556
bsConfig.run_settings.system_env_vars = null;
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const request = require('request');
4+
const http = require('http');
5+
const https = require('https');
6+
7+
const logger = require("../../helpers/logger").winstonLogger;
8+
9+
const { API_URL, consoleHolder } = require('../helper/constants');
10+
11+
/* Below global methods are added here to remove cyclic dependency with helper.js, refactor later */
12+
const httpKeepAliveAgent = new http.Agent({
13+
keepAlive: true,
14+
timeout: 60000,
15+
maxSockets: 2,
16+
maxTotalSockets: 2
17+
});
18+
19+
const httpsKeepAliveAgent = new https.Agent({
20+
keepAlive: true,
21+
timeout: 60000,
22+
maxSockets: 2,
23+
maxTotalSockets: 2
24+
});
25+
26+
const debug = (text) => {
27+
if (process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "true" || process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === "1") {
28+
logger.info(`[ OBSERVABILITY ] ${text}`);
29+
}
30+
}
31+
32+
let packages = {};
33+
34+
exports.requireModule = (module, internal = false) => {
35+
let local_path = "";
36+
if(process.env["browserStackCwd"]){
37+
local_path = path.join(process.env["browserStackCwd"], 'node_modules', module);
38+
} else if(internal) {
39+
local_path = path.join(process.cwd(), 'node_modules', 'browserstack-cypress-cli', 'node_modules', module);
40+
} else {
41+
local_path = path.join(process.cwd(), 'node_modules', module);
42+
}
43+
if(!fs.existsSync(local_path)) {
44+
let global_path;
45+
if(['jest-runner', 'jest-runtime'].includes(module))
46+
global_path = path.join(GLOBAL_MODULE_PATH, 'jest', 'node_modules', module);
47+
else
48+
global_path = path.join(GLOBAL_MODULE_PATH, module);
49+
if(!fs.existsSync(global_path)) {
50+
throw new Error(`${module} doesn't exist.`);
51+
}
52+
return require(global_path);
53+
}
54+
return require(local_path);
55+
}
56+
57+
getPackageVersion = (package_) => {
58+
if(packages[package_]) return packages[package_];
59+
return packages[package_] = this.requireModule(`${package_}/package.json`).version;
60+
}
61+
62+
getAgentVersion = () => {
63+
let _path = path.join(__dirname, '../../../package.json');
64+
if(fs.existsSync(_path))
65+
return require(_path).version;
66+
}
67+
68+
class CrashReporter {
69+
static instance;
70+
71+
constructor() {
72+
}
73+
74+
static getInstance() {
75+
if (!CrashReporter.instance) {
76+
CrashReporter.instance = new CrashReporter();
77+
}
78+
return CrashReporter.instance;
79+
}
80+
81+
setCredentialsForCrashReportUpload(credentialsStr) {
82+
/* User credentials used for reporting crashes */
83+
this.credentialsForCrashReportUpload = JSON.parse(credentialsStr);
84+
}
85+
86+
setConfigDetails(credentialsStr, browserstackConfigFile, cypressConfigFile) {
87+
/* User test config for build run */
88+
this.userConfigForReporting = {
89+
framework: 'Cypress',
90+
browserstackConfigFile: browserstackConfigFile,
91+
cypressConfigFile: cypressConfigFile
92+
};
93+
this.setCredentialsForCrashReportUpload(credentialsStr);
94+
}
95+
96+
uploadCrashReport(exception, stacktrace) {
97+
try {
98+
if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
99+
return debug('[Crash_Report_Upload] Failed to parse user credentials while reporting crash')
100+
}
101+
102+
const data = {
103+
hashed_id: process.env.BS_TESTOPS_BUILD_HASHED_ID,
104+
observability_version: {
105+
frameworkName: 'Cypress',
106+
frameworkVersion: getPackageVersion('cypress'),
107+
sdkVersion: getAgentVersion()
108+
},
109+
exception: {
110+
error: exception.toString(),
111+
stackTrace: stacktrace
112+
},
113+
config: this.userConfigForReporting
114+
}
115+
116+
const options = {
117+
auth: {
118+
...this.credentialsForCrashReportUpload
119+
},
120+
headers: {
121+
'Content-Type': 'application/json',
122+
'X-BSTACK-TESTOPS': 'true'
123+
},
124+
method: 'POST',
125+
url: `${API_URL}/api/v1/analytics`,
126+
body: data,
127+
json: true,
128+
agent: API_URL.includes('https') ? httpsKeepAliveAgent : httpKeepAliveAgent
129+
};
130+
131+
request(options, function callback(error, response, body) {
132+
if(error) {
133+
debug(`[Crash_Report_Upload] Failed due to ${error}`);
134+
} else if(response.statusCode != 200) {
135+
debug(`[Crash_Report_Upload] Failed due to ${response && response.body ? response.body : `Received response from BrowserStack Server with status : ${response.statusCode}`}`);
136+
} else {
137+
debug(`[Crash_Report_Upload] Success response: ${JSON.stringify({status: response.status, body: response.body})}`)
138+
}
139+
});
140+
} catch(e) {
141+
debug(`[Crash_Report_Upload] Processing failed due to ${e && e.stack}`);
142+
}
143+
}
144+
}
145+
146+
module.exports = CrashReporter;

bin/testObservability/helper/constants.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,18 @@ exports.IPC_EVENTS = {
1010
COMMAND: 'testObservability:cypressCommand',
1111
PLATFORM_DETAILS: 'testObservability:cypressPlatformDetails'
1212
};
13+
14+
exports.OBSERVABILITY_ENV_VARS = [
15+
"BROWSERSTACK_TEST_OBSERVABILITY",
16+
"BROWSERSTACK_AUTOMATION",
17+
"BS_TESTOPS_BUILD_COMPLETED",
18+
"BS_TESTOPS_JWT",
19+
"BS_TESTOPS_BUILD_HASHED_ID",
20+
"BS_TESTOPS_ALLOW_SCREENSHOTS",
21+
"OBSERVABILITY_LAUNCH_SDK_VERSION",
22+
"BROWSERSTACK_OBSERVABILITY_DEBUG",
23+
"OBS_CRASH_REPORTING_USERNAME",
24+
"OBS_CRASH_REPORTING_ACCESS_KEY",
25+
"OBS_CRASH_REPORTING_BS_CONFIG_PATH",
26+
"OBS_CRASH_REPORTING_CYPRESS_CONFIG_PATH"
27+
];

0 commit comments

Comments
 (0)