suitest-js-api 3.1.3 → 3.2.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/index.d.ts CHANGED
@@ -85,8 +85,8 @@ declare namespace suitest {
85
85
  pollUrl(url: string, response: string): PollUrlChain;
86
86
  position(x: number, y: number): PositionChain;
87
87
  relativePosition(x: number, y: number): RelativePosition;
88
- press(key: string): PressButtonChain;
89
- press(keys: string[]): PressButtonChain;
88
+ press(key: string, options?: { longPressMs?: string | number }): PressButtonChain;
89
+ press(keys: string[], options?: { longPressMs?: string | number }): PressButtonChain;
90
90
  sleep(milliseconds: number): SleepChain;
91
91
  window(): WindowChain;
92
92
 
@@ -190,8 +190,8 @@ declare namespace suitest {
190
190
  pollUrl(url: string, response: string): PollUrlChain;
191
191
  position(x: number, y: number): PositionChain;
192
192
  relativePosition(x: number, y: number): RelativePosition;
193
- press(key: string): PressButtonChain;
194
- press(keys: string[]): PressButtonChain;
193
+ press(key: string, options?: { longPressMs?: string | number }): PressButtonChain;
194
+ press(keys: string[], options?: { longPressMs?: string | number }): PressButtonChain;
195
195
  runTest(testId: string): RunTestChain;
196
196
  sleep(milliseconds: number): SleepChain;
197
197
  window(): WindowChain;
@@ -20,16 +20,24 @@ const {validate, validators} = require('../validation');
20
20
  const {getRequestType} = require('../utils/socketChainHelper');
21
21
 
22
22
  const pressButtonFactory = (classInstance) => {
23
- const toJSON = (data) => ({
24
- type: getRequestType(data, false),
25
- request: compose(
26
- msg => applyUntilCondition(msg, data),
27
- msg => applyCountAndDelay(msg, data),
28
- )({
23
+ const toJSON = (data) => {
24
+ const base = {
29
25
  type: 'button',
30
26
  ids: data.ids,
31
- }),
32
- });
27
+ };
28
+
29
+ if (data.longPressMs !== undefined) {
30
+ base.longPressMs = data.longPressMs;
31
+ }
32
+
33
+ return {
34
+ type: getRequestType(data, false),
35
+ request: compose(
36
+ msg => applyUntilCondition(msg, data),
37
+ msg => applyCountAndDelay(msg, data),
38
+ )(base),
39
+ };
40
+ };
33
41
 
34
42
  const toStringComposer = makeToStringComposer(toJSON);
35
43
  const thenComposer = makeThenComposer(toJSON);
@@ -67,18 +75,34 @@ const pressButtonFactory = (classInstance) => {
67
75
  return output;
68
76
  };
69
77
 
70
- const pressButtonChain = buttonOrButtons => {
78
+ /**
79
+ * @param {string | string[]} buttonOrButtons
80
+ * @param {{longPressMs?: number}} [options]
81
+ * @returns {PressButtonChain}
82
+ */
83
+ const pressButtonChain = (buttonOrButtons, options = {}) => {
71
84
  const ids = Array.isArray(buttonOrButtons) ? buttonOrButtons : [buttonOrButtons];
72
85
 
73
86
  return makeChain(classInstance, getComposers, {
74
87
  type: 'press',
75
- ids: validate(validators.ARRAY_OF_BUTTONS, ids, invalidInputMessage('pressButton', 'Illegal button ids.')),
88
+ ids: validate(
89
+ validators.ARRAY_OF_BUTTONS,
90
+ ids,
91
+ invalidInputMessage('pressButton', 'Illegal button ids.'),
92
+ ),
93
+ longPressMs: options.longPressMs !== undefined
94
+ ? validate(
95
+ validators.ST_VAR_OR_POSITIVE_NUMBER,
96
+ options.longPressMs,
97
+ invalidInputMessage('pressButton', 'Invalid longPressMs'),
98
+ )
99
+ : undefined,
76
100
  });
77
101
  };
78
102
 
79
103
  return {
80
104
  pressButton: pressButtonChain,
81
- pressButtonAssert: buttonOrButtons => pressButtonChain(buttonOrButtons).toAssert(),
105
+ pressButtonAssert: (...args) => pressButtonChain(...args).toAssert(),
82
106
 
83
107
  // For testing
84
108
  toJSON,
@@ -17,33 +17,40 @@ const path = require('path');
17
17
  const PRESETS = 'presets';
18
18
  const APP_NAME = 'suitest';
19
19
  const ETC_DIR = '/etc';
20
- const IS_WIN = process.platform === 'win32';
21
- const HOME_DIR = IS_WIN
20
+ const IS_WINDOWS = process.platform === 'win32';
21
+ const HOME_DIR = IS_WINDOWS
22
22
  ? process.env.USERPROFILE
23
23
  : process.env.HOME;
24
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`,
25
+ const CONFIG_FORMATS = [
26
+ '.js',
27
+ '.json',
28
+ '.yaml',
29
+ '.yml',
30
+ '.json5',
31
+ '.ini',
33
32
  ];
34
33
 
35
34
  /**
36
- * @description should repeat lookup logic from rc library
37
- * @type {string[]}
35
+ * @description default directories to search. Logic the same as in rc
36
+ * @type {
37
+ * {
38
+ * path: string,
39
+ * filename: string,
40
+ * deepSearch: boolean,
41
+ * isGeneral: boolean
42
+ * } []
43
+ * }
38
44
  */
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(),
45
+ const DEFAULT_PATHS = [
46
+ {path: process.cwd(), filename: `.${APP_NAME}rc`, deepSearch: true, isGeneral: true},
47
+ {path: path.join(HOME_DIR, '.config', APP_NAME), filename: 'config', deepSearch: false, isGeneral: true},
48
+ {path: path.join(HOME_DIR, '.config'), filename: APP_NAME, deepSearch: false, isGeneral: true},
49
+ {path: path.join(HOME_DIR, `.${APP_NAME}`), filename: 'config', deepSearch: false, isGeneral: true},
50
+ {path: HOME_DIR, filename: `.${APP_NAME}rc`, deepSearch: false, isGeneral: true},
51
+
52
+ {path: path.join(ETC_DIR, APP_NAME), filename: 'config', deepSearch: false, isGeneral: false},
53
+ {path: ETC_DIR, filename: `${APP_NAME}rc`, deepSearch: false, isGeneral: false},
47
54
  ];
48
55
 
49
56
  /**
@@ -109,34 +116,73 @@ function findExtendConfigs(defaultConfigObject, extendPath, filePath, foundPaths
109
116
  return mainConfigFile;
110
117
  }
111
118
 
119
+ /**
120
+ * @description Search for configuration files.
121
+ * @param {String} pathToSearch path to directory to search
122
+ * @param {String} filename base filename without extension
123
+ */
124
+ function findConfig(pathToSearch, filename) {
125
+ if (!fs.existsSync(pathToSearch)) {
126
+ return;
127
+ }
128
+ const files = fs.readdirSync(pathToSearch);
129
+ const file = files.find(file => {
130
+ const {name, ext} = path.parse(file);
131
+
132
+ return name === filename && (CONFIG_FORMATS.includes(ext) || !ext);
133
+ });
134
+
135
+ return file ? path.join(pathToSearch, file) : undefined;
136
+ }
137
+
138
+ /**
139
+ * @description Search for configuration files up to the root.
140
+ * @param {String} pathToSearch path to directory to search
141
+ * @param {String} filename base filename without extension
142
+ */
143
+ function findConfigUpToRoot(pathToSearch, filename) {
144
+ const foundConfigFile = findConfig(pathToSearch, filename);
145
+
146
+ if (foundConfigFile || path.parse(pathToSearch).root === pathToSearch) {
147
+ return foundConfigFile;
148
+ }
149
+
150
+ return findConfigUpToRoot(path.join(pathToSearch, '../'), filename);
151
+ }
152
+
112
153
  /**
113
154
  * Read `.suitestrc` launcher config file.
155
+ * Also, searches for default RC paths.
114
156
  * If file not found, return empty object.
115
- * Supports json and ini formats.
157
+ * Supports json, json5, js, yaml, yml, ini formats.
158
+ * Searches for 'extends' property for other config file and if presents merge them.
116
159
  * cli arguments are not parsed.
117
160
  * If file found, but json invalid, throw error.
118
161
  * @returns {Object}
119
162
  */
120
163
  function readRcConfig(pathToConfig) {
121
164
  let mainConfigFilePath = '';
122
- const foundFiles = [];
123
165
 
124
166
  if (pathToConfig) {
125
- foundFiles.push(pathToConfig);
126
167
  mainConfigFilePath = pathToConfig;
127
168
  } 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
- }
169
+ const defaultConfigurations = DEFAULT_PATHS
170
+ .filter(defaultConfig => IS_WINDOWS ? defaultConfig.isGeneral : true);
171
+
172
+ for (const defaultConfig of defaultConfigurations) {
173
+ if (mainConfigFilePath) {
174
+ break;
138
175
  }
139
- });
176
+ if (
177
+ fs.existsSync(defaultConfig.path) &&
178
+ fs.lstatSync(defaultConfig.path).isDirectory()
179
+ ) {
180
+ mainConfigFilePath = (
181
+ defaultConfig.deepSearch ?
182
+ findConfigUpToRoot :
183
+ findConfig)(defaultConfig.path, defaultConfig.filename);
184
+ }
185
+ }
140
186
  }
141
187
 
142
188
  if (!mainConfigFilePath) {
@@ -151,17 +197,15 @@ function readRcConfig(pathToConfig) {
151
197
  configFile,
152
198
  configFile.extends,
153
199
  mainConfigFilePath,
154
- [foundFiles[0]],
200
+ [mainConfigFilePath],
155
201
  ),
156
- configs: foundFiles,
157
- config: foundFiles[0],
202
+ config: mainConfigFilePath,
158
203
  };
159
204
  }
160
205
 
161
206
  return {
162
207
  ...configFile,
163
- configs: foundFiles,
164
- config: foundFiles[0],
208
+ config: mainConfigFilePath,
165
209
  };
166
210
  }
167
211
 
package/lib/texts.js CHANGED
@@ -149,6 +149,7 @@ ${leaves}`,
149
149
  'commandError.timeout': () => 'Failed to take a screenshot due to timeout.',
150
150
  'commandError.generalError': () => 'Failed to take a screenshot.',
151
151
  'commandError.notSupportedDriver': () => 'Screenshots are not supported on this driver.',
152
+ 'commandError.screenshotFailed': () => 'Error while taking screenshot of device. Saved file does not exists or is not readable.',
152
153
 
153
154
  executorStopped: () => 'Test execution was stopped. See our documentation for possible reasons: https://suite.st/docs/error-messages/results-errors/#test-execution-was-stopped',
154
155
 
@@ -99,6 +99,7 @@ const commandErrors = {
99
99
  'timeout': () => t['commandError.timeout'](),
100
100
  'generalError': () => t['commandError.generalError'](),
101
101
  'notSupportedDriver': () => t['commandError.notSupportedDriver'](),
102
+ 'screenshotFailed': () => t['commandError.screenshotFailed'](),
102
103
  };
103
104
 
104
105
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suitest-js-api",
3
- "version": "3.1.3",
3
+ "version": "3.2.0",
4
4
  "main": "index.js",
5
5
  "repository": "git@github.com:SuitestAutomation/suitest-js-api.git",
6
6
  "author": "Suitest <hello@suite.st>",
@@ -85,7 +85,7 @@
85
85
  },
86
86
  "dependencies": {
87
87
  "@suitest/smst-to-text": "^4.4.3",
88
- "@suitest/translate": "^4.4.3",
88
+ "@suitest/translate": "^4.4.4",
89
89
  "@types/node": "^14.0.10",
90
90
  "ajv": "^6.12.2",
91
91
  "ansi-regex": "^5.0.0",