Skip to content

Commit 7b6b299

Browse files
committed
Cypress reporter + plugin
1 parent 425f260 commit 7b6b299

File tree

12 files changed

+2109
-43
lines changed

12 files changed

+2109
-43
lines changed

bin/commands/runs.js

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ const archiver = require("../helpers/archiver"),
2323
packageDiff = require('../helpers/package-diff');
2424
const { getStackTraceUrl } = require('../helpers/sync/syncSpecsLogs');
2525

26+
const {
27+
launchTestSession,
28+
setTestObservabilityFlags,
29+
runCypressTestsLocally
30+
} = require('../testObservability/helper/helper');
31+
2632
module.exports = function run(args, rawArgs) {
2733

2834
markBlockStart('preBuild');
@@ -45,6 +51,12 @@ module.exports = function run(args, rawArgs) {
4551
logger.debug('Completed browserstack.json validation');
4652
markBlockStart('setConfig');
4753
logger.debug('Started setting the configs');
54+
55+
/*
56+
Set testObservability & browserstackAutomation flags
57+
*/
58+
const [isTestObservabilitySession, isBrowserstackInfra] = setTestObservabilityFlags(bsConfig);
59+
4860
utils.setUsageReportingFlag(bsConfig, args.disableUsageReporting);
4961

5062
utils.setDefaults(bsConfig, args);
@@ -55,77 +67,94 @@ module.exports = function run(args, rawArgs) {
5567
// accept the access key from command line or env variable if provided
5668
utils.setAccessKey(bsConfig, args);
5769

58-
let buildReportData = await getInitialDetails(bsConfig, args, rawArgs);
70+
let buildReportData = !isBrowserstackInfra ? null : await getInitialDetails(bsConfig, args, rawArgs);
5971

6072
// accept the build name from command line if provided
6173
utils.setBuildName(bsConfig, args);
6274

63-
// set cypress config filename
64-
utils.setCypressConfigFilename(bsConfig, args);
65-
66-
// set cypress test suite type
67-
utils.setCypressTestSuiteType(bsConfig);
75+
if(isBrowserstackInfra) {
76+
// set cypress config filename
77+
utils.setCypressConfigFilename(bsConfig, args);
6878

69-
// set cypress geo location
70-
utils.setGeolocation(bsConfig, args);
79+
// set cypress test suite type
80+
utils.setCypressTestSuiteType(bsConfig);
7181

72-
// set spec timeout
73-
utils.setSpecTimeout(bsConfig, args);
82+
// set cypress geo location
83+
utils.setGeolocation(bsConfig, args);
7484

85+
// set spec timeout
86+
utils.setSpecTimeout(bsConfig, args);
87+
}
88+
7589
// accept the specs list from command line if provided
7690
utils.setUserSpecs(bsConfig, args);
7791

7892
// accept the env list from command line and set it
7993
utils.setTestEnvs(bsConfig, args);
8094

95+
// set build tag caps
96+
utils.setBuildTags(bsConfig, args);
97+
98+
/*
99+
Send build start to Observability
100+
*/
101+
if(isTestObservabilitySession) await launchTestSession(bsConfig);
102+
81103
// accept the system env list from bsconf and set it
82104
utils.setSystemEnvs(bsConfig);
83105

84-
//accept the local from env variable if provided
85-
utils.setLocal(bsConfig, args);
106+
if(isBrowserstackInfra) {
107+
//accept the local from env variable if provided
108+
utils.setLocal(bsConfig, args);
86109

87-
//set network logs
88-
utils.setNetworkLogs(bsConfig);
110+
//set network logs
111+
utils.setNetworkLogs(bsConfig);
89112

90-
// set Local Mode (on-demand/ always-on)
91-
utils.setLocalMode(bsConfig, args);
113+
// set Local Mode (on-demand/ always-on)
114+
utils.setLocalMode(bsConfig, args);
92115

93-
//accept the local identifier from env variable if provided
94-
utils.setLocalIdentifier(bsConfig, args);
116+
//accept the local identifier from env variable if provided
117+
utils.setLocalIdentifier(bsConfig, args);
95118

96-
// set Local Config File
97-
utils.setLocalConfigFile(bsConfig, args);
119+
// set Local Config File
120+
utils.setLocalConfigFile(bsConfig, args);
98121

99-
// run test in headed mode
100-
utils.setHeaded(bsConfig, args);
122+
// run test in headed mode
123+
utils.setHeaded(bsConfig, args);
101124

102-
// set the no-wrap
103-
utils.setNoWrap(bsConfig, args);
125+
// set the no-wrap
126+
utils.setNoWrap(bsConfig, args);
104127

105-
// add cypress dependency if missing
106-
utils.setCypressNpmDependency(bsConfig);
128+
// add cypress dependency if missing
129+
utils.setCypressNpmDependency(bsConfig);
130+
}
107131

108-
const { packagesInstalled } = await packageInstaller.packageSetupAndInstaller(bsConfig, config.packageDirName, {markBlockStart, markBlockEnd});
132+
const { packagesInstalled } = !isBrowserstackInfra ? false : await packageInstaller.packageSetupAndInstaller(bsConfig, config.packageDirName, {markBlockStart, markBlockEnd});
109133

110-
// set build tag caps
111-
utils.setBuildTags(bsConfig, args);
112-
// set node version
113-
utils.setNodeVersion(bsConfig, args);
134+
if(isBrowserstackInfra) {
135+
// set node version
136+
utils.setNodeVersion(bsConfig, args);
114137

115-
//set browsers
116-
await utils.setBrowsers(bsConfig, args);
138+
//set browsers
139+
await utils.setBrowsers(bsConfig, args);
117140

118-
//set config (--config)
119-
utils.setConfig(bsConfig, args);
141+
//set config (--config)
142+
utils.setConfig(bsConfig, args);
120143

121-
// set sync/async mode (--async/--sync)
122-
utils.setCLIMode(bsConfig, args);
144+
// set sync/async mode (--async/--sync)
145+
utils.setCLIMode(bsConfig, args);
146+
147+
// set other cypress configs e.g. reporter and reporter-options
148+
utils.setOtherConfigs(bsConfig, args);
149+
}
123150

124-
// set other cypress configs e.g. reporter and reporter-options
125-
utils.setOtherConfigs(bsConfig, args);
126151
markBlockEnd('setConfig');
127152
logger.debug("Completed setting the configs");
128153

154+
if(!isBrowserstackInfra) {
155+
return runCypressTestsLocally(bsConfig, args, rawArgs);
156+
}
157+
129158
// Validate browserstack.json values and parallels specified via arguments
130159
markBlockStart('validateConfig');
131160
logger.debug("Started configs validation");

bin/commands/stop.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ const config = require("../helpers/config"),
55
logger = require("../helpers/logger").winstonLogger,
66
Constants = require("../helpers/constants"),
77
utils = require("../helpers/utils"),
8-
getInitialDetails = require('../helpers/getInitialDetails').getInitialDetails;
8+
getInitialDetails = require('../helpers/getInitialDetails').getInitialDetails,
9+
{ printBuildLink } = require('../testObservability/helper/helper');
910

1011
module.exports = function stop(args, rawArgs) {
1112
let bsConfigPath = utils.getConfigPath(args.cf);
@@ -30,6 +31,8 @@ module.exports = function stop(args, rawArgs) {
3031

3132
await utils.stopBrowserStackBuild(bsConfig, args, buildId, rawArgs, buildReportData);
3233

34+
await printBuildLink();
35+
3336
}).catch(function (err) {
3437
logger.error(err);
3538
utils.setUsageReportingFlag(null, args.disableUsageReporting);

bin/helpers/utils.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const usageReporting = require("./usageReporting"),
2020
fileHelpers = require("./fileHelpers"),
2121
config = require("../helpers/config"),
2222
pkg = require('../../package.json'),
23-
transports = require('./logger').transports;
23+
transports = require('./logger').transports,
24+
{ findGitConfig, printBuildLink, isTestObservabilitySession, isBrowserstackInfra } = require('../testObservability/helper/helper');
2425

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

@@ -225,7 +226,7 @@ exports.setDefaults = (bsConfig, args) => {
225226
}
226227

227228
// setting cache_dependencies to true if not present
228-
if (this.isUndefined(bsConfig.run_settings.cache_dependencies)) {
229+
if (bsConfig.run_settings && this.isUndefined(bsConfig.run_settings.cache_dependencies)) {
229230
bsConfig.run_settings.cache_dependencies = true;
230231
}
231232

@@ -532,6 +533,17 @@ exports.setSystemEnvs = (bsConfig) => {
532533
});
533534
}
534535

536+
["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 => {
537+
envKeys[key] = process.env[key];
538+
});
539+
540+
let gitConfigPath = findGitConfig(process.cwd());
541+
if(!isBrowserstackInfra()) process.env.OBSERVABILITY_GIT_CONFIG_PATH_LOCAL = gitConfigPath;
542+
if(gitConfigPath) {
543+
const relativePathFromGitConfig = path.relative(gitConfigPath, process.cwd());
544+
envKeys["OBSERVABILITY_GIT_CONFIG_PATH"] = relativePathFromGitConfig ? relativePathFromGitConfig : 'DEFAULT';
545+
}
546+
535547
if (Object.keys(envKeys).length === 0) {
536548
bsConfig.run_settings.system_env_vars = null;
537549
} else {
@@ -1202,6 +1214,13 @@ exports.setConfig = (bsConfig, args) => {
12021214

12031215
// blindly send other passed configs with run_settings and handle at backend
12041216
exports.setOtherConfigs = (bsConfig, args) => {
1217+
/* Change to when Observability is enabled */
1218+
if(isTestObservabilitySession()) {
1219+
bsConfig["run_settings"]["reporter"] = "browserstack-cypress-cli/bin/testObservability/reporter";
1220+
return;
1221+
}
1222+
1223+
/* Non Observability use-case */
12051224
if (!this.isUndefined(args.reporter)) {
12061225
bsConfig["run_settings"]["reporter"] = args.reporter;
12071226
logger.debug(`reporter set to ${args.reporter}`);
@@ -1361,6 +1380,7 @@ async function processExitHandler(exitData){
13611380
logger.warn(Constants.userMessages.PROCESS_KILL_MESSAGE);
13621381
await this.stopBrowserStackBuild(exitData.bsConfig, exitData.args, exitData.buildId, null, exitData.buildReportData);
13631382
await this.stopLocalBinary(exitData.bsConfig, exitData.bsLocalInstance, exitData.args, null, exitData.buildReportData);
1383+
await printBuildLink();
13641384
process.exit(0);
13651385
}
13661386

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
Cypress.on('command:start', (command) => {
2+
if(
3+
command?.attributes?.name == 'log' ||
4+
(command?.attributes?.name == 'task' &&
5+
(
6+
command?.attributes?.args?.includes('test_observability_command') ||
7+
command?.attributes?.args?.includes('test_observability_log')
8+
)
9+
)
10+
) {
11+
return;
12+
}
13+
/* Send command details */
14+
cy.now('task', 'test_observability_command', {
15+
type: 'COMMAND_START',
16+
command: {
17+
attributes: {
18+
id: command.attributes.id,
19+
name: command.attributes.name,
20+
args: command.attributes.args
21+
},
22+
state: 'pending'
23+
}
24+
}).then((res) => {
25+
}).catch((err) => {
26+
});
27+
28+
/* Send platform details */
29+
cy.now('task', 'test_observability_platform_details', {
30+
testTitle: Cypress.currentTest.title,
31+
browser: Cypress.browser,
32+
platform: Cypress.platform,
33+
cypressVersion: Cypress.version
34+
}).then((res) => {
35+
}).catch((err) => {
36+
});
37+
});
38+
39+
Cypress.on('command:retry', (command) => {
40+
if(
41+
command?.attributes?.name == 'log' ||
42+
(command?.attributes?.name == 'task' &&
43+
(
44+
command?.attributes?.args?.includes('test_observability_command') ||
45+
command?.attributes?.args?.includes('test_observability_log')
46+
)
47+
)
48+
) {
49+
return;
50+
}
51+
cy.now('task', 'test_observability_command', {
52+
type: 'COMMAND_RETRY',
53+
command: {
54+
_log: command._log,
55+
error: {
56+
message: command?.error?.message,
57+
isDefaultAssertionErr: command?.error?.isDefaultAssertionErr
58+
}
59+
}
60+
}).then((res) => {
61+
}).catch((err) => {
62+
});
63+
});
64+
65+
Cypress.on('command:end', (command) => {
66+
if(
67+
command?.attributes?.name == 'log' ||
68+
(command?.attributes?.name == 'task' &&
69+
(
70+
command?.attributes?.args?.includes('test_observability_command') ||
71+
command?.attributes?.args?.includes('test_observability_log')
72+
)
73+
)
74+
) {
75+
return;
76+
}
77+
cy.now('task', 'test_observability_command', {
78+
'type': 'COMMAND_END',
79+
'command': {
80+
'attributes': {
81+
'id': command.attributes.id,
82+
'name': command.attributes.name,
83+
'args': command.attributes.args
84+
},
85+
'state': command.state
86+
}
87+
}).then((res) => {
88+
}).catch((err) => {
89+
});
90+
});
91+
92+
Cypress.Commands.overwrite('log', (originalFn, ...args) => {
93+
if(args.includes('test_observability_log') || args.includes('test_observability_command')) return;
94+
const message = args.reduce((result, logItem) => {
95+
if (typeof logItem === 'object') {
96+
return [result, JSON.stringify(logItem)].join(' ');
97+
}
98+
99+
return [result, logItem ? logItem.toString() : ''].join(' ');
100+
}, '');
101+
cy.now('task', 'test_observability_log', {
102+
'level': 'info',
103+
message,
104+
}).then((res) => {
105+
}).catch((err) => {
106+
});
107+
originalFn(...args);
108+
});
109+
110+
Cypress.Commands.add('trace', (message, file) => {
111+
cy.now('task', 'test_observability_log', {
112+
level: 'trace',
113+
message,
114+
file,
115+
});
116+
});
117+
118+
Cypress.Commands.add('logDebug', (message, file) => {
119+
cy.now('task', 'test_observability_log', {
120+
level: 'debug',
121+
message,
122+
file,
123+
});
124+
});
125+
126+
Cypress.Commands.add('info', (message, file) => {
127+
cy.now('task', 'test_observability_log', {
128+
level: 'info',
129+
message,
130+
file,
131+
});
132+
});
133+
134+
Cypress.Commands.add('warn', (message, file) => {
135+
cy.now('task', 'test_observability_log', {
136+
level: 'warn',
137+
message,
138+
file,
139+
});
140+
});
141+
142+
Cypress.Commands.add('error', (message, file) => {
143+
cy.now('task', 'test_observability_log', {
144+
level: 'error',
145+
message,
146+
file,
147+
});
148+
});
149+
150+
Cypress.Commands.add('fatal', (message, file) => {
151+
cy.now('task', 'test_observability_log', {
152+
level: 'fatal',
153+
message,
154+
file,
155+
});
156+
});

0 commit comments

Comments
 (0)