appium 2.0.0-beta.2 → 2.0.0-beta.23

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 (122) hide show
  1. package/README.md +9 -9
  2. package/build/check-npm-pack-files.js +23 -0
  3. package/build/commands-yml/parse.js +319 -0
  4. package/build/commands-yml/validator.js +130 -0
  5. package/build/index.js +19 -0
  6. package/build/lib/appium-config.schema.json +0 -0
  7. package/build/lib/appium.js +160 -53
  8. package/build/lib/cli/args.js +115 -279
  9. package/build/lib/cli/driver-command.js +11 -1
  10. package/build/lib/cli/extension-command.js +60 -8
  11. package/build/lib/cli/extension.js +30 -7
  12. package/build/lib/cli/npm.js +43 -29
  13. package/build/lib/cli/parser.js +156 -89
  14. package/build/lib/cli/plugin-command.js +11 -1
  15. package/build/lib/cli/utils.js +29 -3
  16. package/build/lib/config-file.js +141 -0
  17. package/build/lib/config.js +53 -65
  18. package/build/lib/driver-config.js +42 -19
  19. package/build/lib/drivers.js +8 -4
  20. package/build/lib/ext-config-io.js +165 -0
  21. package/build/lib/extension-config.js +130 -61
  22. package/build/lib/grid-register.js +22 -24
  23. package/build/lib/logger.js +3 -3
  24. package/build/lib/logsink.js +11 -13
  25. package/build/lib/main.js +197 -77
  26. package/build/lib/plugin-config.js +21 -11
  27. package/build/lib/plugins.js +4 -2
  28. package/build/lib/schema/appium-config-schema.js +253 -0
  29. package/build/lib/schema/arg-spec.js +120 -0
  30. package/build/lib/schema/cli-args.js +188 -0
  31. package/build/lib/schema/cli-transformers.js +76 -0
  32. package/build/lib/schema/index.js +36 -0
  33. package/build/lib/schema/keywords.js +72 -0
  34. package/build/lib/schema/schema.js +357 -0
  35. package/build/lib/utils.js +44 -99
  36. package/build/postinstall.js +90 -0
  37. package/build/test/cli/cli-e2e-specs.js +221 -0
  38. package/build/test/cli/cli-helpers.js +86 -0
  39. package/build/test/cli/cli-specs.js +71 -0
  40. package/build/test/cli/fixtures/test-driver/package.json +27 -0
  41. package/build/test/cli/schema-args-specs.js +48 -0
  42. package/build/test/cli/schema-e2e-specs.js +47 -0
  43. package/build/test/config-e2e-specs.js +112 -0
  44. package/build/test/config-file-e2e-specs.js +209 -0
  45. package/build/test/config-file-specs.js +281 -0
  46. package/build/test/config-specs.js +159 -0
  47. package/build/test/driver-e2e-specs.js +435 -0
  48. package/build/test/driver-specs.js +321 -0
  49. package/build/test/ext-config-io-specs.js +181 -0
  50. package/build/test/extension-config-specs.js +365 -0
  51. package/build/test/fixtures/allow-feat.txt +5 -0
  52. package/build/test/fixtures/caps.json +3 -0
  53. package/build/test/fixtures/config/allow-insecure.txt +3 -0
  54. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
  55. package/build/test/fixtures/config/appium.config.bad.json +32 -0
  56. package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
  57. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
  58. package/build/test/fixtures/config/appium.config.good.js +40 -0
  59. package/build/test/fixtures/config/appium.config.good.json +33 -0
  60. package/build/test/fixtures/config/appium.config.good.yaml +30 -0
  61. package/build/test/fixtures/config/appium.config.invalid.json +31 -0
  62. package/build/test/fixtures/config/appium.config.security-array.json +5 -0
  63. package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
  64. package/build/test/fixtures/config/appium.config.security-path.json +5 -0
  65. package/build/test/fixtures/config/driver-fake.config.json +8 -0
  66. package/build/test/fixtures/config/nodeconfig.json +3 -0
  67. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  68. package/build/test/fixtures/default-args.js +35 -0
  69. package/build/test/fixtures/deny-feat.txt +5 -0
  70. package/build/test/fixtures/driver.schema.js +20 -0
  71. package/build/test/fixtures/extensions.yaml +27 -0
  72. package/build/test/fixtures/flattened-schema.js +504 -0
  73. package/build/test/fixtures/plugin.schema.js +20 -0
  74. package/build/test/fixtures/schema-with-extensions.js +28 -0
  75. package/build/test/grid-register-specs.js +74 -0
  76. package/build/test/helpers.js +75 -0
  77. package/build/test/logger-specs.js +76 -0
  78. package/build/test/npm-specs.js +20 -0
  79. package/build/test/parser-specs.js +314 -0
  80. package/build/test/plugin-e2e-specs.js +316 -0
  81. package/build/test/schema/arg-spec-specs.js +70 -0
  82. package/build/test/schema/cli-args-specs.js +431 -0
  83. package/build/test/schema/schema-specs.js +389 -0
  84. package/build/test/utils-specs.js +266 -0
  85. package/index.js +11 -0
  86. package/lib/appium-config.schema.json +278 -0
  87. package/lib/appium.js +207 -65
  88. package/lib/cli/args.js +174 -375
  89. package/lib/cli/driver-command.js +4 -0
  90. package/lib/cli/extension-command.js +70 -5
  91. package/lib/cli/extension.js +25 -5
  92. package/lib/cli/npm.js +86 -18
  93. package/lib/cli/parser.js +257 -79
  94. package/lib/cli/plugin-command.js +4 -0
  95. package/lib/cli/utils.js +21 -1
  96. package/lib/config-file.js +227 -0
  97. package/lib/config.js +84 -63
  98. package/lib/driver-config.js +66 -11
  99. package/lib/drivers.js +4 -1
  100. package/lib/ext-config-io.js +287 -0
  101. package/lib/extension-config.js +225 -67
  102. package/lib/grid-register.js +27 -24
  103. package/lib/logger.js +1 -1
  104. package/lib/logsink.js +10 -7
  105. package/lib/main.js +214 -77
  106. package/lib/plugin-config.js +35 -6
  107. package/lib/plugins.js +1 -0
  108. package/lib/schema/appium-config-schema.js +287 -0
  109. package/lib/schema/arg-spec.js +222 -0
  110. package/lib/schema/cli-args.js +285 -0
  111. package/lib/schema/cli-transformers.js +123 -0
  112. package/lib/schema/index.js +2 -0
  113. package/lib/schema/keywords.js +135 -0
  114. package/lib/schema/schema.js +577 -0
  115. package/lib/utils.js +42 -88
  116. package/package.json +55 -84
  117. package/postinstall.js +71 -0
  118. package/types/appium-config.d.ts +197 -0
  119. package/types/types.d.ts +201 -0
  120. package/CHANGELOG.md +0 -3515
  121. package/build/lib/cli/parser-helpers.js +0 -82
  122. package/lib/cli/parser-helpers.js +0 -79
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _sinon = _interopRequireDefault(require("sinon"));
8
+
9
+ var _config = require("../lib/config");
10
+
11
+ var _axios = _interopRequireDefault(require("axios"));
12
+
13
+ var _support = require("@appium/support");
14
+
15
+ describe('Config', function () {
16
+ describe('getGitRev', function () {
17
+ it('should get a reasonable git revision', async function () {
18
+ let rev = await (0, _config.getGitRev)();
19
+ rev.should.be.a('string');
20
+ rev.length.should.be.equal(40);
21
+ rev.match(/[0-9a-f]+/i)[0].should.eql(rev);
22
+ });
23
+ });
24
+ describe('getBuildInfo', function () {
25
+ async function verifyBuildInfoUpdate(useLocalGit) {
26
+ const buildInfo = (0, _config.getBuildInfo)();
27
+ mockFs.expects('exists').atLeast(1).returns(useLocalGit);
28
+ buildInfo['git-sha'] = undefined;
29
+ buildInfo.built = undefined;
30
+ await (0, _config.updateBuildInfo)(true);
31
+ buildInfo.should.be.an('object');
32
+ should.exist(buildInfo['git-sha']);
33
+ should.exist(buildInfo.built);
34
+ should.exist(buildInfo.version);
35
+ }
36
+
37
+ let mockFs;
38
+ let getStub;
39
+ beforeEach(function () {
40
+ mockFs = _sinon.default.mock(_support.fs);
41
+ getStub = _sinon.default.stub(_axios.default, 'get');
42
+ });
43
+ afterEach(function () {
44
+ getStub.restore();
45
+ mockFs.restore();
46
+ });
47
+ it('should get a configuration object if the local git metadata is present', async function () {
48
+ await verifyBuildInfoUpdate(true);
49
+ });
50
+ it('should get a configuration object if the local git metadata is not present', async function () {
51
+ getStub.onCall(0).returns({
52
+ data: [{
53
+ name: `v${_config.APPIUM_VER}`,
54
+ zipball_url: 'https://api.github.com/repos/appium/appium/zipball/v1.9.0-beta.1',
55
+ tarball_url: 'https://api.github.com/repos/appium/appium/tarball/v1.9.0-beta.1',
56
+ commit: {
57
+ sha: '3c2752f9f9c56000705a4ae15b3ba68a5d2e644c',
58
+ url: 'https://api.github.com/repos/appium/appium/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c'
59
+ },
60
+ node_id: 'MDM6UmVmNzUzMDU3MDp2MS45LjAtYmV0YS4x'
61
+ }, {
62
+ name: 'v1.8.2-beta',
63
+ zipball_url: 'https://api.github.com/repos/appium/appium/zipball/v1.8.2-beta',
64
+ tarball_url: 'https://api.github.com/repos/appium/appium/tarball/v1.8.2-beta',
65
+ commit: {
66
+ sha: '5b98b9197e75aa85e7507d21d3126c1a63d1ce8f',
67
+ url: 'https://api.github.com/repos/appium/appium/commits/5b98b9197e75aa85e7507d21d3126c1a63d1ce8f'
68
+ },
69
+ node_id: 'MDM6UmVmNzUzMDU3MDp2MS44LjItYmV0YQ=='
70
+ }]
71
+ });
72
+ getStub.onCall(1).returns({
73
+ data: {
74
+ sha: '3c2752f9f9c56000705a4ae15b3ba68a5d2e644c',
75
+ node_id: 'MDY6Q29tbWl0NzUzMDU3MDozYzI3NTJmOWY5YzU2MDAwNzA1YTRhZTE1YjNiYTY4YTVkMmU2NDRj',
76
+ commit: {
77
+ author: {
78
+ name: 'Isaac Murchie',
79
+ email: 'isaac@saucelabs.com',
80
+ date: '2018-08-17T19:48:00Z'
81
+ },
82
+ committer: {
83
+ name: 'Isaac Murchie',
84
+ email: 'isaac@saucelabs.com',
85
+ date: '2018-08-17T19:48:00Z'
86
+ },
87
+ message: 'v1.9.0-beta.1',
88
+ tree: {
89
+ sha: '2c0974727470eba419ea0b9951c52f72f8036b18',
90
+ url: 'https://api.github.com/repos/appium/appium/git/trees/2c0974727470eba419ea0b9951c52f72f8036b18'
91
+ },
92
+ url: 'https://api.github.com/repos/appium/appium/git/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c',
93
+ comment_count: 0,
94
+ verification: {
95
+ verified: false,
96
+ reason: 'unsigned',
97
+ signature: null,
98
+ payload: null
99
+ }
100
+ },
101
+ url: 'https://api.github.com/repos/appium/appium/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c',
102
+ html_url: 'https://github.com/appium/appium/commit/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c',
103
+ comments_url: 'https://api.github.com/repos/appium/appium/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c/comments'
104
+ }
105
+ });
106
+ await verifyBuildInfoUpdate(false);
107
+ });
108
+ });
109
+ });require('source-map-support').install();
110
+
111
+
112
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvY29uZmlnLWUyZS1zcGVjcy5qcyJdLCJuYW1lcyI6WyJkZXNjcmliZSIsIml0IiwicmV2Iiwic2hvdWxkIiwiYmUiLCJhIiwibGVuZ3RoIiwiZXF1YWwiLCJtYXRjaCIsImVxbCIsInZlcmlmeUJ1aWxkSW5mb1VwZGF0ZSIsInVzZUxvY2FsR2l0IiwiYnVpbGRJbmZvIiwibW9ja0ZzIiwiZXhwZWN0cyIsImF0TGVhc3QiLCJyZXR1cm5zIiwidW5kZWZpbmVkIiwiYnVpbHQiLCJhbiIsImV4aXN0IiwidmVyc2lvbiIsImdldFN0dWIiLCJiZWZvcmVFYWNoIiwic2lub24iLCJtb2NrIiwiZnMiLCJzdHViIiwiYXhpb3MiLCJhZnRlckVhY2giLCJyZXN0b3JlIiwib25DYWxsIiwiZGF0YSIsIm5hbWUiLCJBUFBJVU1fVkVSIiwiemlwYmFsbF91cmwiLCJ0YXJiYWxsX3VybCIsImNvbW1pdCIsInNoYSIsInVybCIsIm5vZGVfaWQiLCJhdXRob3IiLCJlbWFpbCIsImRhdGUiLCJjb21taXR0ZXIiLCJtZXNzYWdlIiwidHJlZSIsImNvbW1lbnRfY291bnQiLCJ2ZXJpZmljYXRpb24iLCJ2ZXJpZmllZCIsInJlYXNvbiIsInNpZ25hdHVyZSIsInBheWxvYWQiLCJodG1sX3VybCIsImNvbW1lbnRzX3VybCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7O0FBQ0E7O0FBTUE7O0FBQ0E7O0FBR0FBLFFBQVEsQ0FBQyxRQUFELEVBQVcsWUFBWTtBQUM3QkEsRUFBQUEsUUFBUSxDQUFDLFdBQUQsRUFBYyxZQUFZO0FBQ2hDQyxJQUFBQSxFQUFFLENBQUMsc0NBQUQsRUFBeUMsa0JBQWtCO0FBQzNELFVBQUlDLEdBQUcsR0FBRyxNQUFNLHdCQUFoQjtBQUNBQSxNQUFBQSxHQUFHLENBQUNDLE1BQUosQ0FBV0MsRUFBWCxDQUFjQyxDQUFkLENBQWdCLFFBQWhCO0FBQ0FILE1BQUFBLEdBQUcsQ0FBQ0ksTUFBSixDQUFXSCxNQUFYLENBQWtCQyxFQUFsQixDQUFxQkcs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Y0FBQUEsSUFBSSxFQUFFLGVBREE7QUFFTlMsY0FBQUEsS0FBSyxFQUFFLHFCQUZEO0FBR05DLGNBQUFBLElBQUksRUFBRTtBQUhBLGFBREY7QUFNTkMsWUFBQUEsU0FBUyxFQUFFO0FBQ1RYLGNBQUFBLElBQUksRUFBRSxlQURHO0FBRVRTLGNBQUFBLEtBQUssRUFBRSxxQkFGRTtBQUdUQyxjQUFBQSxJQUFJLEVBQUU7QUFIRyxhQU5MO0FBV05FLFlBQUFBLE9BQU8sRUFBRSxlQVhIO0FBWU5DLFlBQUFBLElBQUksRUFBRTtBQUNKUixjQUFBQSxHQUFHLEVBQUUsMENBREQ7QUFFSkMsY0FBQUEsR0FBRyxFQUFFO0FBRkQsYUFaQTtBQWdCTkEsWUFBQUEsR0FBRyxFQUFFLGlHQWhCQztBQWlCTlEsWUFBQUEsYUFBYSxFQUFFLENBakJUO0FBa0JOQyxZQUFBQSxZQUFZLEVBQUU7QUFDWkMsY0FBQUEsUUFBUSxFQUFFLEtBREU7QUFFWkMsY0FBQUEsTUFBTSxFQUFFLFVBRkk7QUFHWkMsY0FBQUEsU0FBUyxFQUFFLElBSEM7QUFJWkMsY0FBQUEsT0FBTyxFQUFFO0FBSkc7QUFsQlIsV0FKSjtBQTZCSmIsVUFBQUEsR0FBRyxFQUFFLDZGQTdCRDtBQThCSmMsVUFBQUEsUUFBUSxFQUNOLGtGQS9CRTtBQWdDSkMsVUFBQUEsWUFBWSxFQUNWO0FBakNFO0FBRGtCLE9BQTFCO0FBcUNBLFlBQU01QyxxQkFBcUIsQ0FBQyxLQUFELENBQTNCO0FBQ0QsS0FuRUMsQ0FBRjtBQW9FRCxHQS9GTyxDQUFSO0FBZ0dELENBekdPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHtcbiAgZ2V0R2l0UmV2LFxuICBnZXRCdWlsZEluZm8sXG4gIHVwZGF0ZUJ1aWxkSW5mbyxcbiAgQVBQSVVNX1ZFUixcbn0gZnJvbSAnLi4vbGliL2NvbmZpZyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgZnMgfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuXG5cbmRlc2NyaWJlKCdDb25maWcnLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCdnZXRHaXRSZXYnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBnZXQgYSByZWFzb25hYmxlIGdpdCByZXZpc2lvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCByZXYgPSBhd2FpdCBnZXRHaXRSZXYoKTtcbiAgICAgIHJldi5zaG91bGQuYmUuYSgnc3RyaW5nJyk7XG4gICAgICByZXYubGVuZ3RoLnNob3VsZC5iZS5lcXVhbCg0MCk7XG4gICAgICByZXYubWF0Y2goL1swLTlhLWZdKy9pKVswXS5zaG91bGQuZXFsKHJldik7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnZ2V0QnVpbGRJbmZvJywgZnVuY3Rpb24gKCkge1xuICAgIGFzeW5jIGZ1bmN0aW9uIHZlcmlmeUJ1aWxkSW5mb1VwZGF0ZSAodXNlTG9jYWxHaXQpIHtcbiAgICAgIGNvbnN0IGJ1aWxkSW5mbyA9IGdldEJ1aWxkSW5mbygpO1xuICAgICAgbW9ja0ZzLmV4cGVjdHMoJ2V4aXN0cycpLmF0TGVhc3QoMSkucmV0dXJucyh1c2VMb2NhbEdpdCk7XG4gICAgICBidWlsZEluZm9bJ2dpdC1zaGEnXSA9IHVuZGVmaW5lZDtcbiAgICAgIGJ1aWxkSW5mby5idWlsdCA9IHVuZGVmaW5lZDtcbiAgICAgIGF3YWl0IHVwZGF0ZUJ1aWxkSW5mbyh0cnVlKTtcbiAgICAgIGJ1aWxkSW5mby5zaG91bGQuYmUuYW4oJ29iamVjdCcpO1xuICAgICAgc2hvdWxkLmV4aXN0KGJ1aWxkSW5mb1snZ2l0LXNoYSddKTtcbiAgICAgIHNob3VsZC5leGlzdChidWlsZEluZm8uYnVpbHQpO1xuICAgICAgc2hvdWxkLmV4aXN0KGJ1aWxkSW5mby52ZXJzaW9uKTtcbiAgICB9XG5cbiAgICBsZXQgbW9ja0ZzO1xuICAgIGxldCBnZXRTdHViO1xuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbW9ja0ZzID0gc2lub24ubW9jayhmcyk7XG4gICAgICBnZXRTdHViID0gc2lub24uc3R1YihheGlvcywgJ2dldCcpO1xuICAgIH0pO1xuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBnZXRTdHViLnJlc3RvcmUoKTtcbiAgICAgIG1vY2tGcy5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGlmIHRoZSBsb2NhbCBnaXQgbWV0YWRhdGEgaXMgcHJlc2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHZlcmlmeUJ1aWxkSW5mb1VwZGF0ZSh0cnVlKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGdldCBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGlmIHRoZSBsb2NhbCBnaXQgbWV0YWRhdGEgaXMgbm90IHByZXNlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBnZXRTdHViLm9uQ2FsbCgwKS5yZXR1cm5zKHtcbiAgICAgICAgZGF0YTogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6IGB2JHtBUFBJVU1fVkVSfWAsXG4gICAgICAgICAgICB6aXBiYWxsX3VybDpcbiAgICAgICAgICAgICAgJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvYXBwaXVtL2FwcGl1bS96aXBiYWxsL3YxLjkuMC1iZXRhLjEnLFxuICAgICAgICAgICAgdGFyYmFsbF91cmw6XG4gICAgICAgICAgICAgICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL2FwcGl1bS9hcHBpdW0vdGFyYmFsbC92MS45LjAtYmV0YS4xJyxcbiAgICAgICAgICAgIGNvbW1pdDoge1xuICAgICAgICAgICAgICBzaGE6ICczYzI3NTJmOWY5YzU2MDAwNzA1YTRhZTE1YjNiYTY4YTVkMmU2NDRjJyxcbiAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy9hcHBpdW0vYXBwaXVtL2NvbW1pdHMvM2MyNzUyZjlmOWM1NjAwMDcwNWE0YWUxNWIzYmE2OGE1ZDJlNjQ0YycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbm9kZV9pZDogJ01ETTZVbVZtTnpVek1EVTNNRHAyTVM0NUxqQXRZbVYwWVM0eCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAndjEuOC4yLWJldGEnLFxuICAgICAgICAgICAgemlwYmFsbF91cmw6XG4gICAgICAgICAgICAgICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL2FwcGl1bS9hcHBpdW0vemlwYmFsbC92MS44LjItYmV0YScsXG4gICAgICAgICAgICB0YXJiYWxsX3VybDpcbiAgICAgICAgICAgICAgJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvYXBwaXVtL2FwcGl1bS90YXJiYWxsL3YxLjguMi1iZXRhJyxcbiAgICAgICAgICAgIGNvbW1pdDoge1xuICAgICAgICAgICAgICBzaGE6ICc1Yjk4YjkxOTdlNzVhYTg1ZTc1MDdkMjFkMzEyNmMxYTYzZDFjZThmJyxcbiAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy9hcHBpdW0vYXBwaXVtL2NvbW1pdHMvNWI5OGI5MTk3ZTc1YWE4NWU3NTA3ZDIxZDMxMjZjMWE2M2QxY2U4ZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbm9kZV9pZDogJ01ETTZVbVZtTnpVek1EVTNNRHAyTVM0NExqSXRZbVYwWVE9PScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgICAgZ2V0U3R1Yi5vbkNhbGwoMSkucmV0dXJucyh7XG4gICAgICAgIGRhdGE6IHtcbiAgICAgICAgICBzaGE6ICczYzI3NTJmOWY5YzU2MDAwNzA1YTRhZTE1YjNiYTY4YTVkMmU2NDRjJyxcbiAgICAgICAgICBub2RlX2lkOlxuICAgICAgICAgICAgJ01EWTZRMjl0YldsME56VXpNRFUzTURvell6STNOVEptT1dZNVl6VTJNREF3TnpBMVlUUmhaVEUxWWpOaVlUWTRZVFZrTW1VMk5EUmonLFxuICAgICAgICAgIGNvbW1pdDoge1xuICAgICAgICAgICAgYXV0aG9yOiB7XG4gICAgICAgICAgICAgIG5hbWU6ICdJc2FhYyBNdXJjaGllJyxcbiAgICAgICAgICAgICAgZW1haWw6ICdpc2FhY0BzYXVjZWxhYnMuY29tJyxcbiAgICAgICAgICAgICAgZGF0ZTogJzIwMTgtMDgtMTdUMTk6NDg6MDBaJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21taXR0ZXI6IHtcbiAgICAgICAgICAgICAgbmFtZTogJ0lzYWFjIE11cmNoaWUnLFxuICAgICAgICAgICAgICBlbWFpbDogJ2lzYWFjQHNhdWNlbGFicy5jb20nLFxuICAgICAgICAgICAgICBkYXRlOiAnMjAxOC0wOC0xN1QxOTo0ODowMFonLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICd2MS45LjAtYmV0YS4xJyxcbiAgICAgICAgICAgIHRyZWU6IHtcbiAgICAgICAgICAgICAgc2hhOiAnMmMwOTc0NzI3NDcwZWJhNDE5ZWEwYjk5NTFjNTJmNzJmODAzNmIxOCcsXG4gICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvYXBwaXVtL2FwcGl1bS9naXQvdHJlZXMvMmMwOTc0NzI3NDcwZWJhNDE5ZWEwYjk5NTFjNTJmNzJmODAzNmIxOCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy9hcHBpdW0vYXBwaXVtL2dpdC9jb21taXRzLzNjMjc1MmY5ZjljNTYwMDA3MDVhNGFlMTViM2JhNjhhNWQyZTY0NGMnLFxuICAgICAgICAgICAgY29tbWVudF9jb3VudDogMCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXG4gICAgICAgICAgICAgIHJlYXNvbjogJ3Vuc2lnbmVkJyxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlOiBudWxsLFxuICAgICAgICAgICAgICBwYXlsb2FkOiBudWxsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHVybDogJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvYXBwaXVtL2FwcGl1bS9jb21taXRzLzNjMjc1MmY5ZjljNTYwMDA3MDVhNGFlMTViM2JhNjhhNWQyZTY0NGMnLFxuICAgICAgICAgIGh0bWxfdXJsOlxuICAgICAgICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2NvbW1pdC8zYzI3NTJmOWY5YzU2MDAwNzA1YTRhZTE1YjNiYTY4YTVkMmU2NDRjJyxcbiAgICAgICAgICBjb21tZW50c191cmw6XG4gICAgICAgICAgICAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy9hcHBpdW0vYXBwaXVtL2NvbW1pdHMvM2MyNzUyZjlmOWM1NjAwMDcwNWE0YWUxNWIzYmE2OGE1ZDJlNjQ0Yy9jb21tZW50cycsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHZlcmlmeUJ1aWxkSW5mb1VwZGF0ZShmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvY29uZmlnLWUyZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _configFile = require("../lib/config-file");
8
+
9
+ var _schema = require("../lib/schema/schema");
10
+
11
+ var _driverSchema = _interopRequireDefault(require("./fixtures/driver.schema.js"));
12
+
13
+ var _helpers = require("./helpers");
14
+
15
+ describe('config file behavior', function () {
16
+ const GOOD_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.good.json');
17
+ const BAD_NODECONFIG_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.bad-nodeconfig.json');
18
+ const BAD_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.bad.json');
19
+ const INVALID_JSON_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.invalid.json');
20
+ const SECURITY_ARRAY_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.security-array.json');
21
+ const SECURITY_DELIMITED_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.security-delimited.json');
22
+ const SECURITY_PATH_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.security-path.json');
23
+ const UNKNOWN_PROPS_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.ext-unknown-props.json');
24
+ const EXT_PROPS_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.ext-good.json');
25
+ beforeEach(function () {
26
+ (0, _schema.finalizeSchema)();
27
+ });
28
+ afterEach(function () {
29
+ (0, _schema.resetSchema)();
30
+ });
31
+ describe('when provided a path to a config file', function () {
32
+ describe('when the config file is valid per the schema', function () {
33
+ it('should return a valid config object', async function () {
34
+ const result = await (0, _configFile.readConfigFile)(GOOD_FILEPATH, {
35
+ normalize: false
36
+ });
37
+ result.should.deep.equal({
38
+ config: require(GOOD_FILEPATH),
39
+ filepath: GOOD_FILEPATH,
40
+ errors: []
41
+ });
42
+ });
43
+ describe('server.nodeconfig behavior', function () {
44
+ describe('when a string', function () {
45
+ it('should return errors', async function () {
46
+ const result = await (0, _configFile.readConfigFile)(BAD_NODECONFIG_FILEPATH, {
47
+ normalize: false
48
+ });
49
+ result.should.have.nested.property('errors[0].instancePath', '/server/nodeconfig');
50
+ });
51
+ });
52
+ describe('when an object', function () {
53
+ it('should return a valid config object', async function () {
54
+ const result = await (0, _configFile.readConfigFile)(GOOD_FILEPATH, {
55
+ normalize: false
56
+ });
57
+ result.should.have.property('errors').that.is.empty;
58
+ });
59
+ });
60
+ });
61
+ describe('server.allow-insecure behavior', function () {
62
+ describe('when a string path', function () {
63
+ it('should return errors', async function () {
64
+ const result = await (0, _configFile.readConfigFile)(SECURITY_PATH_FILEPATH, {
65
+ normalize: false
66
+ });
67
+ result.should.have.nested.property('errors[0].instancePath', '/server/allow-insecure');
68
+ });
69
+ });
70
+ describe('when a comma-delimited string', function () {
71
+ it('should return errors', async function () {
72
+ const result = await (0, _configFile.readConfigFile)(SECURITY_DELIMITED_FILEPATH, {
73
+ normalize: false
74
+ });
75
+ result.should.have.nested.property('errors[0].instancePath', '/server/allow-insecure');
76
+ });
77
+ });
78
+ describe('when an array', function () {
79
+ it('should return a valid config object', async function () {
80
+ const result = await (0, _configFile.readConfigFile)(SECURITY_ARRAY_FILEPATH, {
81
+ normalize: false
82
+ });
83
+ result.should.deep.equal({
84
+ config: require(SECURITY_ARRAY_FILEPATH),
85
+ filepath: SECURITY_ARRAY_FILEPATH,
86
+ errors: []
87
+ });
88
+ });
89
+ });
90
+ });
91
+ });
92
+ describe('when the config file is invalid per the schema', function () {
93
+ describe('without extensions', function () {
94
+ it('should return an object containing errors', async function () {
95
+ const result = await (0, _configFile.readConfigFile)(BAD_FILEPATH, {
96
+ normalize: false
97
+ });
98
+ result.should.have.deep.property('config', require(BAD_FILEPATH));
99
+ result.should.have.property('filepath', BAD_FILEPATH);
100
+ result.should.have.deep.property('errors').that.contains.members([{
101
+ instancePath: '',
102
+ schemaPath: '#/additionalProperties',
103
+ keyword: 'additionalProperties',
104
+ params: {
105
+ additionalProperty: 'appium-home'
106
+ },
107
+ message: 'must NOT have additional properties',
108
+ isIdentifierLocation: true
109
+ }, {
110
+ instancePath: '/server/allow-cors',
111
+ schemaPath: '#/properties/server/properties/allow-cors/type',
112
+ keyword: 'type',
113
+ params: {
114
+ type: 'boolean'
115
+ },
116
+ message: 'must be boolean'
117
+ }, {
118
+ instancePath: '/server/allow-insecure',
119
+ schemaPath: '#/properties/server/properties/allow-insecure/type',
120
+ keyword: 'type',
121
+ params: {
122
+ type: 'array'
123
+ },
124
+ message: 'must be array'
125
+ }, {
126
+ instancePath: '/server/callback-port',
127
+ schemaPath: '#/properties/server/properties/callback-port/maximum',
128
+ keyword: 'maximum',
129
+ params: {
130
+ comparison: '<=',
131
+ limit: 65535
132
+ },
133
+ message: 'must be <= 65535'
134
+ }, {
135
+ instancePath: '/server/log-level',
136
+ schemaPath: '#/properties/server/properties/log-level/enum',
137
+ keyword: 'enum',
138
+ params: {
139
+ allowedValues: ['info', 'info:debug', 'info:info', 'info:warn', 'info:error', 'warn', 'warn:debug', 'warn:info', 'warn:warn', 'warn:error', 'error', 'error:debug', 'error:info', 'error:warn', 'error:error', 'debug', 'debug:debug', 'debug:info', 'debug:warn', 'debug:error']
140
+ },
141
+ message: 'must be equal to one of the allowed values'
142
+ }, {
143
+ instancePath: '/server/log-no-colors',
144
+ schemaPath: '#/properties/server/properties/log-no-colors/type',
145
+ keyword: 'type',
146
+ params: {
147
+ type: 'boolean'
148
+ },
149
+ message: 'must be boolean'
150
+ }, {
151
+ instancePath: '/server/port',
152
+ schemaPath: '#/properties/server/properties/port/type',
153
+ keyword: 'type',
154
+ params: {
155
+ type: 'integer'
156
+ },
157
+ message: 'must be integer'
158
+ }]).and.lengthOf(7);
159
+ result.should.have.property('reason').that.is.a.string;
160
+ });
161
+ });
162
+ describe('with extensions', function () {
163
+ let result;
164
+ beforeEach(function () {
165
+ (0, _schema.resetSchema)();
166
+ (0, _schema.registerSchema)('driver', 'fake', _driverSchema.default);
167
+ (0, _schema.finalizeSchema)();
168
+ });
169
+ describe('when provided a config file with unknown properties', function () {
170
+ beforeEach(async function () {
171
+ result = await (0, _configFile.readConfigFile)(UNKNOWN_PROPS_FILEPATH, {
172
+ normalize: false
173
+ });
174
+ });
175
+ it('should return an object containing errors', function () {
176
+ result.should.have.deep.property('errors', [{
177
+ instancePath: '/server/driver/fake',
178
+ schemaPath: 'driver-fake.json/additionalProperties',
179
+ keyword: 'additionalProperties',
180
+ params: {
181
+ additionalProperty: 'bubb'
182
+ },
183
+ message: 'must NOT have additional properties',
184
+ isIdentifierLocation: true
185
+ }]);
186
+ });
187
+ });
188
+ describe('when provided a config file with valid properties', function () {
189
+ beforeEach(async function () {
190
+ result = await (0, _configFile.readConfigFile)(EXT_PROPS_FILEPATH, {
191
+ normalize: false
192
+ });
193
+ });
194
+ it('should return an object containing no errors', function () {
195
+ result.should.have.deep.property('errors', []);
196
+ });
197
+ });
198
+ });
199
+ });
200
+ describe('when the config file is invalid JSON', function () {
201
+ it('should reject with a user-friendly error message', async function () {
202
+ await (0, _configFile.readConfigFile)(INVALID_JSON_FILEPATH).should.be.rejectedWith(new RegExp(`${INVALID_JSON_FILEPATH} is invalid`));
203
+ });
204
+ });
205
+ });
206
+ });require('source-map-support').install();
207
+
208
+
209
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvY29uZmlnLWZpbGUtZTJlLXNwZWNzLmpzIl0sIm5hbWVzIjpbImRlc2NyaWJlIiwiR09PRF9GSUxFUEFUSCIsIkJBRF9OT0RFQ09ORklHX0ZJTEVQQVRIIiwiQkFEX0ZJTEVQQVRIIiwiSU5WQUxJRF9KU09OX0ZJTEVQQVRIIiwiU0VDVVJJVFlfQVJSQVlfRklMRVBBVEgiLCJTRUNVUklUWV9ERUxJTUlURURfRklMRVBBVEgiLCJTRUNVUklUWV9QQVRIX0ZJTEVQQVRIIiwiVU5LTk9XTl9QUk9QU19GSUxFUEFUSCIsIkVYVF9QUk9QU19GSUxFUEFUSCIsImJlZm9yZUVhY2giLCJhZnRlckVhY2giLCJpdCIsInJlc3VsdCIsIm5vcm1hbGl6ZSIsInNob3VsZCIsImRlZXAiLCJlcXVhbCIsImNvbmZpZyIsInJlcXVpcmUiLCJmaWxlcGF0aCIsImVycm9ycyIsImhhdmUiLCJuZXN0ZWQiLCJwcm9wZXJ0eSIsInRoYXQiLCJpcyIsImVtcHR5IiwiY29udGFpbnMiLCJtZW1iZXJzIiwiaW5zdGFuY2VQYXRoIiwic2NoZW1hUGF0aCIsImtleXdvcmQiLCJwYXJhbXMiLCJhZGRpdGlvbmFsUHJvcGVydHkiLCJtZXNzYWdlIiwiaXNJZGVudGlmaWVyTG9jYXRpb24iLCJ0eXBlIiwiY29tcGFyaXNvbiIsImxpbWl0IiwiYWxsb3dlZFZhbHVlcyIsImFuZCIsImxlbmd0aE9mIiwiYSIsInN0cmluZyIsImV4dFNjaGVtYSIsImJlIiwicmVqZWN0ZWRXaXRoIiwiUmVnRXhwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQUEsUUFBUSxDQUFDLHNCQUFELEVBQXlCLFlBQVk7QUFDM0MsUUFBTUMsYUFBYSxHQUFHLDZCQUFlLFFBQWYsRUFBeUIseUJBQXpCLENBQXRCO0FBQ0EsUUFBTUMsdUJBQXVCLEdBQUcsNkJBQzlCLFFBRDhCLEVBRTlCLG1DQUY4QixDQUFoQztBQUlBLFFBQU1DLFlBQVksR0FBRyw2QkFBZSxRQUFmLEVB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V0QsV0FaQyxDQUFGO0FBYUQsU0FuQk8sQ0FBUjtBQXFCQXBDLFFBQUFBLFFBQVEsQ0FBQyxtREFBRCxFQUFzRCxZQUFZO0FBQ3hFVSxVQUFBQSxVQUFVLENBQUMsa0JBQWtCO0FBQzNCRyxZQUFBQSxNQUFNLEdBQUcsTUFBTSxnQ0FBZUosa0JBQWYsRUFBbUM7QUFDaERLLGNBQUFBLFNBQVMsRUFBRTtBQURxQyxhQUFuQyxDQUFmO0FBR0QsV0FKUyxDQUFWO0FBS0FGLFVBQUFBLEVBQUUsQ0FBQyw4Q0FBRCxFQUFpRCxZQUFZO0FBQzdEQyxZQUFBQSxNQUFNLENBQUNFLE1BQVAsQ0FBY08sSUFBZCxDQUFtQk4sSUFBbkIsQ0FBd0JRLFFBQXhCLENBQWlDLFFBQWpDLEVBQTJDLEVBQTNDO0FBQ0QsV0FGQyxDQUFGO0FBR0QsU0FUTyxDQUFSO0FBVUQsT0F6Q08sQ0FBUjtBQTBDRCxLQWhKTyxDQUFSO0FBa0pBeEIsSUFBQUEsUUFBUSxDQUFDLHNDQUFELEVBQXlDLFlBQVk7QUFDM0RZLE1BQUFBLEVBQUUsQ0FBQyxrREFBRCxFQUFxRCxrQkFBa0I7QUFDdkUsY0FBTSxnQ0FBZVIscUJBQWYsRUFBc0NXLE1BQXRDLENBQTZDK0IsRUFBN0MsQ0FBZ0RDLFlBQWhELENBQ0osSUFBSUMsTUFBSixDQUFZLEdBQUU1QyxxQkFBc0IsYUFBcEMsQ0FESSxDQUFOO0FBR0QsT0FKQyxDQUFGO0FBS0QsS0FOTyxDQUFSO0FBT0QsR0FyT08sQ0FBUjtBQXNPRCxDQTlRTyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7IHJlYWRDb25maWdGaWxlIH0gZnJvbSAnLi4vbGliL2NvbmZpZy1maWxlJztcbmltcG9ydCB7IGZpbmFsaXplU2NoZW1hLCByZWdpc3RlclNjaGVtYSwgcmVzZXRTY2hlbWEgfSBmcm9tICcuLi9saWIvc2NoZW1hL3NjaGVtYSc7XG5pbXBvcnQgZXh0U2NoZW1hIGZyb20gJy4vZml4dHVyZXMvZHJpdmVyLnNjaGVtYS5qcyc7XG5pbXBvcnQgeyByZXNvbHZlRml4dHVyZSB9IGZyb20gJy4vaGVscGVycyc7XG5cbmRlc2NyaWJlKCdjb25maWcgZmlsZSBiZWhhdmlvcicsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgR09PRF9GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKCdjb25maWcnLCAnYXBwaXVtLmNvbmZpZy5nb29kLmpzb24nKTtcbiAgY29uc3QgQkFEX05PREVDT05GSUdfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZShcbiAgICAnY29uZmlnJyxcbiAgICAnYXBwaXVtLmNvbmZpZy5iYWQtbm9kZWNvbmZpZy5qc29uJyxcbiAgKTtcbiAgY29uc3QgQkFEX0ZJTEVQQVRIID0gcmVzb2x2ZUZpeHR1cmUoJ2NvbmZpZycsICdhcHBpdW0uY29uZmlnLmJhZC5qc29uJyk7XG4gIGNvbnN0IElOVkFMSURfSlNPTl9GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKFxuICAgICdjb25maWcnLFxuICAgICdhcHBpdW0uY29uZmlnLmludmFsaWQuanNvbicsXG4gICk7XG4gIGNvbnN0IFNFQ1VSSVRZX0FSUkFZX0ZJTEVQQVRIID0gcmVzb2x2ZUZpeHR1cmUoXG4gICAgJ2NvbmZpZycsXG4gICAgJ2FwcGl1bS5jb25maWcuc2VjdXJpdHktYXJyYXkuanNvbicsXG4gICk7XG4gIGNvbnN0IFNFQ1VSSVRZX0RFTElNSVRFRF9GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKFxuICAgICdjb25maWcnLFxuICAgICdhcHBpdW0uY29uZmlnLnNlY3VyaXR5LWRlbGltaXRlZC5qc29uJyxcbiAgKTtcbiAgY29uc3QgU0VDVVJJVFlfUEFUSF9GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKFxuICAgICdjb25maWcnLFxuICAgICdhcHBpdW0uY29uZmlnLnNlY3VyaXR5LXBhdGguanNvbicsXG4gICk7XG4gIGNvbnN0IFVOS05PV05fUFJPUFNfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZShcbiAgICAnY29uZmlnJyxcbiAgICAnYXBwaXVtLmNvbmZpZy5leHQtdW5rbm93bi1wcm9wcy5qc29uJyxcbiAgKTtcbiAgY29uc3QgRVhUX1BST1BTX0ZJTEVQQVRIID0gcmVzb2x2ZUZpeHR1cmUoXG4gICAgJ2NvbmZpZycsXG4gICAgJ2FwcGl1bS5jb25maWcuZXh0LWdvb2QuanNvbicsXG4gICk7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgZmluYWxpemVTY2hlbWEoKTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICByZXNldFNjaGVtYSgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhIHBhdGggdG8gYSBjb25maWcgZmlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgdmFsaWQgcGVyIHRoZSBzY2hlbWEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHZhbGlkIGNvbmZpZyBvYmplY3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKEdPT0RfRklMRVBBVEgsIHtcbiAgICAgICAgICBub3JtYWxpemU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgICBjb25maWc6IHJlcXVpcmUoR09PRF9GSUxFUEFUSCksXG4gICAgICAgICAgZmlsZXBhdGg6IEdPT0RfRklMRVBBVEgsXG4gICAgICAgICAgZXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3NlcnZlci5ub2RlY29uZmlnIGJlaGF2aW9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnd2hlbiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBlcnJvcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZShCQURfTk9ERUNPTkZJR19GSUxFUEFUSCwge1xuICAgICAgICAgICAgICBub3JtYWxpemU6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUubmVzdGVkLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnZXJyb3JzWzBdLmluc3RhbmNlUGF0aCcsXG4gICAgICAgICAgICAgICcvc2VydmVyL25vZGVjb25maWcnLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gYW4gb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgdmFsaWQgY29uZmlnIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKEdPT0RfRklMRVBBVEgsIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdlcnJvcnMnKS50aGF0LmlzLmVtcHR5O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnc2VydmVyLmFsbG93LWluc2VjdXJlIGJlaGF2aW9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnd2hlbiBhIHN0cmluZyBwYXRoJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGVycm9ycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKFNFQ1VSSVRZX1BBVEhfRklMRVBBVEgsIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLm5lc3RlZC5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ2Vycm9yc1swXS5pbnN0YW5jZVBhdGgnLFxuICAgICAgICAgICAgICAnL3NlcnZlci9hbGxvdy1pbnNlY3VyZScsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiBhIGNvbW1hLWRlbGltaXRlZCBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZXJyb3JzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoU0VDVVJJVFlfREVMSU1JVEVEX0ZJTEVQQVRILCB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZTogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5uZXN0ZWQucHJvcGVydHkoXG4gICAgICAgICAgICAgICdlcnJvcnNbMF0uaW5zdGFuY2VQYXRoJyxcbiAgICAgICAgICAgICAgJy9zZXJ2ZXIvYWxsb3ctaW5zZWN1cmUnLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gYW4gYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSB2YWxpZCBjb25maWcgb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoU0VDVVJJVFlfQVJSQVlfRklMRVBBVEgsIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzdWx0LnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgICAgICAgY29uZmlnOiByZXF1aXJlKFNFQ1VSSVRZX0FSUkFZX0ZJTEVQQVRIKSxcbiAgICAgICAgICAgICAgZmlsZXBhdGg6IFNFQ1VSSVRZX0FSUkFZX0ZJTEVQQVRILFxuICAgICAgICAgICAgICBlcnJvcnM6IFtdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgaW52YWxpZCBwZXIgdGhlIHNjaGVtYScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCd3aXRob3V0IGV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGVycm9ycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZShCQURfRklMRVBBVEgsIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZTogZmFsc2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLmRlZXAucHJvcGVydHkoJ2NvbmZpZycsIHJlcXVpcmUoQkFEX0ZJTEVQQVRIKSk7XG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmaWxlcGF0aCcsIEJBRF9GSUxFUEFUSCk7XG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLmRlZXAucHJvcGVydHkoJ2Vycm9ycycpLnRoYXQuY29udGFpbnMubWVtYmVycyhbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGluc3RhbmNlUGF0aDogJycsXG4gICAgICAgICAgICAgIHNjaGVtYVBhdGg6ICcjL2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICAga2V5d29yZDogJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnR5OiAnYXBwaXVtLWhvbWUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnbXVzdCBOT1QgaGF2ZSBhZGRpdGlvbmFsIHByb3BlcnRpZXMnLFxuICAgICAgICAgICAgICBpc0lkZW50aWZpZXJMb2NhdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGluc3RhbmNlUGF0aDogJy9zZXJ2ZXIvYWxsb3ctY29ycycsXG4gICAgICAgICAgICAgIHNjaGVtYVBhdGg6ICcjL3Byb3BlcnRpZXMvc2VydmVyL3Byb3BlcnRpZXMvYWxsb3ctY29ycy90eXBlJyxcbiAgICAgICAgICAgICAga2V5d29yZDogJ3R5cGUnLFxuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdtdXN0IGJlIGJvb2xlYW4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnL3NlcnZlci9hbGxvdy1pbnNlY3VyZScsXG4gICAgICAgICAgICAgIHNjaGVtYVBhdGg6ICcjL3Byb3BlcnRpZXMvc2VydmVyL3Byb3BlcnRpZXMvYWxsb3ctaW5zZWN1cmUvdHlwZScsXG4gICAgICAgICAgICAgIGtleXdvcmQ6ICd0eXBlJyxcbiAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2FycmF5J1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnbXVzdCBiZSBhcnJheScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpbnN0YW5jZVBhdGg6ICcvc2VydmVyL2NhbGxiYWNrLXBvcnQnLFxuICAgICAgICAgICAgICBzY2hlbWFQYXRoOlxuICAgICAgICAgICAgICAgICcjL3Byb3BlcnRpZXMvc2VydmVyL3Byb3BlcnRpZXMvY2FsbGJhY2stcG9ydC9tYXhpbXVtJyxcbiAgICAgICAgICAgICAga2V5d29yZDogJ21heGltdW0nLFxuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBjb21wYXJpc29uOiAnPD0nLFxuICAgICAgICAgICAgICAgIGxpbWl0OiA2NTUzNSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ211c3QgYmUgPD0gNjU1MzUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnL3NlcnZlci9sb2ctbGV2ZWwnLFxuICAgICAgICAgICAgICBzY2hlbWFQYXRoOiAnIy9wcm9wZXJ0aWVzL3NlcnZlci9wcm9wZXJ0aWVzL2xvZy1sZXZlbC9lbnVtJyxcbiAgICAgICAgICAgICAga2V5d29yZDogJ2VudW0nLFxuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBhbGxvd2VkVmFsdWVzOiBbXG4gICAgICAgICAgICAgICAgICAnaW5mbycsXG4gICAgICAgICAgICAgICAgICAnaW5mbzpkZWJ1ZycsXG4gICAgICAgICAgICAgICAgICAnaW5mbzppbmZvJyxcbiAgICAgICAgICAgICAgICAgICdpbmZvOndhcm4nLFxuICAgICAgICAgICAgICAgICAgJ2luZm86ZXJyb3InLFxuICAgICAgICAgICAgICAgICAgJ3dhcm4nLFxuICAgICAgICAgICAgICAgICAgJ3dhcm46ZGVidWcnLFxuICAgICAgICAgICAgICAgICAgJ3dhcm46aW5mbycsXG4gICAgICAgICAgICAgICAgICAnd2Fybjp3YXJuJyxcbiAgICAgICAgICAgICAgICAgICd3YXJuOmVycm9yJyxcbiAgICAgICAgICAgICAgICAgICdlcnJvcicsXG4gICAgICAgICAgICAgICAgICAnZXJyb3I6ZGVidWcnLFxuICAgICAgICAgICAgICAgICAgJ2Vycm9yOmluZm8nLFxuICAgICAgICAgICAgICAgICAgJ2Vycm9yOndhcm4nLFxuICAgICAgICAgICAgICAgICAgJ2Vycm9yOmVycm9yJyxcbiAgICAgICAgICAgICAgICAgICdkZWJ1ZycsXG4gICAgICAgICAgICAgICAgICAnZGVidWc6ZGVidWcnLFxuICAgICAgICAgICAgICAgICAgJ2RlYnVnOmluZm8nLFxuICAgICAgICAgICAgICAgICAgJ2RlYnVnOndhcm4nLFxuICAgICAgICAgICAgICAgICAgJ2RlYnVnOmVycm9yJyxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnbXVzdCBiZSBlcXVhbCB0byBvbmUgb2YgdGhlIGFsbG93ZWQgdmFsdWVzJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGluc3RhbmNlUGF0aDogJy9zZXJ2ZXIvbG9nLW5vLWNvbG9ycycsXG4gICAgICAgICAgICAgIHNjaGVtYVBhdGg6ICcjL3Byb3BlcnRpZXMvc2VydmVyL3Byb3BlcnRpZXMvbG9nLW5vLWNvbG9ycy90eXBlJyxcbiAgICAgICAgICAgICAga2V5d29yZDogJ3R5cGUnLFxuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdtdXN0IGJlIGJvb2xlYW4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnL3NlcnZlci9wb3J0JyxcbiAgICAgICAgICAgICAgc2NoZW1hUGF0aDogJyMvcHJvcGVydGllcy9zZXJ2ZXIvcHJvcGVydGllcy9wb3J0L3R5cGUnLFxuICAgICAgICAgICAgICBrZXl3b3JkOiAndHlwZScsXG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdpbnRlZ2VyJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ211c3QgYmUgaW50ZWdlcicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0pLmFuZC5sZW5ndGhPZig3KTtcblxuICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVhc29uJykudGhhdC5pcy5hLnN0cmluZztcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3dpdGggZXh0ZW5zaW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoJy4uL2xpYi9jb25maWctZmlsZScpLlJlYWRDb25maWdGaWxlUmVzdWx0fSAqL1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJlc2V0U2NoZW1hKCk7XG4gICAgICAgICAgcmVnaXN0ZXJTY2hlbWEoJ2RyaXZlcicsICdmYWtlJywgZXh0U2NoZW1hKTtcbiAgICAgICAgICBmaW5hbGl6ZVNjaGVtYSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhIGNvbmZpZyBmaWxlIHdpdGggdW5rbm93biBwcm9wZXJ0aWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoVU5LTk9XTl9QUk9QU19GSUxFUEFUSCwge1xuICAgICAgICAgICAgICBub3JtYWxpemU6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgZXJyb3JzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLmRlZXAucHJvcGVydHkoJ2Vycm9ycycsIFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlUGF0aDogJy9zZXJ2ZXIvZHJpdmVyL2Zha2UnLFxuICAgICAgICAgICAgICAgIHNjaGVtYVBhdGg6XG4gICAgICAgICAgICAgICAgICAnZHJpdmVyLWZha2UuanNvbi9hZGRpdGlvbmFsUHJvcGVydGllcycsXG4gICAgICAgICAgICAgICAga2V5d29yZDogJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHthZGRpdGlvbmFsUHJvcGVydHk6ICdidWJiJ30sXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ211c3QgTk9UIGhhdmUgYWRkaXRpb25hbCBwcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICAgICBpc0lkZW50aWZpZXJMb2NhdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhIGNvbmZpZyBmaWxlIHdpdGggdmFsaWQgcHJvcGVydGllcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKEVYVF9QUk9QU19GSUxFUEFUSCwge1xuICAgICAgICAgICAgICBub3JtYWxpemU6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgbm8gZXJyb3JzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLmRlZXAucHJvcGVydHkoJ2Vycm9ycycsIFtdKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBpcyBpbnZhbGlkIEpTT04nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCB3aXRoIGEgdXNlci1mcmllbmRseSBlcnJvciBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCByZWFkQ29uZmlnRmlsZShJTlZBTElEX0pTT05fRklMRVBBVEgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgbmV3IFJlZ0V4cChgJHtJTlZBTElEX0pTT05fRklMRVBBVEh9IGlzIGludmFsaWRgKSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L2NvbmZpZy1maWxlLWUyZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9