@wdio/browserstack-service 7.32.4 → 7.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/accessibility-handler.d.ts +39 -0
- package/build/accessibility-handler.d.ts.map +1 -0
- package/build/accessibility-handler.js +258 -0
- package/build/cleanup.d.ts +5 -0
- package/build/cleanup.d.ts.map +1 -0
- package/build/cleanup.js +23 -0
- package/build/constants.d.ts +3 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +6 -2
- package/build/cucumber-types.d.ts +17 -0
- package/build/cucumber-types.d.ts.map +1 -1
- package/build/index.d.ts +5 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -1
- package/build/insights-handler.d.ts +19 -3
- package/build/insights-handler.d.ts.map +1 -1
- package/build/insights-handler.js +275 -17
- package/build/launcher.d.ts +6 -0
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +164 -0
- package/build/log4jsAppender.d.ts +2 -0
- package/build/log4jsAppender.d.ts.map +1 -0
- package/build/log4jsAppender.js +26 -0
- package/build/logPatcher.d.ts +13 -0
- package/build/logPatcher.d.ts.map +1 -0
- package/build/logPatcher.js +43 -0
- package/build/logReportingAPI.d.ts +12 -0
- package/build/logReportingAPI.d.ts.map +1 -0
- package/build/logReportingAPI.js +61 -0
- package/build/reporter.d.ts +6 -1
- package/build/reporter.d.ts.map +1 -1
- package/build/reporter.js +42 -1
- package/build/request-handler.d.ts +1 -0
- package/build/request-handler.d.ts.map +1 -1
- package/build/request-handler.js +5 -0
- package/build/scripts/test-event-scripts.d.ts +10 -0
- package/build/scripts/test-event-scripts.d.ts.map +1 -0
- package/build/scripts/test-event-scripts.js +73 -0
- package/build/service.d.ts +6 -3
- package/build/service.d.ts.map +1 -1
- package/build/service.js +50 -7
- package/build/types.d.ts +43 -1
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +48 -1
- package/build/util.d.ts.map +1 -1
- package/build/util.js +448 -11
- package/package.json +6 -5
package/build/util.js
CHANGED
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.sleep = exports.frameworkSupportsHook = exports.getObservabilityBuildTags = exports.getObservabilityBuild = exports.getObservabilityProject = exports.getObservabilityKey = exports.getObservabilityUser = exports.batchAndPostEvents = exports.shouldAddServiceVersion = exports.isBStackSession = exports.isScreenshotCommand = exports.getHookType = exports.getHierarchy = exports.uploadEventData = exports.getLogTag = exports.removeAnsiColors = exports.getScenarioExamples = exports.isBrowserstackSession = exports.getCloudProvider = exports.getUniqueIdentifierForCucumber = exports.getUniqueIdentifier = exports.getGitMetaData = exports.getCiInfo = exports.stopBuildUpstream = exports.launchTestSession = exports.o11yClassErrorHandler = exports.o11yErrorHandler = exports.getParentSuiteName = exports.isBrowserstackCapability = exports.getBrowserCapabilities = exports.getBrowserDescription = exports.DEFAULT_REQUEST_CONFIG = void 0;
|
|
29
|
+
exports.isTrue = exports.isUndefined = exports.getBrowserStackKey = exports.getBrowserStackUser = exports.stopAccessibilityTestRun = exports.getA11yResultsSummary = exports.getA11yResults = exports.createAccessibilityTestRun = exports.isAccessibilityAutomationSession = exports.shouldScanTestForAccessibility = exports.validateCapsWithA11y = exports.pushDataToQueue = exports.sleep = exports.patchConsoleLogs = exports.getFailureObject = exports.frameworkSupportsHook = exports.getObservabilityBuildTags = exports.getObservabilityBuild = exports.getObservabilityProject = exports.getObservabilityKey = exports.getObservabilityUser = exports.batchAndPostEvents = exports.shouldAddServiceVersion = exports.isBStackSession = exports.isScreenshotCommand = exports.getHookType = exports.getHierarchy = exports.uploadEventData = exports.getLogTag = exports.removeAnsiColors = exports.getScenarioExamples = exports.isBrowserstackSession = exports.getCloudProvider = exports.getUniqueIdentifierForCucumber = exports.getUniqueIdentifier = exports.getGitMetaData = exports.nodeRequest = exports.getCiInfo = exports.stopBuildUpstream = exports.launchTestSession = exports.o11yClassErrorHandler = exports.o11yErrorHandler = exports.errorHandler = exports.getParentSuiteName = exports.isBrowserstackCapability = exports.getBrowserCapabilities = exports.getBrowserDescription = exports.DEFAULT_REQUEST_CONFIG = void 0;
|
|
30
30
|
const os_1 = require("os");
|
|
31
31
|
const util_1 = require("util");
|
|
32
32
|
const http_1 = __importDefault(require("http"));
|
|
@@ -38,9 +38,11 @@ const got_1 = __importStar(require("got"));
|
|
|
38
38
|
const git_repo_info_1 = __importDefault(require("git-repo-info"));
|
|
39
39
|
const gitconfiglocal_1 = __importDefault(require("gitconfiglocal"));
|
|
40
40
|
const crash_reporter_1 = __importDefault(require("./crash-reporter"));
|
|
41
|
+
const logPatcher_1 = __importDefault(require("./logPatcher"));
|
|
41
42
|
const constants_1 = require("./constants");
|
|
42
43
|
const request_handler_1 = __importDefault(require("./request-handler"));
|
|
43
44
|
const performance_tester_1 = __importDefault(require("./performance-tester"));
|
|
45
|
+
const test_event_scripts_1 = require("./scripts/test-event-scripts");
|
|
44
46
|
const pGitconfig = (0, util_1.promisify)(gitconfiglocal_1.default);
|
|
45
47
|
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
46
48
|
exports.DEFAULT_REQUEST_CONFIG = {
|
|
@@ -123,6 +125,22 @@ function processError(error, fn, args) {
|
|
|
123
125
|
}
|
|
124
126
|
crash_reporter_1.default.uploadCrashReport(`Error in executing ${fn.name} with args ${argsString} : ${error}`, error && error.stack);
|
|
125
127
|
}
|
|
128
|
+
function errorHandler(fn) {
|
|
129
|
+
return function (...args) {
|
|
130
|
+
try {
|
|
131
|
+
const functionToHandle = fn;
|
|
132
|
+
const result = functionToHandle(...args);
|
|
133
|
+
if (result instanceof Promise) {
|
|
134
|
+
return result.catch(error => log.error(`Error in executing ${fn.name} with args ${args}: ${error}`));
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
log.error(`Error in executing ${fn.name} with args ${args}: ${error}`);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
exports.errorHandler = errorHandler;
|
|
126
144
|
function o11yErrorHandler(fn) {
|
|
127
145
|
return function (...args) {
|
|
128
146
|
try {
|
|
@@ -284,7 +302,7 @@ exports.stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstream()
|
|
|
284
302
|
}
|
|
285
303
|
});
|
|
286
304
|
function getCiInfo() {
|
|
287
|
-
|
|
305
|
+
const env = process.env;
|
|
288
306
|
// Jenkins
|
|
289
307
|
if ((typeof env.JENKINS_URL === 'string' && env.JENKINS_URL.length > 0) || (typeof env.JENKINS_HOME === 'string' && env.JENKINS_HOME.length > 0)) {
|
|
290
308
|
return {
|
|
@@ -295,7 +313,7 @@ function getCiInfo() {
|
|
|
295
313
|
};
|
|
296
314
|
}
|
|
297
315
|
// CircleCI
|
|
298
|
-
if (env.CI
|
|
316
|
+
if (isTrue(env.CI) && isTrue(env.CIRCLECI)) {
|
|
299
317
|
return {
|
|
300
318
|
name: 'CircleCI',
|
|
301
319
|
build_url: env.CIRCLE_BUILD_URL,
|
|
@@ -304,7 +322,7 @@ function getCiInfo() {
|
|
|
304
322
|
};
|
|
305
323
|
}
|
|
306
324
|
// Travis CI
|
|
307
|
-
if (env.CI
|
|
325
|
+
if (isTrue(env.CI) && isTrue(env.TRAVIS)) {
|
|
308
326
|
return {
|
|
309
327
|
name: 'Travis CI',
|
|
310
328
|
build_url: env.TRAVIS_BUILD_WEB_URL,
|
|
@@ -313,7 +331,7 @@ function getCiInfo() {
|
|
|
313
331
|
};
|
|
314
332
|
}
|
|
315
333
|
// Codeship
|
|
316
|
-
if (env.CI
|
|
334
|
+
if (isTrue(env.CI) && env.CI_NAME === 'codeship') {
|
|
317
335
|
return {
|
|
318
336
|
name: 'Codeship',
|
|
319
337
|
build_url: null,
|
|
@@ -331,7 +349,7 @@ function getCiInfo() {
|
|
|
331
349
|
};
|
|
332
350
|
}
|
|
333
351
|
// Drone
|
|
334
|
-
if (env.CI
|
|
352
|
+
if (isTrue(env.CI) && isTrue(env.DRONE)) {
|
|
335
353
|
return {
|
|
336
354
|
name: 'Drone',
|
|
337
355
|
build_url: env.DRONE_BUILD_LINK,
|
|
@@ -340,7 +358,7 @@ function getCiInfo() {
|
|
|
340
358
|
};
|
|
341
359
|
}
|
|
342
360
|
// Semaphore
|
|
343
|
-
if (env.CI
|
|
361
|
+
if (isTrue(env.CI) && isTrue(env.SEMAPHORE)) {
|
|
344
362
|
return {
|
|
345
363
|
name: 'Semaphore',
|
|
346
364
|
build_url: env.SEMAPHORE_ORGANIZATION_URL,
|
|
@@ -349,7 +367,7 @@ function getCiInfo() {
|
|
|
349
367
|
};
|
|
350
368
|
}
|
|
351
369
|
// GitLab
|
|
352
|
-
if (env.CI
|
|
370
|
+
if (isTrue(env.CI) && isTrue(env.GITLAB_CI)) {
|
|
353
371
|
return {
|
|
354
372
|
name: 'GitLab',
|
|
355
373
|
build_url: env.CI_JOB_URL,
|
|
@@ -358,7 +376,7 @@ function getCiInfo() {
|
|
|
358
376
|
};
|
|
359
377
|
}
|
|
360
378
|
// Buildkite
|
|
361
|
-
if (env.CI
|
|
379
|
+
if (isTrue(env.CI) && isTrue(env.BUILDKITE)) {
|
|
362
380
|
return {
|
|
363
381
|
name: 'Buildkite',
|
|
364
382
|
build_url: env.BUILDKITE_BUILD_URL,
|
|
@@ -367,7 +385,7 @@ function getCiInfo() {
|
|
|
367
385
|
};
|
|
368
386
|
}
|
|
369
387
|
// Visual Studio Team Services
|
|
370
|
-
if (env.TF_BUILD
|
|
388
|
+
if (isTrue(env.TF_BUILD) && env.TF_BUILD_BUILDNUMBER) {
|
|
371
389
|
return {
|
|
372
390
|
name: 'Visual Studio Team Services',
|
|
373
391
|
build_url: `${env.SYSTEM_TEAMFOUNDATIONSERVERURI}${env.SYSTEM_TEAMPROJECTID}`,
|
|
@@ -375,16 +393,172 @@ function getCiInfo() {
|
|
|
375
393
|
build_number: env.BUILD_BUILDID
|
|
376
394
|
};
|
|
377
395
|
}
|
|
396
|
+
// Appveyor
|
|
397
|
+
if (isTrue(env.APPVEYOR)) {
|
|
398
|
+
return {
|
|
399
|
+
name: 'Appveyor',
|
|
400
|
+
build_url: `${env.APPVEYOR_URL}/project/${env.APPVEYOR_ACCOUNT_NAME}/${env.APPVEYOR_PROJECT_SLUG}/builds/${env.APPVEYOR_BUILD_ID}`,
|
|
401
|
+
job_name: env.APPVEYOR_JOB_NAME,
|
|
402
|
+
build_number: env.APPVEYOR_BUILD_NUMBER
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
// Azure CI
|
|
406
|
+
if (env.AZURE_HTTP_USER_AGENT && env.TF_BUILD) {
|
|
407
|
+
return {
|
|
408
|
+
name: 'Azure CI',
|
|
409
|
+
build_url: `${env.SYSTEM_TEAMFOUNDATIONSERVERURI}${env.SYSTEM_TEAMPROJECT}/_build/results?buildId=${env.BUILD_BUILDID}`,
|
|
410
|
+
job_name: env.BUILD_BUILDID,
|
|
411
|
+
build_number: env.BUILD_BUILDID
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
// AWS CodeBuild
|
|
415
|
+
if (env.CODEBUILD_BUILD_ID || env.CODEBUILD_RESOLVED_SOURCE_VERSION || env.CODEBUILD_SOURCE_VERSION) {
|
|
416
|
+
return {
|
|
417
|
+
name: 'AWS CodeBuild',
|
|
418
|
+
build_url: env.CODEBUILD_PUBLIC_BUILD_URL,
|
|
419
|
+
job_name: env.CODEBUILD_BUILD_ID,
|
|
420
|
+
build_number: env.CODEBUILD_BUILD_ID
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
// Bamboo
|
|
424
|
+
if (env.bamboo_buildNumber) {
|
|
425
|
+
return {
|
|
426
|
+
name: 'Bamboo',
|
|
427
|
+
build_url: env.bamboo_buildResultsUrl,
|
|
428
|
+
job_name: env.bamboo_shortJobName,
|
|
429
|
+
build_number: env.bamboo_buildNumber
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
// Wercker
|
|
433
|
+
if (env.WERCKER || env.WERCKER_MAIN_PIPELINE_STARTED) {
|
|
434
|
+
return {
|
|
435
|
+
name: 'Wercker',
|
|
436
|
+
build_url: env.WERCKER_BUILD_URL,
|
|
437
|
+
job_name: env.WERCKER_MAIN_PIPELINE_STARTED ? 'Main Pipeline' : null,
|
|
438
|
+
build_number: env.WERCKER_GIT_COMMIT
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
// Google Cloud
|
|
442
|
+
if (env.GCP_PROJECT || env.GCLOUD_PROJECT || env.GOOGLE_CLOUD_PROJECT) {
|
|
443
|
+
return {
|
|
444
|
+
name: 'Google Cloud',
|
|
445
|
+
build_url: null,
|
|
446
|
+
job_name: env.PROJECT_ID,
|
|
447
|
+
build_number: env.BUILD_ID,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
// Shippable
|
|
451
|
+
if (env.SHIPPABLE) {
|
|
452
|
+
return {
|
|
453
|
+
name: 'Shippable',
|
|
454
|
+
build_url: env.SHIPPABLE_BUILD_URL,
|
|
455
|
+
job_name: env.SHIPPABLE_JOB_ID ? `Job #${env.SHIPPABLE_JOB_ID}` : null,
|
|
456
|
+
build_number: env.SHIPPABLE_BUILD_NUMBER
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
// Netlify
|
|
460
|
+
if (isTrue(env.NETLIFY)) {
|
|
461
|
+
return {
|
|
462
|
+
name: 'Netlify',
|
|
463
|
+
build_url: env.DEPLOY_URL,
|
|
464
|
+
job_name: env.SITE_NAME,
|
|
465
|
+
build_number: env.BUILD_ID
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
// Github Actions
|
|
469
|
+
if (isTrue(env.GITHUB_ACTIONS)) {
|
|
470
|
+
return {
|
|
471
|
+
name: 'GitHub Actions',
|
|
472
|
+
build_url: `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`,
|
|
473
|
+
job_name: env.GITHUB_WORKFLOW,
|
|
474
|
+
build_number: env.GITHUB_RUN_ID,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
// Vercel
|
|
478
|
+
if (isTrue(env.CI) && env.VERCEL === '1') {
|
|
479
|
+
return {
|
|
480
|
+
name: 'Vercel',
|
|
481
|
+
build_url: `http://${env.VERCEL_URL}`,
|
|
482
|
+
job_name: null,
|
|
483
|
+
build_number: null,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
// Teamcity
|
|
487
|
+
if (env.TEAMCITY_VERSION) {
|
|
488
|
+
return {
|
|
489
|
+
name: 'Teamcity',
|
|
490
|
+
build_url: null,
|
|
491
|
+
job_name: null,
|
|
492
|
+
build_number: env.BUILD_NUMBER,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
// Concourse
|
|
496
|
+
if (env.CONCOURSE || env.CONCOURSE_URL || env.CONCOURSE_USERNAME || env.CONCOURSE_TEAM) {
|
|
497
|
+
return {
|
|
498
|
+
name: 'Concourse',
|
|
499
|
+
build_url: null,
|
|
500
|
+
job_name: env.BUILD_JOB_NAME || null,
|
|
501
|
+
build_number: env.BUILD_ID || null,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
// GoCD
|
|
505
|
+
if (env.GO_JOB_NAME) {
|
|
506
|
+
return {
|
|
507
|
+
name: 'GoCD',
|
|
508
|
+
build_url: null,
|
|
509
|
+
job_name: env.GO_JOB_NAME,
|
|
510
|
+
build_number: env.GO_PIPELINE_COUNTER,
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
// CodeFresh
|
|
514
|
+
if (env.CF_BUILD_ID) {
|
|
515
|
+
return {
|
|
516
|
+
name: 'CodeFresh',
|
|
517
|
+
build_url: env.CF_BUILD_URL,
|
|
518
|
+
job_name: env.CF_PIPELINE_NAME,
|
|
519
|
+
build_number: env.CF_BUILD_ID,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
378
522
|
// if no matches, return null
|
|
379
523
|
return null;
|
|
380
524
|
}
|
|
381
525
|
exports.getCiInfo = getCiInfo;
|
|
526
|
+
async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout = 120000) {
|
|
527
|
+
try {
|
|
528
|
+
const response = await (0, got_1.default)(`${apiUrl}/${apiEndpoint}`, {
|
|
529
|
+
method: requestType,
|
|
530
|
+
timeout: {
|
|
531
|
+
request: timeout
|
|
532
|
+
},
|
|
533
|
+
...options
|
|
534
|
+
}).json();
|
|
535
|
+
return response;
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
if (error instanceof got_1.HTTPError && error.response) {
|
|
539
|
+
const errorMessageJson = error.response.body ? JSON.parse(error.response.body.toString()) : null;
|
|
540
|
+
const errorMessage = errorMessageJson ? errorMessageJson.message : null;
|
|
541
|
+
if (errorMessage) {
|
|
542
|
+
log.error(`${errorMessage} - ${error.stack}`);
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
log.error(`${error.stack}`);
|
|
546
|
+
}
|
|
547
|
+
throw error;
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
log.error(`Failed to fire api request due to ${error} - ${error.stack}`);
|
|
551
|
+
throw error;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
exports.nodeRequest = nodeRequest;
|
|
382
556
|
async function getGitMetaData() {
|
|
383
557
|
var info = (0, git_repo_info_1.default)();
|
|
384
558
|
if (!info.commonGitDir)
|
|
385
559
|
return {};
|
|
386
560
|
const { remote } = await pGitconfig(info.commonGitDir);
|
|
387
|
-
const remotes = Object.keys(remote).map(remoteName => ({ name: remoteName, url: remote[remoteName]['url'] }));
|
|
561
|
+
const remotes = remote ? Object.keys(remote).map(remoteName => ({ name: remoteName, url: remote[remoteName]['url'] })) : [];
|
|
388
562
|
return {
|
|
389
563
|
name: 'git',
|
|
390
564
|
sha: info.sha,
|
|
@@ -649,8 +823,271 @@ function frameworkSupportsHook(hook, framework) {
|
|
|
649
823
|
if (framework === 'mocha' && (hook === 'before' || hook === 'after' || hook === 'beforeEach' || hook === 'afterEach')) {
|
|
650
824
|
return true;
|
|
651
825
|
}
|
|
826
|
+
if (framework === 'cucumber') {
|
|
827
|
+
return true;
|
|
828
|
+
}
|
|
652
829
|
return false;
|
|
653
830
|
}
|
|
654
831
|
exports.frameworkSupportsHook = frameworkSupportsHook;
|
|
832
|
+
function getFailureObject(error) {
|
|
833
|
+
const stack = error.stack;
|
|
834
|
+
const message = typeof error === 'string' ? error : error.message;
|
|
835
|
+
const backtrace = stack ? removeAnsiColors(stack.toString()) : '';
|
|
836
|
+
return {
|
|
837
|
+
failure: [{ backtrace: [backtrace] }],
|
|
838
|
+
failure_reason: removeAnsiColors(message.toString()),
|
|
839
|
+
failure_type: message ? (message.toString().match(/AssertionError/) ? 'AssertionError' : 'UnhandledError') : null
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
exports.getFailureObject = getFailureObject;
|
|
843
|
+
function patchConsoleLogs() {
|
|
844
|
+
const BSTestOpsPatcher = new logPatcher_1.default({});
|
|
845
|
+
Object.keys(constants_1.consoleHolder).forEach((method) => {
|
|
846
|
+
const origMethod = console[method].bind(console);
|
|
847
|
+
// Make sure we don't override Constructors
|
|
848
|
+
// Arrow functions are not construable
|
|
849
|
+
if (typeof console[method] === 'function'
|
|
850
|
+
&& method !== 'Console') {
|
|
851
|
+
console[method] = (...args) => {
|
|
852
|
+
origMethod(...args);
|
|
853
|
+
BSTestOpsPatcher[method](...args);
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
exports.patchConsoleLogs = patchConsoleLogs;
|
|
655
859
|
const sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
656
860
|
exports.sleep = sleep;
|
|
861
|
+
async function pushDataToQueue(data, requestQueueHandler = undefined) {
|
|
862
|
+
if (!requestQueueHandler) {
|
|
863
|
+
requestQueueHandler = request_handler_1.default.getInstance();
|
|
864
|
+
}
|
|
865
|
+
const req = requestQueueHandler.add(data);
|
|
866
|
+
if (req.proceed && req.data) {
|
|
867
|
+
await uploadEventData(req.data, req.url);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
exports.pushDataToQueue = pushDataToQueue;
|
|
871
|
+
const validateCapsWithA11y = (deviceName, platformMeta, chromeOptions) => {
|
|
872
|
+
var _a, _b;
|
|
873
|
+
try {
|
|
874
|
+
if (deviceName) {
|
|
875
|
+
log.warn('Accessibility Automation will run only on Desktop browsers.');
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
if (((_a = platformMeta === null || platformMeta === void 0 ? void 0 : platformMeta.browser_name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== 'chrome') {
|
|
879
|
+
log.warn('Accessibility Automation will run only on Chrome browsers.');
|
|
880
|
+
return false;
|
|
881
|
+
}
|
|
882
|
+
const browserVersion = platformMeta === null || platformMeta === void 0 ? void 0 : platformMeta.browser_version;
|
|
883
|
+
if (!isUndefined(browserVersion) && !(browserVersion === 'latest' || parseFloat(browserVersion + '') > 94)) {
|
|
884
|
+
log.warn('Accessibility Automation will run only on Chrome browser version greater than 94.');
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
if ((_b = chromeOptions === null || chromeOptions === void 0 ? void 0 : chromeOptions.args) === null || _b === void 0 ? void 0 : _b.includes('--headless')) {
|
|
888
|
+
log.warn('Accessibility Automation will not run on legacy headless mode. Switch to new headless mode or avoid using headless mode.');
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
891
|
+
return true;
|
|
892
|
+
}
|
|
893
|
+
catch (error) {
|
|
894
|
+
log.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
|
|
895
|
+
}
|
|
896
|
+
return false;
|
|
897
|
+
};
|
|
898
|
+
exports.validateCapsWithA11y = validateCapsWithA11y;
|
|
899
|
+
const shouldScanTestForAccessibility = (suiteTitle, testTitle, accessibilityOptions) => {
|
|
900
|
+
try {
|
|
901
|
+
const includeTags = Array.isArray(accessibilityOptions === null || accessibilityOptions === void 0 ? void 0 : accessibilityOptions.includeTagsInTestingScope) ? accessibilityOptions === null || accessibilityOptions === void 0 ? void 0 : accessibilityOptions.includeTagsInTestingScope : [];
|
|
902
|
+
const excludeTags = Array.isArray(accessibilityOptions === null || accessibilityOptions === void 0 ? void 0 : accessibilityOptions.excludeTagsInTestingScope) ? accessibilityOptions === null || accessibilityOptions === void 0 ? void 0 : accessibilityOptions.excludeTagsInTestingScope : [];
|
|
903
|
+
const fullTestName = suiteTitle + ' ' + testTitle;
|
|
904
|
+
const excluded = excludeTags === null || excludeTags === void 0 ? void 0 : excludeTags.some((exclude) => fullTestName.includes(exclude));
|
|
905
|
+
const included = (includeTags === null || includeTags === void 0 ? void 0 : includeTags.length) === 0 || (includeTags === null || includeTags === void 0 ? void 0 : includeTags.some((include) => fullTestName.includes(include)));
|
|
906
|
+
return !excluded && included;
|
|
907
|
+
}
|
|
908
|
+
catch (error) {
|
|
909
|
+
log.debug('Error while validating test case for accessibility before scanning. Error : ', error);
|
|
910
|
+
}
|
|
911
|
+
return false;
|
|
912
|
+
};
|
|
913
|
+
exports.shouldScanTestForAccessibility = shouldScanTestForAccessibility;
|
|
914
|
+
const isAccessibilityAutomationSession = (accessibilityFlag) => {
|
|
915
|
+
try {
|
|
916
|
+
const hasA11yJwtToken = typeof process.env.BSTACK_A11Y_JWT === 'string' && process.env.BSTACK_A11Y_JWT.length > 0 && process.env.BSTACK_A11Y_JWT !== 'null' && process.env.BSTACK_A11Y_JWT !== 'undefined';
|
|
917
|
+
return accessibilityFlag && hasA11yJwtToken;
|
|
918
|
+
}
|
|
919
|
+
catch (error) {
|
|
920
|
+
log.debug(`Exception in verifying the Accessibility session with error : ${error}`);
|
|
921
|
+
}
|
|
922
|
+
return false;
|
|
923
|
+
};
|
|
924
|
+
exports.isAccessibilityAutomationSession = isAccessibilityAutomationSession;
|
|
925
|
+
exports.createAccessibilityTestRun = errorHandler(async function createAccessibilityTestRun(options, config, bsConfig) {
|
|
926
|
+
const userName = getBrowserStackUser(config);
|
|
927
|
+
const accessKey = getBrowserStackKey(config);
|
|
928
|
+
if (isUndefined(userName) || isUndefined(accessKey)) {
|
|
929
|
+
log.error('Exception while creating test run for BrowserStack Accessibility Automation: Missing BrowserStack credentials');
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
const data = {
|
|
933
|
+
'projectName': bsConfig.projectName,
|
|
934
|
+
'buildName': bsConfig.buildName ||
|
|
935
|
+
path_1.default.basename(path_1.default.resolve(process.cwd())),
|
|
936
|
+
'startTime': (new Date()).toISOString(),
|
|
937
|
+
'description': '',
|
|
938
|
+
'source': {
|
|
939
|
+
frameworkName: 'WebdriverIO-' + config.framework,
|
|
940
|
+
frameworkVersion: bsConfig.bstackServiceVersion,
|
|
941
|
+
sdkVersion: bsConfig.bstackServiceVersion
|
|
942
|
+
},
|
|
943
|
+
'settings': bsConfig.accessibilityOptions || {},
|
|
944
|
+
'versionControl': await getGitMetaData(),
|
|
945
|
+
'ciInfo': getCiInfo(),
|
|
946
|
+
'hostInfo': {
|
|
947
|
+
hostname: (0, os_1.hostname)(),
|
|
948
|
+
platform: (0, os_1.platform)(),
|
|
949
|
+
type: (0, os_1.type)(),
|
|
950
|
+
version: (0, os_1.version)(),
|
|
951
|
+
arch: (0, os_1.arch)()
|
|
952
|
+
},
|
|
953
|
+
'browserstackAutomation': true,
|
|
954
|
+
};
|
|
955
|
+
const requestOptions = {
|
|
956
|
+
json: data,
|
|
957
|
+
username: getBrowserStackUser(config),
|
|
958
|
+
password: getBrowserStackKey(config),
|
|
959
|
+
};
|
|
960
|
+
try {
|
|
961
|
+
const response = await nodeRequest('POST', 'test_runs', requestOptions, constants_1.ACCESSIBILITY_API_URL);
|
|
962
|
+
log.debug(`[Create Accessibility Test Run] Success response: ${JSON.stringify(response)}`);
|
|
963
|
+
if (response.data.accessibilityToken) {
|
|
964
|
+
process.env.BSTACK_A11Y_JWT = response.data.accessibilityToken;
|
|
965
|
+
}
|
|
966
|
+
if (response.data.id) {
|
|
967
|
+
process.env.BS_A11Y_TEST_RUN_ID = response.data.id;
|
|
968
|
+
}
|
|
969
|
+
log.debug(`BrowserStack Accessibility Automation Test Run ID: ${response.data.id}`);
|
|
970
|
+
return response.data.scannerVersion;
|
|
971
|
+
}
|
|
972
|
+
catch (error) {
|
|
973
|
+
if (error.response) {
|
|
974
|
+
log.error(`Exception while creating test run for BrowserStack Accessibility Automation: ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`);
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
const errorMessage = error.message;
|
|
978
|
+
if (errorMessage === 'Invalid configuration passed.') {
|
|
979
|
+
log.error(`Exception while creating test run for BrowserStack Accessibility Automation: ${errorMessage || error.stack}`);
|
|
980
|
+
for (const errorkey of error.errors) {
|
|
981
|
+
log.error(errorkey.message);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
log.error(`Exception while creating test run for BrowserStack Accessibility Automation: ${errorMessage || error.stack}`);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
const getA11yResults = async (browser, isBrowserStackSession, isAccessibility) => {
|
|
992
|
+
if (!isBrowserStackSession) {
|
|
993
|
+
log.warn('Not a BrowserStack Automate session, cannot retrieve Accessibility results.');
|
|
994
|
+
return []; // since we are running only on Automate as of now
|
|
995
|
+
}
|
|
996
|
+
if (!(0, exports.isAccessibilityAutomationSession)(isAccessibility)) {
|
|
997
|
+
log.warn('Not an Accessibility Automation session, cannot retrieve Accessibility results.');
|
|
998
|
+
return [];
|
|
999
|
+
}
|
|
1000
|
+
try {
|
|
1001
|
+
const results = await browser.execute(test_event_scripts_1.accessibilityResults);
|
|
1002
|
+
return results;
|
|
1003
|
+
}
|
|
1004
|
+
catch {
|
|
1005
|
+
log.error('No accessibility results were found.');
|
|
1006
|
+
return [];
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
exports.getA11yResults = getA11yResults;
|
|
1010
|
+
const getA11yResultsSummary = async (browser, isBrowserStackSession, isAccessibility) => {
|
|
1011
|
+
if (!isBrowserStackSession) {
|
|
1012
|
+
return {}; // since we are running only on Automate as of now
|
|
1013
|
+
}
|
|
1014
|
+
if (!(0, exports.isAccessibilityAutomationSession)(isAccessibility)) {
|
|
1015
|
+
log.warn('Not an Accessibility Automation session, cannot retrieve Accessibility results summary.');
|
|
1016
|
+
return {};
|
|
1017
|
+
}
|
|
1018
|
+
try {
|
|
1019
|
+
const summaryResults = await browser.execute(test_event_scripts_1.accessibilityResultsSummary);
|
|
1020
|
+
return summaryResults;
|
|
1021
|
+
}
|
|
1022
|
+
catch {
|
|
1023
|
+
log.error('No accessibility summary was found.');
|
|
1024
|
+
return {};
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
exports.getA11yResultsSummary = getA11yResultsSummary;
|
|
1028
|
+
exports.stopAccessibilityTestRun = errorHandler(async function stopAccessibilityTestRun() {
|
|
1029
|
+
const hasA11yJwtToken = typeof process.env.BSTACK_A11Y_JWT === 'string' && process.env.BSTACK_A11Y_JWT.length > 0 && process.env.BSTACK_A11Y_JWT !== 'null' && process.env.BSTACK_A11Y_JWT !== 'undefined';
|
|
1030
|
+
if (!hasA11yJwtToken) {
|
|
1031
|
+
return {
|
|
1032
|
+
status: 'error',
|
|
1033
|
+
message: 'Build creation had failed.'
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
const data = {
|
|
1037
|
+
'endTime': (new Date()).toISOString(),
|
|
1038
|
+
};
|
|
1039
|
+
const requestOptions = { ...{
|
|
1040
|
+
json: data,
|
|
1041
|
+
headers: {
|
|
1042
|
+
'Authorization': `Bearer ${process.env.BSTACK_A11Y_JWT}`,
|
|
1043
|
+
}
|
|
1044
|
+
} };
|
|
1045
|
+
try {
|
|
1046
|
+
const response = await nodeRequest('PUT', 'test_runs/stop', requestOptions, constants_1.ACCESSIBILITY_API_URL);
|
|
1047
|
+
if (response.data && response.data.error) {
|
|
1048
|
+
throw new Error('Invalid request: ' + response.data.error);
|
|
1049
|
+
}
|
|
1050
|
+
else if (response.error) {
|
|
1051
|
+
throw new Error('Invalid request: ' + response.error);
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
log.info(`BrowserStack Accessibility Automation Test Run marked as completed at ${new Date().toISOString()}`);
|
|
1055
|
+
return { status: 'success', message: '' };
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
catch (error) {
|
|
1059
|
+
if (error.response && error.response.status && error.response.statusText && error.response.data) {
|
|
1060
|
+
log.error(`Exception while marking completion of BrowserStack Accessibility Automation Test Run: ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`);
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
log.error(`Exception while marking completion of BrowserStack Accessibility Automation Test Run: ${error.message || util_2.default.format(error)}`);
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
status: 'error',
|
|
1067
|
+
message: error.message ||
|
|
1068
|
+
(error.response ? `${error.response.status}:${error.response.statusText}` : error)
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
function getBrowserStackUser(config) {
|
|
1073
|
+
if (process.env.BROWSERSTACK_USERNAME) {
|
|
1074
|
+
return process.env.BROWSERSTACK_USERNAME;
|
|
1075
|
+
}
|
|
1076
|
+
return config.user;
|
|
1077
|
+
}
|
|
1078
|
+
exports.getBrowserStackUser = getBrowserStackUser;
|
|
1079
|
+
function getBrowserStackKey(config) {
|
|
1080
|
+
if (process.env.BROWSERSTACK_ACCESS_KEY) {
|
|
1081
|
+
return process.env.BROWSERSTACK_ACCESS_KEY;
|
|
1082
|
+
}
|
|
1083
|
+
return config.key;
|
|
1084
|
+
}
|
|
1085
|
+
exports.getBrowserStackKey = getBrowserStackKey;
|
|
1086
|
+
function isUndefined(value) {
|
|
1087
|
+
return value === undefined || value === null;
|
|
1088
|
+
}
|
|
1089
|
+
exports.isUndefined = isUndefined;
|
|
1090
|
+
function isTrue(value) {
|
|
1091
|
+
return (value + '').toLowerCase() === 'true';
|
|
1092
|
+
}
|
|
1093
|
+
exports.isTrue = isTrue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browserstack-service",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.34.0",
|
|
4
4
|
"description": "WebdriverIO service for better Browserstack integration",
|
|
5
5
|
"author": "Adam Bjerstedt <abjerstedt@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
|
|
@@ -26,15 +26,16 @@
|
|
|
26
26
|
"@types/gitconfiglocal": "^2.0.1",
|
|
27
27
|
"@wdio/logger": "7.26.0",
|
|
28
28
|
"@wdio/reporter": "7.25.4",
|
|
29
|
-
"@wdio/types": "7.
|
|
29
|
+
"@wdio/types": "7.33.0",
|
|
30
30
|
"browserstack-local": "^1.4.5",
|
|
31
31
|
"csv-writer": "^1.6.0",
|
|
32
32
|
"form-data": "^4.0.0",
|
|
33
33
|
"git-repo-info": "^2.1.1",
|
|
34
34
|
"gitconfiglocal": "^2.1.0",
|
|
35
35
|
"got": "^11.0.2",
|
|
36
|
-
"uuid": "^
|
|
37
|
-
"webdriverio": "7.
|
|
36
|
+
"uuid": "^9.0.1",
|
|
37
|
+
"webdriverio": "7.34.0",
|
|
38
|
+
"winston-transport": "^4.5.0"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
41
|
"@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
@@ -43,5 +44,5 @@
|
|
|
43
44
|
"access": "public"
|
|
44
45
|
},
|
|
45
46
|
"types": "./build/index.d.ts",
|
|
46
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "9a1640148030bbadd646deb582c24a54fede12a3"
|
|
47
48
|
}
|