@testim/testim-cli 3.200.0 → 3.204.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/OverrideTestDataBuilder.js +1 -1
- package/commons/featureFlags.js +1 -3
- package/commons/getSessionPlayerRequire.js +22 -2
- package/commons/logger.js +58 -48
- package/commons/testimServicesApi.js +14 -0
- package/executionQueue.js +2 -2
- package/lib/coralogix-winston.transport.js +105 -0
- package/npm-shrinkwrap.json +640 -247
- package/package.json +8 -8
- package/player/stepActions/pixelValidationStepAction.js +7 -4
- package/player/utils/eyeSdkService.js +15 -8
- package/reports/junitReporter.js +0 -3
- package/runner.js +1 -10
- package/runners/ParallelWorkerManager.js +2 -2
- package/runners/TestPlanRunner.js +40 -11
- package/services/gridService.js +1 -2
- package/testRunHandler.js +14 -3
- package/workers/BaseWorker.js +1 -3
- package/workers/WorkerSelenium.js +3 -0
- package/lib/coralogix-bunyan.stream.js +0 -56
|
@@ -32,7 +32,7 @@ class OverrideTestDataBuilder {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
if (this.isObjectNotArray(params) && typeof params.overrideAllTestsData !== 'undefined') {
|
|
35
|
-
if (
|
|
35
|
+
if (_.isObject(params.overrideAllTestsData) && !_.isEmpty(params.overrideAllTestsData)) {
|
|
36
36
|
const testNames = this.testInfoList.map(test => test.name);
|
|
37
37
|
testNames.forEach(testName => this.overrideSingeTest(testName, params.overrideAllTestsData));
|
|
38
38
|
delete params.overrideAllTestsData;
|
package/commons/featureFlags.js
CHANGED
|
@@ -37,7 +37,6 @@ class FeatureFlagsService {
|
|
|
37
37
|
useSafariWebdriverVisibilityChecks: new Rox.Flag(),
|
|
38
38
|
useClickimVisibilityChecks: new Rox.Flag(),
|
|
39
39
|
useIEWebdriverVisibilityChecks: new Rox.Flag(),
|
|
40
|
-
enableTDKRun: new Rox.Flag(true),
|
|
41
40
|
runGetElementCodeInAut: new Rox.Flag(),
|
|
42
41
|
enableNpmPackageInstallUsingNpmCli: new Rox.Flag(),
|
|
43
42
|
enableFrameSwitchOptimization: new Rox.Flag(),
|
|
@@ -47,8 +46,6 @@ class FeatureFlagsService {
|
|
|
47
46
|
warnOnBadNetwork: new Rox.Flag(false),
|
|
48
47
|
overrideAzureStorageUrl: new Rox.Flag(),
|
|
49
48
|
useJsInputCodeInSafari: new Rox.Flag(),
|
|
50
|
-
testNameTestDataInJunitReport: new Rox.Flag(),
|
|
51
|
-
countRetries: new Rox.Flag(),
|
|
52
49
|
autoSaveDownloadFileFireFox: new Rox.Flag(true),
|
|
53
50
|
safariSelectOptionDispatchEventOnSelectElement: new Rox.Flag(true),
|
|
54
51
|
experimentalPreCodeCompilation: new Rox.Flag(false),
|
|
@@ -57,6 +54,7 @@ class FeatureFlagsService {
|
|
|
57
54
|
useSameBrowserForMultiTests: new LabFeatureFlag('labs'),
|
|
58
55
|
highSpeedMode: new LabFeatureFlag(),
|
|
59
56
|
usePortedHtml5DragDrop: new Rox.Flag(),
|
|
57
|
+
applitoolsNewIntegration: new Rox.Flag(),
|
|
60
58
|
};
|
|
61
59
|
Rox.register('default', this.flags);
|
|
62
60
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const perf = require('./performance-logger');
|
|
4
4
|
|
|
5
5
|
perf.log('getSessionPlayerRequire start');
|
|
6
6
|
const getSessionPlayerFolder = require('./prepareRunnerAndTestimStartUtils').getSessionPlayerFolder;
|
|
7
|
+
|
|
7
8
|
const testimAppDataFolder = getSessionPlayerFolder();
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* @type {{
|
|
11
|
+
sessionPlayer: typeof import('../../../clickim/src/background/session/sessionPlayer').SessionPlayer;
|
|
12
|
+
utils: typeof import('../../../clickim/src/lib/utils').utils;
|
|
13
|
+
commonConstants: typeof import('../../../clickim/src/common/commonConstantsStrong');
|
|
14
|
+
locatorBuilderUtils: import('../../../clickim/src/locators/locatorBuilderUtils')['locatorBuilderUtils'];
|
|
15
|
+
assetService: import('../../../clickim/src/background/assetService')['assetService'];
|
|
16
|
+
localAssetService: import('../../../clickim/src/background/localAssetService');
|
|
17
|
+
urlUtils: import('../../../clickim/src/background/portMatch/urlUtils');
|
|
18
|
+
positionUtils: import('../../../clickim/src/lib/positionUtils');
|
|
19
|
+
visibilityUtils: import('../../../clickim/src/background/visibilityUtils');
|
|
20
|
+
apiCall: import('../../../clickim/src/common/playback/apiCall')['apiCall'];
|
|
21
|
+
stepParamBuilder: typeof import('../../../clickim/src/common/stepParamsBuilder').StepParamsBuilder;
|
|
22
|
+
stepParamExpressionEvaluator: import('../../../clickim/src/common/stepParamExpressionEvaluator');
|
|
23
|
+
manifestVersion: string | undefined;
|
|
24
|
+
EyeSdkBuilder: typeof import('../../../clickim/src/background/eyeSdkBuilder').EyeSdkBuilder
|
|
25
|
+
}}
|
|
26
|
+
*/
|
|
27
|
+
const sessionPlayer = require(require('path').join(testimAppDataFolder, 'sessionPlayer.js')); // eslint-disable-line import/no-dynamic-require
|
|
28
|
+
|
|
9
29
|
module.exports = sessionPlayer;
|
|
10
30
|
perf.log('getSessionPlayerRequire end');
|
package/commons/logger.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const winston = require('winston');
|
|
4
|
+
const os = require('os');
|
|
4
5
|
|
|
6
|
+
const hostname = os.hostname();
|
|
5
7
|
const runnerVersion = getRunnerVersion();
|
|
6
8
|
const config = require('./config');
|
|
7
9
|
|
|
@@ -24,42 +26,45 @@ function getRunnerVersion() {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function getStreamsAndWaitForFlushPromise() {
|
|
27
|
-
const
|
|
28
|
-
const streams = [];
|
|
29
|
+
const transports = [];
|
|
29
30
|
|
|
30
31
|
let waitForFlush = () => Promise.resolve();
|
|
31
32
|
|
|
32
33
|
if (!config.IS_ON_PREM) {
|
|
33
|
-
const
|
|
34
|
+
const { CoralogixTransport } = require('../lib/coralogix-winston.transport');
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
streams.push({
|
|
39
|
-
level,
|
|
40
|
-
stream: new CoralogixBunyan.CoralogixStream({ category: 'ROOT' }),
|
|
41
|
-
type: 'raw',
|
|
36
|
+
CoralogixTransport.configure(loggerConfig);
|
|
37
|
+
const loggerInstance = new CoralogixTransport({
|
|
38
|
+
category: 'ROOT',
|
|
42
39
|
});
|
|
40
|
+
transports.push(loggerInstance);
|
|
41
|
+
|
|
42
|
+
waitForFlush = () => loggerInstance.waitForFlush();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
if (config.LOGGER_CONSOLE) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
streams.push({
|
|
50
|
-
level,
|
|
51
|
-
stream: prettyStdOut,
|
|
52
|
-
type: 'raw',
|
|
53
|
-
});
|
|
46
|
+
transports.push(new winston.transports.Console({
|
|
47
|
+
format: winston.format.combine(winston.format.colorize(), winston.format.simple()),
|
|
48
|
+
}));
|
|
54
49
|
}
|
|
55
|
-
return [
|
|
50
|
+
return [transports, waitForFlush];
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
const [
|
|
53
|
+
const [transports, waitForFlush] = getStreamsAndWaitForFlushPromise();
|
|
54
|
+
const level = config.LOGGER_DEBUG ? 'debug' : 'info';
|
|
55
|
+
const defaultMeta = {};
|
|
56
|
+
if (isLocal.indexOf('@echo') === -1) {
|
|
57
|
+
Object.assign(defaultMeta, devFlags());
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
} else {
|
|
60
|
+
Object.assign(defaultMeta, localFlags());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const winstonMainLogger = winston.createLogger({
|
|
64
|
+
levels: winston.config.syslog.levels,
|
|
65
|
+
level,
|
|
66
|
+
transports,
|
|
67
|
+
defaultMeta: { name: 'runner', hostname, nodeVersion: process.version, runnerVersion, ...defaultMeta },
|
|
63
68
|
});
|
|
64
69
|
|
|
65
70
|
let executionId = null;
|
|
@@ -77,8 +82,8 @@ function setProxyUri(proxyUri) {
|
|
|
77
82
|
if (config.IS_ON_PREM || !proxyUri) {
|
|
78
83
|
return;
|
|
79
84
|
}
|
|
80
|
-
const
|
|
81
|
-
|
|
85
|
+
const { CoralogixTransport } = require('../lib/coralogix-winston.transport');
|
|
86
|
+
CoralogixTransport.configure({ ...loggerConfig, proxyUri });
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
function releaseFlags() {
|
|
@@ -102,53 +107,58 @@ function localFlags() {
|
|
|
102
107
|
};
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
function
|
|
106
|
-
|
|
110
|
+
function addExecutionMetadata(dataExecutionId) {
|
|
111
|
+
const logData = {};
|
|
112
|
+
if (executionId && !dataExecutionId) {
|
|
107
113
|
logData.executionId = executionId;
|
|
108
114
|
}
|
|
109
115
|
|
|
110
|
-
logData.runnerVersion = runnerVersion;
|
|
111
116
|
logData.projectId = projectId;
|
|
112
|
-
logData.
|
|
113
|
-
|
|
114
|
-
if (isLocal.indexOf('@echo') === -1) {
|
|
115
|
-
Object.assign(logData, devFlags());
|
|
116
|
-
|
|
117
|
+
logData.time = (new Date()).toISOString();
|
|
117
118
|
|
|
118
|
-
return logData;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
Object.assign(logData, localFlags());
|
|
122
119
|
return logData;
|
|
123
120
|
}
|
|
124
121
|
|
|
125
122
|
class Logger {
|
|
126
123
|
constructor(logger) {
|
|
127
124
|
this._logger = logger;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.
|
|
125
|
+
this.debug = this.debug.bind(this);
|
|
126
|
+
this.info = this.info.bind(this);
|
|
127
|
+
this.warn = this.warn.bind(this);
|
|
128
|
+
this.error = this.error.bind(this);
|
|
129
|
+
this.fatal = this.fatal.bind(this);
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
debug(msg, data = {}) {
|
|
135
|
-
this.
|
|
133
|
+
this.innerLog('debug', msg, data);
|
|
136
134
|
}
|
|
137
135
|
|
|
138
136
|
info(msg, data = {}) {
|
|
139
|
-
this.
|
|
137
|
+
this.innerLog('info', msg, data);
|
|
140
138
|
}
|
|
141
139
|
|
|
142
140
|
warn(msg, data = {}) {
|
|
143
|
-
this.
|
|
141
|
+
this.innerLog('warning', msg, data);
|
|
144
142
|
}
|
|
145
143
|
|
|
146
144
|
error(msg, data = {}) {
|
|
147
|
-
this.
|
|
145
|
+
this.innerLog('error', msg, data);
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
fatal(msg, data = {}) {
|
|
151
|
-
this.
|
|
149
|
+
this.innerLog('crit', msg, data);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
innerLog(level, msg, data = {}) {
|
|
153
|
+
try {
|
|
154
|
+
this._logger.log(level, Object.assign({ meta: data }, { message: msg }, addExecutionMetadata(data.executionId)));
|
|
155
|
+
} catch (err) {
|
|
156
|
+
try {
|
|
157
|
+
this._logger.log('crit', Object.assign({ message: `failed to log message ${err.message}, ${err.stack}` }, addExecutionMetadata(data.executionId)));
|
|
158
|
+
} catch (err) {
|
|
159
|
+
// well what can we do
|
|
160
|
+
}
|
|
161
|
+
}
|
|
152
162
|
}
|
|
153
163
|
|
|
154
164
|
waitForFlush() {
|
|
@@ -157,7 +167,7 @@ class Logger {
|
|
|
157
167
|
}
|
|
158
168
|
|
|
159
169
|
function getLogger(loggerName) {
|
|
160
|
-
return new Logger(
|
|
170
|
+
return new Logger(winstonMainLogger.child({ category: loggerName }));
|
|
161
171
|
}
|
|
162
172
|
|
|
163
173
|
module.exports = {
|
|
@@ -428,6 +428,19 @@ function addTestRetry({
|
|
|
428
428
|
}), DEFAULT_REQUEST_RETRY);
|
|
429
429
|
}
|
|
430
430
|
|
|
431
|
+
/**
|
|
432
|
+
* @param {string} projectId
|
|
433
|
+
* @returns {Promise<import('../../../clickim/src/common/api/testimApplitoolsApi').ApplitoolsIntegrationData>}
|
|
434
|
+
*/
|
|
435
|
+
function getApplitoolsIntegrationData(projectId) {
|
|
436
|
+
try {
|
|
437
|
+
return getWithAuth(`/integration/applitools/v3/connected?projectId=${projectId}`);
|
|
438
|
+
} catch (err) {
|
|
439
|
+
logger.warn('could\'nt get applitools integration data.', { err });
|
|
440
|
+
return {};
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
431
444
|
module.exports = {
|
|
432
445
|
getS3Artifact,
|
|
433
446
|
getTestPlan,
|
|
@@ -459,4 +472,5 @@ module.exports = {
|
|
|
459
472
|
getHybridGridProvider,
|
|
460
473
|
loadTest,
|
|
461
474
|
isTestResultCompleted,
|
|
475
|
+
getApplitoolsIntegrationData,
|
|
462
476
|
};
|
package/executionQueue.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const TestRun = require('./testRunHandler.js');
|
|
4
4
|
|
|
5
5
|
class ExecutionQueue {
|
|
6
|
-
constructor(executionId, testList, options, branchToUse, testStatus) {
|
|
7
|
-
this._waitingTests = testList.map(testInfo => new TestRun(executionId, testInfo, options, branchToUse, testStatus));
|
|
6
|
+
constructor(executionId, executionName, testList, options, branchToUse, testStatus) {
|
|
7
|
+
this._waitingTests = testList.map(testInfo => new TestRun(executionId, executionName, testInfo, options, branchToUse, testStatus));
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
getNext() {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const { Log, Severity, CoralogixLogger } = require('@testim/coralogix-logger');
|
|
2
|
+
const TransportStream = require('winston-transport');
|
|
3
|
+
|
|
4
|
+
const severityMap = {
|
|
5
|
+
silly: Severity.verbose,
|
|
6
|
+
verbose: Severity.verbose,
|
|
7
|
+
info: Severity.info,
|
|
8
|
+
http: Severity.info,
|
|
9
|
+
warn: Severity.warning,
|
|
10
|
+
warning: Severity.warning,
|
|
11
|
+
error: Severity.error,
|
|
12
|
+
silent: Severity.verbose,
|
|
13
|
+
critical: Severity.critical,
|
|
14
|
+
crit: Severity.critical,
|
|
15
|
+
debug: Severity.debug,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
class CoralogixTransport extends TransportStream {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
options = Object.assign({}, CoralogixTransport.options, options);
|
|
21
|
+
super(options);
|
|
22
|
+
this.options = options;
|
|
23
|
+
this.logger = new CoralogixLogger(options.category);
|
|
24
|
+
this.name = 'Coralogix Transport';
|
|
25
|
+
if (options.timestamp) {
|
|
26
|
+
this.timestamp = options.timestamp;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
log(info, callback) {
|
|
31
|
+
const { category, level, message: msg, meta: infoMeta = {}, ...restMeta } = info;
|
|
32
|
+
const meta = Object.assign({}, infoMeta, this.options.extraFields, restMeta);
|
|
33
|
+
const log = new Log();
|
|
34
|
+
|
|
35
|
+
log.severity = severityMap[level];
|
|
36
|
+
log.text = msg;
|
|
37
|
+
log.category = category;
|
|
38
|
+
if (meta.className) {
|
|
39
|
+
log.className = meta.className;
|
|
40
|
+
}
|
|
41
|
+
if (meta.methodName) {
|
|
42
|
+
log.methodName = meta.methodName;
|
|
43
|
+
}
|
|
44
|
+
if (meta.threadId) {
|
|
45
|
+
log.threadId = meta.threadId;
|
|
46
|
+
}
|
|
47
|
+
delete meta.className;
|
|
48
|
+
delete meta.methodName;
|
|
49
|
+
delete meta.threadId;
|
|
50
|
+
delete meta.category;
|
|
51
|
+
delete meta.level;
|
|
52
|
+
delete meta.message;
|
|
53
|
+
let errorOverride = false;
|
|
54
|
+
if (infoMeta instanceof Error) {
|
|
55
|
+
errorOverride = true;
|
|
56
|
+
meta.msg = infoMeta.message + infoMeta.stack;
|
|
57
|
+
if (msg) {
|
|
58
|
+
meta.msg = `${msg}\n${meta.msg}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (infoMeta.err instanceof Error) {
|
|
62
|
+
meta.err = {
|
|
63
|
+
message: infoMeta.err.message,
|
|
64
|
+
stack: infoMeta.err.stack,
|
|
65
|
+
name: infoMeta.err.name,
|
|
66
|
+
type: infoMeta.err.type,
|
|
67
|
+
cause: infoMeta.err.cause,
|
|
68
|
+
...infoMeta.err,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (infoMeta.reason instanceof Error) {
|
|
73
|
+
meta.reason = {
|
|
74
|
+
message: infoMeta.reason.message,
|
|
75
|
+
stack: infoMeta.reason.stack,
|
|
76
|
+
name: infoMeta.reason.name,
|
|
77
|
+
type: infoMeta.reason.type,
|
|
78
|
+
cause: infoMeta.reason.cause,
|
|
79
|
+
...infoMeta.reason,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// still have keys after deleting the above
|
|
84
|
+
if (Object.keys(meta).length > 0) {
|
|
85
|
+
if (msg && !errorOverride) {
|
|
86
|
+
meta.msg = msg;
|
|
87
|
+
}
|
|
88
|
+
log.text = meta;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
this.logger.addLog(log);
|
|
92
|
+
callback(null, true);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
waitForFlush() {
|
|
96
|
+
return this.logger.waitForFlush();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static configure(config) {
|
|
100
|
+
CoralogixLogger.configure(config);
|
|
101
|
+
CoralogixTransport.options = config;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports.CoralogixTransport = CoralogixTransport;
|