appium 2.0.0-beta.9 → 2.0.0-rc.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.
Files changed (208) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +149 -58
  3. package/build/lib/appium.d.ts +229 -0
  4. package/build/lib/appium.d.ts.map +1 -0
  5. package/build/lib/appium.js +677 -449
  6. package/build/lib/appium.js.map +1 -0
  7. package/build/lib/cli/args.d.ts +17 -0
  8. package/build/lib/cli/args.d.ts.map +1 -0
  9. package/build/lib/cli/args.js +263 -300
  10. package/build/lib/cli/args.js.map +1 -0
  11. package/build/lib/cli/driver-command.d.ts +102 -0
  12. package/build/lib/cli/driver-command.d.ts.map +1 -0
  13. package/build/lib/cli/driver-command.js +131 -81
  14. package/build/lib/cli/driver-command.js.map +1 -0
  15. package/build/lib/cli/extension-command.d.ts +402 -0
  16. package/build/lib/cli/extension-command.d.ts.map +1 -0
  17. package/build/lib/cli/extension-command.js +799 -383
  18. package/build/lib/cli/extension-command.js.map +1 -0
  19. package/build/lib/cli/extension.d.ts +23 -0
  20. package/build/lib/cli/extension.d.ts.map +1 -0
  21. package/build/lib/cli/extension.js +70 -68
  22. package/build/lib/cli/extension.js.map +1 -0
  23. package/build/lib/cli/parser.d.ts +84 -0
  24. package/build/lib/cli/parser.d.ts.map +1 -0
  25. package/build/lib/cli/parser.js +252 -148
  26. package/build/lib/cli/parser.js.map +1 -0
  27. package/build/lib/cli/plugin-command.d.ts +99 -0
  28. package/build/lib/cli/plugin-command.d.ts.map +1 -0
  29. package/build/lib/cli/plugin-command.js +125 -81
  30. package/build/lib/cli/plugin-command.js.map +1 -0
  31. package/build/lib/cli/utils.d.ts +29 -0
  32. package/build/lib/cli/utils.d.ts.map +1 -0
  33. package/build/lib/cli/utils.js +72 -51
  34. package/build/lib/cli/utils.js.map +1 -0
  35. package/build/lib/config-file.d.ts +100 -0
  36. package/build/lib/config-file.d.ts.map +1 -0
  37. package/build/lib/config-file.js +207 -0
  38. package/build/lib/config-file.js.map +1 -0
  39. package/build/lib/config.d.ts +49 -0
  40. package/build/lib/config.d.ts.map +1 -0
  41. package/build/lib/config.js +262 -223
  42. package/build/lib/config.js.map +1 -0
  43. package/build/lib/constants.d.ts +56 -0
  44. package/build/lib/constants.d.ts.map +1 -0
  45. package/build/lib/constants.js +73 -0
  46. package/build/lib/constants.js.map +1 -0
  47. package/build/lib/extension/driver-config.d.ts +82 -0
  48. package/build/lib/extension/driver-config.d.ts.map +1 -0
  49. package/build/lib/extension/driver-config.js +210 -0
  50. package/build/lib/extension/driver-config.js.map +1 -0
  51. package/build/lib/extension/extension-config.d.ts +270 -0
  52. package/build/lib/extension/extension-config.d.ts.map +1 -0
  53. package/build/lib/extension/extension-config.js +601 -0
  54. package/build/lib/extension/extension-config.js.map +1 -0
  55. package/build/lib/extension/index.d.ts +48 -0
  56. package/build/lib/extension/index.d.ts.map +1 -0
  57. package/build/lib/extension/index.js +105 -0
  58. package/build/lib/extension/index.js.map +1 -0
  59. package/build/lib/extension/manifest-migrations.d.ts +27 -0
  60. package/build/lib/extension/manifest-migrations.d.ts.map +1 -0
  61. package/build/lib/extension/manifest-migrations.js +134 -0
  62. package/build/lib/extension/manifest-migrations.js.map +1 -0
  63. package/build/lib/extension/manifest.d.ts +145 -0
  64. package/build/lib/extension/manifest.d.ts.map +1 -0
  65. package/build/lib/extension/manifest.js +528 -0
  66. package/build/lib/extension/manifest.js.map +1 -0
  67. package/build/lib/extension/package-changed.d.ts +11 -0
  68. package/build/lib/extension/package-changed.d.ts.map +1 -0
  69. package/build/lib/extension/package-changed.js +62 -0
  70. package/build/lib/extension/package-changed.js.map +1 -0
  71. package/build/lib/extension/plugin-config.d.ts +56 -0
  72. package/build/lib/extension/plugin-config.d.ts.map +1 -0
  73. package/build/lib/extension/plugin-config.js +102 -0
  74. package/build/lib/extension/plugin-config.js.map +1 -0
  75. package/build/lib/grid-register.d.ts +10 -0
  76. package/build/lib/grid-register.d.ts.map +1 -0
  77. package/build/lib/grid-register.js +122 -144
  78. package/build/lib/grid-register.js.map +1 -0
  79. package/build/lib/logger.d.ts +3 -0
  80. package/build/lib/logger.d.ts.map +1 -0
  81. package/build/lib/logger.js +5 -17
  82. package/build/lib/logger.js.map +1 -0
  83. package/build/lib/logsink.d.ts +4 -0
  84. package/build/lib/logsink.d.ts.map +1 -0
  85. package/build/lib/logsink.js +189 -184
  86. package/build/lib/logsink.js.map +1 -0
  87. package/build/lib/main.d.ts +62 -0
  88. package/build/lib/main.d.ts.map +1 -0
  89. package/build/lib/main.js +406 -234
  90. package/build/lib/main.js.map +1 -0
  91. package/build/lib/schema/arg-spec.d.ts +143 -0
  92. package/build/lib/schema/arg-spec.d.ts.map +1 -0
  93. package/build/lib/schema/arg-spec.js +164 -0
  94. package/build/lib/schema/arg-spec.js.map +1 -0
  95. package/build/lib/schema/cli-args.d.ts +19 -0
  96. package/build/lib/schema/cli-args.d.ts.map +1 -0
  97. package/build/lib/schema/cli-args.js +220 -0
  98. package/build/lib/schema/cli-args.js.map +1 -0
  99. package/build/lib/schema/cli-transformers.d.ts +5 -0
  100. package/build/lib/schema/cli-transformers.d.ts.map +1 -0
  101. package/build/lib/schema/cli-transformers.js +124 -0
  102. package/build/lib/schema/cli-transformers.js.map +1 -0
  103. package/build/lib/schema/index.d.ts +3 -0
  104. package/build/lib/schema/index.d.ts.map +1 -0
  105. package/build/lib/schema/index.js +19 -0
  106. package/build/lib/schema/index.js.map +1 -0
  107. package/build/lib/schema/keywords.d.ts +24 -0
  108. package/build/lib/schema/keywords.d.ts.map +1 -0
  109. package/build/lib/schema/keywords.js +128 -0
  110. package/build/lib/schema/keywords.js.map +1 -0
  111. package/build/lib/schema/schema.d.ts +260 -0
  112. package/build/lib/schema/schema.d.ts.map +1 -0
  113. package/build/lib/schema/schema.js +640 -0
  114. package/build/lib/schema/schema.js.map +1 -0
  115. package/build/lib/utils.d.ts +276 -0
  116. package/build/lib/utils.d.ts.map +1 -0
  117. package/build/lib/utils.js +372 -192
  118. package/build/lib/utils.js.map +1 -0
  119. package/build/types/cli.d.ts +134 -0
  120. package/build/types/cli.d.ts.map +1 -0
  121. package/build/types/cli.js +3 -0
  122. package/build/types/cli.js.map +1 -0
  123. package/build/types/index.d.ts +15 -0
  124. package/build/types/index.d.ts.map +1 -0
  125. package/build/types/index.js +19 -0
  126. package/build/types/index.js.map +1 -0
  127. package/build/types/manifest/base.d.ts +135 -0
  128. package/build/types/manifest/base.d.ts.map +1 -0
  129. package/build/types/manifest/base.js +3 -0
  130. package/build/types/manifest/base.js.map +1 -0
  131. package/build/types/manifest/index.d.ts +21 -0
  132. package/build/types/manifest/index.d.ts.map +1 -0
  133. package/build/types/manifest/index.js +42 -0
  134. package/build/types/manifest/index.js.map +1 -0
  135. package/build/types/manifest/v3.d.ts +139 -0
  136. package/build/types/manifest/v3.d.ts.map +1 -0
  137. package/build/types/manifest/v3.js +3 -0
  138. package/build/types/manifest/v3.js.map +1 -0
  139. package/build/types/manifest/v4.d.ts +139 -0
  140. package/build/types/manifest/v4.d.ts.map +1 -0
  141. package/build/types/manifest/v4.js +3 -0
  142. package/build/types/manifest/v4.js.map +1 -0
  143. package/driver.d.ts +1 -0
  144. package/driver.js +14 -0
  145. package/index.js +11 -0
  146. package/lib/appium.js +545 -188
  147. package/lib/cli/args.js +275 -407
  148. package/lib/cli/driver-command.js +132 -24
  149. package/lib/cli/extension-command.js +751 -272
  150. package/lib/cli/extension.js +38 -19
  151. package/lib/cli/parser.js +267 -95
  152. package/lib/cli/plugin-command.js +122 -22
  153. package/lib/cli/utils.js +24 -10
  154. package/lib/config-file.js +220 -0
  155. package/lib/config.js +243 -132
  156. package/lib/constants.js +79 -0
  157. package/lib/extension/driver-config.js +247 -0
  158. package/lib/extension/extension-config.js +709 -0
  159. package/lib/extension/index.js +116 -0
  160. package/lib/extension/manifest-migrations.js +136 -0
  161. package/lib/extension/manifest.js +580 -0
  162. package/lib/extension/package-changed.js +64 -0
  163. package/lib/extension/plugin-config.js +112 -0
  164. package/lib/grid-register.js +49 -35
  165. package/lib/logger.js +1 -2
  166. package/lib/logsink.js +59 -36
  167. package/lib/main.js +392 -104
  168. package/lib/schema/arg-spec.js +229 -0
  169. package/lib/schema/cli-args.js +241 -0
  170. package/lib/schema/cli-transformers.js +119 -0
  171. package/lib/schema/index.js +2 -0
  172. package/lib/schema/keywords.js +136 -0
  173. package/lib/schema/schema.js +725 -0
  174. package/lib/utils.js +310 -89
  175. package/package.json +84 -84
  176. package/plugin.d.ts +1 -0
  177. package/plugin.js +13 -0
  178. package/scripts/autoinstall-extensions.js +243 -0
  179. package/support.d.ts +1 -0
  180. package/support.js +13 -0
  181. package/tsconfig.json +25 -0
  182. package/types/cli.ts +193 -0
  183. package/types/index.ts +20 -0
  184. package/types/manifest/README.md +30 -0
  185. package/types/manifest/base.ts +158 -0
  186. package/types/manifest/index.ts +28 -0
  187. package/types/manifest/v3.ts +161 -0
  188. package/types/manifest/v4.ts +161 -0
  189. package/CHANGELOG.md +0 -3669
  190. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  191. package/build/lib/cli/argparse-actions.js +0 -104
  192. package/build/lib/cli/npm.js +0 -207
  193. package/build/lib/cli/parser-helpers.js +0 -93
  194. package/build/lib/driver-config.js +0 -77
  195. package/build/lib/drivers.js +0 -99
  196. package/build/lib/extension-config.js +0 -253
  197. package/build/lib/plugin-config.js +0 -59
  198. package/build/lib/plugins.js +0 -16
  199. package/build/postinstall.js +0 -90
  200. package/lib/cli/argparse-actions.js +0 -77
  201. package/lib/cli/npm.js +0 -183
  202. package/lib/cli/parser-helpers.js +0 -91
  203. package/lib/driver-config.js +0 -46
  204. package/lib/drivers.js +0 -84
  205. package/lib/extension-config.js +0 -209
  206. package/lib/plugin-config.js +0 -34
  207. package/lib/plugins.js +0 -11
  208. package/postinstall.js +0 -71
