suitest-js-api 2.5.2 → 3.0.3
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/config/index.js +7 -7
- package/index.d.ts +23 -71
- package/lib/api/endpoints.js +0 -7
- package/lib/api/webSockets.js +1 -1
- package/lib/api/wsContentTypes.js +0 -2
- package/lib/chains/elementChain.js +90 -19
- package/lib/chains/saveScreenshotChain.js +60 -5
- package/lib/commands/closeSession.js +4 -29
- package/lib/commands/openSession.js +13 -52
- package/lib/commands/pairDevice.js +3 -3
- package/lib/commands/releaseDevice.js +1 -1
- package/lib/commands/setAppConfig.js +0 -2
- package/lib/commands/{interactive.js → startREPL.js} +10 -8
- package/lib/composers/attributesComposer.js +18 -0
- package/lib/composers/cssPropsComposer.js +18 -0
- package/lib/composers/handleComposer.js +23 -0
- package/lib/composers/index.js +6 -0
- package/lib/composers/thenComposer.js +1 -2
- package/lib/constants/composer.js +3 -0
- package/lib/constants/element.js +2 -0
- package/lib/constants/enviroment.js +6 -1
- package/lib/constants/index.js +1 -0
- package/lib/constants/ipcMessageId.js +1 -1
- package/lib/constants/modes.js +1 -2
- package/lib/constants/session.js +1 -3
- package/lib/constants/timestamp.js +1 -1
- package/lib/constants/validationKeys.js +5 -5
- package/lib/constants/vrc.js +2 -0
- package/lib/testLauncher/SuitestLauncher.js +65 -77
- package/lib/testLauncher/buildArgs.js +3 -6
- package/lib/testLauncher/commands/run.js +111 -0
- package/lib/testLauncher/composeConfig.js +154 -15
- package/lib/testLauncher/launcherLogger.js +3 -23
- package/lib/testLauncher/processArgs.js +1 -1
- package/lib/testLauncher/repl.js +3 -3
- package/lib/texts.js +18 -39
- package/lib/utils/AuthContext.js +17 -76
- package/lib/utils/getDeviceInfo.js +16 -10
- package/lib/utils/logger.js +4 -3
- package/lib/utils/{interactiveProgressHandler.js → progressHandler.js} +1 -1
- package/lib/utils/sentry/Raven.js +1 -1
- package/lib/utils/sessionStarter.js +43 -38
- package/lib/utils/socketChainHelper.js +17 -8
- package/lib/utils/stackTraceParser.js +25 -1
- package/lib/utils/testHelpers/mockHelpers.js +0 -2
- package/lib/utils/testHelpers/mockWebSocket.js +1 -1
- package/lib/utils/testHelpers/testLauncherTest.js +0 -43
- package/lib/utils/testLauncherHelper.js +38 -105
- package/lib/validation/elementPropTypes.js +2 -0
- package/lib/validation/jsonSchemas.js +97 -97
- package/lib/validation/validators.js +25 -3
- package/lib/validation/validatorsMap.js +13 -13
- package/package.json +7 -5
- package/suitest.js +7 -15
- package/typeDefinition/ElementChain.d.ts +29 -1
- package/typeDefinition/constants/Element.d.ts +2 -0
- package/typeDefinition/constants/Vrc.d.ts +2 -0
- package/typeDefinition/modifiers.d.ts +13 -0
- package/lib/commands/endTest.js +0 -28
- package/lib/commands/startTest.js +0 -55
- package/lib/commands/startTestPack.js +0 -93
- package/lib/testLauncher/commands/automated.js +0 -70
- package/lib/testLauncher/commands/common.js +0 -43
- package/lib/testLauncher/commands/interactive.js +0 -70
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const {once} = require('ramda');
|
|
2
|
+
const {composeConfig} = require('../composeConfig');
|
|
3
|
+
const texts = require('../../texts');
|
|
4
|
+
const logLevels = require('../../constants/logLevels');
|
|
5
|
+
const SuitestLauncher = require('../SuitestLauncher');
|
|
6
|
+
const suitest = require('../../../index');
|
|
7
|
+
|
|
8
|
+
const command = 'run';
|
|
9
|
+
const describe = 'Command for start testing';
|
|
10
|
+
|
|
11
|
+
const builder = yargs => {
|
|
12
|
+
yargs
|
|
13
|
+
.option('token-id', {
|
|
14
|
+
alias: 'k',
|
|
15
|
+
describe: 'Suitest Token Key, can be generated on the profile page',
|
|
16
|
+
global: false,
|
|
17
|
+
})
|
|
18
|
+
.option('token-password', {
|
|
19
|
+
alias: 'p',
|
|
20
|
+
describe: 'Suitest Token Password, can be generated on the profile page',
|
|
21
|
+
global: false,
|
|
22
|
+
})
|
|
23
|
+
.option('device-id', {
|
|
24
|
+
alias: 'd',
|
|
25
|
+
describe: 'Device you want to connect to',
|
|
26
|
+
global: false,
|
|
27
|
+
})
|
|
28
|
+
.option('app-config-id', {
|
|
29
|
+
alias: 'c',
|
|
30
|
+
describe: 'Application configuration id to launch the app with',
|
|
31
|
+
global: false,
|
|
32
|
+
})
|
|
33
|
+
.option('preset', {
|
|
34
|
+
describe: 'Preset for configuration and device.',
|
|
35
|
+
array: true,
|
|
36
|
+
global: false,
|
|
37
|
+
})
|
|
38
|
+
.option('inspect', {
|
|
39
|
+
describe: 'Will launch user command with --inspect execArgv, used for debugging',
|
|
40
|
+
global: false,
|
|
41
|
+
})
|
|
42
|
+
.option('inspect-brk', {
|
|
43
|
+
describe: 'Will launch user command with --inspect-brk execArgv, used for debugging',
|
|
44
|
+
global: false,
|
|
45
|
+
})
|
|
46
|
+
.option('config-file', {
|
|
47
|
+
describe: texts.cliConfig(),
|
|
48
|
+
global: false,
|
|
49
|
+
type: 'string',
|
|
50
|
+
})
|
|
51
|
+
.option('default-timeout', {
|
|
52
|
+
describe: texts.defaultTimeout(),
|
|
53
|
+
global: false,
|
|
54
|
+
type: 'number',
|
|
55
|
+
})
|
|
56
|
+
.option('disallow-crash-reports', {
|
|
57
|
+
describe: texts.cliDisallowCrashReports(),
|
|
58
|
+
global: false,
|
|
59
|
+
type: 'boolean',
|
|
60
|
+
})
|
|
61
|
+
.option('log-dir', {
|
|
62
|
+
describe: texts['tl.logDirDescription'](),
|
|
63
|
+
global: false,
|
|
64
|
+
})
|
|
65
|
+
.option('log-level', {
|
|
66
|
+
describe: texts.cliLogLevel(),
|
|
67
|
+
global: false,
|
|
68
|
+
choices: Object.values(logLevels),
|
|
69
|
+
})
|
|
70
|
+
.option('timestamp', {
|
|
71
|
+
describe: texts.cliTimestamp(),
|
|
72
|
+
global: false,
|
|
73
|
+
type: 'string',
|
|
74
|
+
})
|
|
75
|
+
.option('screenshot-dir', {
|
|
76
|
+
describe: 'Directory for saving screenshots.',
|
|
77
|
+
global: false,
|
|
78
|
+
type: 'string',
|
|
79
|
+
})
|
|
80
|
+
.option('concurrency', {
|
|
81
|
+
describe: 'How many parallel sessions of the test runner should be spawned. '
|
|
82
|
+
+ 'I.e. on how many devices will it run in parallel. 0 = unlimited',
|
|
83
|
+
default: 0,
|
|
84
|
+
global: false,
|
|
85
|
+
})
|
|
86
|
+
.option('include-changelist', {
|
|
87
|
+
describe: 'If unapplied changes should be tested with runSnippet command.',
|
|
88
|
+
boolean: true,
|
|
89
|
+
default: false,
|
|
90
|
+
global: false,
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const handler = async(argv) => {
|
|
95
|
+
const {ownArgs, userCommandArgs} = composeConfig(argv);
|
|
96
|
+
|
|
97
|
+
suitest.configuration.override(ownArgs);
|
|
98
|
+
|
|
99
|
+
const suitestLauncher = new SuitestLauncher(ownArgs, userCommandArgs);
|
|
100
|
+
|
|
101
|
+
await suitestLauncher.runTokenSession();
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/* istanbul ignore next */
|
|
105
|
+
module.exports = {
|
|
106
|
+
command,
|
|
107
|
+
describe,
|
|
108
|
+
builder,
|
|
109
|
+
// Make sure async handler is called only once (yargs bug)
|
|
110
|
+
handler: global._suitestTesting ? handler : once(handler),
|
|
111
|
+
};
|
|
@@ -1,11 +1,113 @@
|
|
|
1
|
-
|
|
1
|
+
// TODO: add test coverage for file
|
|
2
|
+
|
|
2
3
|
const {pickNonNil} = require('../utils/common');
|
|
3
4
|
const {hideOwnArgs} = require('./processArgs');
|
|
4
5
|
const suitest = require('../../index');
|
|
5
6
|
const fs = require('fs');
|
|
6
|
-
const rc = require('rc');
|
|
7
7
|
const SuitestError = require('../utils/SuitestError');
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
invalidUserConfig,
|
|
10
|
+
circularDependencyError,
|
|
11
|
+
} = require('../texts');
|
|
12
|
+
const yaml = require('js-yaml');
|
|
13
|
+
const JSON5 = require('json5');
|
|
14
|
+
const ini = require('ini');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
const PRESETS = 'presets';
|
|
18
|
+
const APP_NAME = 'suitest';
|
|
19
|
+
const ETC_DIR = '/etc';
|
|
20
|
+
const IS_WIN = process.platform === 'win32';
|
|
21
|
+
const HOME_DIR = IS_WIN
|
|
22
|
+
? process.env.USERPROFILE
|
|
23
|
+
: process.env.HOME;
|
|
24
|
+
|
|
25
|
+
const CONFIG_FILES = [
|
|
26
|
+
`.${APP_NAME}rc.js`,
|
|
27
|
+
`.${APP_NAME}rc.json`,
|
|
28
|
+
`.${APP_NAME}rc.yaml`,
|
|
29
|
+
`.${APP_NAME}rc.yml`,
|
|
30
|
+
`.${APP_NAME}rc.json5`,
|
|
31
|
+
`.${APP_NAME}rc.ini`,
|
|
32
|
+
`.${APP_NAME}rc`,
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @description should repeat lookup logic from rc library
|
|
37
|
+
* @type {string[]}
|
|
38
|
+
*/
|
|
39
|
+
const LOOKUP_DIRS = [
|
|
40
|
+
path.join(HOME_DIR, `.${APP_NAME}rc`),
|
|
41
|
+
path.join(HOME_DIR, `.${APP_NAME}`, 'config'),
|
|
42
|
+
path.join(HOME_DIR, '.config', APP_NAME),
|
|
43
|
+
path.join(HOME_DIR, '.config', APP_NAME, 'config'),
|
|
44
|
+
path.join(ETC_DIR, `.${APP_NAME}rc`),
|
|
45
|
+
path.join(ETC_DIR, APP_NAME, 'config'),
|
|
46
|
+
process.cwd(),
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @description Reads file from path and returns file as an object. Supports json, yaml, json5 and ini formats.
|
|
51
|
+
* @param {String} filePath path to file
|
|
52
|
+
*/
|
|
53
|
+
function readConfigFile(filePath) {
|
|
54
|
+
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
55
|
+
|
|
56
|
+
switch (path.extname(filePath)) {
|
|
57
|
+
case '.yaml':
|
|
58
|
+
case '.yml':
|
|
59
|
+
return yaml.load(fileContent);
|
|
60
|
+
case '.json5':
|
|
61
|
+
return JSON5.parse(fileContent);
|
|
62
|
+
case '.ini':
|
|
63
|
+
return ini.parse(fileContent);
|
|
64
|
+
case '.js':
|
|
65
|
+
return require(filePath);
|
|
66
|
+
default:
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(fileContent);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return ini.parse(fileContent);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @description Recursive search and merging for Extends configs
|
|
77
|
+
* @param {object} defaultConfigObject main configuration file object
|
|
78
|
+
* @param {String} extendPath extend path of other configuration file to merge with
|
|
79
|
+
* @param {String} filePath currently in read configuration file path
|
|
80
|
+
* @param {Array} foundPaths array of extends paths. Used to verify circular dependency
|
|
81
|
+
*/
|
|
82
|
+
function findExtendConfigs(defaultConfigObject, extendPath, filePath, foundPaths) {
|
|
83
|
+
const pathToConfig = path.join(path.dirname(filePath), extendPath);
|
|
84
|
+
|
|
85
|
+
if (foundPaths.includes(pathToConfig)) {
|
|
86
|
+
throw new SuitestError(circularDependencyError(pathToConfig));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const additionalConfigFile = readConfigFile(pathToConfig);
|
|
90
|
+
const mainConfigFile = {...additionalConfigFile};
|
|
91
|
+
|
|
92
|
+
Object.keys(defaultConfigObject).forEach((objKey) => {
|
|
93
|
+
if (objKey === PRESETS) {
|
|
94
|
+
mainConfigFile.presets = {...mainConfigFile[objKey], ...defaultConfigObject[objKey]};
|
|
95
|
+
} else {
|
|
96
|
+
mainConfigFile[objKey] = defaultConfigObject[objKey];
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
if ('extends' in additionalConfigFile) {
|
|
101
|
+
return findExtendConfigs(
|
|
102
|
+
mainConfigFile,
|
|
103
|
+
additionalConfigFile.extends,
|
|
104
|
+
pathToConfig,
|
|
105
|
+
[...foundPaths, pathToConfig],
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return mainConfigFile;
|
|
110
|
+
}
|
|
9
111
|
|
|
10
112
|
/**
|
|
11
113
|
* Read `.suitestrc` launcher config file.
|
|
@@ -15,16 +117,56 @@ const {invalidUserConfig} = require('../texts');
|
|
|
15
117
|
* If file found, but json invalid, throw error.
|
|
16
118
|
* @returns {Object}
|
|
17
119
|
*/
|
|
18
|
-
function readRcConfig() {
|
|
19
|
-
|
|
20
|
-
|
|
120
|
+
function readRcConfig(pathToConfig) {
|
|
121
|
+
let mainConfigFilePath = '';
|
|
122
|
+
const foundFiles = [];
|
|
123
|
+
|
|
124
|
+
if (pathToConfig) {
|
|
125
|
+
foundFiles.push(pathToConfig);
|
|
126
|
+
mainConfigFilePath = pathToConfig;
|
|
127
|
+
} else {
|
|
128
|
+
LOOKUP_DIRS.forEach((projectDir) => {
|
|
129
|
+
if (!mainConfigFilePath && fs.existsSync(projectDir)) {
|
|
130
|
+
const files = fs.readdirSync(projectDir)
|
|
131
|
+
.filter(fileName => CONFIG_FILES.includes(fileName))
|
|
132
|
+
.map(file => path.join(projectDir, file));
|
|
133
|
+
|
|
134
|
+
if (files.length > 0) {
|
|
135
|
+
mainConfigFilePath = files[0];
|
|
136
|
+
foundFiles.push(files[0]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!mainConfigFilePath) {
|
|
21
143
|
return {};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const configFile = readConfigFile(mainConfigFilePath);
|
|
147
|
+
|
|
148
|
+
if ('extends' in configFile) {
|
|
149
|
+
return {
|
|
150
|
+
...findExtendConfigs(
|
|
151
|
+
configFile,
|
|
152
|
+
configFile.extends,
|
|
153
|
+
mainConfigFilePath,
|
|
154
|
+
[foundFiles[0]],
|
|
155
|
+
),
|
|
156
|
+
configs: foundFiles,
|
|
157
|
+
config: foundFiles[0],
|
|
158
|
+
};
|
|
159
|
+
}
|
|
22
160
|
|
|
23
|
-
return
|
|
161
|
+
return {
|
|
162
|
+
...configFile,
|
|
163
|
+
configs: foundFiles,
|
|
164
|
+
config: foundFiles[0],
|
|
165
|
+
};
|
|
24
166
|
}
|
|
25
167
|
|
|
26
168
|
/**
|
|
27
|
-
* Read
|
|
169
|
+
* Read json config file provided by user.
|
|
28
170
|
* @param {string} path - path to config file
|
|
29
171
|
* @throws {SuitestError}
|
|
30
172
|
* @returns {Object} - parsed json
|
|
@@ -40,11 +182,10 @@ function readUserConfig(path) {
|
|
|
40
182
|
/**
|
|
41
183
|
* Compose config from rc file, user config file and cli args
|
|
42
184
|
* @param {Object} argv - yargs cli args object
|
|
43
|
-
* @param {boolean} askPassword - ask for password or not
|
|
44
185
|
* @returns {{ownArgs: Object, userCommandArgs: string[]}}
|
|
45
186
|
*/
|
|
46
|
-
const composeConfig =
|
|
47
|
-
const rcConfig = readRcConfig();
|
|
187
|
+
const composeConfig = (argv) => {
|
|
188
|
+
const rcConfig = readRcConfig(argv.configFile);
|
|
48
189
|
const configFilePath = argv.configFile || rcConfig.configFile;
|
|
49
190
|
const userConfig = configFilePath ? readUserConfig(configFilePath) : {};
|
|
50
191
|
|
|
@@ -55,10 +196,6 @@ const composeConfig = async(argv, askPassword) => {
|
|
|
55
196
|
};
|
|
56
197
|
const userCommandArgs = hideOwnArgs();
|
|
57
198
|
|
|
58
|
-
if (askPassword) {
|
|
59
|
-
ownArgs.password = ownArgs.password || await promptPassword();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
199
|
return {
|
|
63
200
|
ownArgs,
|
|
64
201
|
userCommandArgs,
|
|
@@ -66,6 +203,8 @@ const composeConfig = async(argv, askPassword) => {
|
|
|
66
203
|
};
|
|
67
204
|
|
|
68
205
|
module.exports = {
|
|
206
|
+
readConfigFile,
|
|
207
|
+
findExtendConfigs,
|
|
69
208
|
composeConfig,
|
|
70
209
|
readRcConfig,
|
|
71
210
|
readUserConfig,
|
|
@@ -6,26 +6,16 @@
|
|
|
6
6
|
const {stColors} = require('../utils/logger');
|
|
7
7
|
const {logger} = require('../../index');
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Log snipepts
|
|
11
|
-
*/
|
|
12
|
-
function deviceLines(devicesLines, deviceId, deviceName) {
|
|
13
|
-
logger.log('');
|
|
14
|
-
logger.log(`Test started on ${deviceName ? stColors.bold(deviceName) : deviceId}`);
|
|
15
|
-
devicesLines.forEach(log => logger.log(log.msg, deviceId));
|
|
16
|
-
logger.log(`Test finished on ${deviceName ? stColors.bold(deviceName) : deviceId}`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
9
|
function argsValidationError(error) {
|
|
20
10
|
logger.error(error);
|
|
21
11
|
logger.log('');
|
|
22
12
|
logger.log(
|
|
23
|
-
'Try running `suitest --help` to see usage information or consult our docs at https://suite.st/docs'
|
|
13
|
+
'Try running `suitest --help` to see usage information or consult our docs at https://suite.st/docs',
|
|
24
14
|
);
|
|
25
15
|
logger.log('');
|
|
26
16
|
}
|
|
27
17
|
|
|
28
|
-
function
|
|
18
|
+
function final(failedCount, succeededCount) {
|
|
29
19
|
logger.log('');
|
|
30
20
|
logger.log(
|
|
31
21
|
stColors.mild('Test ')
|
|
@@ -35,20 +25,10 @@ function finalAutomated(failedCount, succeededCount) {
|
|
|
35
25
|
logger.log('');
|
|
36
26
|
}
|
|
37
27
|
|
|
38
|
-
function finalInteractive(finishedWithErrors) {
|
|
39
|
-
logger.log('');
|
|
40
|
-
finishedWithErrors
|
|
41
|
-
? logger.error('Test finished with errors')
|
|
42
|
-
: logger.success('Test run completed successfully. Bye!');
|
|
43
|
-
logger.log('');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
28
|
module.exports = {
|
|
47
29
|
stColors,
|
|
48
30
|
snippets: {
|
|
49
31
|
argsValidationError,
|
|
50
|
-
|
|
51
|
-
finalAutomated,
|
|
52
|
-
finalInteractive,
|
|
32
|
+
final,
|
|
53
33
|
},
|
|
54
34
|
};
|
|
@@ -3,7 +3,7 @@ const parser = require('yargs-parser');
|
|
|
3
3
|
// Specify which options should be treated as boolen.
|
|
4
4
|
// This will enable setting boolean option value to true if not defined explicitly,
|
|
5
5
|
// eg: '--disallow-crash-reports' will be parsed as '--disallow-crash-reports=true'
|
|
6
|
-
const booleanOpts = ['disallow-crash-reports'];
|
|
6
|
+
const booleanOpts = ['disallow-crash-reports', 'include-changelist'];
|
|
7
7
|
const inspectOpts = ['inspect', 'inspect-brk'];
|
|
8
8
|
|
|
9
9
|
const parseOptions = argv => {
|
package/lib/testLauncher/repl.js
CHANGED
|
@@ -59,7 +59,7 @@ function setupRepl(opts, isTTY) {
|
|
|
59
59
|
|
|
60
60
|
const watcher = chokidar.watch(watch, {ignored, cwd}).on(
|
|
61
61
|
'change',
|
|
62
|
-
file => setTimeout(() => onFileChange(file, cwd, callFile, repeater), 50)
|
|
62
|
+
file => setTimeout(() => onFileChange(file, cwd, callFile, repeater), 50),
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
const prompt = 'Suitest $ ';
|
|
@@ -89,7 +89,7 @@ function setupRepl(opts, isTTY) {
|
|
|
89
89
|
* Module resolution is relative to cwd.
|
|
90
90
|
* @param {String} repeater - string representation of repeater
|
|
91
91
|
* @param {String} cwd - current working directory
|
|
92
|
-
* @param {string} callFilename - name of the file where "
|
|
92
|
+
* @param {string} callFilename - name of the file where "startREPL" was called.
|
|
93
93
|
* @returns {*}
|
|
94
94
|
*/
|
|
95
95
|
function repeaterFromString(repeater, cwd, callFilename) {
|
|
@@ -137,7 +137,7 @@ async function onFileChange(file, cwd, callFile, repeater) {
|
|
|
137
137
|
const funcBody = colors.white(getShortFunctionBody(func));
|
|
138
138
|
|
|
139
139
|
console.log(colors.magenta(
|
|
140
|
-
replFilesChanged(funcBody)
|
|
140
|
+
replFilesChanged(funcBody),
|
|
141
141
|
));
|
|
142
142
|
|
|
143
143
|
// Run the repeater without allowing the process to exit with an error
|
package/lib/texts.js
CHANGED
|
@@ -33,7 +33,6 @@ module.exports = {
|
|
|
33
33
|
// Auth errors
|
|
34
34
|
authNotAllowed: commandName => `You're not allowed to execute .${commandName} function. Make sure you're logged in with the correct credentials.`,
|
|
35
35
|
authFailed: () => 'Authentication failed. Make sure you\'re trying to login with correct credentials.',
|
|
36
|
-
authFailedAutomated: () => 'Authentication failed. Make sure your token is valid and exists.',
|
|
37
36
|
notWhitelistedIp: () => 'Unauthorized access - your IP address is not whitelisted. Please contact your Suitest administrator for more information.',
|
|
38
37
|
connectionNotEstablished: () => 'A session with the Suitest server was not established or was already closed. You need to open a session before you can execute test commands',
|
|
39
38
|
|
|
@@ -43,6 +42,7 @@ module.exports = {
|
|
|
43
42
|
`provided for .${methodName} function.` + (field ? ` ${field}` : ''),
|
|
44
43
|
invalidConfigObj: () => 'provided for configuration object.',
|
|
45
44
|
invalidUserConfig: template`Failed to process config file '${0}'.\n\t${1}.\n\tMake sure path is correct and file is in valid json format.`,
|
|
45
|
+
circularDependencyError: (path) => `Circular dependency found on ${path} path.`,
|
|
46
46
|
|
|
47
47
|
// WebSockets errors
|
|
48
48
|
wsNotConnected: () => 'Connection to Suitest has been interrupted. Please make sure you are online and double check your login credentials.',
|
|
@@ -53,7 +53,6 @@ module.exports = {
|
|
|
53
53
|
chainExpected: () => 'Until condition expects a chain as an input parameter',
|
|
54
54
|
invalidInheredProps: template`Matching properties against repo values works only for elements stored in repo.\nEither select the element by it's API-ID or specify property values to match against.\nAffected properties: ${0}`,
|
|
55
55
|
invalidVideoInheredProps: template`Matching properties against repo values works only for elements stored in repo. \nEither select the element by it's API-ID or specify property values to match against.\nAffected properties: ${0}`,
|
|
56
|
-
testPackNotFound: template`Test pack ${0} not found. If it is a new test pack, make sure version changes are applied.\nCheck https://suite.st/docs/versions/#changed-assets for more info.`,
|
|
57
56
|
|
|
58
57
|
/**
|
|
59
58
|
* @description SuitestError.SERVER_ERROR message
|
|
@@ -81,41 +80,31 @@ Put an "await" in front of those chains or call .abandon() to suppress these war
|
|
|
81
80
|
${leaves}`,
|
|
82
81
|
|
|
83
82
|
// test launcher
|
|
84
|
-
launcherGreeting: (version
|
|
83
|
+
launcherGreeting: (version) => {
|
|
85
84
|
const offsetInHours = (new Date()).getTimezoneOffset() / 60;
|
|
86
85
|
|
|
87
86
|
return '' +
|
|
88
87
|
`Hi there! This is Suitest test launcher v${version}.\n` +
|
|
89
|
-
|
|
88
|
+
'Preparing to start execution ...\n' +
|
|
90
89
|
`← Time logs are provided in local time zone (UTC${offsetInHours > 0 ? '-' : '+'}${Math.abs(offsetInHours)})\n\n`;
|
|
91
90
|
},
|
|
92
91
|
|
|
93
|
-
|
|
92
|
+
launcherSummary: (testCommand, executionLog, ...devices) => {
|
|
94
93
|
return '' +
|
|
95
|
-
`Test command: ${testCommand}\n` +
|
|
96
|
-
`Log directory: ${executionLog}\n` +
|
|
97
|
-
`Device: ${device}\n\n` +
|
|
98
|
-
|
|
99
|
-
'TIP: Assertions are marked with "A", chain evaluations are marked with "E", application console logs are marked as "AL".\n';
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
launcherSummaryAutomated: (testPackId, testCommand, executionLog, ...devices) => {
|
|
103
|
-
return '' +
|
|
104
|
-
`Test pack id: ${testPackId}\n` +
|
|
105
94
|
`Test command: ${testCommand}\n` +
|
|
106
|
-
`Log directory: ${executionLog}\n` +
|
|
95
|
+
(executionLog ? `Log directory: ${executionLog}\n` : '') +
|
|
107
96
|
'Devices: \n' +
|
|
108
|
-
` - ${devices.join('\n - ')}
|
|
97
|
+
` - ${devices.join('\n - ')}\n` +
|
|
98
|
+
'TIP: Assertions are marked with "A", chain evaluations are marked with "E", application console logs are marked as "AL".\n';
|
|
109
99
|
},
|
|
110
100
|
|
|
111
|
-
fileLogSummary: (testCommand, orgId, appConfigId,
|
|
101
|
+
fileLogSummary: (testCommand, orgId, appConfigId, startTime) => {
|
|
112
102
|
return '' +
|
|
113
103
|
'Suitest test execution log\n' +
|
|
114
104
|
'--------------------------\n\n' +
|
|
115
105
|
`- Date ${startTime}.\n` +
|
|
116
106
|
`- Organization ID: ${orgId}\n` +
|
|
117
107
|
`- App config ID: ${appConfigId}\n` +
|
|
118
|
-
(testPackId? `- Test pack ID: ${testPackId}\n` : '') +
|
|
119
108
|
`- Test command: ${testCommand}\n\n\n`;
|
|
120
109
|
},
|
|
121
110
|
|
|
@@ -134,16 +123,15 @@ ${leaves}`,
|
|
|
134
123
|
launcherWrongDeviceId: template`The deviceId ${0} is unknown. Device may have been deleted.`,
|
|
135
124
|
|
|
136
125
|
'tl.noArguments': () => 'Command was not specified',
|
|
137
|
-
'tl.seeMoreCommandsOptions': template`Run ${0}
|
|
126
|
+
'tl.seeMoreCommandsOptions': template`Run ${0} to see those commands options`,
|
|
138
127
|
'tl.finishedWithErrors': () => 'Some executions finished with errors',
|
|
139
128
|
'tl.finishedWithSuccess': () => 'All executions finished successfully',
|
|
140
|
-
'tl.promptPassword': () => 'Please enter your password: ',
|
|
141
129
|
'tl.failedToCreateDir': (code, path) => `${code} error occurred while creating a new directory "${path}"`,
|
|
142
130
|
'tl.createDirPermissionDenied': (path) => `Cannot create log file (${path}) Permission denied`,
|
|
143
131
|
'tl.executionMode': template`Execution mode: `,
|
|
144
132
|
'tl.cmdAttributionTip': template`\nTIP: Assertions are marked with "A", chain evaluations are marked with "E".`,
|
|
145
133
|
'tl.logDirDescription': () => 'If defined, additional logging to specified folder will be performed.',
|
|
146
|
-
'tl.
|
|
134
|
+
'tl.inspectOnlyForSingleDevice': () => 'Please connect to single device to enable debugging.',
|
|
147
135
|
'tl.differentLauncherAndLibVersions': template`The version of suitest library (${0}) provided from your script is different from suitest launcher (${1})`,
|
|
148
136
|
'tl.newVersionAvailable': template`New version (${0}) of Suitest JavaScript API is out, please upgrade: \`npm i suitest-js-api\``,
|
|
149
137
|
|
|
@@ -151,8 +139,10 @@ ${leaves}`,
|
|
|
151
139
|
'errorType.syntaxError.modifierMissing': template`${0} chain missing modifier.`,
|
|
152
140
|
'errorType.suitestCommand': template`provided for 'suitest ${0}' command. It`,
|
|
153
141
|
'errorType.suitestTestCommand': `Seems you forgot to provide a test command${EOL}check https://suite.st/docs/suitest-api/test-launcher/#usage for more info`,
|
|
154
|
-
'errorType.testPackNoDevices': () => 'There are no devices associated with this test pack.',
|
|
155
142
|
'errorType.testCannotBeFetched': (testId, mainTest) => `Test cannot be fetched test id: ${mainTest ? mainTest + ' > ... > ' + testId : testId}`,
|
|
143
|
+
'errorType.noDevices': () => 'There are no devices associated with current configuration',
|
|
144
|
+
'errorType.specifyRunningDevices': () => 'Please specify Configuration id and device id, or presets',
|
|
145
|
+
'errorType.notFoundPresets': (notFoundPresets) => `Presets ${notFoundPresets.join(', ')} were not found in your configuration`,
|
|
156
146
|
|
|
157
147
|
'commandError.notSupportedPlatform': () => 'Screenshots are not supported on this device.',
|
|
158
148
|
'commandError.timeout': () => 'Failed to take a screenshot due to timeout.',
|
|
@@ -167,15 +157,13 @@ ${leaves}`,
|
|
|
167
157
|
ipcFailedToCreateServer: template`Failed to create IPC server. Port ${0} is busy.`,
|
|
168
158
|
|
|
169
159
|
// suffixes
|
|
170
|
-
'suffix.sessionWillClose': () => 'Test session will now close and all remaining Suitest commands will fail.
|
|
160
|
+
'suffix.sessionWillClose': () => 'Test session will now close and all remaining Suitest commands will fail.',
|
|
171
161
|
|
|
172
162
|
// logger msg
|
|
173
|
-
commandExecuted: (name) => `command "${name}" was executed`,
|
|
174
163
|
sessionOpen: () => 'Connecting to Suitest ...',
|
|
175
164
|
sessionOpened: () => 'Connected to Suitest',
|
|
176
165
|
sessionClosing: () => 'Disconnecting from Suitest',
|
|
177
166
|
sessionClosed: () => 'Disconnected from Suitest',
|
|
178
|
-
commandWillBeExecuted: (name) => `command "${name}" will be executed`,
|
|
179
167
|
|
|
180
168
|
connectingToDevice: (name, id) => `Connecting to "${name}" (${id})`,
|
|
181
169
|
connectedToDevice: (name, id) => `Connected to "${name}" (${id})`,
|
|
@@ -186,17 +174,8 @@ ${leaves}`,
|
|
|
186
174
|
|
|
187
175
|
disconnectedFromDevice: () => 'Disconnected from device',
|
|
188
176
|
disconnectingFromDevice: () => 'Disconnecting from device',
|
|
189
|
-
testWillBeStarted: (name) => name ? `Test ${name} will be started` : 'New test will be started',
|
|
190
|
-
testWasStarted: (name) => name ? `Test ${name} was started` : 'New test was started',
|
|
191
|
-
testPackWillBeStarted: (name) => `Test pack ${name} will be started`,
|
|
192
|
-
testPackWasStarted: (name) => `Test pack ${name} was started`,
|
|
193
|
-
startTestDeprecate: () => '.startTest with arguments is deprecated',
|
|
194
|
-
|
|
195
|
-
// Warnings
|
|
196
|
-
warnConfigureDeprecation: () => '.configure() command is deprecated and will be removed soon. Use separete commands for each field or .suitestrc file or cli args for configuration.',
|
|
197
|
-
warnVideoAsElementDeprecation: () => '.element({video: true}) is deprecated and will be removed soon, use .video() instead.',
|
|
198
177
|
|
|
199
|
-
|
|
178
|
+
replWarn: () => 'Ignored the "startREPL" command. This command works only for single device.',
|
|
200
179
|
replWelcomeMessage: (vars, cwd, watch, repeater, varColor) => {
|
|
201
180
|
return '' +
|
|
202
181
|
'Test execution has been paused for the interactive session\n' +
|
|
@@ -219,11 +198,11 @@ ${leaves}`,
|
|
|
219
198
|
replFailedToRequire: template`Failed to require file ${0}. (You may need to update your "watch" parameter)`,
|
|
220
199
|
replIpcErrorInChildProcess: template`IPC error in child process `,
|
|
221
200
|
replIpcNotImplemented: template`IPC protocol not implemented for message: ${0}`,
|
|
222
|
-
replIpcNotAvailable: template`suitest.
|
|
201
|
+
replIpcNotAvailable: template`suitest.startREPL() command only works when used together with Suitest launcher.`,
|
|
223
202
|
replFailedToFindRepeater: template`Error: Failed to find the repeater "${0}".`,
|
|
224
203
|
replRepeaterNotAFunc: template`Error: Repeater "${0}" is not a function. Value: ${1}`,
|
|
225
|
-
replNotATty: template`You seem to be using suitest from a CLI that is not a TTY. Some features of suitest.
|
|
226
|
-
replWrongNodeVersion: template`Error: To use "suitest.
|
|
204
|
+
replNotATty: template`You seem to be using suitest from a CLI that is not a TTY. Some features of suitest.startREPL command may not work as expected. In case of problems try switching to the default system's CLI program, like bash on Linux or cmd on Windows. Sometimes replacing "suitest" command with "node node_modules/suitest-js-api/lib/testLauncher/" could help as well`,
|
|
205
|
+
replWrongNodeVersion: template`Error: To use "suitest.startREPL" you need NodeJS version v9.4 or newer. You are using ${0}. Please update.`,
|
|
227
206
|
|
|
228
207
|
// Cli args
|
|
229
208
|
cliLogLevel: () => `Logger verbosity level [default: "${logLevels.normal}"]`,
|