Skip to content

Commit d3f3431

Browse files
authored
Master merge
2 parents 7705530 + 4346144 commit d3f3431

File tree

11 files changed

+624
-54
lines changed

11 files changed

+624
-54
lines changed

bin/accessibility-automation/cypress/index.js

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -336,26 +336,23 @@ afterEach(() => {
336336
} else if (attributes.prevAttempts && attributes.prevAttempts.length > 0) {
337337
filePath = (attributes.prevAttempts[0].invocationDetails && attributes.prevAttempts[0].invocationDetails.relativeFile) || '';
338338
}
339-
const payloadToSend = {
340-
"saveResults": shouldScanTestForAccessibility,
341-
"testDetails": {
342-
"name": attributes.title,
343-
"testRunId": '5058', // variable not consumed, shouldn't matter what we send
344-
"filePath": filePath,
345-
"scopeList": [
346-
filePath,
347-
attributes.title
348-
]
349-
},
350-
"platform": {
351-
"os_name": os_data,
352-
"os_version": Cypress.env("OS_VERSION"),
353-
"browser_name": Cypress.browser.name,
354-
"browser_version": Cypress.browser.version
339+
340+
let testRunUuid = null;
341+
cy.task('get_test_run_uuid', { testIdentifier: attributes.title })
342+
.then((response) => {
343+
if (response && response.testRunUuid) {
344+
testRunUuid = response.testRunUuid;
355345
}
356-
};
357-
browserStackLog(`Saving accessibility test results`);
358-
cy.wrap(saveTestResults(win, payloadToSend), {timeout: 30000}).then(() => {
346+
347+
const payloadToSend = {
348+
"thTestRunUuid": testRunUuid,
349+
"thBuildUuid": Cypress.env("BROWSERSTACK_TESTHUB_UUID"),
350+
"thJwtToken": Cypress.env("BROWSERSTACK_TESTHUB_JWT")
351+
};
352+
browserStackLog(`Payload to send: ${JSON.stringify(payloadToSend)}`);
353+
354+
return cy.wrap(saveTestResults(win, payloadToSend), {timeout: 30000});
355+
}).then(() => {
359356
browserStackLog(`Saved accessibility test results`);
360357
})
361358

bin/accessibility-automation/plugin/index.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const path = require("node:path");
22
const { decodeJWTToken } = require("../../helpers/utils");
33
const utils = require('../../helpers/utils');
4+
const http = require('http');
45

56
const browserstackAccessibility = (on, config) => {
67
let browser_validation = true;
@@ -14,6 +15,51 @@ const browserstackAccessibility = (on, config) => {
1415

1516
return null
1617
},
18+
get_test_run_uuid({ testIdentifier, retries = 15, interval = 300 } = {}) {
19+
return new Promise((resolve) => {
20+
if(!testIdentifier) return resolve(null);
21+
const port = process.env.REPORTER_API_PORT_NO;
22+
let attempt = 0;
23+
const fetchUuid = () => {
24+
const options = {
25+
hostname: '127.0.0.1',
26+
port,
27+
path: `/test-uuid?testIdentifier=${encodeURIComponent(testIdentifier)}`,
28+
method: 'GET',
29+
timeout: 2000
30+
};
31+
const httpModule = http;
32+
const req = httpModule.request(options, (res) => {
33+
let data = '';
34+
res.on('data', (chunk) => data += chunk);
35+
res.on('end', () => {
36+
if(res.statusCode === 200) {
37+
try {
38+
const json = JSON.parse(data || '{}');
39+
return resolve({ testRunUuid: json.testRunUuid || null });
40+
} catch(e) {
41+
return resolve(null);
42+
}
43+
} else if (res.statusCode === 404) {
44+
// Server up but endpoint not responding as expected – stop retrying.
45+
return resolve(null);
46+
} else {
47+
retryOrResolve();
48+
}
49+
});
50+
});
51+
req.on('error', () => retryOrResolve());
52+
req.on('timeout', () => { req.destroy(); retryOrResolve(); });
53+
req.end();
54+
};
55+
const retryOrResolve = () => {
56+
attempt += 1;
57+
if(attempt >= retries) return resolve(null);
58+
setTimeout(fetchUuid, interval);
59+
};
60+
fetchUuid();
61+
});
62+
}
1763
})
1864
on('before:browser:launch', (browser = {}, launchOptions) => {
1965
try {
@@ -51,6 +97,10 @@ const browserstackAccessibility = (on, config) => {
5197
config.env.ACCESSIBILITY_EXTENSION_PATH = process.env.ACCESSIBILITY_EXTENSION_PATH
5298
config.env.OS_VERSION = process.env.OS_VERSION
5399
config.env.OS = process.env.OS
100+
config.env.BROWSERSTACK_TESTHUB_UUID = process.env.BROWSERSTACK_TESTHUB_UUID
101+
config.env.BROWSERSTACK_TESTHUB_JWT = process.env.BROWSERSTACK_TESTHUB_JWT
102+
config.env.BROWSERSTACK_TESTHUB_API_PORT = process.env.BROWSERSTACK_TESTHUB_API_PORT
103+
config.env.REPORTER_API_PORT_NO = process.env.REPORTER_API_PORT_NO
54104

55105
config.env.IS_ACCESSIBILITY_EXTENSION_LOADED = browser_validation.toString()
56106

bin/commands/runs.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ const {
3737
supportFileCleanup
3838
} = require('../accessibility-automation/helper');
3939
const { isTurboScaleSession, getTurboScaleGridDetails, patchCypressConfigFileContent, atsFileCleanup } = require('../helpers/atsHelper');
40-
40+
const { shouldProcessEventForTesthub, checkAndSetAccessibility, findAvailablePort } = require('../testhub/utils');
41+
const TestHubHandler = require('../testhub/testhubHandler');
4142

4243
module.exports = function run(args, rawArgs) {
4344
utils.normalizeTestReportingEnvVars();
@@ -112,9 +113,15 @@ module.exports = function run(args, rawArgs) {
112113
// set build tag caps
113114
utils.setBuildTags(bsConfig, args);
114115

116+
checkAndSetAccessibility(bsConfig, isAccessibilitySession);
117+
118+
const preferredPort = 5348;
119+
const port = await findAvailablePort(preferredPort);
120+
process.env.REPORTER_API_PORT_NO = port
121+
115122
// Send build start to TEST REPORTING AND ANALYTICS
116-
if(isTestObservabilitySession) {
117-
await launchTestSession(bsConfig, bsConfigPath);
123+
if(shouldProcessEventForTesthub()) {
124+
await TestHubHandler.launchBuild(bsConfig, bsConfigPath);
118125
utils.setO11yProcessHooks(null, bsConfig, args, null, buildReportData);
119126
}
120127

@@ -149,10 +156,6 @@ module.exports = function run(args, rawArgs) {
149156
// add cypress dependency if missing
150157
utils.setCypressNpmDependency(bsConfig);
151158

152-
if (isAccessibilitySession && isBrowserstackInfra) {
153-
await createAccessibilityTestRun(bsConfig);
154-
}
155-
156159
if (turboScaleSession) {
157160
const gridDetails = await getTurboScaleGridDetails(bsConfig, args, rawArgs);
158161

@@ -206,7 +209,7 @@ module.exports = function run(args, rawArgs) {
206209
markBlockStart('validateConfig');
207210
logger.debug("Started configs validation");
208211
return capabilityHelper.validate(bsConfig, args).then(function (cypressConfigFile) {
209-
if(process.env.BROWSERSTACK_TEST_ACCESSIBILITY) {
212+
if(process.env.BROWSERSTACK_TEST_ACCESSIBILITY === 'true') {
210213
setAccessibilityEventListeners(bsConfig);
211214
}
212215
if(process.env.BS_TESTOPS_BUILD_COMPLETED) {

bin/helpers/helper.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ exports.getGitMetaData = () => {
182182
}
183183
})
184184
}
185+
186+
exports.getHostInfo = () => {
187+
return {
188+
hostname: os.hostname(),
189+
platform: os.platform(),
190+
type: os.type(),
191+
version: os.version(),
192+
arch: os.arch()
193+
}
194+
}
195+
185196
exports.getCiInfo = () => {
186197
var env = process.env;
187198
// Jenkins

bin/helpers/utils.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const usageReporting = require("./usageReporting"),
2727
{ OBSERVABILITY_ENV_VARS, TEST_OBSERVABILITY_REPORTER } = require('../testObservability/helper/constants');
2828

2929
const { default: axios } = require("axios");
30+
const { shouldProcessEventForTesthub } = require("../testhub/utils");
3031

3132
exports.validateBstackJson = (bsConfigPath) => {
3233
return new Promise(function (resolve, reject) {
@@ -1499,7 +1500,7 @@ exports.splitStringByCharButIgnoreIfWithinARange = (str, splitChar, leftLimiter,
14991500

15001501
// blindly send other passed configs with run_settings and handle at backend
15011502
exports.setOtherConfigs = (bsConfig, args) => {
1502-
if(o11yHelpers.isTestObservabilitySession() && process.env.BS_TESTOPS_JWT) {
1503+
if(shouldProcessEventForTesthub()) {
15031504
bsConfig["run_settings"]["reporter"] = TEST_OBSERVABILITY_REPORTER;
15041505
return;
15051506
}
@@ -1754,15 +1755,14 @@ exports.getVideoConfig = (cypressConfig, bsConfig = {}) => {
17541755
video: true,
17551756
videoUploadOnPasses: true
17561757
}
1757-
// Reading bsconfig in case of enforce_settings
1758-
if ( this.isUndefined(bsConfig.run_settings) || this.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) ) {
1759-
if (!this.isUndefined(cypressConfig.video)) conf.video = cypressConfig.video;
1760-
if (!this.isUndefined(cypressConfig.videoUploadOnPasses)) conf.videoUploadOnPasses = cypressConfig.videoUploadOnPasses;
1761-
}
1762-
else {
1763-
if (!this.isUndefined(bsConfig.run_settings) && !this.isUndefined(bsConfig.run_settings.video)) conf.video = bsConfig.run_settings.video;
1764-
if (!this.isUndefined(bsConfig.run_settings) && !this.isUndefined(bsConfig.run_settings.videoUploadOnPasses)) conf.videoUploadOnPasses = bsConfig.run_settings.videoUploadOnPasses;
1765-
}
1758+
1759+
// here if we have enforce_setting: true then cypressConfig will be {} as we are not reading cypress.config.js file in that case
1760+
if (!this.isUndefined(bsConfig.run_settings) && !this.isUndefined(bsConfig.run_settings.video)) conf.video = bsConfig.run_settings.video;
1761+
if (!this.isUndefined(bsConfig.run_settings) && !this.isUndefined(bsConfig.run_settings.videoUploadOnPasses)) conf.videoUploadOnPasses = bsConfig.run_settings.videoUploadOnPasses;
1762+
if (!this.isUndefined(cypressConfig.video)) { conf.video = cypressConfig.video;}
1763+
if (!this.isUndefined(cypressConfig.videoUploadOnPasses)){ conf.videoUploadOnPasses = cypressConfig.videoUploadOnPasses;}
1764+
if (!this.isUndefined(cypressConfig.e2e) && !this.isUndefined(cypressConfig.e2e.video)) { conf.video = cypressConfig.e2e.video;}
1765+
if (!this.isUndefined(cypressConfig.e2e) && !this.isUndefined(cypressConfig.e2e.videoUploadOnPasses)){ conf.videoUploadOnPasses = cypressConfig.e2e.videoUploadOnPasses;}
17661766

17671767
// set video in cli config in case of cypress 13 or above as default value is false there.
17681768
this.setVideoCliConfig(bsConfig,conf);

bin/testObservability/helper/helper.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ exports.printBuildLink = async (shouldStopSession, exitCode = null) => {
116116
if(exitCode) process.exit(exitCode);
117117
}
118118

119-
const nodeRequest = (type, url, data, config) => {
119+
exports.nodeRequest = (type, url, data, config) => {
120120
const requestQueueHandler = require('./requestQueueHandler');
121121
return new Promise(async (resolve, reject) => {
122122
const options = {
@@ -269,7 +269,7 @@ exports.getPackageVersion = (package_, bsConfig = null) => {
269269
return packageVersion;
270270
}
271271

272-
const setEnvironmentVariablesForRemoteReporter = (BS_TESTOPS_JWT, BS_TESTOPS_BUILD_HASHED_ID, BS_TESTOPS_ALLOW_SCREENSHOTS, OBSERVABILITY_LAUNCH_SDK_VERSION) => {
272+
exports.setEnvironmentVariablesForRemoteReporter = (BS_TESTOPS_JWT, BS_TESTOPS_BUILD_HASHED_ID, BS_TESTOPS_ALLOW_SCREENSHOTS, OBSERVABILITY_LAUNCH_SDK_VERSION) => {
273273
process.env.BS_TESTOPS_JWT = BS_TESTOPS_JWT;
274274
process.env.BS_TESTOPS_BUILD_HASHED_ID = BS_TESTOPS_BUILD_HASHED_ID;
275275
process.env.BS_TESTOPS_ALLOW_SCREENSHOTS = BS_TESTOPS_ALLOW_SCREENSHOTS;
@@ -343,7 +343,7 @@ exports.setCrashReportingConfigFromReporter = (credentialsStr, bsConfigPath, cyp
343343
}
344344
}
345345

346-
const setCrashReportingConfig = (bsConfig, bsConfigPath) => {
346+
exports.setCrashReportingConfig = (bsConfig, bsConfigPath) => {
347347
try {
348348
const browserstackConfigFile = utils.readBsConfigJSON(bsConfigPath);
349349
const cypressConfigFile = getCypressConfigFileContent(bsConfig, null);
@@ -414,10 +414,10 @@ exports.launchTestSession = async (user_config, bsConfigPath) => {
414414
}
415415
};
416416

417-
const response = await nodeRequest('POST','api/v1/builds',data,config);
417+
const response = await exports.nodeRequest('POST','api/v1/builds',data,config);
418418
exports.debug('Build creation successfull!');
419419
process.env.BS_TESTOPS_BUILD_COMPLETED = true;
420-
setEnvironmentVariablesForRemoteReporter(response.data.jwt, response.data.build_hashed_id, response.data.allow_screenshots, data.observability_version.sdkVersion);
420+
exports.setEnvironmentVariablesForRemoteReporter(response.data.jwt, response.data.build_hashed_id, response.data.allow_screenshots, data.observability_version.sdkVersion);
421421
if(this.isBrowserstackInfra() && (user_config.run_settings.auto_import_dev_dependencies != true)) helper.setBrowserstackCypressCliDependency(user_config);
422422
} catch(error) {
423423
if(!error.errorType) {
@@ -444,7 +444,7 @@ exports.launchTestSession = async (user_config, bsConfigPath) => {
444444
}
445445

446446
process.env.BS_TESTOPS_BUILD_COMPLETED = false;
447-
setEnvironmentVariablesForRemoteReporter(null, null, null);
447+
exports.setEnvironmentVariablesForRemoteReporter(null, null, null);
448448
}
449449
}
450450
}
@@ -503,7 +503,7 @@ exports.batchAndPostEvents = async (eventUrl, kind, data) => {
503503
try {
504504
const eventsUuids = data.map(eventData => `${eventData.event_type}:${eventData.test_run ? eventData.test_run.uuid : (eventData.hook_run ? eventData.hook_run.uuid : null)}`).join(', ');
505505
exports.debugOnConsole(`[Request Batch Send] for events:uuids ${eventsUuids}`);
506-
const response = await nodeRequest('POST',eventUrl,data,config);
506+
const response = await exports.nodeRequest('POST',eventUrl,data,config);
507507
exports.debugOnConsole(`[Request Batch Response] for events:uuids ${eventsUuids}`);
508508
if(response.data.error) {
509509
throw({message: response.data.error});
@@ -570,7 +570,7 @@ exports.uploadEventData = async (eventData, run=0) => {
570570
try {
571571
const eventsUuids = data.map(eventData => `${eventData.event_type}:${eventData.test_run ? eventData.test_run.uuid : (eventData.hook_run ? eventData.hook_run.uuid : null)}`).join(', ');
572572
exports.debugOnConsole(`[Request Send] for events:uuids ${eventsUuids}`);
573-
const response = await nodeRequest('POST',event_api_url,data,config);
573+
const response = await exports.nodeRequest('POST',event_api_url,data,config);
574574
exports.debugOnConsole(`[Request Repsonse] ${util.format(response.data)} for events:uuids ${eventsUuids}`)
575575
if(response.data.error) {
576576
throw({message: response.data.error});
@@ -681,7 +681,7 @@ exports.stopBuildUpstream = async () => {
681681
};
682682

683683
try {
684-
const response = await nodeRequest('PUT',`api/v1/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID}/stop`,data,config);
684+
const response = await exports.nodeRequest('PUT',`api/v1/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID}/stop`,data,config);
685685
if(response.data && response.data.error) {
686686
throw({message: response.data.error});
687687
} else {

0 commit comments

Comments
 (0)