package/lib/cli/utils.js CHANGED
@@ -7,9 +7,9 @@ const JSON_SPACES = 4;
7
7
  /***
8
8
  * Log an error to the console and exit the process.
9
9
  * @param {boolean} json - whether we should log json or text
10
- * @param {string} msg - error message
10
+ * @param {any} msg - error message, object, Error instance, etc.
11
11
  */
12
- function errAndQuit (json, msg) {
12
+ function errAndQuit(json, msg) {
13
13
  if (json) {
14
14
  console.log(JSON.stringify({error: `${msg}`}, null, JSON_SPACES));
15
15
  } else {
@@ -26,7 +26,7 @@ function errAndQuit (json, msg) {
26
26
  * @param {boolean} json - whether we are in json mode (and should therefore not log)
27
27
  * @param {string} msg - string to log
28
28
  */
29
- function log (json, msg) {
29
+ function log(json, msg) {
30
30
  !json && console.log(msg);
31
31
  }
32
32
 
@@ -36,7 +36,7 @@ function log (json, msg) {
36
36
  * @param {string} msg - string to log
37
37
  * @param {function} fn - function to wrap with spinning
38
38
  */
39
- async function spinWith (json, msg, fn) {
39
+ async function spinWith(json, msg, fn) {
40
40
  if (json) {
41
41
  return await fn();
42
42
  }
@@ -52,9 +52,23 @@ async function spinWith (json, msg, fn) {
52
52
  }
53
53
  }
54
54
 
55
- export {
56
- errAndQuit,
57
- log,
58
- spinWith,
59
- JSON_SPACES
60
- };
55
+ class RingBuffer {
56
+ constructor(size = 50) {
57
+ this.size = size;
58
+ this.buffer = [];
59
+ }
60
+ getBuff() {
61
+ return this.buffer;
62
+ }
63
+ dequeue() {
64
+ this.buffer.shift();
65
+ }
66
+ enqueue(item) {
67
+ if (this.buffer.length >= this.size) {
68
+ this.dequeue();
69
+ }
70
+ this.buffer.push(item);
71
+ }
72
+ }
73
+
74
+ export {errAndQuit, log, spinWith, JSON_SPACES, RingBuffer};
@@ -0,0 +1,220 @@
1
+ import betterAjvErrors from '@sidvind/better-ajv-errors';
2
+ import {lilconfig} from 'lilconfig';
3
+ import _ from 'lodash';
4
+ import yaml from 'yaml';
5
+ import {getSchema, validate} from './schema/schema';
6
+
7
+ /**
8
+ * lilconfig loader to handle `.yaml` files
9
+ * @type {import('lilconfig').LoaderSync}
10
+ */
11
+ function yamlLoader(filepath, content) {
12
+ return yaml.parse(content);
13
+ }
14
+
15
+ /**
16
+ * A cache of the raw config file (a JSON string) at a filepath.
17
+ * This is used for better error reporting.
18
+ * Note that config files needn't be JSON, but it helps if they are.
19
+ * @type {Map<string,RawJson>}
20
+ */
21
+ const rawConfig = new Map();
22
+
23
+ /**
24
+ * Custom JSON loader that caches the raw config file (for use with `better-ajv-errors`).
25
+ * If it weren't for this cache, this would be unnecessary.
26
+ * @type {import('lilconfig').LoaderSync}
27
+ */
28
+ function jsonLoader(filepath, content) {
29
+ rawConfig.set(filepath, content);
30
+ return JSON.parse(content);
31
+ }
32
+
33
+ /**
34
+ * Loads a config file from an explicit path
35
+ * @param {LilconfigAsyncSearcher} lc - lilconfig instance
36
+ * @param {string} filepath - Path to config file
37
+ * @returns {Promise<import('lilconfig').LilconfigResult>}
38
+ */
39
+ async function loadConfigFile(lc, filepath) {
40
+ try {
41
+ // removing "await" will cause any rejection to _not_ be caught in this block!
42
+ return await lc.load(filepath);
43
+ } catch (/** @type {unknown} */ err) {
44
+ if (/** @type {NodeJS.ErrnoException} */ (err).code === 'ENOENT') {
45
+ /** @type {NodeJS.ErrnoException} */ (
46
+ err
47
+ ).message = `Config file not found at user-provided path: ${filepath}`;
48
+ throw err;
49
+ } else if (err instanceof SyntaxError) {
50
+ // generally invalid JSON
51
+ err.message = `Config file at user-provided path ${filepath} is invalid:\n${err.message}`;
52
+ throw err;
53
+ }
54
+ throw err;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Searches for a config file
60
+ * @param {LilconfigAsyncSearcher} lc - lilconfig instance
61
+ * @returns {Promise<import('lilconfig').LilconfigResult>}
62
+ */
63
+ async function searchConfigFile(lc) {
64
+ return await lc.search();
65
+ }
66
+
67
+ /**
68
+ * Given an array of errors and the result of loading a config file, generate a
69
+ * helpful string for the user.
70
+ *
71
+ * - If `opts` contains a `json` property, this should be the original JSON
72
+ * _string_ of the config file. This is only applicable if the config file
73
+ * was in JSON format. If present, it will associate line numbers with errors.
74
+ * - If `errors` happens to be empty, this will throw.
75
+ * @param {import('ajv').ErrorObject[]} errors - Non-empty array of errors. Required.
76
+ * @param {ReadConfigFileResult['config']|any} [config] -
77
+ * Configuration & metadata
78
+ * @param {FormatConfigErrorsOptions} [opts]
79
+ * @throws {TypeError} If `errors` is empty
80
+ * @returns {string}
81
+ */
82
+ export function formatErrors(errors = [], config = {}, opts = {}) {
83
+ if (errors && !errors.length) {
84
+ throw new TypeError('Array of errors must be non-empty');
85
+ }
86
+ return betterAjvErrors(getSchema(opts.schemaId), config, errors, {
87
+ json: opts.json,
88
+ format: 'cli',
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Given an optional path, read a config file. Validates the config file.
94
+ *
95
+ * Call {@link validate} if you already have a config object.
96
+ * @param {string} [filepath] - Path to config file, if we have one
97
+ * @param {ReadConfigFileOptions} [opts] - Options
98
+ * @public
99
+ * @returns {Promise<ReadConfigFileResult>} Contains config and filepath, if found, and any errors
100
+ */
101
+ export async function readConfigFile(filepath, opts = {}) {
102
+ const lc = lilconfig('appium', {
103
+ loaders: {
104
+ '.yaml': yamlLoader,
105
+ '.yml': yamlLoader,
106
+ '.json': jsonLoader,
107
+ noExt: jsonLoader,
108
+ },
109
+ packageProp: 'appiumConfig',
110
+ });
111
+
112
+ const result = filepath ? await loadConfigFile(lc, filepath) : await searchConfigFile(lc);
113
+
114
+ if (result?.filepath && !result?.isEmpty) {
115
+ const {pretty = true} = opts;
116
+ try {
117
+ let configResult;
118
+ const errors = validate(result.config);
119
+ if (_.isEmpty(errors)) {
120
+ configResult = {...result, errors};
121
+ } else {
122
+ const reason = formatErrors(errors, result.config, {
123
+ json: rawConfig.get(result.filepath),
124
+ pretty,
125
+ });
126
+ configResult = reason ? {...result, errors, reason} : {...result, errors};
127
+ }
128
+
129
+ // normalize (to camel case) all top-level property names of the config file
130
+ configResult.config = normalizeConfig(/** @type {AppiumConfig} */ (configResult.config));
131
+
132
+ return configResult;
133
+ } finally {
134
+ // clean up the raw config file cache, which is only kept to better report errors.
135
+ rawConfig.delete(result.filepath);
136
+ }
137
+ }
138
+ return result ?? {};
139
+ }
140
+
141
+ /**
142
+ * Convert schema property names to either a) the value of the `appiumCliDest` property, if any; or b) camel-case
143
+ * @param {AppiumConfig} config - Configuration object
144
+ * @returns {NormalizedAppiumConfig} New object with camel-cased keys (or `dest` keys).
145
+ */
146
+ export function normalizeConfig(config) {
147
+ const schema = getSchema();
148
+ /**
149
+ * @param {AppiumConfig} config
150
+ * @param {string} [section] - Keypath (lodash `_.get()` style) to section of config. If omitted, assume root Appium config schema
151
+ * @todo Rewrite as a loop
152
+ * @returns Normalized section of config
153
+ */
154
+ const normalize = (config, section) => {
155
+ const obj = _.isUndefined(section) ? config : _.get(config, section, config);
156
+
157
+ const mappedObj = _.mapKeys(obj, (__, prop) =>
158
+ _.get(schema, `properties.server.properties[${prop}].appiumCliDest`, _.camelCase(prop))
159
+ );
160
+
161
+ return _.mapValues(mappedObj, (value, property) => {
162
+ const nextSection = section ? `${section}.${property}` : property;
163
+ return isSchemaTypeObject(schema.properties?.[property])
164
+ ? normalize(config, nextSection)
165
+ : value;
166
+ });
167
+ };
168
+
169
+ /**
170
+ * Returns `true` if the schema prop references an object, or if it's an object itself
171
+ * @param {import('ajv').SchemaObject|object} schema - Referencing schema object
172
+ */
173
+ const isSchemaTypeObject = (schema) => Boolean(schema?.properties || schema?.type === 'object');
174
+
175
+ return normalize(config);
176
+ }
177
+
178
+ /**
179
+ * Result of calling {@link readConfigFile}.
180
+ * @typedef ReadConfigFileResult
181
+ * @property {import('ajv').ErrorObject[]} [errors] - Validation errors
182
+ * @property {string} [filepath] - The path to the config file, if found
183
+ * @property {boolean} [isEmpty] - If `true`, the config file exists but is empty
184
+ * @property {NormalizedAppiumConfig} [config] - The parsed configuration
185
+ * @property {string|import('@sidvind/better-ajv-errors').IOutputError[]} [reason] - Human-readable error messages and suggestions. If the `pretty` option is `true`, this will be a nice string to print.
186
+ */
187
+
188
+ /**
189
+ * Options for {@link readConfigFile}.
190
+ * @typedef ReadConfigFileOptions
191
+ * @property {boolean} [pretty=true] If `false`, do not use color and fancy formatting in the `reason` property of the {@link ReadConfigFileResult}. The value of `reason` is then suitable for machine-reading.
192
+ */
193
+
194
+ /**
195
+ * This is an `AsyncSearcher` which is inexplicably _not_ exported by the `lilconfig` type definition.
196
+ * @typedef {ReturnType<import('lilconfig')["lilconfig"]>} LilconfigAsyncSearcher
197
+ */
198
+
199
+ /**
200
+ * The contents of an Appium config file. Generated from schema
201
+ * @typedef {import('@appium/types').AppiumConfig} AppiumConfig
202
+ */
203
+
204
+ /**
205
+ * The contents of an Appium config file with camelcased property names (and using `appiumCliDest` value if present). Generated from {@link AppiumConfig}
206
+ * @typedef {import('@appium/types').NormalizedAppiumConfig} NormalizedAppiumConfig
207
+ */
208
+
209
+ /**
210
+ * The string should be a raw JSON string.
211
+ * @typedef {string} RawJson
212
+ */
213
+
214
+ /**
215
+ * Options for {@link formatErrors}.
216
+ * @typedef FormatConfigErrorsOptions
217
+ * @property {import('./config-file').RawJson} [json] - Raw JSON config (as string)
218
+ * @property {boolean} [pretty=true] - Whether to format errors as a CLI-friendly string
219
+ * @property {string} [schemaId] - Specific ID of a prop; otherwise entire schema
220
+ */