@wdio/browserstack-service 7.31.1 → 7.32.1
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/crash-reporter.d.ts +14 -0
- package/build/crash-reporter.d.ts.map +1 -0
- package/build/crash-reporter.js +117 -0
- package/build/insights-handler.d.ts +7 -1
- package/build/insights-handler.d.ts.map +1 -1
- package/build/insights-handler.js +137 -35
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +20 -0
- package/build/performance-tester.d.ts +15 -0
- package/build/performance-tester.d.ts.map +1 -0
- package/build/performance-tester.js +98 -0
- package/build/reporter.d.ts +21 -3
- package/build/reporter.d.ts.map +1 -1
- package/build/reporter.js +176 -34
- package/build/service.d.ts.map +1 -1
- package/build/service.js +36 -17
- package/build/types.d.ts +15 -0
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +25 -7
- package/build/util.d.ts.map +1 -1
- package/build/util.js +108 -22
- package/package.json +4 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Capabilities, Options } from '@wdio/types';
|
|
2
|
+
import type { BrowserstackConfig, UserConfigforReporting } from './types';
|
|
3
|
+
export default class CrashReporter {
|
|
4
|
+
static userConfigForReporting: UserConfigforReporting;
|
|
5
|
+
private static credentialsForCrashReportUpload;
|
|
6
|
+
static setCredentialsForCrashReportUpload(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner): void;
|
|
7
|
+
static setConfigDetails(userConfig: Options.Testrunner, capabilities: Capabilities.RemoteCapability, options: BrowserstackConfig & Options.Testrunner): void;
|
|
8
|
+
static uploadCrashReport(exception: any, stackTrace: string): Promise<void>;
|
|
9
|
+
static deletePIIKeysFromObject(obj: {
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}): void;
|
|
12
|
+
static filterPII(userConfig: Options.Testrunner): any;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=crash-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crash-reporter.d.ts","sourceRoot":"","sources":["../src/crash-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAMxD,OAAO,KAAK,EAAE,kBAAkB,EAAmC,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAK1G,MAAM,CAAC,OAAO,OAAO,aAAa;IAE9B,OAAc,sBAAsB,EAAE,sBAAsB,CAAK;IAEjE,OAAO,CAAC,MAAM,CAAC,+BAA+B,CAAsC;IAEpF,MAAM,CAAC,kCAAkC,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IAQtH,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU;WAgBxI,iBAAiB,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM;IA6CjE,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE;IAO1D,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU;CAyBlD"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
7
|
+
const got_1 = __importDefault(require("got"));
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const package_json_1 = require("../package.json");
|
|
10
|
+
const constants_1 = require("./constants");
|
|
11
|
+
const util_1 = require("./util");
|
|
12
|
+
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
13
|
+
class CrashReporter {
|
|
14
|
+
static setCredentialsForCrashReportUpload(options, config) {
|
|
15
|
+
this.credentialsForCrashReportUpload = {
|
|
16
|
+
username: (0, util_1.getObservabilityUser)(options, config),
|
|
17
|
+
password: (0, util_1.getObservabilityKey)(options, config)
|
|
18
|
+
};
|
|
19
|
+
process.env.CREDENTIALS_FOR_CRASH_REPORTING = JSON.stringify(this.credentialsForCrashReportUpload);
|
|
20
|
+
}
|
|
21
|
+
static setConfigDetails(userConfig, capabilities, options) {
|
|
22
|
+
const configWithoutPII = this.filterPII(userConfig);
|
|
23
|
+
this.userConfigForReporting = {
|
|
24
|
+
framework: userConfig.framework,
|
|
25
|
+
services: configWithoutPII.services,
|
|
26
|
+
capabilities: capabilities,
|
|
27
|
+
env: {
|
|
28
|
+
'BROWSERSTACK_BUILD': process.env.BROWSERSTACK_BUILD,
|
|
29
|
+
'BROWSERSTACK_BUILD_NAME': process.env.BROWSERSTACK_BUILD_NAME,
|
|
30
|
+
'BUILD_TAG': process.env.BUILD_TAG
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
process.env.USER_CONFIG_FOR_REPORTING = JSON.stringify(this.userConfigForReporting);
|
|
34
|
+
this.setCredentialsForCrashReportUpload(options, userConfig);
|
|
35
|
+
}
|
|
36
|
+
static async uploadCrashReport(exception, stackTrace) {
|
|
37
|
+
try {
|
|
38
|
+
if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
|
|
39
|
+
this.credentialsForCrashReportUpload = process.env.CREDENTIALS_FOR_CRASH_REPORTING !== undefined ? JSON.parse(process.env.CREDENTIALS_FOR_CRASH_REPORTING) : this.credentialsForCrashReportUpload;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return log.error(`[Crash_Report_Upload] Failed to parse user credentials while reporting crash due to ${error}`);
|
|
44
|
+
}
|
|
45
|
+
if (!this.credentialsForCrashReportUpload.username || !this.credentialsForCrashReportUpload.password) {
|
|
46
|
+
return log.error('[Crash_Report_Upload] Failed to parse user credentials while reporting crash');
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
if (Object.keys(this.userConfigForReporting).length === 0) {
|
|
50
|
+
this.userConfigForReporting = process.env.USER_CONFIG_FOR_REPORTING !== undefined ? JSON.parse(process.env.USER_CONFIG_FOR_REPORTING) : {};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
log.error(`[Crash_Report_Upload] Failed to parse user config while reporting crash due to ${error}`);
|
|
55
|
+
this.userConfigForReporting = {};
|
|
56
|
+
}
|
|
57
|
+
const data = {
|
|
58
|
+
hashed_id: process.env.BS_TESTOPS_BUILD_HASHED_ID,
|
|
59
|
+
observability_version: {
|
|
60
|
+
frameworkName: 'WebdriverIO-' + (this.userConfigForReporting.framework || 'null'),
|
|
61
|
+
sdkVersion: package_json_1.version
|
|
62
|
+
},
|
|
63
|
+
exception: {
|
|
64
|
+
error: exception.toString(),
|
|
65
|
+
stackTrace: stackTrace
|
|
66
|
+
},
|
|
67
|
+
config: this.userConfigForReporting
|
|
68
|
+
};
|
|
69
|
+
const url = `${constants_1.DATA_ENDPOINT}/api/v1/analytics`;
|
|
70
|
+
got_1.default.post(url, {
|
|
71
|
+
...util_1.DEFAULT_REQUEST_CONFIG,
|
|
72
|
+
...this.credentialsForCrashReportUpload,
|
|
73
|
+
json: data
|
|
74
|
+
}).text().then(response => {
|
|
75
|
+
log.debug(`[Crash_Report_Upload] Success response: ${JSON.stringify(response)}`);
|
|
76
|
+
}).catch((error) => {
|
|
77
|
+
log.error(`[Crash_Report_Upload] Failed due to ${error}`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
static deletePIIKeysFromObject(obj) {
|
|
81
|
+
if (!obj) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
['user', 'username', 'key', 'accessKey'].forEach(key => delete obj[key]);
|
|
85
|
+
}
|
|
86
|
+
static filterPII(userConfig) {
|
|
87
|
+
const configWithoutPII = JSON.parse(JSON.stringify(userConfig));
|
|
88
|
+
this.deletePIIKeysFromObject(configWithoutPII);
|
|
89
|
+
const finalServices = [];
|
|
90
|
+
const initialServices = configWithoutPII.services;
|
|
91
|
+
delete configWithoutPII.services;
|
|
92
|
+
try {
|
|
93
|
+
for (const serviceArray of initialServices) {
|
|
94
|
+
if (Array.isArray(serviceArray) && serviceArray.length >= 2 && serviceArray[0] === 'browserstack') {
|
|
95
|
+
for (let idx = 1; idx < serviceArray.length; idx++) {
|
|
96
|
+
this.deletePIIKeysFromObject(serviceArray[idx]);
|
|
97
|
+
serviceArray[idx] && this.deletePIIKeysFromObject(serviceArray[idx].testObservabilityOptions);
|
|
98
|
+
}
|
|
99
|
+
finalServices.push(serviceArray);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
/* Wrong configuration like strings instead of json objects could break this method, needs no action */
|
|
106
|
+
log.error(`Error in parsing user config PII with error ${err ? (err.stack || err) : err}`);
|
|
107
|
+
return configWithoutPII;
|
|
108
|
+
}
|
|
109
|
+
configWithoutPII.services = finalServices;
|
|
110
|
+
return configWithoutPII;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/* User test config for build run minus PII */
|
|
114
|
+
CrashReporter.userConfigForReporting = {};
|
|
115
|
+
/* User credentials used for reporting crashes in browserstack service */
|
|
116
|
+
CrashReporter.credentialsForCrashReportUpload = {};
|
|
117
|
+
exports.default = CrashReporter;
|
|
@@ -2,7 +2,7 @@ import type { Capabilities, Frameworks } from '@wdio/types';
|
|
|
2
2
|
import type { Browser, MultiRemoteBrowser } from 'webdriverio';
|
|
3
3
|
import type { BeforeCommandArgs, AfterCommandArgs } from '@wdio/reporter';
|
|
4
4
|
import type { Pickle, ITestCaseHookParameter } from './cucumber-types';
|
|
5
|
-
|
|
5
|
+
declare class _InsightsHandler {
|
|
6
6
|
private _browser;
|
|
7
7
|
private _framework?;
|
|
8
8
|
private _tests;
|
|
@@ -31,10 +31,16 @@ export default class InsightsHandler {
|
|
|
31
31
|
*/
|
|
32
32
|
browserCommand(commandType: string, args: BeforeCommandArgs & AfterCommandArgs, test?: Frameworks.Test | ITestCaseHookParameter): Promise<void>;
|
|
33
33
|
private attachHookData;
|
|
34
|
+
private setHooksFromSuite;
|
|
34
35
|
private getHierarchy;
|
|
36
|
+
private getTestRunId;
|
|
37
|
+
private getTestRunIdFromSuite;
|
|
35
38
|
private sendTestRunEvent;
|
|
36
39
|
private sendTestRunEventForCucumber;
|
|
37
40
|
private getIntegrationsObject;
|
|
38
41
|
private getIdentifier;
|
|
39
42
|
}
|
|
43
|
+
declare const InsightsHandler: typeof _InsightsHandler;
|
|
44
|
+
type InsightsHandler = _InsightsHandler;
|
|
45
|
+
export default InsightsHandler;
|
|
40
46
|
//# sourceMappingURL=insights-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insights-handler.d.ts","sourceRoot":"","sources":["../src/insights-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAGzE,OAAO,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"insights-handler.d.ts","sourceRoot":"","sources":["../src/insights-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAGzE,OAAO,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAsBtE,cAAM,gBAAgB;IASL,OAAO,CAAC,QAAQ;IAAwI,OAAO,CAAC,UAAU,CAAC;IAPxL,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,aAAa,CAAC,CAAc;IACpC,OAAO,CAAC,SAAS,CAA2D;IAC5E,OAAO,CAAC,cAAc,CAAC,CAAQ;IAC/B,OAAO,CAAC,oBAAoB,CAAoC;gBAE3C,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,EAAU,UAAU,CAAC,oBAAQ;IAa1L,MAAM;IAWN,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG;IAgB/C,SAAS,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,UAAU;IAqD/D,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI;IAUjC,SAAS,CAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,UAAU;IAUrE;;QAEI;IAEE,cAAc,CAAE,KAAK,EAAE,sBAAsB;IA+B7C,aAAa,CAAE,KAAK,EAAE,sBAAsB;IAI5C,UAAU,CAAE,IAAI,EAAE,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM;IAuBzD,SAAS,CAAE,IAAI,EAAE,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,YAAY;IAgCzF,aAAa,CACf,WAAW,SAA2C,EACtD,YAAY,SAA4C;IAUtD,QAAQ;IAId;;OAEG;IAEG,cAAc,CAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,CAAC,IAAI,GAAG,sBAAsB;IA4DtI,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,qBAAqB;YAoBf,gBAAgB;YA6EhB,2BAA2B;IAsFzC,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,aAAa;CAMxB;AAGD,QAAA,MAAM,eAAe,EAAE,OAAO,gBAA0D,CAAA;AACxF,KAAK,eAAe,GAAG,gBAAgB,CAAA;AAEvC,eAAe,eAAe,CAAA"}
|
|
@@ -5,10 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const path_1 = __importDefault(require("path"));
|
|
7
7
|
const uuid_1 = require("uuid");
|
|
8
|
+
const reporter_1 = __importDefault(require("./reporter"));
|
|
8
9
|
const util_1 = require("./util");
|
|
9
10
|
const request_handler_1 = __importDefault(require("./request-handler"));
|
|
10
11
|
const constants_1 = require("./constants");
|
|
11
|
-
class
|
|
12
|
+
class _InsightsHandler {
|
|
12
13
|
constructor(_browser, browserCaps, isAppAutomate, sessionId, _framework) {
|
|
13
14
|
this._browser = _browser;
|
|
14
15
|
this._framework = _framework;
|
|
@@ -36,33 +37,69 @@ class InsightsHandler {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
async beforeHook(test, context) {
|
|
39
|
-
if (this._framework
|
|
40
|
-
|
|
41
|
-
const hookId = (0, uuid_1.v4)();
|
|
42
|
-
this._tests[fullTitle] = {
|
|
43
|
-
uuid: hookId,
|
|
44
|
-
startedAt: (new Date()).toISOString()
|
|
45
|
-
};
|
|
46
|
-
this.attachHookData(context, hookId);
|
|
47
|
-
await this.sendTestRunEvent(test, 'HookRunStarted');
|
|
40
|
+
if (!(0, util_1.frameworkSupportsHook)('before', this._framework)) {
|
|
41
|
+
return;
|
|
48
42
|
}
|
|
43
|
+
const fullTitle = (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
44
|
+
const hookId = (0, uuid_1.v4)();
|
|
45
|
+
this._tests[fullTitle] = {
|
|
46
|
+
uuid: hookId,
|
|
47
|
+
startedAt: (new Date()).toISOString()
|
|
48
|
+
};
|
|
49
|
+
this.attachHookData(context, hookId);
|
|
50
|
+
await this.sendTestRunEvent(test, 'HookRunStarted');
|
|
49
51
|
}
|
|
50
52
|
async afterHook(test, result) {
|
|
51
|
-
if (this._framework
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
if (!(0, util_1.frameworkSupportsHook)('after', this._framework)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const fullTitle = (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
57
|
+
if (this._tests[fullTitle]) {
|
|
58
|
+
this._tests[fullTitle].finishedAt = (new Date()).toISOString();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this._tests[fullTitle] = {
|
|
62
|
+
finishedAt: (new Date()).toISOString()
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
await this.sendTestRunEvent(test, 'HookRunFinished', result);
|
|
66
|
+
const hookType = (0, util_1.getHookType)(test.title);
|
|
67
|
+
/*
|
|
68
|
+
If any of the `beforeAll`, `beforeEach`, `afterEach` then the tests after the hook won't run in mocha (https://github.com/mochajs/mocha/issues/4392)
|
|
69
|
+
So if any of this hook fails, then we are sending the next tests in the suite as skipped.
|
|
70
|
+
This won't be needed for `afterAll`, as even if `afterAll` fails all the tests that we need are already run by then, so we don't need to send the stats for them separately
|
|
71
|
+
*/
|
|
72
|
+
if (!result.passed && (hookType === 'BEFORE_EACH' || hookType === 'BEFORE_ALL' || hookType === 'AFTER_EACH')) {
|
|
73
|
+
const sendTestSkip = async (skippedTest) => {
|
|
74
|
+
// We only need to send the tests that whose state is not determined yet. The state of tests which is determined will already be sent.
|
|
75
|
+
if (skippedTest.state === undefined) {
|
|
76
|
+
const fullTitle = `${skippedTest.parent.title} - ${skippedTest.title}`;
|
|
77
|
+
this._tests[fullTitle] = {
|
|
78
|
+
uuid: (0, uuid_1.v4)(),
|
|
79
|
+
startedAt: (new Date()).toISOString(),
|
|
80
|
+
finishedAt: (new Date()).toISOString()
|
|
81
|
+
};
|
|
82
|
+
await this.sendTestRunEvent(skippedTest, 'TestRunSkipped');
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/*
|
|
86
|
+
Recursively send the tests as skipped for all suites below the hook. This is to handle nested describe blocks
|
|
87
|
+
*/
|
|
88
|
+
const sendSuiteSkipped = async (suite) => {
|
|
89
|
+
for (const skippedTest of suite.tests) {
|
|
90
|
+
await sendTestSkip(skippedTest);
|
|
91
|
+
}
|
|
92
|
+
for (const skippedSuite of suite.suites) {
|
|
93
|
+
await sendSuiteSkipped(skippedSuite);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
await sendSuiteSkipped(test.ctx.test.parent);
|
|
62
97
|
}
|
|
63
98
|
}
|
|
64
99
|
async beforeTest(test) {
|
|
65
|
-
|
|
100
|
+
if (this._framework !== 'mocha')
|
|
101
|
+
return;
|
|
102
|
+
const fullTitle = (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
66
103
|
this._tests[fullTitle] = {
|
|
67
104
|
uuid: (0, uuid_1.v4)(),
|
|
68
105
|
startedAt: (new Date()).toISOString()
|
|
@@ -70,7 +107,9 @@ class InsightsHandler {
|
|
|
70
107
|
await this.sendTestRunEvent(test, 'TestRunStarted');
|
|
71
108
|
}
|
|
72
109
|
async afterTest(test, result) {
|
|
73
|
-
|
|
110
|
+
if (this._framework !== 'mocha')
|
|
111
|
+
return;
|
|
112
|
+
const fullTitle = (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
74
113
|
this._tests[fullTitle] = {
|
|
75
114
|
...(this._tests[fullTitle] || {}),
|
|
76
115
|
finishedAt: (new Date()).toISOString()
|
|
@@ -179,7 +218,8 @@ class InsightsHandler {
|
|
|
179
218
|
return;
|
|
180
219
|
}
|
|
181
220
|
const identifier = this.getIdentifier(test);
|
|
182
|
-
|
|
221
|
+
const testMeta = this._tests[identifier] || reporter_1.default.getTests()[identifier];
|
|
222
|
+
if (!testMeta) {
|
|
183
223
|
return;
|
|
184
224
|
}
|
|
185
225
|
// log screenshot
|
|
@@ -187,7 +227,7 @@ class InsightsHandler {
|
|
|
187
227
|
await (0, util_1.uploadEventData)([{
|
|
188
228
|
event_type: 'LogCreated',
|
|
189
229
|
logs: [{
|
|
190
|
-
test_run_uuid:
|
|
230
|
+
test_run_uuid: testMeta.uuid,
|
|
191
231
|
timestamp: new Date().toISOString(),
|
|
192
232
|
message: args.result.value,
|
|
193
233
|
kind: 'TEST_SCREENSHOT'
|
|
@@ -203,7 +243,7 @@ class InsightsHandler {
|
|
|
203
243
|
const req = this._requestQueueHandler.add({
|
|
204
244
|
event_type: 'LogCreated',
|
|
205
245
|
logs: [{
|
|
206
|
-
test_run_uuid:
|
|
246
|
+
test_run_uuid: testMeta.uuid,
|
|
207
247
|
timestamp: new Date().toISOString(),
|
|
208
248
|
kind: 'HTTP',
|
|
209
249
|
http_response: {
|
|
@@ -222,14 +262,37 @@ class InsightsHandler {
|
|
|
222
262
|
* private methods
|
|
223
263
|
*/
|
|
224
264
|
attachHookData(context, hookId) {
|
|
225
|
-
if (
|
|
265
|
+
if (context.currentTest && context.currentTest.parent) {
|
|
266
|
+
const parentTest = `${context.currentTest.parent.title} - ${context.currentTest.title}`;
|
|
267
|
+
if (!this._hooks[parentTest]) {
|
|
268
|
+
this._hooks[parentTest] = [];
|
|
269
|
+
}
|
|
270
|
+
this._hooks[parentTest].push(hookId);
|
|
226
271
|
return;
|
|
227
272
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this._hooks[parentTest] = [];
|
|
273
|
+
else if (context.test) {
|
|
274
|
+
this.setHooksFromSuite(context.test.parent, hookId);
|
|
231
275
|
}
|
|
232
|
-
|
|
276
|
+
}
|
|
277
|
+
setHooksFromSuite(parent, hookId) {
|
|
278
|
+
if (!parent) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (parent.tests && parent.tests.length > 0) {
|
|
282
|
+
const uniqueIdentifier = (0, util_1.getUniqueIdentifier)(parent.tests[0], this._framework);
|
|
283
|
+
if (!this._hooks[uniqueIdentifier]) {
|
|
284
|
+
this._hooks[uniqueIdentifier] = [];
|
|
285
|
+
}
|
|
286
|
+
this._hooks[uniqueIdentifier].push(hookId);
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
for (const suite of parent.suites) {
|
|
290
|
+
const result = this.setHooksFromSuite(suite, hookId);
|
|
291
|
+
if (result) {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return false;
|
|
233
296
|
}
|
|
234
297
|
/*
|
|
235
298
|
* Get hierarchy info
|
|
@@ -237,7 +300,8 @@ class InsightsHandler {
|
|
|
237
300
|
getHierarchy(test) {
|
|
238
301
|
const value = [];
|
|
239
302
|
if (test.ctx && test.ctx.test) {
|
|
240
|
-
|
|
303
|
+
// If we already have the parent object, utilize it else get from context
|
|
304
|
+
let parent = typeof test.parent === 'object' ? test.parent : test.ctx.test.parent;
|
|
241
305
|
while (parent && parent.title !== '') {
|
|
242
306
|
value.push(parent.title);
|
|
243
307
|
parent = parent.parent;
|
|
@@ -245,9 +309,40 @@ class InsightsHandler {
|
|
|
245
309
|
}
|
|
246
310
|
return value.reverse();
|
|
247
311
|
}
|
|
312
|
+
getTestRunId(context) {
|
|
313
|
+
if (!context) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (context.currentTest) {
|
|
317
|
+
const uniqueIdentifier = (0, util_1.getUniqueIdentifier)(context.currentTest, this._framework);
|
|
318
|
+
return this._tests[uniqueIdentifier] && this._tests[uniqueIdentifier].uuid;
|
|
319
|
+
}
|
|
320
|
+
if (!context.test) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
return this.getTestRunIdFromSuite(context.test.parent);
|
|
324
|
+
}
|
|
325
|
+
getTestRunIdFromSuite(parent) {
|
|
326
|
+
if (!parent) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
for (const test of parent.tests) {
|
|
330
|
+
const uniqueIdentifier = (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
331
|
+
if (this._tests[uniqueIdentifier]) {
|
|
332
|
+
return this._tests[uniqueIdentifier].uuid;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
for (const suite of parent.suites) {
|
|
336
|
+
const testRunId = this.getTestRunIdFromSuite(suite);
|
|
337
|
+
if (testRunId) {
|
|
338
|
+
return testRunId;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
248
343
|
async sendTestRunEvent(test, eventType, results) {
|
|
249
344
|
var _a;
|
|
250
|
-
const fullTitle = (0, util_1.getUniqueIdentifier)(test);
|
|
345
|
+
const fullTitle = (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
251
346
|
const testMetaData = this._tests[fullTitle];
|
|
252
347
|
const testData = {
|
|
253
348
|
uuid: testMetaData.uuid,
|
|
@@ -287,19 +382,24 @@ class InsightsHandler {
|
|
|
287
382
|
testData.hooks = this._hooks[fullTitle];
|
|
288
383
|
}
|
|
289
384
|
}
|
|
290
|
-
if (eventType
|
|
385
|
+
if (eventType === 'TestRunStarted' || eventType === 'TestRunSkipped' || eventType === 'HookRunStarted') {
|
|
291
386
|
testData.integrations = {};
|
|
292
387
|
if (this._browser && this._platformMeta) {
|
|
293
388
|
const provider = (0, util_1.getCloudProvider)(this._browser);
|
|
294
389
|
testData.integrations[provider] = this.getIntegrationsObject();
|
|
295
390
|
}
|
|
296
391
|
}
|
|
392
|
+
if (eventType === 'TestRunSkipped') {
|
|
393
|
+
testData.result = 'skipped';
|
|
394
|
+
eventType = 'TestRunFinished';
|
|
395
|
+
}
|
|
297
396
|
const uploadData = {
|
|
298
397
|
event_type: eventType,
|
|
299
398
|
};
|
|
300
399
|
/* istanbul ignore if */
|
|
301
400
|
if (eventType.match(/HookRun/)) {
|
|
302
401
|
testData.hook_type = ((_a = testData.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) ? (0, util_1.getHookType)(testData.name.toLowerCase()) : 'undefined';
|
|
402
|
+
testData.test_run_id = this.getTestRunId(test.ctx);
|
|
303
403
|
uploadData.hook_run = testData;
|
|
304
404
|
}
|
|
305
405
|
else {
|
|
@@ -400,7 +500,9 @@ class InsightsHandler {
|
|
|
400
500
|
if ('pickle' in test) {
|
|
401
501
|
return (0, util_1.getUniqueIdentifierForCucumber)(test);
|
|
402
502
|
}
|
|
403
|
-
return (0, util_1.getUniqueIdentifier)(test);
|
|
503
|
+
return (0, util_1.getUniqueIdentifier)(test, this._framework);
|
|
404
504
|
}
|
|
405
505
|
}
|
|
506
|
+
// https://github.com/microsoft/TypeScript/issues/6543
|
|
507
|
+
const InsightsHandler = (0, util_1.o11yClassErrorHandler)(_InsightsHandler);
|
|
406
508
|
exports.default = InsightsHandler;
|
package/build/launcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAKlE,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAapF,KAAK,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7C,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,2BAA4B,YAAW,QAAQ,CAAC,eAAe;IAQ5E,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,OAAO;IATnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAQ;gBAGrB,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACzD,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IAqEjC,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IA2GtF,UAAU;IAsDV,UAAU,CAAC,GAAG,EAAC,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkBrD;;;OAGG;IACG,YAAY,CAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBhE,WAAW,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAC,MAAM;IAoF3F,sBAAsB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IAyCrE;;;OAGG;IACH,oBAAoB;IA6BpB,sBAAsB,CAAC,QAAQ,CAAC,EAAC,MAAM,EAAE,SAAS,CAAC,EAAC,MAAM,EAAE,eAAe,CAAC,EAAC,MAAM;CAQtF"}
|
package/build/launcher.js
CHANGED
|
@@ -38,8 +38,10 @@ const BrowserstackLocalLauncher = __importStar(require("browserstack-local"));
|
|
|
38
38
|
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
39
39
|
// @ts-ignore
|
|
40
40
|
const package_json_1 = require("../package.json");
|
|
41
|
+
const crash_reporter_1 = __importDefault(require("./crash-reporter"));
|
|
41
42
|
const constants_1 = require("./constants");
|
|
42
43
|
const util_2 = require("./util");
|
|
44
|
+
const performance_tester_1 = __importDefault(require("./performance-tester"));
|
|
43
45
|
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
44
46
|
class BrowserstackLauncherService {
|
|
45
47
|
constructor(_options, capabilities, _config) {
|
|
@@ -96,6 +98,9 @@ class BrowserstackLauncherService {
|
|
|
96
98
|
}
|
|
97
99
|
});
|
|
98
100
|
}
|
|
101
|
+
if (process.env.BROWSERSTACK_O11Y_PERF_MEASUREMENT) {
|
|
102
|
+
performance_tester_1.default.startMonitoring('performance-report-launcher.csv');
|
|
103
|
+
}
|
|
99
104
|
// by default observability will be true unless specified as false
|
|
100
105
|
this._options.testObservability = this._options.testObservability == false ? false : true;
|
|
101
106
|
if (this._options.testObservability &&
|
|
@@ -103,6 +108,12 @@ class BrowserstackLauncherService {
|
|
|
103
108
|
process.env.BROWSERSTACK_RERUN && process.env.BROWSERSTACK_RERUN_TESTS) {
|
|
104
109
|
this._config.specs = process.env.BROWSERSTACK_RERUN_TESTS.split(',');
|
|
105
110
|
}
|
|
111
|
+
try {
|
|
112
|
+
crash_reporter_1.default.setConfigDetails(this._config, capabilities, this._options);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
log.error(`[Crash_Report_Upload] Config processing failed due to ${error}`);
|
|
116
|
+
}
|
|
106
117
|
}
|
|
107
118
|
async onPrepare(config, capabilities) {
|
|
108
119
|
/**
|
|
@@ -208,6 +219,15 @@ class BrowserstackLauncherService {
|
|
|
208
219
|
console.log(`\nVisit https://observability.browserstack.com/builds/${process.env.BS_TESTOPS_BUILD_HASHED_ID} to view build report, insights, and many more debugging information all at one place!\n`);
|
|
209
220
|
}
|
|
210
221
|
}
|
|
222
|
+
if (process.env.BROWSERSTACK_O11Y_PERF_MEASUREMENT) {
|
|
223
|
+
await performance_tester_1.default.stopAndGenerate('performance-launcher.html');
|
|
224
|
+
performance_tester_1.default.calculateTimes(['launchTestSession', 'stopBuildUpstream']);
|
|
225
|
+
if (!process.env.START_TIME) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const duration = (new Date()).getTime() - (new Date(process.env.START_TIME)).getTime();
|
|
229
|
+
log.info(`Total duration is ${duration / 1000} s`);
|
|
230
|
+
}
|
|
211
231
|
if (!this.browserstackLocal || !this.browserstackLocal.isRunning()) {
|
|
212
232
|
return;
|
|
213
233
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { PerformanceObserver } from 'perf_hooks';
|
|
3
|
+
export default class PerformanceTester {
|
|
4
|
+
static _observer: PerformanceObserver;
|
|
5
|
+
static _csvWriter: any;
|
|
6
|
+
private static _events;
|
|
7
|
+
static started: boolean;
|
|
8
|
+
static startMonitoring(csvName?: string): void;
|
|
9
|
+
static getPerformance(): import("perf_hooks").Performance;
|
|
10
|
+
static calculateTimes(methods: string[]): number;
|
|
11
|
+
static stopAndGenerate(filename?: string): Promise<void>;
|
|
12
|
+
static generateReport(entries: any[]): string;
|
|
13
|
+
static generateCSV(entries: any[]): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=performance-tester.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-tester.d.ts","sourceRoot":"","sources":["../src/performance-tester.ts"],"names":[],"mappings":";AAEA,OAAO,EAAe,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAM7D,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAClC,MAAM,CAAC,SAAS,EAAE,mBAAmB,CAAA;IACrC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAA;IACtB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAyB;IAC/C,MAAM,CAAC,OAAO,UAAQ;IAEtB,MAAM,CAAC,eAAe,CAAC,OAAO,GAAE,MAAiC;IAiBjE,MAAM,CAAC,cAAc;IAIrB,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAI,MAAM;WAepC,eAAe,CAAC,QAAQ,GAAE,MAA+B;IAoBtE,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE;IAWpC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE;CAuBpC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const csv_writer_1 = require("csv-writer");
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const perf_hooks_1 = require("perf_hooks");
|
|
9
|
+
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
10
|
+
const util_1 = require("./util");
|
|
11
|
+
const log = (0, logger_1.default)('@wdio/browserstack-service');
|
|
12
|
+
class PerformanceTester {
|
|
13
|
+
static startMonitoring(csvName = 'performance-report.csv') {
|
|
14
|
+
this._observer = new perf_hooks_1.PerformanceObserver(list => {
|
|
15
|
+
list.getEntries().forEach(entry => {
|
|
16
|
+
this._events.push(entry);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
this._observer.observe({ buffered: true, entryTypes: ['function'] });
|
|
20
|
+
this.started = true;
|
|
21
|
+
this._csvWriter = (0, csv_writer_1.createObjectCsvWriter)({
|
|
22
|
+
path: csvName,
|
|
23
|
+
header: [
|
|
24
|
+
{ id: 'name', title: 'Function Name' },
|
|
25
|
+
{ id: 'time', title: 'Execution Time (ms)' }
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
static getPerformance() {
|
|
30
|
+
return perf_hooks_1.performance;
|
|
31
|
+
}
|
|
32
|
+
static calculateTimes(methods) {
|
|
33
|
+
const times = {};
|
|
34
|
+
this._events.map((entry) => {
|
|
35
|
+
if (!times[entry.name]) {
|
|
36
|
+
times[entry.name] = 0;
|
|
37
|
+
}
|
|
38
|
+
times[entry.name] += entry.duration;
|
|
39
|
+
});
|
|
40
|
+
const timeTaken = methods.reduce((a, c) => {
|
|
41
|
+
return times[c] + (a || 0);
|
|
42
|
+
}, 0);
|
|
43
|
+
log.info(`Time for ${methods} is `, timeTaken);
|
|
44
|
+
return timeTaken;
|
|
45
|
+
}
|
|
46
|
+
static async stopAndGenerate(filename = 'performance-own.html') {
|
|
47
|
+
if (!this.started)
|
|
48
|
+
return;
|
|
49
|
+
await (0, util_1.sleep)(2000); // Wait to 2s just to finish any running callbacks for timerify
|
|
50
|
+
this._observer.disconnect();
|
|
51
|
+
this.started = false;
|
|
52
|
+
this.generateCSV(this._events);
|
|
53
|
+
const content = this.generateReport(this._events);
|
|
54
|
+
const path = process.cwd() + '/' + filename;
|
|
55
|
+
fs_1.default.writeFile(path, content, err => {
|
|
56
|
+
if (err) {
|
|
57
|
+
log.error('Error in writing html', err);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
log.info('Performance report is at ', path);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
static generateReport(entries) {
|
|
64
|
+
let html = '<!DOCTYPE html><html><head><title>Performance Report</title></head><body>';
|
|
65
|
+
html += '<h1>Performance Report</h1>';
|
|
66
|
+
html += '<table><thead><tr><th>Function Name</th><th>Duration (ms)</th></tr></thead><tbody>';
|
|
67
|
+
entries.forEach((entry) => {
|
|
68
|
+
html += `<tr><td>${entry.name}</td><td>${entry.duration}</td></tr>`;
|
|
69
|
+
});
|
|
70
|
+
html += '</tbody></table></body></html>';
|
|
71
|
+
return html;
|
|
72
|
+
}
|
|
73
|
+
static generateCSV(entries) {
|
|
74
|
+
const times = {};
|
|
75
|
+
entries.map((entry) => {
|
|
76
|
+
if (!times[entry.name]) {
|
|
77
|
+
times[entry.name] = 0;
|
|
78
|
+
}
|
|
79
|
+
times[entry.name] += entry.duration;
|
|
80
|
+
return {
|
|
81
|
+
name: entry.name,
|
|
82
|
+
time: entry.duration
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
const dat = Object.entries(times).map(([key, value]) => {
|
|
86
|
+
return {
|
|
87
|
+
name: key,
|
|
88
|
+
time: value
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
this._csvWriter.writeRecords(dat)
|
|
92
|
+
.then(() => log.info('Performance CSV report generated successfully'))
|
|
93
|
+
.catch((error) => console.error(error));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
PerformanceTester._events = [];
|
|
97
|
+
PerformanceTester.started = false;
|
|
98
|
+
exports.default = PerformanceTester;
|
package/build/reporter.d.ts
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
import WDIOReporter, { SuiteStats, TestStats, RunnerStats } from '@wdio/reporter';
|
|
2
|
-
|
|
1
|
+
import WDIOReporter, { SuiteStats, TestStats, RunnerStats, HookStats } from '@wdio/reporter';
|
|
2
|
+
import { TestMeta } from './types';
|
|
3
|
+
declare class _TestReporter extends WDIOReporter {
|
|
3
4
|
private _capabilities;
|
|
4
5
|
private _config?;
|
|
5
6
|
private _observability;
|
|
6
7
|
private _sessionId?;
|
|
7
8
|
private _suiteName?;
|
|
8
9
|
private _requestQueueHandler;
|
|
9
|
-
|
|
10
|
+
private _suites;
|
|
11
|
+
private static _tests;
|
|
12
|
+
private _gitConfigPath?;
|
|
13
|
+
private _gitConfigured;
|
|
14
|
+
onRunnerStart(runnerStats: RunnerStats): Promise<void>;
|
|
15
|
+
configureGit(): Promise<void>;
|
|
16
|
+
static getTests(): Record<string, TestMeta>;
|
|
10
17
|
onSuiteStart(suiteStats: SuiteStats): void;
|
|
18
|
+
onSuiteEnd(): void;
|
|
19
|
+
needToSendData(testType?: string, event?: string): boolean;
|
|
20
|
+
onTestEnd(testStats: TestStats): Promise<void>;
|
|
21
|
+
onTestStart(testStats: TestStats): Promise<void>;
|
|
22
|
+
onHookStart(hookStats: HookStats): Promise<void>;
|
|
23
|
+
onHookEnd(hookStats: HookStats): Promise<void>;
|
|
24
|
+
getHookIdentifier(hookStats: HookStats): string;
|
|
25
|
+
sendTestRunEvent(testStats: TestStats | HookStats, eventType: string): Promise<void>;
|
|
11
26
|
onTestSkip(testStats: TestStats): Promise<void>;
|
|
12
27
|
}
|
|
28
|
+
declare const TestReporter: typeof _TestReporter;
|
|
29
|
+
type TestReporter = _TestReporter;
|
|
30
|
+
export default TestReporter;
|
|
13
31
|
//# sourceMappingURL=reporter.d.ts.map
|