New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@nightwatch/browserstack

Package Overview
Dependencies
Maintainers
6
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nightwatch/browserstack - npm Package Compare versions

Comparing version 3.2.0 to 3.2.1

nightwatch/observabilityLogPatcherHook.js

252

nightwatch/globals.js
const LocalTunnel = require('../src/local-tunnel');
const TestObservability = require('../src/testObservability');
const {CUSTOM_REPORTER_CALLBACK_TIMEOUT} = require('../src/utils/constants');
const {CUSTOM_REPORTER_CALLBACK_TIMEOUT, EVENTS} = require('../src/utils/constants');
const CrashReporter = require('../src/utils/crashReporter');
const helper = require('../src/utils/helper');
const Logger = require('../src/utils/logger');
const {v4: uuidv4} = require('uuid');
const path = require('path');
const AccessibilityAutomation = require('../src/accessibilityAutomation');
const eventHelper = require('../src/utils/eventHelper');
const localTunnel = new LocalTunnel();

@@ -15,3 +17,28 @@ const testObservability = new TestObservability();

const nightwatchRerunFile = process.env.NIGHTWATCH_RERUN_REPORT_FILE;
const _tests = {};
const _testCasesData = {};
let currentTestUUID = '';
let workerList = {};
eventHelper.eventEmitter.on(EVENTS.LOG_INIT, (loggingData) => {
const testCaseStartedId = loggingData.message.replace('TEST-OBSERVABILITY-PID-TESTCASE-MAPPING-', '').slice(1, -1);
const testCaseId = _testCasesData[testCaseStartedId]?.testCaseId;
currentTestUUID = _tests[testCaseId]?.uuid;
});
eventHelper.eventEmitter.on(EVENTS.LOG, (loggingData) => {
if (currentTestUUID && currentTestUUID !== '') {
testObservability.appendTestItemLog(loggingData, currentTestUUID);
}
});
const handleScreenshotUpload = async (data) => {
try {
const {args, uuid} = data;
await testObservability.createScreenshotLogEvent(uuid, args.path, Date.now());
} catch (error) {
CrashReporter.uploadCrashReport(error.message, error.stack);
}
};
module.exports = {

@@ -41,3 +68,3 @@

}
await Promise.all(promises);

