appium 3.2.2 → 3.3.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 (250) hide show
  1. package/build/lib/appium.d.ts +147 -205
  2. package/build/lib/appium.d.ts.map +1 -1
  3. package/build/lib/appium.js +169 -282
  4. package/build/lib/appium.js.map +1 -1
  5. package/build/lib/bidi-commands.d.ts.map +1 -1
  6. package/build/lib/bidi-commands.js +11 -11
  7. package/build/lib/bidi-commands.js.map +1 -1
  8. package/build/lib/bootstrap/appium-initializer.d.ts +21 -0
  9. package/build/lib/bootstrap/appium-initializer.d.ts.map +1 -0
  10. package/build/lib/bootstrap/appium-initializer.js +146 -0
  11. package/build/lib/bootstrap/appium-initializer.js.map +1 -0
  12. package/build/lib/bootstrap/appium-main-runner.d.ts +22 -0
  13. package/build/lib/bootstrap/appium-main-runner.d.ts.map +1 -0
  14. package/build/lib/bootstrap/appium-main-runner.js +109 -0
  15. package/build/lib/bootstrap/appium-main-runner.js.map +1 -0
  16. package/build/lib/bootstrap/config-file.d.ts +37 -0
  17. package/build/lib/bootstrap/config-file.d.ts.map +1 -0
  18. package/build/lib/{config-file.js → bootstrap/config-file.js} +62 -138
  19. package/build/lib/bootstrap/config-file.js.map +1 -0
  20. package/build/lib/bootstrap/grid-v3-register.d.ts +20 -0
  21. package/build/lib/bootstrap/grid-v3-register.d.ts.map +1 -0
  22. package/build/lib/bootstrap/grid-v3-register.js +185 -0
  23. package/build/lib/bootstrap/grid-v3-register.js.map +1 -0
  24. package/build/lib/bootstrap/init-types.d.ts +16 -0
  25. package/build/lib/bootstrap/init-types.d.ts.map +1 -0
  26. package/build/lib/bootstrap/init-types.js +3 -0
  27. package/build/lib/bootstrap/init-types.js.map +1 -0
  28. package/build/lib/bootstrap/main-helpers.d.ts +55 -0
  29. package/build/lib/bootstrap/main-helpers.d.ts.map +1 -0
  30. package/build/lib/bootstrap/main-helpers.js +187 -0
  31. package/build/lib/bootstrap/main-helpers.js.map +1 -0
  32. package/build/lib/bootstrap/node-helpers.d.ts +32 -0
  33. package/build/lib/bootstrap/node-helpers.d.ts.map +1 -0
  34. package/build/lib/bootstrap/node-helpers.js +201 -0
  35. package/build/lib/bootstrap/node-helpers.js.map +1 -0
  36. package/build/lib/bootstrap/startup-config.d.ts +22 -0
  37. package/build/lib/bootstrap/startup-config.d.ts.map +1 -0
  38. package/build/lib/bootstrap/startup-config.js +111 -0
  39. package/build/lib/bootstrap/startup-config.js.map +1 -0
  40. package/build/lib/cli/args.d.ts +16 -12
  41. package/build/lib/cli/args.d.ts.map +1 -1
  42. package/build/lib/cli/args.js +20 -40
  43. package/build/lib/cli/args.js.map +1 -1
  44. package/build/lib/cli/driver-command.d.ts +51 -93
  45. package/build/lib/cli/driver-command.d.ts.map +1 -1
  46. package/build/lib/cli/driver-command.js +11 -66
  47. package/build/lib/cli/driver-command.js.map +1 -1
  48. package/build/lib/cli/extension-command.d.ts +173 -377
  49. package/build/lib/cli/extension-command.d.ts.map +1 -1
  50. package/build/lib/cli/extension-command.js +387 -656
  51. package/build/lib/cli/extension-command.js.map +1 -1
  52. package/build/lib/cli/extension.d.ts +10 -15
  53. package/build/lib/cli/extension.d.ts.map +1 -1
  54. package/build/lib/cli/extension.js +15 -33
  55. package/build/lib/cli/extension.js.map +1 -1
  56. package/build/lib/cli/parser.d.ts +37 -66
  57. package/build/lib/cli/parser.d.ts.map +1 -1
  58. package/build/lib/cli/parser.js +69 -104
  59. package/build/lib/cli/parser.js.map +1 -1
  60. package/build/lib/cli/plugin-command.d.ts +50 -90
  61. package/build/lib/cli/plugin-command.d.ts.map +1 -1
  62. package/build/lib/cli/plugin-command.js +11 -63
  63. package/build/lib/cli/plugin-command.js.map +1 -1
  64. package/build/lib/cli/setup-command.d.ts +21 -26
  65. package/build/lib/cli/setup-command.d.ts.map +1 -1
  66. package/build/lib/cli/setup-command.js +19 -61
  67. package/build/lib/cli/setup-command.js.map +1 -1
  68. package/build/lib/cli/utils.d.ts +33 -35
  69. package/build/lib/cli/utils.d.ts.map +1 -1
  70. package/build/lib/cli/utils.js +48 -50
  71. package/build/lib/cli/utils.js.map +1 -1
  72. package/build/lib/constants.d.ts +23 -23
  73. package/build/lib/constants.d.ts.map +1 -1
  74. package/build/lib/constants.js +10 -15
  75. package/build/lib/constants.js.map +1 -1
  76. package/build/lib/doctor/doctor.d.ts +40 -57
  77. package/build/lib/doctor/doctor.d.ts.map +1 -1
  78. package/build/lib/doctor/doctor.js +31 -62
  79. package/build/lib/doctor/doctor.js.map +1 -1
  80. package/build/lib/extension/driver-config.d.ts +18 -77
  81. package/build/lib/extension/driver-config.d.ts.map +1 -1
  82. package/build/lib/extension/driver-config.js +37 -125
  83. package/build/lib/extension/driver-config.js.map +1 -1
  84. package/build/lib/extension/extension-config.d.ts +103 -210
  85. package/build/lib/extension/extension-config.d.ts.map +1 -1
  86. package/build/lib/extension/extension-config.js +180 -342
  87. package/build/lib/extension/extension-config.js.map +1 -1
  88. package/build/lib/extension/index.d.ts +12 -29
  89. package/build/lib/extension/index.d.ts.map +1 -1
  90. package/build/lib/extension/index.js +33 -75
  91. package/build/lib/extension/index.js.map +1 -1
  92. package/build/lib/extension/manifest-migrations.d.ts +3 -20
  93. package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
  94. package/build/lib/extension/manifest-migrations.js +20 -101
  95. package/build/lib/extension/manifest-migrations.js.map +1 -1
  96. package/build/lib/extension/manifest.d.ts +61 -107
  97. package/build/lib/extension/manifest.d.ts.map +1 -1
  98. package/build/lib/extension/manifest.js +181 -356
  99. package/build/lib/extension/manifest.js.map +1 -1
  100. package/build/lib/extension/package-changed.d.ts +1 -3
  101. package/build/lib/extension/package-changed.d.ts.map +1 -1
  102. package/build/lib/extension/package-changed.js +8 -15
  103. package/build/lib/extension/package-changed.js.map +1 -1
  104. package/build/lib/extension/plugin-config.d.ts +10 -52
  105. package/build/lib/extension/plugin-config.d.ts.map +1 -1
  106. package/build/lib/extension/plugin-config.js +11 -63
  107. package/build/lib/extension/plugin-config.js.map +1 -1
  108. package/build/lib/helpers/build.d.ts +22 -0
  109. package/build/lib/helpers/build.d.ts.map +1 -0
  110. package/build/lib/helpers/build.js +109 -0
  111. package/build/lib/helpers/build.js.map +1 -0
  112. package/build/lib/helpers/capability.d.ts +38 -0
  113. package/build/lib/helpers/capability.d.ts.map +1 -0
  114. package/build/lib/helpers/capability.js +128 -0
  115. package/build/lib/helpers/capability.js.map +1 -0
  116. package/build/lib/helpers/network.d.ts +14 -0
  117. package/build/lib/helpers/network.d.ts.map +1 -0
  118. package/build/lib/helpers/network.js +35 -0
  119. package/build/lib/helpers/network.js.map +1 -0
  120. package/build/lib/insecure-features.js +6 -6
  121. package/build/lib/insecure-features.js.map +1 -1
  122. package/build/lib/inspector-commands.d.ts +6 -0
  123. package/build/lib/inspector-commands.d.ts.map +1 -1
  124. package/build/lib/inspector-commands.js +6 -0
  125. package/build/lib/inspector-commands.js.map +1 -1
  126. package/build/lib/logger.d.ts +2 -3
  127. package/build/lib/logger.d.ts.map +1 -1
  128. package/build/lib/logger.js +2 -3
  129. package/build/lib/logger.js.map +1 -1
  130. package/build/lib/logsink.d.ts +13 -22
  131. package/build/lib/logsink.d.ts.map +1 -1
  132. package/build/lib/logsink.js +48 -103
  133. package/build/lib/logsink.js.map +1 -1
  134. package/build/lib/main.d.ts +15 -58
  135. package/build/lib/main.d.ts.map +1 -1
  136. package/build/lib/main.js +25 -425
  137. package/build/lib/main.js.map +1 -1
  138. package/build/lib/schema/arg-spec.d.ts +32 -107
  139. package/build/lib/schema/arg-spec.d.ts.map +1 -1
  140. package/build/lib/schema/arg-spec.js +11 -107
  141. package/build/lib/schema/arg-spec.js.map +1 -1
  142. package/build/lib/schema/cli-args-guards.d.ts +34 -0
  143. package/build/lib/schema/cli-args-guards.d.ts.map +1 -0
  144. package/build/lib/schema/cli-args-guards.js +49 -0
  145. package/build/lib/schema/cli-args-guards.js.map +1 -0
  146. package/build/lib/schema/cli-args.d.ts +3 -15
  147. package/build/lib/schema/cli-args.d.ts.map +1 -1
  148. package/build/lib/schema/cli-args.js +17 -107
  149. package/build/lib/schema/cli-args.js.map +1 -1
  150. package/build/lib/schema/cli-transformers.d.ts +15 -12
  151. package/build/lib/schema/cli-transformers.d.ts.map +1 -1
  152. package/build/lib/schema/cli-transformers.js +15 -45
  153. package/build/lib/schema/cli-transformers.js.map +1 -1
  154. package/build/lib/schema/format-errors.d.ts +28 -0
  155. package/build/lib/schema/format-errors.d.ts.map +1 -0
  156. package/build/lib/schema/format-errors.js +29 -0
  157. package/build/lib/schema/format-errors.js.map +1 -0
  158. package/build/lib/schema/index.d.ts +4 -2
  159. package/build/lib/schema/index.d.ts.map +1 -1
  160. package/build/lib/schema/index.js +2 -0
  161. package/build/lib/schema/index.js.map +1 -1
  162. package/build/lib/schema/keywords.d.ts +12 -20
  163. package/build/lib/schema/keywords.d.ts.map +1 -1
  164. package/build/lib/schema/keywords.js +6 -51
  165. package/build/lib/schema/keywords.js.map +1 -1
  166. package/build/lib/schema/schema.d.ts +106 -231
  167. package/build/lib/schema/schema.d.ts.map +1 -1
  168. package/build/lib/schema/schema.js +88 -358
  169. package/build/lib/schema/schema.js.map +1 -1
  170. package/build/lib/utils.d.ts +7 -267
  171. package/build/lib/utils.d.ts.map +1 -1
  172. package/build/lib/utils.js +10 -409
  173. package/build/lib/utils.js.map +1 -1
  174. package/lib/{appium.js → appium.ts} +297 -341
  175. package/lib/bidi-commands.ts +10 -14
  176. package/lib/bootstrap/appium-initializer.ts +212 -0
  177. package/lib/bootstrap/appium-main-runner.ts +172 -0
  178. package/lib/bootstrap/config-file.ts +178 -0
  179. package/lib/bootstrap/grid-v3-register.ts +250 -0
  180. package/lib/bootstrap/init-types.ts +31 -0
  181. package/lib/bootstrap/main-helpers.ts +223 -0
  182. package/lib/bootstrap/node-helpers.ts +180 -0
  183. package/lib/bootstrap/startup-config.ts +143 -0
  184. package/lib/cli/{args.js → args.ts} +45 -56
  185. package/lib/cli/driver-command.ts +122 -0
  186. package/lib/cli/{extension-command.js → extension-command.ts} +827 -906
  187. package/lib/cli/extension.ts +65 -0
  188. package/lib/cli/{parser.js → parser.ts} +93 -116
  189. package/lib/cli/plugin-command.ts +117 -0
  190. package/lib/cli/{setup-command.js → setup-command.ts} +59 -74
  191. package/lib/cli/utils.ts +97 -0
  192. package/lib/{constants.js → constants.ts} +30 -41
  193. package/lib/doctor/{doctor.js → doctor.ts} +82 -92
  194. package/lib/extension/driver-config.ts +165 -0
  195. package/lib/extension/{extension-config.js → extension-config.ts} +291 -405
  196. package/lib/extension/index.ts +143 -0
  197. package/lib/extension/manifest-migrations.ts +57 -0
  198. package/lib/extension/manifest.ts +369 -0
  199. package/lib/extension/{package-changed.js → package-changed.ts} +9 -18
  200. package/lib/extension/plugin-config.ts +62 -0
  201. package/lib/helpers/build.ts +111 -0
  202. package/lib/helpers/capability.ts +171 -0
  203. package/lib/helpers/network.ts +30 -0
  204. package/lib/insecure-features.ts +1 -1
  205. package/lib/inspector-commands.ts +6 -1
  206. package/lib/{logger.js → logger.ts} +1 -2
  207. package/lib/{logsink.js → logsink.ts} +91 -137
  208. package/lib/main.ts +60 -0
  209. package/lib/schema/arg-spec.ts +131 -0
  210. package/lib/schema/cli-args-guards.ts +67 -0
  211. package/lib/schema/cli-args.ts +171 -0
  212. package/lib/schema/cli-transformers.ts +83 -0
  213. package/lib/schema/format-errors.ts +43 -0
  214. package/lib/schema/index.ts +4 -0
  215. package/lib/schema/keywords.ts +96 -0
  216. package/lib/schema/schema.ts +448 -0
  217. package/lib/utils.ts +73 -0
  218. package/package.json +17 -18
  219. package/scripts/autoinstall-extensions.js +3 -0
  220. package/build/lib/config-file.d.ts +0 -100
  221. package/build/lib/config-file.d.ts.map +0 -1
  222. package/build/lib/config-file.js.map +0 -1
  223. package/build/lib/config.d.ts +0 -70
  224. package/build/lib/config.d.ts.map +0 -1
  225. package/build/lib/config.js +0 -390
  226. package/build/lib/config.js.map +0 -1
  227. package/build/lib/grid-register.d.ts +0 -10
  228. package/build/lib/grid-register.d.ts.map +0 -1
  229. package/build/lib/grid-register.js +0 -134
  230. package/build/lib/grid-register.js.map +0 -1
  231. package/lib/cli/driver-command.js +0 -174
  232. package/lib/cli/extension.js +0 -74
  233. package/lib/cli/plugin-command.js +0 -164
  234. package/lib/cli/utils.js +0 -91
  235. package/lib/config-file.js +0 -228
  236. package/lib/config.js +0 -389
  237. package/lib/extension/driver-config.js +0 -245
  238. package/lib/extension/index.js +0 -169
  239. package/lib/extension/manifest-migrations.js +0 -136
  240. package/lib/extension/manifest.js +0 -550
  241. package/lib/extension/plugin-config.js +0 -112
  242. package/lib/grid-register.js +0 -146
  243. package/lib/main.js +0 -545
  244. package/lib/schema/arg-spec.js +0 -229
  245. package/lib/schema/cli-args.js +0 -254
  246. package/lib/schema/cli-transformers.js +0 -113
  247. package/lib/schema/index.js +0 -2
  248. package/lib/schema/keywords.js +0 -136
  249. package/lib/schema/schema.js +0 -725
  250. package/lib/utils.js +0 -512
@@ -1,45 +1,79 @@
1
1
  import '@colors/colors';
2
2
  import _ from 'lodash';
3
- import { util, doctor, logger } from '@appium/support';
3
+ import {util, doctor, logger} from '@appium/support';
4
+ import type {AppiumLogger, DoctorCheckResult, IDoctorCheck} from '@appium/types';
4
5
 
5
- export const EXIT_CODE = /** @type {const} */ Object.freeze({
6
+ /**
7
+ * Process exit codes returned by {@link Doctor.run}.
8
+ */
9
+ export const EXIT_CODE = Object.freeze({
6
10
  SUCCESS: 0,
7
11
  HAS_MAJOR_ISSUES: 127,
8
- });
12
+ } as const);
13
+
14
+ /** Exit code values produced by {@link Doctor.run}. */
15
+ export type DoctorExitCode = (typeof EXIT_CODE)[keyof typeof EXIT_CODE];
16
+
17
+ /**
18
+ * A failed check reported during {@link Doctor} diagnostics.
19
+ */
20
+ export interface DoctorIssue {
21
+ /** The check that produced this issue. */
22
+ check: IDoctorCheck;
23
+ /** Colored message string as logged during diagnosis. */
24
+ error: string;
25
+ /** Set after a successful automatic fix attempt. */
26
+ fixed?: boolean;
27
+ }
9
28
 
10
29
  export class Doctor {
11
- /**
12
- * @param {DoctorCheck[]} [checks=[]]
13
- */
14
- constructor(checks = []) {
30
+ private readonly log: AppiumLogger;
31
+ private readonly checks: IDoctorCheck[];
32
+ private foundIssues: DoctorIssue[];
33
+
34
+ constructor(checks: IDoctorCheck[] = []) {
15
35
  this.log = logger.getLogger('Doctor');
16
- /** @type {DoctorCheck[]} */
17
36
  this.checks = checks;
18
37
  this.checks
19
38
  .filter((c) => _.isNil(c.log))
20
- .forEach((c) => { c.log = this.log; });
21
- /** @type {DoctorIssue[]} */
39
+ .forEach((c) => {
40
+ c.log = this.log;
41
+ });
22
42
  this.foundIssues = [];
23
43
  }
24
44
 
25
- /**
26
- * @returns {DoctorIssue[]}
27
- */
28
- get issuesRequiredToFix() {
45
+ private get issuesRequiredToFix(): DoctorIssue[] {
29
46
  return this.foundIssues.filter((f) => !f.check.isOptional());
30
47
  }
31
48
 
49
+ private get issuesOptionalToFix(): DoctorIssue[] {
50
+ return this.foundIssues.filter((f) => f.check.isOptional());
51
+ }
52
+
32
53
  /**
33
- * @returns {DoctorIssue[]}
54
+ * Runs diagnostics, reports issues, attempts automatic fixes where supported, and returns an exit code.
55
+ *
56
+ * @returns {@link EXIT_CODE.SUCCESS} when there are no issues or all issues were resolved;
57
+ * {@link EXIT_CODE.HAS_MAJOR_ISSUES} when manual intervention is still required or fixes failed.
34
58
  */
35
- get issuesOptionalToFix() {
36
- return this.foundIssues.filter((f) => f.check.isOptional());
59
+ async run(): Promise<DoctorExitCode> {
60
+ await this.diagnose();
61
+ if (this.reportSuccess()) {
62
+ return EXIT_CODE.SUCCESS;
63
+ }
64
+ if (await this.reportManualIssues()) {
65
+ return EXIT_CODE.HAS_MAJOR_ISSUES;
66
+ }
67
+ if (!(await this.runAutoFixes())) {
68
+ return EXIT_CODE.HAS_MAJOR_ISSUES;
69
+ }
70
+ return EXIT_CODE.SUCCESS;
37
71
  }
38
72
 
39
73
  /**
40
74
  * The doctor shows the report
41
75
  */
42
- async diagnose() {
76
+ private async diagnose(): Promise<void> {
43
77
  this.log.info(`### Starting doctor diagnostics ###`);
44
78
  this.foundIssues = [];
45
79
  for (const check of this.checks) {
@@ -49,20 +83,15 @@ export class Doctor {
49
83
  this.foundIssues.push(issue);
50
84
  }
51
85
  }
52
- this.log.info(
53
- `### Diagnostic completed, ${this.buildFixMessage()}. ###`
54
- );
86
+ this.log.info(`### Diagnostic completed, ${this.buildFixMessage()}. ###`);
55
87
  this.log.info('');
56
88
  }
57
89
 
58
- /**
59
- * @returns {Promise<boolean>}
60
- */
61
- async reportManualIssues() {
90
+ private async reportManualIssues(): Promise<boolean> {
62
91
  const manualIssues = _.filter(this.issuesRequiredToFix, (f) => !f.check.hasAutofix());
63
92
  const manualIssuesOptional = _.filter(this.issuesOptionalToFix, (f) => !f.check.hasAutofix());
64
93
 
65
- const handleIssues = async (headerLogs, issues) => {
94
+ const handleIssues = async (headerLogs: string[], issues: DoctorIssue[]): Promise<void> => {
66
95
  if (_.isEmpty(issues)) {
67
96
  return;
68
97
  }
@@ -70,14 +99,13 @@ export class Doctor {
70
99
  for (const logMsg of headerLogs) {
71
100
  this.log.info(logMsg);
72
101
  }
73
- /** @type {string[]} */
74
- const fixMessages = [];
102
+ const fixMessages: string[] = [];
75
103
  for (const issue of issues) {
76
- let message;
104
+ let message: string | null;
77
105
  try {
78
106
  message = await issue.check.fix();
79
107
  } catch (e) {
80
- message = e.message;
108
+ message = (e as Error).message;
81
109
  }
82
110
  if (message) {
83
111
  fixMessages.push(message);
@@ -89,14 +117,20 @@ export class Doctor {
89
117
  this.log.info('');
90
118
  };
91
119
 
92
- await handleIssues([
93
- '### Manual Fixes Needed ###',
94
- 'The configuration cannot be automatically fixed, please do the following first:',
95
- ], manualIssues);
96
- await handleIssues([
97
- '### Optional Manual Fixes ###',
98
- 'To fix these optional issues, please do the following manually:',
99
- ], manualIssuesOptional);
120
+ await handleIssues(
121
+ [
122
+ '### Manual Fixes Needed ###',
123
+ 'The configuration cannot be automatically fixed, please do the following first:',
124
+ ],
125
+ manualIssues
126
+ );
127
+ await handleIssues(
128
+ [
129
+ '### Optional Manual Fixes ###',
130
+ 'To fix these optional issues, please do the following manually:',
131
+ ],
132
+ manualIssuesOptional
133
+ );
100
134
 
101
135
  if (manualIssues.length > 0) {
102
136
  this.log.info('###');
@@ -108,15 +142,12 @@ export class Doctor {
108
142
  return false;
109
143
  }
110
144
 
111
- /**
112
- * @param {DoctorIssue} f
113
- */
114
- async runAutoFix(f) {
145
+ private async runAutoFix(f: DoctorIssue): Promise<void> {
115
146
  this.log.info(`### Fixing: ${f.error} ###`);
116
147
  try {
117
148
  await f.check.fix();
118
149
  } catch (err) {
119
- if (err.constructor.name === doctor.FixSkippedError.name) {
150
+ if (err instanceof doctor.FixSkippedError) {
120
151
  this.log.info(`### Skipped fix ###`);
121
152
  return;
122
153
  } else {
@@ -137,10 +168,7 @@ export class Doctor {
137
168
  }
138
169
  }
139
170
 
140
- /**
141
- * @returns {Promise<boolean>}
142
- */
143
- async runAutoFixes() {
171
+ private async runAutoFixes(): Promise<boolean> {
144
172
  const autoFixes = _.filter(this.foundIssues, (f) => f.check.hasAutofix());
145
173
  for (const f of autoFixes) {
146
174
  await this.runAutoFix(f);
@@ -158,29 +186,7 @@ export class Doctor {
158
186
  return true;
159
187
  }
160
188
 
161
- /**
162
- * @returns {Promise<EXIT_CODE[keyof EXIT_CODE]>}
163
- */
164
- async run() {
165
- await this.diagnose();
166
- if (this.reportSuccess()) {
167
- return EXIT_CODE.SUCCESS;
168
- }
169
- if (await this.reportManualIssues()) {
170
- return EXIT_CODE.HAS_MAJOR_ISSUES;
171
- }
172
- if (!await this.runAutoFixes()) {
173
- return EXIT_CODE.HAS_MAJOR_ISSUES;
174
- }
175
- return EXIT_CODE.SUCCESS;
176
- }
177
-
178
- /**
179
- * @param {DoctorCheckResult} result
180
- * @param {DoctorCheck} check
181
- * @returns {DoctorIssue?}
182
- */
183
- toIssue(result, check) {
189
+ private toIssue(result: DoctorCheckResult, check: IDoctorCheck): DoctorIssue | null {
184
190
  if (result.ok) {
185
191
  this.log.info(` ${'\u2714'.green} ${result.message}`);
186
192
  return null;
@@ -196,18 +202,14 @@ export class Doctor {
196
202
  };
197
203
  }
198
204
 
199
- /**
200
- * @returns {string}
201
- */
202
- buildFixMessage() {
203
- return `${util.pluralize('required fix', this.issuesRequiredToFix.length, true)} needed, ` +
204
- `${util.pluralize('optional fix', this.issuesOptionalToFix.length, true)} possible`;
205
+ private buildFixMessage(): string {
206
+ return (
207
+ `${util.pluralize('required fix', this.issuesRequiredToFix.length, true)} needed, ` +
208
+ `${util.pluralize('optional fix', this.issuesOptionalToFix.length, true)} possible`
209
+ );
205
210
  }
206
211
 
207
- /**
208
- * @returns {boolean}
209
- */
210
- reportSuccess() {
212
+ private reportSuccess(): boolean {
211
213
  if (this.issuesRequiredToFix.length === 0 && this.issuesOptionalToFix.length === 0) {
212
214
  this.log.info('Everything looks good, bye!');
213
215
  this.log.info('');
@@ -216,15 +218,3 @@ export class Doctor {
216
218
  return false;
217
219
  }
218
220
  }
219
-
220
- /**
221
- * @typedef DoctorIssue
222
- * @property {DoctorCheck} check
223
- * @property {string} error
224
- * @property {boolean} [fixed]
225
- */
226
-
227
- /**
228
- * @typedef {import('@appium/types').IDoctorCheck} DoctorCheck
229
- * @typedef {import('@appium/types').DoctorCheckResult} DoctorCheckResult
230
- */
@@ -0,0 +1,165 @@
1
+ import _ from 'lodash';
2
+ import type {DriverClass, DriverType, StringRecord} from '@appium/types';
3
+ import type {ExtManifest, ExtName, ExtRecord} from 'appium/types';
4
+ import {DRIVER_TYPE} from '../constants';
5
+ import {log} from '../logger';
6
+ import type {ExtManifestProblem} from './extension-config';
7
+ import {ExtensionConfig} from './extension-config';
8
+ import type {Manifest} from './manifest';
9
+
10
+ export type MatchedDriver = {
11
+ driver: DriverClass;
12
+ version: string;
13
+ driverName: string;
14
+ };
15
+
16
+ export class DriverConfig extends ExtensionConfig<DriverType> {
17
+ private static readonly _instances = new WeakMap<Manifest, DriverConfig>();
18
+ private knownAutomationNames = new Set<string>();
19
+
20
+ private constructor(manifest: Manifest) {
21
+ super(DRIVER_TYPE, manifest);
22
+ }
23
+
24
+ static create(manifest: Manifest): DriverConfig {
25
+ const instance = new DriverConfig(manifest);
26
+ if (DriverConfig.getInstance(manifest)) {
27
+ throw new Error(
28
+ `Manifest with APPIUM_HOME ${manifest.appiumHome} already has a DriverConfig; use DriverConfig.getInstance() to retrieve it.`
29
+ );
30
+ }
31
+ DriverConfig._instances.set(manifest, instance);
32
+ return instance;
33
+ }
34
+
35
+ static getInstance(manifest: Manifest): DriverConfig | undefined {
36
+ return DriverConfig._instances.get(manifest);
37
+ }
38
+
39
+ async validate(): Promise<ExtRecord<DriverType>> {
40
+ this.knownAutomationNames.clear();
41
+ return await super._validate(this.manifest.getExtensionData(DRIVER_TYPE));
42
+ }
43
+
44
+ public override extensionDesc(
45
+ driverName: ExtName<DriverType>,
46
+ {version, automationName}: ExtManifest<DriverType>
47
+ ): string {
48
+ return `${String(driverName)}@${version} (automationName '${automationName}')`;
49
+ }
50
+
51
+ async findMatchingDriver<C extends StringRecord>({
52
+ automationName,
53
+ platformName,
54
+ }: C): Promise<MatchedDriver> {
55
+ if (!_.isString(platformName)) {
56
+ throw new Error('You must include a platformName capability');
57
+ }
58
+
59
+ if (!_.isString(automationName)) {
60
+ throw new Error('You must include an automationName capability');
61
+ }
62
+
63
+ log.info(
64
+ `Attempting to find matching driver for automationName ` +
65
+ `'${automationName}' and platformName '${platformName}'`
66
+ );
67
+
68
+ try {
69
+ const {driverName, mainClass, version} = this._getDriverBySupport(automationName, platformName);
70
+ log.info(`The '${driverName}' driver was installed and matched caps.`);
71
+ log.info(`Will require it at ${this.getInstallPath(driverName)}`);
72
+ const driver = await this.requireAsync(driverName as ExtName<DriverType>);
73
+ if (!driver) {
74
+ throw new Error(
75
+ `Driver '${driverName}' did not export a class with name '${mainClass}'. Contact the author of the driver!`
76
+ );
77
+ }
78
+ return {driver, version, driverName};
79
+ } catch (err: any) {
80
+ const msg =
81
+ `Could not find a driver for automationName ` +
82
+ `'${automationName}' and platformName '${platformName}'. ` +
83
+ `Have you installed a driver that supports those ` +
84
+ `capabilities? Run 'appium driver list --installed' to see. ` +
85
+ `(Lower-level error: ${err.message})`;
86
+ throw new Error(msg);
87
+ }
88
+ }
89
+
90
+ protected override getConfigProblems(
91
+ extManifest: ExtManifest<DriverType>,
92
+ extName: string
93
+ ): ExtManifestProblem[] {
94
+ void extName;
95
+ const problems: ExtManifestProblem[] = [];
96
+ const {platformNames, automationName} = extManifest;
97
+
98
+ if (!_.isArray(platformNames)) {
99
+ problems.push({
100
+ err: 'Missing or incorrect supported platformNames list.',
101
+ val: platformNames,
102
+ });
103
+ } else if (_.isEmpty(platformNames)) {
104
+ problems.push({
105
+ err: 'Empty platformNames list.',
106
+ val: platformNames,
107
+ });
108
+ } else {
109
+ for (const pName of platformNames) {
110
+ if (!_.isString(pName)) {
111
+ problems.push({
112
+ err: 'Incorrectly formatted platformName.',
113
+ val: pName,
114
+ });
115
+ }
116
+ }
117
+ }
118
+
119
+ if (!_.isString(automationName)) {
120
+ problems.push({
121
+ err: 'Missing or incorrect automationName',
122
+ val: automationName,
123
+ });
124
+ }
125
+
126
+ if (this.knownAutomationNames.has(automationName as string)) {
127
+ problems.push({
128
+ err: 'Multiple drivers claim support for the same automationName',
129
+ val: automationName,
130
+ });
131
+ }
132
+
133
+ this.knownAutomationNames.add(automationName as string);
134
+
135
+ return problems;
136
+ }
137
+
138
+ private _getDriverBySupport(
139
+ matchAutomationName: string,
140
+ matchPlatformName: string
141
+ ): ExtManifest<DriverType> & {driverName: string} {
142
+ const drivers = this.installedExtensions;
143
+ for (const [driverName, driverData] of _.toPairs(drivers)) {
144
+ const {automationName, platformNames} = driverData;
145
+ const aNameMatches = automationName.toLowerCase() === matchAutomationName.toLowerCase();
146
+ const pNameMatches = _.includes(platformNames.map((p) => _.toLower(p)), matchPlatformName.toLowerCase());
147
+
148
+ if (aNameMatches && pNameMatches) {
149
+ return {driverName, ...driverData};
150
+ }
151
+
152
+ if (aNameMatches) {
153
+ throw new Error(
154
+ `Driver '${driverName}' supports automationName ` +
155
+ `'${automationName}', but Appium could not find ` +
156
+ `support for platformName '${matchPlatformName}'. Supported ` +
157
+ `platformNames are: ` +
158
+ JSON.stringify(platformNames)
159
+ );
160
+ }
161
+ }
162
+
163
+ throw new Error(`Could not find installed driver to support given caps`);
164
+ }
165
+ }