@@ -51,6 +78,182 @@ done();

},
registerEventHandlers(eventBroadcaster) {
eventBroadcaster.on('TestCaseStarted', async (args) => {
if (!helper.isTestObservabilitySession()) {
return;
}
try {
_testCasesData[args.envelope.id] = {
...args.envelope
};
const reportData = args.report;
const testCaseId = reportData.testCaseStarted[args.envelope.id].testCaseId;
const pickleId = reportData.testCases.find((testCase) => testCase.id === testCaseId).pickleId;
const pickleData = reportData.pickle.find((pickle) => pickle.id === pickleId);
const gherkinDocument = reportData?.gherkinDocument.find((document) => document.uri === pickleData.uri);
const featureData = gherkinDocument.feature;
const uniqueId = uuidv4();
process.env.TEST_OPS_TEST_UUID = uniqueId;
Object.values(workerList).forEach((worker) => {
worker.process.on('message', async (data) => {
if (data.eventType === EVENTS.LOG_INIT) {
const testCaseStartedId = data.loggingData.message.replace('TEST-OBSERVABILITY-PID-TESTCASE-MAPPING-', '').slice(1, -1);
const testCaseId = _testCasesData[testCaseStartedId]?.testCaseId;
const uuid = _tests[testCaseId]?.uuid;
await worker.process.send({testCaseStartedId, uuid});
}
});
});
const testMetaData = {
uuid: uniqueId,
startedAt: new Date().toISOString()
};
if (pickleData) {
testMetaData.scenario = {
name: pickleData.name
};
}
if (gherkinDocument && featureData) {
testMetaData.feature = {
path: gherkinDocument.uri,
name: featureData.name,
description: featureData.description
};
}
_tests[testCaseId] = testMetaData;
await testObservability.sendTestRunEventForCucumber(reportData, gherkinDocument, pickleData, 'TestRunStarted', testMetaData, args);
} catch (error) {
CrashReporter.uploadCrashReport(error.message, error.stack);
Logger.error(`Something went wrong in processing report file for test observability - ${error.message} with stacktrace ${error.stack}`);
}
});
eventBroadcaster.on('TestCaseFinished', async (args) => {
if (!helper.isTestObservabilitySession()) {
return;
}
try {
const reportData = args.report;
const testCaseId = _testCasesData[args.envelope.testCaseStartedId].testCaseId;
const pickleId = reportData.testCases.find((testCase) => testCase.id === testCaseId).pickleId;
const pickleData = reportData.pickle.find((pickle) => pickle.id === pickleId);
const gherkinDocument = reportData?.gherkinDocument.find((document) => document.uri === pickleData.uri);
const testMetaData = _tests[testCaseId];
if (testMetaData) {
delete _tests[testCaseId];
testMetaData.finishedAt = new Date().toISOString();
await testObservability.sendTestRunEventForCucumber(reportData, gherkinDocument, pickleData, 'TestRunFinished', testMetaData, args);
}
} catch (error) {
CrashReporter.uploadCrashReport(error.message, error.stack);
Logger.error(`Something went wrong in processing report file for test observability - ${error.message} with stacktrace ${error.stack}`);
}
});
eventBroadcaster.on('TestStepStarted', (args) => {
if (!helper.isTestObservabilitySession()) {
return;
}
try {
const reportData = args.report;
const testCaseId = _testCasesData[args.envelope.testCaseStartedId].testCaseId;
const pickleId = reportData.testCases.find((testCase) => testCase.id === testCaseId).pickleId;
const pickleData = reportData.pickle.find((pickle) => pickle.id === pickleId);
const testSteps = reportData.testCases.find((testCase) => testCase.id === testCaseId).testSteps;
const testStepId = reportData.testStepStarted[args.envelope.testCaseStartedId].testStepId;
const pickleStepId = testSteps.find((testStep) => testStep.id === testStepId).pickleStepId;
if (pickleStepId && _tests['testStepId'] !== testStepId) {
_tests['testStepId'] = testStepId;
const pickleStepData = pickleData.steps.find((pickle) => pickle.id === pickleStepId);
const testMetaData = _tests[testCaseId] || {steps: []};
if (testMetaData && !testMetaData.steps) {
testMetaData.steps = [];
}
testMetaData.steps?.push({
id: pickleStepData.id,
text: pickleStepData.text,
started_at: new Date().toISOString()
});
_tests[testCaseId] = testMetaData;
}
} catch (error) {
CrashReporter.uploadCrashReport(error.message, error.stack);
Logger.error(`Something went wrong in processing report file for test observability - ${error.message} with stacktrace ${error.stack}`);
}
});
eventBroadcaster.on('TestStepFinished', async (args) => {
if (!helper.isTestObservabilitySession()) {
return;
}
try {
const reportData = args.report;
const testCaseId = _testCasesData[args.envelope.testCaseStartedId].testCaseId;
const testStepFinished = reportData.testStepFinished[args.envelope.testCaseStartedId];
const pickleId = reportData.testCases.find((testCase) => testCase.id === testCaseId).pickleId;
const pickleData = reportData.pickle.find((pickle) => pickle.id === pickleId);
const testSteps = reportData.testCases.find((testCase) => testCase.id === testCaseId).testSteps;
const testStepId = reportData.testStepFinished[args.envelope.testCaseStartedId].testStepId;
const pickleStepId = testSteps.find((testStep) => testStep.id === testStepId).pickleStepId;
let failure;
let failureType;
if (testStepFinished.testStepResult?.status.toString().toLowerCase() === 'failed') {
failure = (testStepFinished.testStepResult?.exception === undefined) ? testStepFinished.testStepResult?.message : testStepFinished.testStepResult?.exception?.message;
failureType = (testStepFinished.testStepResult?.exception === undefined) ? 'UnhandledError' : testStepFinished.testStepResult?.message;
}
if (pickleStepId && _tests['testStepId']) {
const pickleStepData = pickleData.steps.find((pickle) => pickle.id === pickleStepId);
const testMetaData = _tests[testCaseId] || {steps: []};
if (!testMetaData.steps) {
testMetaData.steps = [{
id: pickleStepData.id,
text: pickleStepData.text,
finished_at: new Date().toISOString(),
result: testStepFinished.testStepResult?.status,
duration: testStepFinished.testStepResult?.duration?.seconds,
failure: failure,
failureType: failureType
}];
} else {
testMetaData.steps.forEach((step) => {
if (step.id === pickleStepData.id) {
step.finished_at = new Date().toISOString();
step.result = testStepFinished.testStepResult?.status;
step.duration = testStepFinished.testStepResult?.duration?.seconds;
step.failure = failure;
step.failureType = failureType;
}
});
}
_tests[testCaseId] = testMetaData;
delete _tests['testStepId'];
if (testStepFinished.httpOutput && testStepFinished.httpOutput.length > 0) {
for (const [index, output] of testStepFinished.httpOutput.entries()) {
if (index % 2 === 0) {
await testObservability.createHttpLogEvent(output, testStepFinished.httpOutput[index + 1], testMetaData.uuid);
}
}
}
}
} catch (error) {
CrashReporter.uploadCrashReport(error.message, error.stack);
Logger.error(`Something went wrong in processing report file for test observability - ${error.message} with stacktrace ${error.stack}`);
}
});
eventBroadcaster.on('ScreenshotCreated', async (args) => {
if (!helper.isTestObservabilitySession()) {return}
handleScreenshotUpload({args: args, uuid: process.env.TEST_OPS_TEST_UUID});
});
eventBroadcaster.on('TestRunStarted', async (test) => {
await accessibilityAutomation.beforeEachExecution(test);
});
eventBroadcaster.on('TestRunFinished', async (test) => {

@@ -60,2 +263,3 @@ await accessibilityAutomation.afterEachExecution(test);

},
onEvent({eventName, hook_type, ...args}) {

@@ -92,2 +296,6 @@ if (typeof browser !== 'undefined' && eventName === 'TestRunStarted') {

if (helper.isTestObservabilitySession()) {
if (helper.isCucumberTestSuite(settings)) {
cucumberPatcher();
settings.test_runner.options['require'] = path.resolve(__dirname, 'observabilityLogPatcherHook.js');
}
settings.globals['customReporterCallbackTimeout'] = CUSTOM_REPORTER_CALLBACK_TIMEOUT;

@@ -125,2 +333,7 @@ if (testObservability._user && testObservability._key) {

if (helper.isTestObservabilitySession()) {
process.env.NIGHTWATCH_RERUN_FAILED = nightwatchRerun;
process.env.NIGHTWATCH_RERUN_REPORT_FILE = nightwatchRerunFile;
if (process.env.BROWSERSTACK_RERUN === 'true' && process.env.BROWSERSTACK_RERUN_TESTS) {
await helper.deleteRerunFile();
}
try {

@@ -134,7 +347,3 @@ await testObservability.stopBuildUpstream();

}
process.env.NIGHTWATCH_RERUN_FAILED = nightwatchRerun;
process.env.NIGHTWATCH_RERUN_REPORT_FILE = nightwatchRerunFile;
if (process.env.BROWSERSTACK_RERUN === 'true' && process.env.BROWSERSTACK_RERUN_TESTS) {
await helper.deleteRerunFile();
}
process.exit();
}

@@ -189,1 +398,28 @@ if (helper.isAccessibilitySession()){

};
const cucumberPatcher = () => {
try {
const Coordinator = helper.requireModule('@cucumber/cucumber/lib/runtime/parallel/coordinator.js');
class CoordinatorPatcher extends Coordinator.default {
constructor(...args) {
super(...args);
}
startWorker(...args) {
const workerData = super.startWorker(...args);
workerList = this.workers;
return workerData;
}
parseWorkerMessage(...args) {
if ([EVENTS.LOG, EVENTS.LOG_INIT].includes(args[1]?.eventType)) {return}
return super.parseWorkerMessage(...args);
}
}
Coordinator.default = CoordinatorPatcher;
} catch (error) {
Logger.debug(`Error while patching cucumber ${error}`);
}
};

3

package.json
{
"name": "@nightwatch/browserstack",
"version": "3.2.0",
"version": "3.2.1",
"description": "Nightwatch plugin for integration with browserstack.",

@@ -47,2 +47,3 @@ "main": "index.js",

"strip-ansi": "^6.0.1",
"winston-transport": "^4.5.0",
"uuid": "^9.0.0"

@@ -49,0 +50,0 @@ },

@@ -364,6 +364,6 @@ const path = require('path');

try {
let session = await browser.session();
const session = await browser.session();
if (session) {
let pageOpen = true;
let currentURL = await browser.driver.getCurrentUrl();
const currentURL = await browser.driver.getCurrentUrl();

@@ -399,3 +399,3 @@ let url = {};

} else {
await browser.executeScript(`
await browser.executeAsyncScript(`
const e = new CustomEvent('A11Y_FORCE_STOP');

@@ -439,3 +439,3 @@ window.dispatchEvent(e);

};
let final_res = await browser.executeAsyncScript(
const final_res = await browser.executeAsyncScript(
`

@@ -479,3 +479,3 @@ const callback = arguments[arguments.length - 1];

try {
let results = await browser.executeScript(`
const results = await browser.executeScript(`
return new Promise(function (resolve, reject) {

@@ -513,3 +513,3 @@ try {

try {
let summaryResults = await browser.executeScript(`
const summaryResults = await browser.executeScript(`
return new Promise(function (resolve, reject) {

@@ -516,0 +516,0 @@ try{

@@ -127,3 +127,3 @@ const os = require('os');

try {
const response = await makeRequest('PUT', `api/v1/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID}/stop`, data, config);
const response = await makeRequest('PUT', `api/v1/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID}/stop`, data, config, API_URL, false);
if (response.data?.error) {

@@ -376,4 +376,113 @@ throw {message: response.data.error};

}
async sendTestRunEventForCucumber(reportData, gherkinDocument, pickleData, eventType, testMetaData, args = {}) {
const {feature, scenario, steps, uuid, startedAt, finishedAt} = testMetaData || {};
const examples = helper.getScenarioExamples(gherkinDocument, pickleData);
const fullNameWithExamples = examples
? pickleData.name + ' (' + examples.join(', ') + ')'
: pickleData.name;
const testData = {
uuid: uuid,
started_at: startedAt,
finished_at: finishedAt,
type: 'test',
body: {
lang: 'nightwatch',
code: null
},
name: fullNameWithExamples,
scope: fullNameWithExamples,
scopes: [feature?.name || ''],
tags: pickleData.tags?.map(({name}) => (name)),
identifier: scenario?.name,
file_name: path.relative(process.cwd(), feature.path),
location: path.relative(process.cwd(), feature.path),
vc_filepath: (this._gitMetadata && this._gitMetadata.root) ? path.relative(this._gitMetadata.root, feature.path) : null,
framework: 'nightwatch',
result: 'pending',
meta: {
feature: feature,
scenario: scenario,
steps: steps,
examples: examples
}
};
try {
if (eventType === 'TestRunFinished') {
const currentSessionCapabilities = reportData.session[args.envelope.testCaseStartedId];
if (currentSessionCapabilities.error) {
throw new Error(`Error in driver capabilities: ${JSON.stringify(currentSessionCapabilities.error)}`);
}
const sessionCapabilities = currentSessionCapabilities.capabilities;
if ((sessionCapabilities) && (args.envelope.testCaseStartedId === currentSessionCapabilities.testCaseStartedId)) {
testData.integrations = {};
const provider = helper.getCloudProvider(currentSessionCapabilities.host);
testData.integrations[provider] = helper.getIntegrationsObject(sessionCapabilities, currentSessionCapabilities.sessionId);
} else {
Logger.debug('Failed to upload integrations data');
}
}
} catch (error) {
CrashReporter.uploadCrashReport(error.message, error.stack);
}
if (reportData.testCaseFinished && steps) {
const testCaseResult = reportData.testCaseFinished[args.envelope.testCaseStartedId];
let result = 'passed';
steps.every((step) => {
if (step.result === 'FAILED'){
result = 'failed';
testCaseResult.failure = step.failure;
testCaseResult.failureType = step.failureType;
return false;
} else if (step.result === 'SKIPPED') {
result = 'skipped';
return false;
}
return true;
});
testData.finished_at = new Date().toISOString();
testData.result = result;
testData.duration_in_ms = testCaseResult.timestamp.nanos / 1000000;
if (result === 'failed') {
testData.failure = [
{
'backtrace': [testCaseResult?.failure ? stripAnsi(testCaseResult?.failure) : 'unknown']
}
],
testData.failure_reason = testCaseResult?.failure ? stripAnsi(testCaseResult?.failure) : testCaseResult.message;
if (testCaseResult?.failureType) {
testData.failure_type = testCaseResult.failureType.match(/AssertError/)
? 'AssertionError'
: 'UnhandledError';
}
}
}
const uploadData = {
event_type: eventType,
test_run: testData
};
await helper.uploadEventData(uploadData);
}
async appendTestItemLog (log, testUuid) {
try {
if (testUuid) {
log.test_run_uuid = testUuid;
await helper.uploadEventData({event_type: 'LogCreated', logs: [log]});
}
} catch (error) {
Logger.error(`Exception in uploading log data to Observability with error : ${error}`);
}
}
}
module.exports = TestObservability;

@@ -10,2 +10,12 @@ exports.BATCH_SIZE = 1000;

exports.CUSTOM_REPORTER_CALLBACK_TIMEOUT = 3600000;
exports.consoleHolder = Object.assign({}, console);
// Regex = TEST-OBSERVABILITY-PID-TESTCASE-MAPPING-ea78bf4a-d02b-40bc-8f52-7b53a4350b2c
exports.PID_MAPPING_REGEX = /^TEST-OBSERVABILITY-PID-TESTCASE-MAPPING-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
exports.IPC_SERVER_NAME = 'browserstackTestObservability';
exports.EVENTS = {
LOG: 'testObservability:log',
LOG_INIT: 'testObservability:log:init',
SCREENSHOT: 'testObservability:screenshot'
};
exports.ACCESSIBILITY_URL= 'https://accessibility.browserstack.com/api';
const helper = require('./helper');
const {makeRequest} = require('./requestHelper');
const Logger = require('./logger');
const {API_URL} = require('./constants');

@@ -66,3 +67,3 @@ class CrashReporter {

};
await makeRequest('POST', 'api/v1/analytics', data, config);
await makeRequest('POST', 'api/v1/analytics', data, config, API_URL, false);
} catch (error) {

@@ -69,0 +70,0 @@ Logger.error(`[Crash_Report_Upload] Failed due to ${error}`);

@@ -11,7 +11,21 @@ const os = require('os');

const {makeRequest} = require('./requestHelper');
const {RERUN_FILE, DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS, DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS} = require('./constants');
const {RERUN_FILE, DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS, DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS, consoleHolder} = require('./constants');
const requestQueueHandler = require('./requestQueueHandler');
const Logger = require('./logger');
const LogPatcher = require('./logPatcher');
const BSTestOpsPatcher = new LogPatcher({});
console = {};
Object.keys(consoleHolder).forEach(method => {
console[method] = (...args) => {
BSTestOpsPatcher[method](...args);
};
});
exports.debug = (text) => {
if (process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === 'true' || process.env.BROWSERSTACK_OBSERVABILITY_DEBUG === '1') {
consoleHolder.log(`\n[${(new Date()).toISOString()}][ OBSERVABILITY ] ${text}\n`);
}
};
exports.generateLocalIdentifier = () => {

@@ -96,123 +110,237 @@ const formattedDate = new Intl.DateTimeFormat('en-GB', {

exports.isTrue = (value) => (value+ '').toLowerCase() === 'true';
exports.getCIVendor = () => {
var env = process.env;
const ciInfo = this.getCiInfo();
if (ciInfo) {
return ciInfo.name;
}
return null;
};
exports.getCiInfo = () => {
const env = process.env;
// Jenkins
if ((typeof env.JENKINS_URL === 'string' && env.JENKINS_URL.length > 0) || (typeof env.JENKINS_HOME === 'string' && env.JENKINS_HOME.length > 0)) {
return 'Jenkins';
return {
name: 'Jenkins',
build_url: env.BUILD_URL,
job_name: env.JOB_NAME,
build_number: env.BUILD_NUMBER
};
}
// CircleCI
if (env.CI === 'true' && env.CIRCLECI === 'true') {
return 'CircleCI';
if (this.isTrue(env.CI) && this.isTrue(env.CIRCLECI)) {
return {
name: 'CircleCI',
build_url: env.CIRCLE_BUILD_URL,
job_name: env.CIRCLE_JOB,
build_number: env.CIRCLE_BUILD_NUM
};
}
// Travis CI
if (env.CI === 'true' && env.TRAVIS === 'true') {
return 'TravisCI';
if (this.isTrue(env.CI) && this.isTrue(env.TRAVIS)) {
return {
name: 'Travis CI',
build_url: env.TRAVIS_BUILD_WEB_URL,
job_name: env.TRAVIS_JOB_NAME,
build_number: env.TRAVIS_BUILD_NUMBER
};
}
// Codeship
if (env.CI === 'true' && env.CI_NAME === 'codeship') {
return 'Codeship';
if (this.isTrue(env.CI) && this.isTrue(env.CI_NAME)) {
return {
name: 'Codeship',
build_url: null,
job_name: null,
build_number: null
};
}
// Bitbucket
if (env.BITBUCKET_BRANCH && env.BITBUCKET_COMMIT) {
return 'Bitbucket';
return {
name: 'Bitbucket',
build_url: env.BITBUCKET_GIT_HTTP_ORIGIN,
job_name: null,
build_number: env.BITBUCKET_BUILD_NUMBER
};
}
// Drone
if (env.CI === 'true' && env.DRONE === 'true') {
return 'Drone';
if (this.isTrue(env.CI) && this.isTrue(env.DRONE)) {
return {
name: 'Drone',
build_url: env.DRONE_BUILD_LINK,
job_name: null,
build_number: env.DRONE_BUILD_NUMBER
};
}
// Semaphore
if (env.CI === 'true' && env.SEMAPHORE === 'true') {
return 'Semaphore';
if (this.isTrue(env.CI) && this.isTrue(env.SEMAPHORE)) {
return {
name: 'Semaphore',
build_url: env.SEMAPHORE_ORGANIZATION_URL,
job_name: env.SEMAPHORE_JOB_NAME,
build_number: env.SEMAPHORE_JOB_ID
};
}
// GitLab
if (env.CI === 'true' && env.GITLAB_CI === 'true') {
return 'GitLab';
if (this.isTrue(env.CI) && this.isTrue(env.GITLAB_CI)) {
return {
name: 'GitLab',
build_url: env.CI_JOB_URL,
job_name: env.CI_JOB_NAME,
build_number: env.CI_JOB_ID
};
}
// Buildkite
if (env.CI === 'true' && env.BUILDKITE === 'true') {
return 'Buildkite';
if (this.isTrue(env.CI) && this.isTrue(env.BUILDKITE)) {
return {
name: 'Buildkite',
build_url: env.BUILDKITE_BUILD_URL,
job_name: env.BUILDKITE_LABEL || env.BUILDKITE_PIPELINE_NAME,
build_number: env.BUILDKITE_BUILD_NUMBER
};
}
// Visual Studio Team Services
if (env.TF_BUILD === 'True') {
return 'Visual Studio Team Services';
if (this.isTrue(env.TF_BUILD)) {
return {
name: 'Visual Studio Team Services',
build_url: `${env.SYSTEM_TEAMFOUNDATIONSERVERURI}${env.SYSTEM_TEAMPROJECTID}`,
job_name: env.SYSTEM_DEFINITIONID,
build_number: env.BUILD_BUILDID
};
}
};
// Appveyor
if (this.isTrue(env.APPVEYOR)) {
return {
name: 'Appveyor',
build_url: `${env.APPVEYOR_URL}/project/${env.APPVEYOR_ACCOUNT_NAME}/${env.APPVEYOR_PROJECT_SLUG}/builds/${env.APPVEYOR_BUILD_ID}`,
job_name: env.APPVEYOR_JOB_NAME,
build_number: env.APPVEYOR_BUILD_NUMBER
};
}
// Azure CI
if (env.AZURE_HTTP_USER_AGENT && env.TF_BUILD) {
return {
name: 'Azure CI',
build_url: `${env.SYSTEM_TEAMFOUNDATIONSERVERURI}${env.SYSTEM_TEAMPROJECT}/_build/results?buildId=${env.BUILD_BUILDID}`,
job_name: env.BUILD_BUILDID,
build_number: env.BUILD_BUILDID
};
}
// AWS CodeBuild
if (env.CODEBUILD_BUILD_ID || env.CODEBUILD_RESOLVED_SOURCE_VERSION || env.CODEBUILD_SOURCE_VERSION) {
return {
name: 'AWS CodeBuild',
build_url: env.CODEBUILD_PUBLIC_BUILD_URL,
job_name: env.CODEBUILD_BUILD_ID,
build_number: env.CODEBUILD_BUILD_ID
};
}
// Bamboo
if (env.bamboo_buildNumber) {
return {
name: 'Bamboo',
build_url: env.bamboo_buildResultsUrl,
job_name: env.bamboo_shortJobName,
build_number: env.bamboo_buildNumber
};
}
// Wercker
if (env.WERCKER || env.WERCKER_MAIN_PIPELINE_STARTED) {
return {
name: 'Wercker',
build_url: env.WERCKER_BUILD_URL,
job_name: env.WERCKER_MAIN_PIPELINE_STARTED ? 'Main Pipeline' : null,
build_number: env.WERCKER_GIT_COMMIT
};
}
// Google Cloud
if (env.GCP_PROJECT || env.GCLOUD_PROJECT || env.GOOGLE_CLOUD_PROJECT) {
return {
name: 'Google Cloud',
build_url: null,
job_name: env.PROJECT_ID,
build_number: env.BUILD_ID
};
}
// Shippable
if (env.SHIPPABLE) {
return {
name: 'Shippable',
build_url: env.SHIPPABLE_BUILD_URL,
job_name: env.SHIPPABLE_JOB_ID ? `Job #${env.SHIPPABLE_JOB_ID}` : null,
build_number: env.SHIPPABLE_BUILD_NUMBER
};
}
// Netlify
if (this.isTrue(env.NETLIFY)) {
return {
name: 'Netlify',
build_url: env.DEPLOY_URL,
job_name: env.SITE_NAME,
build_number: env.BUILD_ID
};
}
// Github Actions
if (this.isTrue(env.GITHUB_ACTIONS)) {
return {
name: 'GitHub Actions',
build_url: `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`,
job_name: env.GITHUB_WORKFLOW,
build_number: env.GITHUB_RUN_ID
};
}
// Vercel
if (this.isTrue(env.CI) && env.VERCEL === '1') {
return {
name: 'Vercel',
build_url: `http://${env.VERCEL_URL}`,
job_name: null,
build_number: null
};
}
// Teamcity
if (env.TEAMCITY_VERSION) {
return {
name: 'Teamcity',
build_url: null,
job_name: null,
build_number: env.BUILD_NUMBER
};
}
// Concourse
if (env.CONCOURSE || env.CONCOURSE_URL || env.CONCOURSE_USERNAME || env.CONCOURSE_TEAM) {
return {
name: 'Concourse',
build_url: null,
job_name: env.BUILD_JOB_NAME || null,
build_number: env.BUILD_ID || null
};
}
// GoCD
if (env.GO_JOB_NAME) {
return {
name: 'GoCD',
build_url: null,
job_name: env.GO_JOB_NAME,
build_number: env.GO_PIPELINE_COUNTER
};
}
// CodeFresh
if (env.CF_BUILD_ID) {
return {
name: 'CodeFresh',
build_url: env.CF_BUILD_URL,
job_name: env.CF_PIPELINE_NAME,
build_number: env.CF_BUILD_ID
};
}
// if no matches, return null
exports.getCiInfo = () => {
var env = process.env;
const ciVendor = this.getCIVendor();
switch (ciVendor) {
case 'Jenkins':
return {
name: 'Jenkins',
build_url: env.BUILD_URL,
job_name: env.JOB_NAME,
build_number: env.BUILD_NUMBER
};
case 'CircleCI':
return {
name: 'CircleCI',
build_url: env.CIRCLE_BUILD_URL,
job_name: env.CIRCLE_JOB,
build_number: env.CIRCLE_BUILD_NUM
};
case 'TravisCI':
return {
name: 'Travis CI',
build_url: env.TRAVIS_BUILD_WEB_URL,
job_name: env.TRAVIS_JOB_NAME,
build_number: env.TRAVIS_BUILD_NUMBER
};
case 'Codeship':
return {
name: 'Codeship',
build_url: null,
job_name: null,
build_number: null
};
case 'Bitbucket':
return {
name: 'Bitbucket',
build_url: env.BITBUCKET_GIT_HTTP_ORIGIN,
job_name: null,
build_number: env.BITBUCKET_BUILD_NUMBER
};
case 'Drone':
return {
name: 'Drone',
build_url: env.DRONE_BUILD_LINK,
job_name: null,
build_number: env.DRONE_BUILD_NUMBER
};
case 'Semaphore':
return {
name: 'Semaphore',
build_url: env.SEMAPHORE_ORGANIZATION_URL,
job_name: env.SEMAPHORE_JOB_NAME,
build_number: env.SEMAPHORE_JOB_ID
};
case 'GitLab':
return {
name: 'GitLab',
build_url: env.CI_JOB_URL,
job_name: env.CI_JOB_NAME,
build_number: env.CI_JOB_ID
};
case 'Buildkite':
return {
name: 'Buildkite',
build_url: env.BUILDKITE_BUILD_URL,
job_name: env.BUILDKITE_LABEL || env.BUILDKITE_PIPELINE_NAME,
build_number: env.BUILDKITE_BUILD_NUMBER
};
case 'Visual Studio Team Services':
return {
name: 'Visual Studio Team Services',
build_url: `${env.SYSTEM_TEAMFOUNDATIONSERVERURI}${env.SYSTEM_TEAMPROJECTID}`,
job_name: env.SYSTEM_DEFINITIONID,
build_number: env.BUILD_BUILDID
};
default:
return null;
}
return {
name: null,
build_number: null
};
};

@@ -452,3 +580,3 @@

exports.getCloudProvider = (hostname) => {
if (hostname.includes('browserstack')) {
if (hostname && hostname.includes('browserstack')) {
return 'browserstack';

@@ -517,6 +645,46 @@ }

exports.getScenarioExamples = (gherkinDocument, scenario) => {
if (!(scenario.astNodeIds?.length > 1)) {
return;
}
const pickleId = scenario.astNodeIds[0];
const examplesId = scenario.astNodeIds[1];
const gherkinDocumentChildren = gherkinDocument.feature?.children;
let examples = [];
gherkinDocumentChildren?.forEach(child => {
if (child.rule) {
child.rule.children.forEach(childLevel2 => {
if (childLevel2.scenario && childLevel2.scenario.id === pickleId && childLevel2.scenario.examples) {
const passedExamples = childLevel2.scenario.examples.flatMap((val) => (val.tableBody)).find((item) => item.id === examplesId)?.cells.map((val) => (val.value));
if (passedExamples) {
examples = passedExamples;
}
}
});
} else if (child.scenario && child.scenario.id === pickleId && child.scenario.examples) {
const passedExamples = child.scenario.examples.flatMap((val) => (val.tableBody)).find((item) => item.id === examplesId)?.cells.map((val) => (val.value));
if (passedExamples) {
examples = passedExamples;
}
}
});
if (examples.length) {
return examples;
}
return;
};
exports.isCucumberTestSuite = (settings) => {
return settings?.test_runner?.type === 'cucumber';
};
exports.getPlatformVersion = (driver) => {
let platformVersion = null;
try {
let caps = driver.desiredCapabilities || {};
const caps = driver.desiredCapabilities || {};
if (!this.isUndefined(caps['bstack:options']) && !this.isUndefined(caps['bstack:options']['osVersion'])){

@@ -523,0 +691,0 @@ platformVersion = caps['bstack:options']['osVersion'];

@@ -9,3 +9,3 @@ const {API_URL, SCREENSHOT_EVENT_URL} = require('./constants');

keepAlive: true,
timeout: 60000,
timeout: 45000,
maxSockets: 2,

@@ -21,3 +21,3 @@ maxTotalSockets: 2

exports.makeRequest = (type, url, data, config, requestUrl=API_URL) => {
exports.makeRequest = (type, url, data, config, requestUrl=API_URL, jsonResponse = true) => {
const isHttps = requestUrl.includes('https');

@@ -47,6 +47,8 @@ let agent;

} else {
try {
if (body && typeof(body) !== 'object') {body = JSON.parse(body)}
} catch (e) {
reject('Not a JSON response from BrowserStack Server');
if (jsonResponse) {
try {
if (body && typeof(body) !== 'object') {body = JSON.parse(body)}
} catch (e) {
reject('Not a JSON response from BrowserStack Server');
}
}

@@ -53,0 +55,0 @@ resolve({

@@ -13,3 +13,3 @@ const {BATCH_SIZE, BATCH_INTERVAL} = require('./constants');

this.pollEventBatchInterval = null;
RequestQueueHandler.pending_test_uploads = 0;
this.pending_test_uploads = 0;
}

@@ -35,3 +35,4 @@

this.queue.push(event);
let data = null; const shouldProceed = this.shouldProceed();
let data = null;
const shouldProceed = this.shouldProceed();
if (shouldProceed) {

@@ -38,0 +39,0 @@ data = this.queue.slice(0, BATCH_SIZE);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc