appium-xcuitest-driver 4.16.0 → 4.16.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [4.16.2](https://github.com/appium/appium-xcuitest-driver/compare/v4.16.1...v4.16.2) (2022-12-18)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * XCTest command ([#1471](https://github.com/appium/appium-xcuitest-driver/issues/1471)) ([d176f45](https://github.com/appium/appium-xcuitest-driver/commit/d176f455c23b4c6b59ff72be36d3050c60bcf470))
7
+
8
+ ## [4.16.1](https://github.com/appium/appium-xcuitest-driver/compare/v4.16.0...v4.16.1) (2022-12-17)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * /wda/device/appearance as withoutSession ([#1472](https://github.com/appium/appium-xcuitest-driver/issues/1472)) ([00eba1d](https://github.com/appium/appium-xcuitest-driver/commit/00eba1d9eb42c998ffe93d978cb9fb4c5f761b35))
14
+
1
15
  ## [4.16.0](https://github.com/appium/appium-xcuitest-driver/compare/v4.15.2...v4.16.0) (2022-12-16)
2
16
 
3
17
 
package/README.md CHANGED
@@ -1048,6 +1048,7 @@ The API calls returns a map with the following entries:
1048
1048
  * testName: Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')
1049
1049
  * passed: Did the tests pass?
1050
1050
  * crashed: Did the tests crash?
1051
+ * status: Test result status (e.g.: 'passed', 'failed', 'crashed')
1051
1052
  * duration: How long did the tests take (in seconds)
1052
1053
  * failureMessage: Failure message (if applicable)
1053
1054
  * location The geolocation of the test (if applicable)
@@ -30,7 +30,7 @@ commands.mobileSetAppearance = async function mobileSetAppearance(opts = {}) {
30
30
  try {
31
31
  return void (await this.proxyCommand('/wda/device/appearance', 'POST', {
32
32
  name: style
33
- }));
33
+ }, false));
34
34
  } catch (e) {
35
35
  this.log.debug(e.stack);
36
36
  }
@@ -57,4 +57,4 @@ commands.mobileGetAppearance = async function mobileGetAppearance() {
57
57
  };
58
58
  var _default = commands;
59
59
  exports.default = _default;
60
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIm1vYmlsZVNldEFwcGVhcmFuY2UiLCJvcHRzIiwic3R5bGUiLCJpbmNsdWRlcyIsIl8iLCJ0b0xvd2VyIiwiRXJyb3IiLCJ1dGlsIiwiY29tcGFyZVZlcnNpb25zIiwicGxhdGZvcm1WZXJzaW9uIiwiaXNTaW11bGF0b3IiLCJkZXZpY2UiLCJzZXRBcHBlYXJhbmNlIiwiZSIsImxvZyIsImRlYnVnIiwic3RhY2siLCJwcm94eUNvbW1hbmQiLCJuYW1lIiwibW9iaWxlU2lyaUNvbW1hbmQiLCJ0ZXh0IiwibW9iaWxlR2V0QXBwZWFyYW5jZSIsImdldEFwcGVhcmFuY2UiLCJpZ24iLCJ1c2VySW50ZXJmYWNlU3R5bGUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvY29tbWFuZHMvYXBwZWFyYW5jZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcblxuXG5jb25zdCBjb21tYW5kcyA9IHt9O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNldEFwcGVhcmFuY2VPcHRpb25zXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHN0eWxlIC0gQ3VycmVudGx5IHR3byBzdHlsZXMgYXJlIHN1cHBvcnRlZDpcbiAqIC0gZGFya1xuICogLSBsaWdodFxuICovXG5cbi8qKlxuICogU2V0IHRoZSBkZXZpY2UncyBVSSBhcHBlYXJhbmNlIHN0eWxlXG4gKlxuICogQHNpbmNlIGlPUyAxMi4wXG4gKiBAcGFyYW0ge1NldEFwcGVhcmFuY2VPcHRpb25zfSBvcHRzXG4gKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlIGN1cnJlbnQgcGxhdGZvcm0gZG9lcyBub3Qgc3VwcG9ydCBVSVxuICogYXBwZWFyYW5jZSBjaGFuZ2VzXG4gKi9cbmNvbW1hbmRzLm1vYmlsZVNldEFwcGVhcmFuY2UgPSBhc3luYyBmdW5jdGlvbiBtb2JpbGVTZXRBcHBlYXJhbmNlIChvcHRzID0ge30pIHtcbiAgY29uc3Qge1xuICAgIHN0eWxlLFxuICB9ID0gb3B0cztcbiAgaWYgKCFbJ2xpZ2h0JywgJ2RhcmsnXS5pbmNsdWRlcyhfLnRvTG93ZXIoc3R5bGUpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlICdzdHlsZScgdmFsdWUgaXMgZXhwZWN0ZWQgdG8gZXF1YWwgZWl0aGVyICdsaWdodCcgb3IgJ2RhcmsnYCk7XG4gIH1cbiAgaWYgKHV0aWwuY29tcGFyZVZlcnNpb25zKHRoaXMub3B0cy5wbGF0Zm9ybVZlcnNpb24sICc8JywgJzEyLjAnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2hhbmdpbmcgYXBwZWFyYW5jZSBpcyBvbmx5IHN1cHBvcnRlZCBzaW5jZSBpT1MgMTInKTtcbiAgfVxuXG4gIGlmICh0aGlzLmlzU2ltdWxhdG9yKCkpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHZvaWQgKGF3YWl0IHRoaXMub3B0cy5kZXZpY2Uuc2V0QXBwZWFyYW5jZShzdHlsZSkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGUuc3RhY2spO1xuICAgIH1cbiAgfVxuICB0cnkge1xuICAgIHJldHVybiB2b2lkIChhd2FpdCB0aGlzLnByb3h5Q29tbWFuZCgnL3dkYS9kZXZpY2UvYXBwZWFyYW5jZScsICdQT1NUJywge25hbWU6IHN0eWxlfSkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoZS5zdGFjayk7XG4gIH1cbiAgLy8gRmFsbCBiYWNrIHRvIHRoZSB1Z2x5IFNpcmkgd29ya2Fyb3VuZCBpZiB0aGUgY3VycmVudCBTREsgaXMgdG9vIG9sZFxuICBhd2FpdCB0aGlzLm1vYmlsZVNpcmlDb21tYW5kKHtcbiAgICB0ZXh0OiBgVHVybiAke18udG9Mb3dlcihzdHlsZSkgPT09ICdkYXJrJyA/ICdvbicgOiAnb2ZmJ30gZGFyayBtb2RlYCxcbiAgfSk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEFwcGVhcmFuY2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdHlsZSAtIFRoZSBkZXZpY2UncyBVSSBhcHBlYXJhbmNlIHZhbHVlLlxuICogVGhpcyBjb3VsZCBiZSBvbmUgb2Y6XG4gKiAtIGBsaWdodGBcbiAqIC0gYGRhcmtgXG4gKiAtIGB1bmtub3duYFxuICogLSBgdW5zdXBwb3J0ZWRgXG4gKi9cblxuLyoqXG4gKiBHZXQgdGhlIGRldmljZSdzIFVJIGFwcGVhcmFuY2Ugc3R5bGUuXG4gKlxuICogQHNpbmNlIFhjb2RlIFNESyAxMVxuICogQHJldHVybnMge0FwcGVhcmFuY2V9XG4gKi9cbmNvbW1hbmRzLm1vYmlsZUdldEFwcGVhcmFuY2UgPSBhc3luYyBmdW5jdGlvbiBtb2JpbGVHZXRBcHBlYXJhbmNlICgpIHtcbiAgaWYgKHV0aWwuY29tcGFyZVZlcnNpb25zKHRoaXMub3B0cy5wbGF0Zm9ybVZlcnNpb24sICc8JywgJzEyLjAnKSkge1xuICAgIHJldHVybiAndW5zdXBwb3J0ZWQnO1xuICB9XG5cbiAgbGV0IHN0eWxlO1xuICBpZiAodGhpcy5pc1NpbXVsYXRvcigpKSB7XG4gICAgdHJ5IHtcbiAgICAgIHN0eWxlID0gYXdhaXQgdGhpcy5vcHRzLmRldmljZS5nZXRBcHBlYXJhbmNlKCk7XG4gICAgfSBjYXRjaCAoaWduKSB7fVxuICB9XG4gIGlmICghc3R5bGUpIHtcbiAgICBzdHlsZSA9IChhd2FpdCB0aGlzLnByb3h5Q29tbWFuZCgnL3dkYS9kZXZpY2UvaW5mbycsICdHRVQnKSkudXNlckludGVyZmFjZVN0eWxlIHx8ICd1bmtub3duJztcbiAgfVxuICByZXR1cm4ge1xuICAgIHN0eWxlLFxuICB9O1xufTtcblxuXG5leHBvcnQgeyBjb21tYW5kcyB9O1xuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUdBLE1BQU1BLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFBQztBQWtCcEJBLFFBQVEsQ0FBQ0MsbUJBQW1CLEdBQUcsZUFBZUEsbUJBQW1CLENBQUVDLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRTtFQUM1RSxNQUFNO0lBQ0pDO0VBQ0YsQ0FBQyxHQUFHRCxJQUFJO0VBQ1IsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDRSxRQUFRLENBQUNDLGVBQUMsQ0FBQ0MsT0FBTyxDQUFDSCxLQUFLLENBQUMsQ0FBQyxFQUFFO0lBQ2pELE1BQU0sSUFBSUksS0FBSyxDQUFFLGlFQUFnRSxDQUFDO0VBQ3BGO0VBQ0EsSUFBSUMsYUFBSSxDQUFDQyxlQUFlLENBQUMsSUFBSSxDQUFDUCxJQUFJLENBQUNRLGVBQWUsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEVBQUU7SUFDaEUsTUFBTSxJQUFJSCxLQUFLLENBQUMsb0RBQW9ELENBQUM7RUFDdkU7RUFFQSxJQUFJLElBQUksQ0FBQ0ksV0FBVyxFQUFFLEVBQUU7SUFDdEIsSUFBSTtNQUNGLE9BQU8sTUFBTSxNQUFNLElBQUksQ0FBQ1QsSUFBSSxDQUFDVSxNQUFNLENBQUNDLGFBQWEsQ0FBQ1YsS0FBSyxDQUFDLENBQUM7SUFDM0QsQ0FBQyxDQUFDLE9BQU9XLENBQUMsRUFBRTtNQUNWLElBQUksQ0FBQ0MsR0FBRyxDQUFDQyxLQUFLLENBQUNGLENBQUMsQ0FBQ0csS0FBSyxDQUFDO0lBQ3pCO0VBQ0Y7RUFDQSxJQUFJO0lBQ0YsT0FBTyxNQUFNLE1BQU0sSUFBSSxDQUFDQyxZQUFZLENBQUMsd0JBQXdCLEVBQUUsTUFBTSxFQUFFO01BQUNDLElBQUksRUFBRWhCO0lBQUssQ0FBQyxDQUFDLENBQUM7RUFDeEYsQ0FBQyxDQUFDLE9BQU9XLENBQUMsRUFBRTtJQUNWLElBQUksQ0FBQ0MsR0FBRyxDQUFDQyxLQUFLLENBQUNGLENBQUMsQ0FBQ0csS0FBSyxDQUFDO0VBQ3pCO0VBRUEsTUFBTSxJQUFJLENBQUNHLGlCQUFpQixDQUFDO0lBQzNCQyxJQUFJLEVBQUcsUUFBT2hCLGVBQUMsQ0FBQ0MsT0FBTyxDQUFDSCxLQUFLLENBQUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxHQUFHLEtBQU07RUFDM0QsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQWtCREgsUUFBUSxDQUFDc0IsbUJBQW1CLEdBQUcsZUFBZUEsbUJBQW1CLEdBQUk7RUFDbkUsSUFBSWQsYUFBSSxDQUFDQyxlQUFlLENBQUMsSUFBSSxDQUFDUCxJQUFJLENBQUNRLGVBQWUsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEVBQUU7SUFDaEUsT0FBTyxhQUFhO0VBQ3RCO0VBRUEsSUFBSVAsS0FBSztFQUNULElBQUksSUFBSSxDQUFDUSxXQUFXLEVBQUUsRUFBRTtJQUN0QixJQUFJO01BQ0ZSLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQ0QsSUFBSSxDQUFDVSxNQUFNLENBQUNXLGFBQWEsRUFBRTtJQUNoRCxDQUFDLENBQUMsT0FBT0MsR0FBRyxFQUFFLENBQUM7RUFDakI7RUFDQSxJQUFJLENBQUNyQixLQUFLLEVBQUU7SUFDVkEsS0FBSyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUNlLFlBQVksQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsRUFBRU8sa0JBQWtCLElBQUksU0FBUztFQUM5RjtFQUNBLE9BQU87SUFDTHRCO0VBQ0YsQ0FBQztBQUNILENBQUM7QUFBQyxlQUlhSCxRQUFRO0FBQUEifQ==
60
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIm1vYmlsZVNldEFwcGVhcmFuY2UiLCJvcHRzIiwic3R5bGUiLCJpbmNsdWRlcyIsIl8iLCJ0b0xvd2VyIiwiRXJyb3IiLCJ1dGlsIiwiY29tcGFyZVZlcnNpb25zIiwicGxhdGZvcm1WZXJzaW9uIiwiaXNTaW11bGF0b3IiLCJkZXZpY2UiLCJzZXRBcHBlYXJhbmNlIiwiZSIsImxvZyIsImRlYnVnIiwic3RhY2siLCJwcm94eUNvbW1hbmQiLCJuYW1lIiwibW9iaWxlU2lyaUNvbW1hbmQiLCJ0ZXh0IiwibW9iaWxlR2V0QXBwZWFyYW5jZSIsImdldEFwcGVhcmFuY2UiLCJpZ24iLCJ1c2VySW50ZXJmYWNlU3R5bGUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvY29tbWFuZHMvYXBwZWFyYW5jZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcblxuXG5jb25zdCBjb21tYW5kcyA9IHt9O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNldEFwcGVhcmFuY2VPcHRpb25zXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHN0eWxlIC0gQ3VycmVudGx5IHR3byBzdHlsZXMgYXJlIHN1cHBvcnRlZDpcbiAqIC0gZGFya1xuICogLSBsaWdodFxuICovXG5cbi8qKlxuICogU2V0IHRoZSBkZXZpY2UncyBVSSBhcHBlYXJhbmNlIHN0eWxlXG4gKlxuICogQHNpbmNlIGlPUyAxMi4wXG4gKiBAcGFyYW0ge1NldEFwcGVhcmFuY2VPcHRpb25zfSBvcHRzXG4gKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlIGN1cnJlbnQgcGxhdGZvcm0gZG9lcyBub3Qgc3VwcG9ydCBVSVxuICogYXBwZWFyYW5jZSBjaGFuZ2VzXG4gKi9cbmNvbW1hbmRzLm1vYmlsZVNldEFwcGVhcmFuY2UgPSBhc3luYyBmdW5jdGlvbiBtb2JpbGVTZXRBcHBlYXJhbmNlIChvcHRzID0ge30pIHtcbiAgY29uc3Qge1xuICAgIHN0eWxlLFxuICB9ID0gb3B0cztcbiAgaWYgKCFbJ2xpZ2h0JywgJ2RhcmsnXS5pbmNsdWRlcyhfLnRvTG93ZXIoc3R5bGUpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlICdzdHlsZScgdmFsdWUgaXMgZXhwZWN0ZWQgdG8gZXF1YWwgZWl0aGVyICdsaWdodCcgb3IgJ2RhcmsnYCk7XG4gIH1cbiAgaWYgKHV0aWwuY29tcGFyZVZlcnNpb25zKHRoaXMub3B0cy5wbGF0Zm9ybVZlcnNpb24sICc8JywgJzEyLjAnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2hhbmdpbmcgYXBwZWFyYW5jZSBpcyBvbmx5IHN1cHBvcnRlZCBzaW5jZSBpT1MgMTInKTtcbiAgfVxuXG4gIGlmICh0aGlzLmlzU2ltdWxhdG9yKCkpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHZvaWQgKGF3YWl0IHRoaXMub3B0cy5kZXZpY2Uuc2V0QXBwZWFyYW5jZShzdHlsZSkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGUuc3RhY2spO1xuICAgIH1cbiAgfVxuICB0cnkge1xuICAgIHJldHVybiB2b2lkIChhd2FpdCB0aGlzLnByb3h5Q29tbWFuZCgnL3dkYS9kZXZpY2UvYXBwZWFyYW5jZScsICdQT1NUJywge25hbWU6IHN0eWxlfSwgZmFsc2UpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMubG9nLmRlYnVnKGUuc3RhY2spO1xuICB9XG4gIC8vIEZhbGwgYmFjayB0byB0aGUgdWdseSBTaXJpIHdvcmthcm91bmQgaWYgdGhlIGN1cnJlbnQgU0RLIGlzIHRvbyBvbGRcbiAgYXdhaXQgdGhpcy5tb2JpbGVTaXJpQ29tbWFuZCh7XG4gICAgdGV4dDogYFR1cm4gJHtfLnRvTG93ZXIoc3R5bGUpID09PSAnZGFyaycgPyAnb24nIDogJ29mZid9IGRhcmsgbW9kZWAsXG4gIH0pO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBBcHBlYXJhbmNlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3R5bGUgLSBUaGUgZGV2aWNlJ3MgVUkgYXBwZWFyYW5jZSB2YWx1ZS5cbiAqIFRoaXMgY291bGQgYmUgb25lIG9mOlxuICogLSBgbGlnaHRgXG4gKiAtIGBkYXJrYFxuICogLSBgdW5rbm93bmBcbiAqIC0gYHVuc3VwcG9ydGVkYFxuICovXG5cbi8qKlxuICogR2V0IHRoZSBkZXZpY2UncyBVSSBhcHBlYXJhbmNlIHN0eWxlLlxuICpcbiAqIEBzaW5jZSBYY29kZSBTREsgMTFcbiAqIEByZXR1cm5zIHtBcHBlYXJhbmNlfVxuICovXG5jb21tYW5kcy5tb2JpbGVHZXRBcHBlYXJhbmNlID0gYXN5bmMgZnVuY3Rpb24gbW9iaWxlR2V0QXBwZWFyYW5jZSAoKSB7XG4gIGlmICh1dGlsLmNvbXBhcmVWZXJzaW9ucyh0aGlzLm9wdHMucGxhdGZvcm1WZXJzaW9uLCAnPCcsICcxMi4wJykpIHtcbiAgICByZXR1cm4gJ3Vuc3VwcG9ydGVkJztcbiAgfVxuXG4gIGxldCBzdHlsZTtcbiAgaWYgKHRoaXMuaXNTaW11bGF0b3IoKSkge1xuICAgIHRyeSB7XG4gICAgICBzdHlsZSA9IGF3YWl0IHRoaXMub3B0cy5kZXZpY2UuZ2V0QXBwZWFyYW5jZSgpO1xuICAgIH0gY2F0Y2ggKGlnbikge31cbiAgfVxuICBpZiAoIXN0eWxlKSB7XG4gICAgc3R5bGUgPSAoYXdhaXQgdGhpcy5wcm94eUNvbW1hbmQoJy93ZGEvZGV2aWNlL2luZm8nLCAnR0VUJykpLnVzZXJJbnRlcmZhY2VTdHlsZSB8fCAndW5rbm93bic7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBzdHlsZSxcbiAgfTtcbn07XG5cblxuZXhwb3J0IHsgY29tbWFuZHMgfTtcbmV4cG9ydCBkZWZhdWx0IGNvbW1hbmRzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQ0E7QUFHQSxNQUFNQSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQUM7QUFrQnBCQSxRQUFRLENBQUNDLG1CQUFtQixHQUFHLGVBQWVBLG1CQUFtQixDQUFFQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUU7RUFDNUUsTUFBTTtJQUNKQztFQUNGLENBQUMsR0FBR0QsSUFBSTtFQUNSLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQ0UsUUFBUSxDQUFDQyxlQUFDLENBQUNDLE9BQU8sQ0FBQ0gsS0FBSyxDQUFDLENBQUMsRUFBRTtJQUNqRCxNQUFNLElBQUlJLEtBQUssQ0FBRSxpRUFBZ0UsQ0FBQztFQUNwRjtFQUNBLElBQUlDLGFBQUksQ0FBQ0MsZUFBZSxDQUFDLElBQUksQ0FBQ1AsSUFBSSxDQUFDUSxlQUFlLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxFQUFFO0lBQ2hFLE1BQU0sSUFBSUgsS0FBSyxDQUFDLG9EQUFvRCxDQUFDO0VBQ3ZFO0VBRUEsSUFBSSxJQUFJLENBQUNJLFdBQVcsRUFBRSxFQUFFO0lBQ3RCLElBQUk7TUFDRixPQUFPLE1BQU0sTUFBTSxJQUFJLENBQUNULElBQUksQ0FBQ1UsTUFBTSxDQUFDQyxhQUFhLENBQUNWLEtBQUssQ0FBQyxDQUFDO0lBQzNELENBQUMsQ0FBQyxPQUFPVyxDQUFDLEVBQUU7TUFDVixJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsS0FBSyxDQUFDRixDQUFDLENBQUNHLEtBQUssQ0FBQztJQUN6QjtFQUNGO0VBQ0EsSUFBSTtJQUNGLE9BQU8sTUFBTSxNQUFNLElBQUksQ0FBQ0MsWUFBWSxDQUFDLHdCQUF3QixFQUFFLE1BQU0sRUFBRTtNQUFDQyxJQUFJLEVBQUVoQjtJQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztFQUMvRixDQUFDLENBQUMsT0FBT1csQ0FBQyxFQUFFO0lBQ1YsSUFBSSxDQUFDQyxHQUFHLENBQUNDLEtBQUssQ0FBQ0YsQ0FBQyxDQUFDRyxLQUFLLENBQUM7RUFDekI7RUFFQSxNQUFNLElBQUksQ0FBQ0csaUJBQWlCLENBQUM7SUFDM0JDLElBQUksRUFBRyxRQUFPaEIsZUFBQyxDQUFDQyxPQUFPLENBQUNILEtBQUssQ0FBQyxLQUFLLE1BQU0sR0FBRyxJQUFJLEdBQUcsS0FBTTtFQUMzRCxDQUFDLENBQUM7QUFDSixDQUFDO0FBa0JESCxRQUFRLENBQUNzQixtQkFBbUIsR0FBRyxlQUFlQSxtQkFBbUIsR0FBSTtFQUNuRSxJQUFJZCxhQUFJLENBQUNDLGVBQWUsQ0FBQyxJQUFJLENBQUNQLElBQUksQ0FBQ1EsZUFBZSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsRUFBRTtJQUNoRSxPQUFPLGFBQWE7RUFDdEI7RUFFQSxJQUFJUCxLQUFLO0VBQ1QsSUFBSSxJQUFJLENBQUNRLFdBQVcsRUFBRSxFQUFFO0lBQ3RCLElBQUk7TUFDRlIsS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDRCxJQUFJLENBQUNVLE1BQU0sQ0FBQ1csYUFBYSxFQUFFO0lBQ2hELENBQUMsQ0FBQyxPQUFPQyxHQUFHLEVBQUUsQ0FBQztFQUNqQjtFQUNBLElBQUksQ0FBQ3JCLEtBQUssRUFBRTtJQUNWQSxLQUFLLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQ2UsWUFBWSxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxFQUFFTyxrQkFBa0IsSUFBSSxTQUFTO0VBQzlGO0VBQ0EsT0FBTztJQUNMdEI7RUFDRixDQUFDO0FBQ0gsQ0FBQztBQUFDLGVBSWFILFFBQVE7QUFBQSJ9
@@ -1 +1 @@
1
- {"version":3,"file":"appearance.js","names":["commands","mobileSetAppearance","opts","style","includes","_","toLower","Error","util","compareVersions","platformVersion","isSimulator","device","setAppearance","e","log","debug","stack","proxyCommand","name","mobileSiriCommand","text","mobileGetAppearance","getAppearance","ign","userInterfaceStyle"],"sources":["../../../lib/commands/appearance.js"],"sourcesContent":["import _ from 'lodash';\nimport { util } from 'appium/support';\n\n\nconst commands = {};\n\n/**\n * @typedef {Object} SetAppearanceOptions\n *\n * @property {string} style - Currently two styles are supported:\n * - dark\n * - light\n */\n\n/**\n * Set the device's UI appearance style\n *\n * @since iOS 12.0\n * @param {SetAppearanceOptions} opts\n * @throws {Error} if the current platform does not support UI\n * appearance changes\n */\ncommands.mobileSetAppearance = async function mobileSetAppearance (opts = {}) {\n const {\n style,\n } = opts;\n if (!['light', 'dark'].includes(_.toLower(style))) {\n throw new Error(`The 'style' value is expected to equal either 'light' or 'dark'`);\n }\n if (util.compareVersions(this.opts.platformVersion, '<', '12.0')) {\n throw new Error('Changing appearance is only supported since iOS 12');\n }\n\n if (this.isSimulator()) {\n try {\n return void (await this.opts.device.setAppearance(style));\n } catch (e) {\n this.log.debug(e.stack);\n }\n }\n try {\n return void (await this.proxyCommand('/wda/device/appearance', 'POST', {name: style}));\n } catch (e) {\n this.log.debug(e.stack);\n }\n // Fall back to the ugly Siri workaround if the current SDK is too old\n await this.mobileSiriCommand({\n text: `Turn ${_.toLower(style) === 'dark' ? 'on' : 'off'} dark mode`,\n });\n};\n\n/**\n * @typedef {Object} Appearance\n * @property {string} style - The device's UI appearance value.\n * This could be one of:\n * - `light`\n * - `dark`\n * - `unknown`\n * - `unsupported`\n */\n\n/**\n * Get the device's UI appearance style.\n *\n * @since Xcode SDK 11\n * @returns {Appearance}\n */\ncommands.mobileGetAppearance = async function mobileGetAppearance () {\n if (util.compareVersions(this.opts.platformVersion, '<', '12.0')) {\n return 'unsupported';\n }\n\n let style;\n if (this.isSimulator()) {\n try {\n style = await this.opts.device.getAppearance();\n } catch (ign) {}\n }\n if (!style) {\n style = (await this.proxyCommand('/wda/device/info', 'GET')).userInterfaceStyle || 'unknown';\n }\n return {\n style,\n };\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":";;;;;;;;AAAA;AACA;AAGA,MAAMA,QAAQ,GAAG,CAAC,CAAC;AAAC;AAkBpBA,QAAQ,CAACC,mBAAmB,GAAG,eAAeA,mBAAmB,CAAEC,IAAI,GAAG,CAAC,CAAC,EAAE;EAC5E,MAAM;IACJC;EACF,CAAC,GAAGD,IAAI;EACR,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAACE,QAAQ,CAACC,eAAC,CAACC,OAAO,CAACH,KAAK,CAAC,CAAC,EAAE;IACjD,MAAM,IAAII,KAAK,CAAE,iEAAgE,CAAC;EACpF;EACA,IAAIC,aAAI,CAACC,eAAe,CAAC,IAAI,CAACP,IAAI,CAACQ,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE;IAChE,MAAM,IAAIH,KAAK,CAAC,oDAAoD,CAAC;EACvE;EAEA,IAAI,IAAI,CAACI,WAAW,EAAE,EAAE;IACtB,IAAI;MACF,OAAO,MAAM,MAAM,IAAI,CAACT,IAAI,CAACU,MAAM,CAACC,aAAa,CAACV,KAAK,CAAC,CAAC;IAC3D,CAAC,CAAC,OAAOW,CAAC,EAAE;MACV,IAAI,CAACC,GAAG,CAACC,KAAK,CAACF,CAAC,CAACG,KAAK,CAAC;IACzB;EACF;EACA,IAAI;IACF,OAAO,MAAM,MAAM,IAAI,CAACC,YAAY,CAAC,wBAAwB,EAAE,MAAM,EAAE;MAACC,IAAI,EAAEhB;IAAK,CAAC,CAAC,CAAC;EACxF,CAAC,CAAC,OAAOW,CAAC,EAAE;IACV,IAAI,CAACC,GAAG,CAACC,KAAK,CAACF,CAAC,CAACG,KAAK,CAAC;EACzB;EAEA,MAAM,IAAI,CAACG,iBAAiB,CAAC;IAC3BC,IAAI,EAAG,QAAOhB,eAAC,CAACC,OAAO,CAACH,KAAK,CAAC,KAAK,MAAM,GAAG,IAAI,GAAG,KAAM;EAC3D,CAAC,CAAC;AACJ,CAAC;AAkBDH,QAAQ,CAACsB,mBAAmB,GAAG,eAAeA,mBAAmB,GAAI;EACnE,IAAId,aAAI,CAACC,eAAe,CAAC,IAAI,CAACP,IAAI,CAACQ,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE;IAChE,OAAO,aAAa;EACtB;EAEA,IAAIP,KAAK;EACT,IAAI,IAAI,CAACQ,WAAW,EAAE,EAAE;IACtB,IAAI;MACFR,KAAK,GAAG,MAAM,IAAI,CAACD,IAAI,CAACU,MAAM,CAACW,aAAa,EAAE;IAChD,CAAC,CAAC,OAAOC,GAAG,EAAE,CAAC;EACjB;EACA,IAAI,CAACrB,KAAK,EAAE;IACVA,KAAK,GAAG,CAAC,MAAM,IAAI,CAACe,YAAY,CAAC,kBAAkB,EAAE,KAAK,CAAC,EAAEO,kBAAkB,IAAI,SAAS;EAC9F;EACA,OAAO;IACLtB;EACF,CAAC;AACH,CAAC;AAAC,eAIaH,QAAQ;AAAA"}
1
+ {"version":3,"file":"appearance.js","names":["commands","mobileSetAppearance","opts","style","includes","_","toLower","Error","util","compareVersions","platformVersion","isSimulator","device","setAppearance","e","log","debug","stack","proxyCommand","name","mobileSiriCommand","text","mobileGetAppearance","getAppearance","ign","userInterfaceStyle"],"sources":["../../../lib/commands/appearance.js"],"sourcesContent":["import _ from 'lodash';\nimport { util } from 'appium/support';\n\n\nconst commands = {};\n\n/**\n * @typedef {Object} SetAppearanceOptions\n *\n * @property {string} style - Currently two styles are supported:\n * - dark\n * - light\n */\n\n/**\n * Set the device's UI appearance style\n *\n * @since iOS 12.0\n * @param {SetAppearanceOptions} opts\n * @throws {Error} if the current platform does not support UI\n * appearance changes\n */\ncommands.mobileSetAppearance = async function mobileSetAppearance (opts = {}) {\n const {\n style,\n } = opts;\n if (!['light', 'dark'].includes(_.toLower(style))) {\n throw new Error(`The 'style' value is expected to equal either 'light' or 'dark'`);\n }\n if (util.compareVersions(this.opts.platformVersion, '<', '12.0')) {\n throw new Error('Changing appearance is only supported since iOS 12');\n }\n\n if (this.isSimulator()) {\n try {\n return void (await this.opts.device.setAppearance(style));\n } catch (e) {\n this.log.debug(e.stack);\n }\n }\n try {\n return void (await this.proxyCommand('/wda/device/appearance', 'POST', {name: style}, false));\n } catch (e) {\n this.log.debug(e.stack);\n }\n // Fall back to the ugly Siri workaround if the current SDK is too old\n await this.mobileSiriCommand({\n text: `Turn ${_.toLower(style) === 'dark' ? 'on' : 'off'} dark mode`,\n });\n};\n\n/**\n * @typedef {Object} Appearance\n * @property {string} style - The device's UI appearance value.\n * This could be one of:\n * - `light`\n * - `dark`\n * - `unknown`\n * - `unsupported`\n */\n\n/**\n * Get the device's UI appearance style.\n *\n * @since Xcode SDK 11\n * @returns {Appearance}\n */\ncommands.mobileGetAppearance = async function mobileGetAppearance () {\n if (util.compareVersions(this.opts.platformVersion, '<', '12.0')) {\n return 'unsupported';\n }\n\n let style;\n if (this.isSimulator()) {\n try {\n style = await this.opts.device.getAppearance();\n } catch (ign) {}\n }\n if (!style) {\n style = (await this.proxyCommand('/wda/device/info', 'GET')).userInterfaceStyle || 'unknown';\n }\n return {\n style,\n };\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":";;;;;;;;AAAA;AACA;AAGA,MAAMA,QAAQ,GAAG,CAAC,CAAC;AAAC;AAkBpBA,QAAQ,CAACC,mBAAmB,GAAG,eAAeA,mBAAmB,CAAEC,IAAI,GAAG,CAAC,CAAC,EAAE;EAC5E,MAAM;IACJC;EACF,CAAC,GAAGD,IAAI;EACR,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAACE,QAAQ,CAACC,eAAC,CAACC,OAAO,CAACH,KAAK,CAAC,CAAC,EAAE;IACjD,MAAM,IAAII,KAAK,CAAE,iEAAgE,CAAC;EACpF;EACA,IAAIC,aAAI,CAACC,eAAe,CAAC,IAAI,CAACP,IAAI,CAACQ,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE;IAChE,MAAM,IAAIH,KAAK,CAAC,oDAAoD,CAAC;EACvE;EAEA,IAAI,IAAI,CAACI,WAAW,EAAE,EAAE;IACtB,IAAI;MACF,OAAO,MAAM,MAAM,IAAI,CAACT,IAAI,CAACU,MAAM,CAACC,aAAa,CAACV,KAAK,CAAC,CAAC;IAC3D,CAAC,CAAC,OAAOW,CAAC,EAAE;MACV,IAAI,CAACC,GAAG,CAACC,KAAK,CAACF,CAAC,CAACG,KAAK,CAAC;IACzB;EACF;EACA,IAAI;IACF,OAAO,MAAM,MAAM,IAAI,CAACC,YAAY,CAAC,wBAAwB,EAAE,MAAM,EAAE;MAACC,IAAI,EAAEhB;IAAK,CAAC,EAAE,KAAK,CAAC,CAAC;EAC/F,CAAC,CAAC,OAAOW,CAAC,EAAE;IACV,IAAI,CAACC,GAAG,CAACC,KAAK,CAACF,CAAC,CAACG,KAAK,CAAC;EACzB;EAEA,MAAM,IAAI,CAACG,iBAAiB,CAAC;IAC3BC,IAAI,EAAG,QAAOhB,eAAC,CAACC,OAAO,CAACH,KAAK,CAAC,KAAK,MAAM,GAAG,IAAI,GAAG,KAAM;EAC3D,CAAC,CAAC;AACJ,CAAC;AAkBDH,QAAQ,CAACsB,mBAAmB,GAAG,eAAeA,mBAAmB,GAAI;EACnE,IAAId,aAAI,CAACC,eAAe,CAAC,IAAI,CAACP,IAAI,CAACQ,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE;IAChE,OAAO,aAAa;EACtB;EAEA,IAAIP,KAAK;EACT,IAAI,IAAI,CAACQ,WAAW,EAAE,EAAE;IACtB,IAAI;MACFR,KAAK,GAAG,MAAM,IAAI,CAACD,IAAI,CAACU,MAAM,CAACW,aAAa,EAAE;IAChD,CAAC,CAAC,OAAOC,GAAG,EAAE,CAAC;EACjB;EACA,IAAI,CAACrB,KAAK,EAAE;IACVA,KAAK,GAAG,CAAC,MAAM,IAAI,CAACe,YAAY,CAAC,kBAAkB,EAAE,KAAK,CAAC,EAAEO,kBAAkB,IAAI,SAAS;EAC9F;EACA,OAAO;IACLtB;EACF,CAAC;AACH,CAAC;AAAC,eAIaH,QAAQ;AAAA"}
@@ -52,6 +52,7 @@ function parseXCTestStdout(stdout) {
52
52
  }
53
53
  return parseInt(value, 10);
54
54
  }
55
+ return value;
55
56
  }
56
57
  if (!stdout) {
57
58
  return [];
@@ -68,12 +69,26 @@ function parseXCTestStdout(stdout) {
68
69
  for (const prop of properties) {
69
70
  if (entryIndex === 0) {
70
71
  output.testName = prop.trim();
72
+ } else if (prop.trim().startsWith('Location')) {
73
+ output.location = prop.substring(prop.indexOf('Location') + 8).trim();
71
74
  } else {
72
75
  let [key, value] = prop.split(':');
73
76
  output[parseKey(key.trim())] = parseValue(value ? value.trim() : '');
74
77
  }
75
78
  entryIndex++;
76
79
  }
80
+ if (!output.passed) {
81
+ output.passed = output.status === 'passed';
82
+ output.crashed = output.status === 'crashed';
83
+ } else if (!output.status) {
84
+ if (output.passed) {
85
+ output.status = 'passed';
86
+ } else if (output.crashed) {
87
+ output.status = 'crashed';
88
+ } else {
89
+ output.status = 'failed';
90
+ }
91
+ }
77
92
  results.push(output);
78
93
  }
79
94
  return results;
@@ -95,8 +110,9 @@ commands.mobileRunXCTest = async function runXCTest({
95
110
  return await new _bluebird.default((resolve, reject) => {
96
111
  let mostRecentLogObject = null;
97
112
  let xctestTimeout;
113
+ let lastErrorMessage = null;
98
114
  if (timeout > 0) {
99
- xctestTimeout = setTimeout(() => reject(`Timed out after '${timeout}ms' waiting for XCTest to complete`), timeout);
115
+ xctestTimeout = setTimeout(() => reject(new _driver.errors.TimeoutError(`Timed out after '${timeout}ms' waiting for XCTest to complete`)), timeout);
100
116
  }
101
117
  subproc.on('output', (stdout, stderr) => {
102
118
  if (stdout) {
@@ -107,13 +123,16 @@ commands.mobileRunXCTest = async function runXCTest({
107
123
  this.log.debug(err.stack);
108
124
  }
109
125
  }
126
+ if (stderr) {
127
+ lastErrorMessage = stderr;
128
+ }
110
129
  stdout && xctestLog.info(stdout);
111
130
  stderr && xctestLog.error(stderr);
112
131
  });
113
132
  subproc.on('exit', (code, signal) => {
114
133
  clearTimeout(xctestTimeout);
115
134
  if (code !== 0) {
116
- const err = new Error(mostRecentLogObject);
135
+ const err = new Error(lastErrorMessage || mostRecentLogObject);
117
136
  err.code = code;
118
137
  if (signal != null) {
119
138
  err.signal = signal;
@@ -160,4 +179,4 @@ commands.mobileListXCTestsInTestBundle = async function listXCTestsInTestBundle(
160
179
  Object.assign(commands);
161
180
  var _default = commands;
162
181
  exports.default = _default;
163
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIlhDVEVTVF9USU1FT1VUIiwieGN0ZXN0TG9nIiwibG9nZ2VyIiwiZ2V0TG9nZ2VyIiwiYXNzZXJ0SURCIiwib3B0cyIsImRldmljZSIsImlkYiIsImxhdW5jaFdpdGhJREIiLCJFcnJvciIsInBhcnNlWENUZXN0U3Rkb3V0Iiwic3Rkb3V0IiwicGFyc2VLZXkiLCJuYW1lIiwid29yZHMiLCJzcGxpdCIsIm91dCIsIndvcmQiLCJzdWJzdHIiLCJ0b1VwcGVyQ2FzZSIsInRvTG93ZXJDYXNlIiwicGFyc2VWYWx1ZSIsInZhbHVlIiwiaXNOYU4iLCJfIiwiaXNTdHJpbmciLCJpbmRleE9mIiwicGFyc2VGbG9hdCIsInBhcnNlSW50IiwibGluZXMiLCJ0cmltIiwibGVuZ3RoIiwiaW5jbHVkZXMiLCJyZXN1bHRzIiwibGluZSIsInByb3BlcnRpZXMiLCJvdXRwdXQiLCJlbnRyeUluZGV4IiwicHJvcCIsInRlc3ROYW1lIiwia2V5IiwicHVzaCIsIm1vYmlsZVJ1blhDVGVzdCIsInJ1blhDVGVzdCIsInRlc3RSdW5uZXJCdW5kbGVJZCIsImFwcFVuZGVyVGVzdEJ1bmRsZUlkIiwieGN0ZXN0QnVuZGxlSWQiLCJ0ZXN0VHlwZSIsImVudiIsImFyZ3MiLCJ0aW1lb3V0Iiwic3VicHJvYyIsInJ1blhDVUlUZXN0IiwiQiIsInJlc29sdmUiLCJyZWplY3QiLCJtb3N0UmVjZW50TG9nT2JqZWN0IiwieGN0ZXN0VGltZW91dCIsInNldFRpbWVvdXQiLCJvbiIsInN0ZGVyciIsImVyciIsImxvZyIsIndhcm4iLCJkZWJ1ZyIsInN0YWNrIiwiaW5mbyIsImVycm9yIiwiY29kZSIsInNpZ25hbCIsImNsZWFyVGltZW91dCIsInJlc3VsdCIsInBhc3NlZCIsIm1vYmlsZUluc3RhbGxYQ1Rlc3RCdW5kbGUiLCJpbnN0YWxsWENUZXN0QnVuZGxlIiwieGN0ZXN0QXBwIiwiZXJyb3JzIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJyZXMiLCJoZWxwZXJzIiwiY29uZmlndXJlQXBwIiwibW9iaWxlTGlzdFhDVGVzdEJ1bmRsZXMiLCJsaXN0WENUZXN0c0luVGVzdEJ1bmRsZSIsImxpc3RYQ1Rlc3RCdW5kbGVzIiwibW9iaWxlTGlzdFhDVGVzdHNJblRlc3RCdW5kbGUiLCJidW5kbGUiLCJPYmplY3QiLCJhc3NpZ24iXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvY29tbWFuZHMveGN0ZXN0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBlcnJvcnMgfSBmcm9tICdhcHBpdW0vZHJpdmVyJztcblxuXG5jb25zdCBjb21tYW5kcyA9IHt9O1xuXG5jb25zdCBYQ1RFU1RfVElNRU9VVCA9IDYwICogNjAgKiAxMDAwOyAvLyA2MCBtaW51dGUgdGltZW91dFxuXG5jb25zdCB4Y3Rlc3RMb2cgPSBsb2dnZXIuZ2V0TG9nZ2VyKCdYQ1Rlc3QnKTtcblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgSURCIGlzIHByZXNlbnQgYW5kIHRoYXQgbGF1bmNoV2l0aElEQiB3YXMgdXNlZFxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRzIE9wdHMgb2JqZWN0IGZyb20gdGhlIGRyaXZlciBpbnN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0SURCIChvcHRzKSB7XG4gIGlmICghb3B0cy5kZXZpY2U/LmlkYiB8fCAhb3B0cy5sYXVuY2hXaXRoSURCKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUbyB1c2UgWENUZXN0IHJ1bm5lciwgSURCIChodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svaWRiKSBtdXN0IGJlIGluc3RhbGxlZCBgICtcbiAgICAgIGBhbmQgc2Vzc2lvbnMgbXVzdCBiZSBydW4gd2l0aCB0aGUgXCJsYXVuY2hXaXRoSURCXCIgY2FwYWJpbGl0eWApO1xuICB9XG4gIHJldHVybiBvcHRzLmRldmljZS5pZGI7XG59XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBYQ1Rlc3RSZXN1bHRcbiAqXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdGVzdE5hbWUgTmFtZSBvZiB0aGUgdGVzdCAoZS5nLjogJ1hDVGVzdGVyQXBwVUlUZXN0cyAtIFhDVGVzdGVyQXBwVUlUZXN0cy5YQ1Rlc3RlckFwcFVJVGVzdHMvdGVzdEV4YW1wbGUnKVxuICogQHByb3BlcnR5IHtib29sZWFufSBwYXNzZWQgRGlkIHRoZSB0ZXN0cyBwYXNzP1xuICogQHByb3BlcnR5IHtib29sZWFufSBjcmFzaGVkIERpZCB0aGUgdGVzdHMgY3Jhc2g/XG4gKiBAcHJvcGVydHkge251bWJlcn0gZHVyYXRpb24gSG93IGxvbmcgZGlkIHRoZSB0ZXN0cyB0YWtlIChpbiBzZWNvbmRzKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZhaWx1cmVNZXNzYWdlIEZhaWx1cmUgbWVzc2FnZSAoaWYgYXBwbGljYWJsZSlcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2NhdGlvbiBUaGUgZ2VvbG9jYXRpb24gb2YgdGhlIHRlc3RzIChpZiBhcHBsaWNhYmxlKVxuICovXG5cbi8qKlxuICogUGFyc2UgdGhlIHN0ZG91dCBvZiBYQyB0ZXN0IGxvZ1xuICogQHBhcmFtIHtzdHJpbmd9IHN0ZG91dCBBIGxpbmUgb2Ygc3RhbmRhcmQgb3V0IGZyb20gYGlkYiB4Y3Rlc3QgcnVuIC4uLmBcbiAqIEByZXR1cm5zIHtBcnJheTxYQ1Rlc3RSZXN1bHQ+fSByZXN1bHRzIFRoZSBmaW5hbCBvdXRwdXQgb2YgdGhlIFhDVGVzdCBydW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlWENUZXN0U3Rkb3V0IChzdGRvdXQpIHtcbiAgLy8gUGFyc2VzIGEgJ2tleScgaW50byBKU09OIGZvcm1hdFxuICBmdW5jdGlvbiBwYXJzZUtleSAobmFtZSkge1xuICAgIGNvbnN0IHdvcmRzID0gbmFtZS5zcGxpdCgnICcpO1xuICAgIGxldCBvdXQgPSAnJztcbiAgICBmb3IgKGNvbnN0IHdvcmQgb2Ygd29yZHMpIHtcbiAgICAgIG91dCArPSB3b3JkLnN1YnN0cigwLCAxKS50b1VwcGVyQ2FzZSgpICsgd29yZC5zdWJzdHIoMSk7XG4gICAgfVxuICAgIHJldHVybiBvdXQuc3Vic3RyKDAsIDEpLnRvTG93ZXJDYXNlKCkgKyBvdXQuc3Vic3RyKDEpO1xuICB9XG5cbiAgLy8gUGFyc2VzIGEgJ3ZhbHVlJyBpbnRvIEpTT04gZm9ybWF0XG4gIGZ1bmN0aW9uIHBhcnNlVmFsdWUgKHZhbHVlKSB7XG4gICAgdmFsdWUgPSB2YWx1ZSB8fCAnJztcbiAgICBzd2l0Y2ggKHZhbHVlLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIGNhc2UgJ3RydWUnOiByZXR1cm4gdHJ1ZTtcbiAgICAgIGNhc2UgJ2ZhbHNlJzogcmV0dXJuIGZhbHNlO1xuICAgICAgY2FzZSAnJzogcmV0dXJuIG51bGw7XG4gICAgICBkZWZhdWx0OiBicmVhaztcbiAgICB9XG4gICAgaWYgKCFpc05hTih2YWx1ZSkpIHtcbiAgICAgIGlmICghXy5pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlLmluZGV4T2YoJy4nKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgfVxuICB9XG4gIGlmICghc3Rkb3V0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLy8gUGFyc2UgZWFjaCBsaW5lIGludG8gYW4gYXJyYXlcbiAgY29uc3QgbGluZXMgPSBzdGRvdXQudHJpbSgpLnNwbGl0KCdcXG4nKTtcblxuICAvLyBPbmUgc2luZ2xlIHN0cmluZywganVzdCByZXR1cm4gdGhlIHN0cmluZ1xuICBpZiAobGluZXMubGVuZ3RoID09PSAxICYmICFsaW5lc1swXS5pbmNsdWRlcygnfCcpKSB7XG4gICAgcmV0dXJuIFtsaW5lc1swXV07XG4gIH1cblxuICBjb25zdCByZXN1bHRzID0gW107XG4gIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgIC8vIFRoZSBwcm9wZXJ0aWVzIGFyZSBzcGxpdCB1cCBieSBwaXBlcyBhbmQgZWFjaCBwcm9wZXJ0eVxuICAgIC8vIGhhcyB0aGUgZm9ybWF0IFwiU29tZSBLZXkgOiBTb21lIFZhbHVlXCJcbiAgICBjb25zdCBwcm9wZXJ0aWVzID0gbGluZS5zcGxpdCgnfCcpO1xuXG4gICAgLy8gUGFyc2UgZWFjaCBwcm9wZXJ0eVxuICAgIGNvbnN0IG91dHB1dCA9IHt9O1xuICAgIGxldCBlbnRyeUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcGVydGllcykge1xuICAgICAgaWYgKGVudHJ5SW5kZXggPT09IDApIHtcbiAgICAgICAgLy8gVGhlIGZpcnN0IHByb3BlcnR5IG9ubHkgY29udGFpbnMgb25lIHN0cmluZyB0aGF0IGNvbnRhaW5zXG4gICAgICAgIC8vIHRoZSB0ZXN0IG5hbWUgKGUuZy46ICdYQ1Rlc3RlckFwcFVJVGVzdHMgLSBYQ1Rlc3RlckFwcFVJVGVzdHMuWENUZXN0ZXJBcHBVSVRlc3RzL3Rlc3RFeGFtcGxlJylcbiAgICAgICAgb3V0cHV0LnRlc3ROYW1lID0gcHJvcC50cmltKCk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIGxldCBba2V5LCB2YWx1ZV0gPSBwcm9wLnNwbGl0KCc6Jyk7XG4gICAgICAgIG91dHB1dFtwYXJzZUtleShrZXkudHJpbSgpKV0gPSBwYXJzZVZhbHVlKHZhbHVlID8gdmFsdWUudHJpbSgpIDogJycpO1xuICAgICAgfVxuICAgICAgZW50cnlJbmRleCsrO1xuICAgIH1cbiAgICAvLyBBZGQgdGhpcyBsaW5lIHRvIHRoZSByZXN1bHRzXG4gICAgcmVzdWx0cy5wdXNoKG91dHB1dCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUnVuWENVSVRlc3RSZXNwb25zZVxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8WENUZXN0UmVzdWx0Pn0gcmVzdWx0cyBUaGUgcmVzdWx0cyBvZiBhbGwgdGhlIHRlc3RzIHdpdGggaW5mb3JtYXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb2RlIFRoZSBleGl0IGNvZGUgb2YgdGhlIHByb2Nlc3NcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzaWduYWwgVGhlIHNpZ25hbCB0aGF0IHRlcm1pbmF0ZWQgdGhlIHByb2Nlc3MgKG9yIG51bGwpIChlLmcuOiBTSUdURVJNKVxuICpcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFJ1blhDVUlUZXN0T3B0aW9uc1xuICpcbiAqIEBwcm9wZXJ0eSB7IXN0cmluZ30gdGVzdFJ1bm5lckJ1bmRsZUlkIFRlc3QgYXBwIGJ1bmRsZSAoZS5nLjogJ2lvLmFwcGl1bS5YQ1Rlc3RlckFwcFVJVGVzdHMueGN0cnVubmVyJylcbiAqIEBwcm9wZXJ0eSB7IXN0cmluZ30gYXBwVW5kZXJUZXN0QnVuZGxlSWQgQXBwLXVuZGVyLXRlc3QgYnVuZGxlXG4gKiBAcHJvcGVydHkgeyFzdHJpbmd9IHhjVGVzdEJ1bmRsZUlEIHhjdGVzdCBidW5kbGUgaWRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0ZXN0VHlwZSBbdWldIFhDIHRlc3QgdHlwZS4gJ2FwcCcsICd1aScsIG9yICdsb2dpYydcbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBlbnYgRW52aXJvbm1lbnQgdmFyaWFibGVzIHBhc3NlZCB0byB0ZXN0XG4gKiBAcHJvcGVydHkge0FycmF5PFN0cmluZz59IGFyZ3MgTGF1bmNoIGFyZ3VtZW50cyB0byBzdGFydCB0aGUgdGVzdCB3aXRoIChzZWUgaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2RvY3VtZW50YXRpb24veGN0ZXN0L3hjdWlhcHBsaWNhdGlvbi8xNTAwNDc3LWxhdW5jaGFyZ3VtZW50cyBmb3IgcmVmZXJlbmNlKVxuICogQHByb3BlcnR5IHtudW1iZXJ9IHRpbWVvdXQgWzM2MDAwMF0gVGltZW91dCBpZiBzZXNzaW9uIGRvZXNuJ3QgY29tcGxldGUgYWZ0ZXIgZ2l2ZW4gdGltZSAoaW4gbWlsbGlzZWNvbmRzKVxuICovXG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7RXJyb3J9IFhDVUlUZXN0RXJyb3JcbiAqXG4gKiBAcHJvcGVydHkge251bWJlcn0gY29kZSBTdWJwcm9jZXNzIGV4aXQgY29kZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNpZ25hbCBUaGUgc2lnbmFsIChTSUcqKSB0aGF0IGNhdXNlZCB0aGUgcHJvY2VzcyB0byBmYWlsXG4gKiBAcHJvcGVydHkgeyFBcnJheTxYQ1Rlc3RSZXN1bHQ+fSByZXN1bHRzIFRoZSBvdXRwdXQgb2YgdGhlIGZhaWxlZCB0ZXN0IChpZiB0aGVyZSBpcyBvdXRwdXQpXG4gKi9cblxuLyoqXG4gKiBSdW4gYW4gWENUZXN0LiBMYXVuY2hlcyBhIHN1YnByb2Nlc3MgdGhhdCBydW5zIHRoZSBYQyBUZXN0IGFuZCBibG9ja3NcbiAqIHVudGlsIGl0IGlzIGNvbXBsZXRlLiBQYXJzZXMgdGhlIHN0ZG91dCBvZiB0aGUgcHJvY2VzcyBhbmQgcmV0dXJuc1xuICogcmVzdWx0IGFzIGFuIGFycmF5XG4gKlxuICogU2VlIGh0dHBzOi8vZmJpZGIuaW8vZG9jcy90ZXN0X2V4ZWN1dGlvbiBmb3IgcmVmZXJlbmNlXG4gKlxuICogQHBhcmFtIHtSdW5YQ1VJVGVzdE9wdGlvbnN9IHJ1blhDVUlUZXN0T3B0aW9uc1xuICogQHRocm93cyB7WENVSVRlc3RFcnJvcn0gRXJyb3IgdGhyb3duIGlmIHN1YnByb2Nlc3MgcmV0dXJucyBub24temVybyBleGl0IGNvZGVcbiAqIEByZXR1cm5zIHtSdW5YQ1VJVGVzdFJlc3BvbnNlfVxuICovXG5jb21tYW5kcy5tb2JpbGVSdW5YQ1Rlc3QgPSBhc3luYyBmdW5jdGlvbiBydW5YQ1Rlc3QgKHtcbiAgdGVzdFJ1bm5lckJ1bmRsZUlkLFxuICBhcHBVbmRlclRlc3RCdW5kbGVJZCxcbiAgeGN0ZXN0QnVuZGxlSWQsXG4gIHRlc3RUeXBlID0gJ3VpJyxcbiAgZW52LFxuICBhcmdzLFxuICB0aW1lb3V0ID0gWENURVNUX1RJTUVPVVQsXG59KSB7XG4gIGNvbnN0IHN1YnByb2MgPSBhd2FpdCBhc3NlcnRJREIodGhpcy5vcHRzKS5ydW5YQ1VJVGVzdChcbiAgICAgICAgdGVzdFJ1bm5lckJ1bmRsZUlkLCBhcHBVbmRlclRlc3RCdW5kbGVJZCwgeGN0ZXN0QnVuZGxlSWQsIHtlbnYsIGFyZ3MsIHRlc3RUeXBlfSxcbiAgKTtcbiAgcmV0dXJuIGF3YWl0IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgbW9zdFJlY2VudExvZ09iamVjdCA9IG51bGw7XG4gICAgbGV0IHhjdGVzdFRpbWVvdXQ7XG4gICAgaWYgKHRpbWVvdXQgPiAwKSB7XG4gICAgICB4Y3Rlc3RUaW1lb3V0ID0gc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4gcmVqZWN0KGBUaW1lZCBvdXQgYWZ0ZXIgJyR7dGltZW91dH1tcycgd2FpdGluZyBmb3IgWENUZXN0IHRvIGNvbXBsZXRlYCksXG4gICAgICAgIHRpbWVvdXRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgc3VicHJvYy5vbignb3V0cHV0JywgKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgICBpZiAoc3Rkb3V0KSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbW9zdFJlY2VudExvZ09iamVjdCA9IHBhcnNlWENUZXN0U3Rkb3V0KHN0ZG91dCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIC8vIEZhaWxzIGlmIGxvZyBwYXJzaW5nIGZhaWxzLlxuICAgICAgICAgIC8vIFRoaXMgaXMgaW4gY2FzZSBJREIgY2hhbmdlcyB0aGUgd2F5IHRoYXQgbG9ncyBhcmUgZm9ybWF0dGVkIGFuZFxuICAgICAgICAgIC8vIGl0IGJyZWFrcyAncGFyc2VYQ1Rlc3RTdGRvdXQnLiBJZiB0aGF0IGhhcHBlbnMgd2Ugc3RpbGwgd2FudCB0aGUgcHJvY2Vzc1xuICAgICAgICAgIC8vIHRvIGZpbmlzaFxuICAgICAgICAgIHRoaXMubG9nLndhcm4oYEZhaWxlZCB0byBwYXJzZSBsb2dzIGZyb20gdGVzdCBvdXRwdXQ6ICcke3N0ZG91dH0nYCk7XG4gICAgICAgICAgdGhpcy5sb2cuZGVidWcoZXJyLnN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc3Rkb3V0ICYmIHhjdGVzdExvZy5pbmZvKHN0ZG91dCk7XG4gICAgICBzdGRlcnIgJiYgeGN0ZXN0TG9nLmVycm9yKHN0ZGVycik7XG4gICAgfSk7XG5cbiAgICBzdWJwcm9jLm9uKCdleGl0JywgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHhjdGVzdFRpbWVvdXQpO1xuICAgICAgaWYgKGNvZGUgIT09IDApIHtcbiAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKG1vc3RSZWNlbnRMb2dPYmplY3QpO1xuICAgICAgICBlcnIuY29kZSA9IGNvZGU7XG4gICAgICAgIGlmIChzaWduYWwgIT0gbnVsbCkge1xuICAgICAgICAgIGVyci5zaWduYWwgPSBzaWduYWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vc3RSZWNlbnRMb2dPYmplY3QpIHtcbiAgICAgICAgICBlcnIucmVzdWx0ID0gbW9zdFJlY2VudExvZ09iamVjdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICB9XG4gICAgICByZXNvbHZlKHtcbiAgICAgICAgY29kZSwgc2lnbmFsLCByZXN1bHRzOiBtb3N0UmVjZW50TG9nT2JqZWN0LCBwYXNzZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEluc3RhbGxYQ1Rlc3RCdW5kbGVPcHRzXG4gKlxuICogQHByb3BlcnR5IHt4Y3Rlc3RBcHB9IHhjdGVzdEJ1bmRsZSBQYXRoIG9mIHRoZSBYQ1Rlc3QgYXBwIChVUkwgb3IgLmFwcClcbiAqL1xuXG4vKipcbiAqIEluc3RhbGwgYW4gWENUZXN0QnVuZGxlXG4gKlxuICogQHBhcmFtIHtJbnN0YWxsWENUZXN0QnVuZGxlT3B0cyF9IG9wdHMgSW5zdGFsbCB4Y3Rlc3QgYnVuZGxlIG9wdHNcbiAqL1xuY29tbWFuZHMubW9iaWxlSW5zdGFsbFhDVGVzdEJ1bmRsZSA9IGFzeW5jIGZ1bmN0aW9uIGluc3RhbGxYQ1Rlc3RCdW5kbGUgKG9wdHMpIHtcbiAgY29uc3QgeyB4Y3Rlc3RBcHAgfSA9IG9wdHM7XG4gIGlmICghXy5pc1N0cmluZyh4Y3Rlc3RBcHApKSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihgJ3hjdGVzdEFwcCcgaXMgYSByZXF1aXJlZCBwYXJhbWV0ZXIgZm9yICdpbnN0YWxsWENUZXN0QnVuZGxlJyBhbmQgYCArXG4gICAgICBgbXVzdCBiZSBhIHN0cmluZy4gRm91bmQgJyR7eGN0ZXN0QXBwfSdgKTtcbiAgfVxuICB4Y3Rlc3RMb2cuaW5mbyhgSW5zdGFsbGluZyBidW5kbGUgJyR7eGN0ZXN0QXBwfSdgKTtcbiAgY29uc3QgaWRiID0gYXNzZXJ0SURCKHRoaXMub3B0cyk7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuaGVscGVycy5jb25maWd1cmVBcHAoeGN0ZXN0QXBwLCAnLnhjdGVzdCcpO1xuICBhd2FpdCBpZGIuaW5zdGFsbFhDVGVzdEJ1bmRsZShyZXMpO1xufTtcblxuLyoqXG4gKiBMaXN0IFhDVGVzdCBidW5kbGVzIHRoYXQgYXJlIGluc3RhbGxlZCBvbiBkZXZpY2VcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gTGlzdCBvZiBYQ1Rlc3QgYnVuZGxlcyAoZS5nLjogXCJYQ1Rlc3RlckFwcFVJVGVzdHMuWENUZXN0ZXJBcHBVSVRlc3RzL3Rlc3RMYXVuY2hQZXJmb3JtYW5jZVwiKVxuICovXG5jb21tYW5kcy5tb2JpbGVMaXN0WENUZXN0QnVuZGxlcyA9IGFzeW5jIGZ1bmN0aW9uIGxpc3RYQ1Rlc3RzSW5UZXN0QnVuZGxlICgpIHtcbiAgcmV0dXJuIGF3YWl0IGFzc2VydElEQih0aGlzLm9wdHMpLmxpc3RYQ1Rlc3RCdW5kbGVzKCk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IExpc3RYQ1Rlc3RzT3B0c1xuICpcbiAqIEBwcm9wZXJ0eSB7IXN0cmluZ30gYnVuZGxlIEJ1bmRsZSBJRCBvZiB0aGUgWENUZXN0XG4gKi9cblxuLyoqXG4gKiBMaXN0IFhDVGVzdHMgaW4gYSB0ZXN0IGJ1bmRsZVxuICpcbiAqIEBwYXJhbSB7IUxpc3RYQ1Rlc3RzT3B0c30gb3B0cyBYQ1Rlc3QgbGlzdCBvcHRpb25zXG4gKlxuICogQHJldHVybnMge0FycmF5PHN0cmluZz59IFRoZSBsaXN0IG9mIHhjdGVzdHMgaW4gdGhlIHRlc3QgYnVuZGxlXG4gKiAgICAoZS5nLjogWyAnWENUZXN0ZXJBcHBVSVRlc3RzLlhDVGVzdGVyQXBwVUlUZXN0cy90ZXN0RXhhbXBsZScsXG4gICAgICAgICAgICAgICAgJ1hDVGVzdGVyQXBwVUlUZXN0cy5YQ1Rlc3RlckFwcFVJVGVzdHMvdGVzdExhdW5jaFBlcmZvcm1hbmNlJyBdIClcbiAqL1xuY29tbWFuZHMubW9iaWxlTGlzdFhDVGVzdHNJblRlc3RCdW5kbGUgPSBhc3luYyBmdW5jdGlvbiBsaXN0WENUZXN0c0luVGVzdEJ1bmRsZSAob3B0cykge1xuICBjb25zdCB7IGJ1bmRsZSB9ID0gb3B0cztcbiAgaWYgKCFfLmlzU3RyaW5nKGJ1bmRsZSkpIHtcbiAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRBcmd1bWVudEVycm9yKGAnYnVuZGxlJyBpcyBhIHJlcXVpcmVkIHBhcmFtZXRlciBmb3IgJ2xpc3RYQ1Rlc3RzSW5UZXN0QnVuZGxlJyBhbmQgYCArXG4gICAgICBgbXVzdCBiZSBhIHN0cmluZy4gRm91bmQgJyR7YnVuZGxlfSdgKTtcbiAgfVxuICBjb25zdCBpZGIgPSBhc3NlcnRJREIodGhpcy5vcHRzKTtcbiAgcmV0dXJuIGF3YWl0IGlkYi5saXN0WENUZXN0c0luVGVzdEJ1bmRsZShidW5kbGUpO1xufTtcblxuT2JqZWN0LmFzc2lnbihjb21tYW5kcyk7XG5leHBvcnQgeyBjb21tYW5kcyB9O1xuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUdBLE1BQU1BLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFBQztBQUVwQixNQUFNQyxjQUFjLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJO0FBRXJDLE1BQU1DLFNBQVMsR0FBR0MsZUFBTSxDQUFDQyxTQUFTLENBQUMsUUFBUSxDQUFDO0FBT3JDLFNBQVNDLFNBQVMsQ0FBRUMsSUFBSSxFQUFFO0VBQUE7RUFDL0IsSUFBSSxrQkFBQ0EsSUFBSSxDQUFDQyxNQUFNLHlDQUFYLGFBQWFDLEdBQUcsS0FBSSxDQUFDRixJQUFJLENBQUNHLGFBQWEsRUFBRTtJQUM1QyxNQUFNLElBQUlDLEtBQUssQ0FBRSxnRkFBK0UsR0FDN0YsOERBQTZELENBQUM7RUFDbkU7RUFDQSxPQUFPSixJQUFJLENBQUNDLE1BQU0sQ0FBQ0MsR0FBRztBQUN4QjtBQW1CTyxTQUFTRyxpQkFBaUIsQ0FBRUMsTUFBTSxFQUFFO0VBRXpDLFNBQVNDLFFBQVEsQ0FBRUMsSUFBSSxFQUFFO0lBQ3ZCLE1BQU1DLEtBQUssR0FBR0QsSUFBSSxDQUFDRSxLQUFLLENBQUMsR0FBRyxDQUFDO0lBQzdCLElBQUlDLEdBQUcsR0FBRyxFQUFFO0lBQ1osS0FBSyxNQUFNQyxJQUFJLElBQUlILEtBQUssRUFBRTtNQUN4QkUsR0FBRyxJQUFJQyxJQUFJLENBQUNDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUNDLFdBQVcsRUFBRSxHQUFHRixJQUFJLENBQUNDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDekQ7SUFDQSxPQUFPRixHQUFHLENBQUNFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUNFLFdBQVcsRUFBRSxHQUFHSixHQUFHLENBQUNFLE1BQU0sQ0FBQyxDQUFDLENBQUM7RUFDdkQ7RUFHQSxTQUFT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
182
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIlhDVEVTVF9USU1FT1VUIiwieGN0ZXN0TG9nIiwibG9nZ2VyIiwiZ2V0TG9nZ2VyIiwiYXNzZXJ0SURCIiwib3B0cyIsImRldmljZSIsImlkYiIsImxhdW5jaFdpdGhJREIiLCJFcnJvciIsInBhcnNlWENUZXN0U3Rkb3V0Iiwic3Rkb3V0IiwicGFyc2VLZXkiLCJuYW1lIiwid29yZHMiLCJzcGxpdCIsIm91dCIsIndvcmQiLCJzdWJzdHIiLCJ0b1VwcGVyQ2FzZSIsInRvTG93ZXJDYXNlIiwicGFyc2VWYWx1ZSIsInZhbHVlIiwiaXNOYU4iLCJfIiwiaXNTdHJpbmciLCJpbmRleE9mIiwicGFyc2VGbG9hdCIsInBhcnNlSW50IiwibGluZXMiLCJ0cmltIiwibGVuZ3RoIiwiaW5jbHVkZXMiLCJyZXN1bHRzIiwibGluZSIsInByb3BlcnRpZXMiLCJvdXRwdXQiLCJlbnRyeUluZGV4IiwicHJvcCIsInRlc3ROYW1lIiwic3RhcnRzV2l0aCIsImxvY2F0aW9uIiwic3Vic3RyaW5nIiwia2V5IiwicGFzc2VkIiwic3RhdHVzIiwiY3Jhc2hlZCIsInB1c2giLCJtb2JpbGVSdW5YQ1Rlc3QiLCJydW5YQ1Rlc3QiLCJ0ZXN0UnVubmVyQnVuZGxlSWQiLCJhcHBVbmRlclRlc3RCdW5kbGVJZCIsInhjdGVzdEJ1bmRsZUlkIiwidGVzdFR5cGUiLCJlbnYiLCJhcmdzIiwidGltZW91dCIsInN1YnByb2MiLCJydW5YQ1VJVGVzdCIsIkIiLCJyZXNvbHZlIiwicmVqZWN0IiwibW9zdFJlY2VudExvZ09iamVjdCIsInhjdGVzdFRpbWVvdXQiLCJsYXN0RXJyb3JNZXNzYWdlIiwic2V0VGltZW91dCIsImVycm9ycyIsIlRpbWVvdXRFcnJvciIsIm9uIiwic3RkZXJyIiwiZXJyIiwibG9nIiwid2FybiIsImRlYnVnIiwic3RhY2siLCJpbmZvIiwiZXJyb3IiLCJjb2RlIiwic2lnbmFsIiwiY2xlYXJUaW1lb3V0IiwicmVzdWx0IiwibW9iaWxlSW5zdGFsbFhDVGVzdEJ1bmRsZSIsImluc3RhbGxYQ1Rlc3RCdW5kbGUiLCJ4Y3Rlc3RBcHAiLCJJbnZhbGlkQXJndW1lbnRFcnJvciIsInJlcyIsImhlbHBlcnMiLCJjb25maWd1cmVBcHAiLCJtb2JpbGVMaXN0WENUZXN0QnVuZGxlcyIsImxpc3RYQ1Rlc3RzSW5UZXN0QnVuZGxlIiwibGlzdFhDVGVzdEJ1bmRsZXMiLCJtb2JpbGVMaXN0WENUZXN0c0luVGVzdEJ1bmRsZSIsImJ1bmRsZSIsIk9iamVjdCIsImFzc2lnbiJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy94Y3Rlc3QuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuXG5cbmNvbnN0IGNvbW1hbmRzID0ge307XG5cbmNvbnN0IFhDVEVTVF9USU1FT1VUID0gNjAgKiA2MCAqIDEwMDA7IC8vIDYwIG1pbnV0ZSB0aW1lb3V0XG5cbmNvbnN0IHhjdGVzdExvZyA9IGxvZ2dlci5nZXRMb2dnZXIoJ1hDVGVzdCcpO1xuXG4vKipcbiAqIEFzc2VydHMgdGhhdCBJREIgaXMgcHJlc2VudCBhbmQgdGhhdCBsYXVuY2hXaXRoSURCIHdhcyB1c2VkXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG9wdHMgT3B0cyBvYmplY3QgZnJvbSB0aGUgZHJpdmVyIGluc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRJREIgKG9wdHMpIHtcbiAgaWYgKCFvcHRzLmRldmljZT8uaWRiIHx8ICFvcHRzLmxhdW5jaFdpdGhJREIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRvIHVzZSBYQ1Rlc3QgcnVubmVyLCBJREIgKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9pZGIpIG11c3QgYmUgaW5zdGFsbGVkIGAgK1xuICAgICAgYGFuZCBzZXNzaW9ucyBtdXN0IGJlIHJ1biB3aXRoIHRoZSBcImxhdW5jaFdpdGhJREJcIiBjYXBhYmlsaXR5YCk7XG4gIH1cbiAgcmV0dXJuIG9wdHMuZGV2aWNlLmlkYjtcbn1cblxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFhDVGVzdFJlc3VsdFxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0ZXN0TmFtZSBOYW1lIG9mIHRoZSB0ZXN0IChlLmcuOiAnWENUZXN0ZXJBcHBVSVRlc3RzIC0gWENUZXN0ZXJBcHBVSVRlc3RzLlhDVGVzdGVyQXBwVUlUZXN0cy90ZXN0RXhhbXBsZScpXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHBhc3NlZCBEaWQgdGhlIHRlc3RzIHBhc3M/XG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNyYXNoZWQgRGlkIHRoZSB0ZXN0cyBjcmFzaD9cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdGF0dXMgVGVzdCByZXN1bHQgc3RhdHVzIChlLmcuOiAncGFzc2VkJywgJ2ZhaWxlZCcsICdjcmFzaGVkJylcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkdXJhdGlvbiBIb3cgbG9uZyBkaWQgdGhlIHRlc3RzIHRha2UgKGluIHNlY29uZHMpXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZmFpbHVyZU1lc3NhZ2UgRmFpbHVyZSBtZXNzYWdlIChpZiBhcHBsaWNhYmxlKVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvY2F0aW9uIFRoZSBnZW9sb2NhdGlvbiBvZiB0aGUgdGVzdHMgKGlmIGFwcGxpY2FibGUpXG4gKi9cblxuLyoqXG4gKiBQYXJzZSB0aGUgc3Rkb3V0IG9mIFhDIHRlc3QgbG9nXG4gKiBAcGFyYW0ge3N0cmluZ30gc3Rkb3V0IEEgbGluZSBvZiBzdGFuZGFyZCBvdXQgZnJvbSBgaWRiIHhjdGVzdCBydW4gLi4uYFxuICogQHJldHVybnMge0FycmF5PFhDVGVzdFJlc3VsdD59IHJlc3VsdHMgVGhlIGZpbmFsIG91dHB1dCBvZiB0aGUgWENUZXN0IHJ1blxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VYQ1Rlc3RTdGRvdXQgKHN0ZG91dCkge1xuICAvLyBQYXJzZXMgYSAna2V5JyBpbnRvIEpTT04gZm9ybWF0XG4gIGZ1bmN0aW9uIHBhcnNlS2V5IChuYW1lKSB7XG4gICAgY29uc3Qgd29yZHMgPSBuYW1lLnNwbGl0KCcgJyk7XG4gICAgbGV0IG91dCA9ICcnO1xuICAgIGZvciAoY29uc3Qgd29yZCBvZiB3b3Jkcykge1xuICAgICAgb3V0ICs9IHdvcmQuc3Vic3RyKDAsIDEpLnRvVXBwZXJDYXNlKCkgKyB3b3JkLnN1YnN0cigxKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dC5zdWJzdHIoMCwgMSkudG9Mb3dlckNhc2UoKSArIG91dC5zdWJzdHIoMSk7XG4gIH1cblxuICAvLyBQYXJzZXMgYSAndmFsdWUnIGludG8gSlNPTiBmb3JtYXRcbiAgZnVuY3Rpb24gcGFyc2VWYWx1ZSAodmFsdWUpIHtcbiAgICB2YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgIHN3aXRjaCAodmFsdWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAndHJ1ZSc6IHJldHVybiB0cnVlO1xuICAgICAgY2FzZSAnZmFsc2UnOiByZXR1cm4gZmFsc2U7XG4gICAgICBjYXNlICcnOiByZXR1cm4gbnVsbDtcbiAgICAgIGRlZmF1bHQ6IGJyZWFrO1xuICAgIH1cbiAgICBpZiAoIWlzTmFOKHZhbHVlKSkge1xuICAgICAgaWYgKCFfLmlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmICghc3Rkb3V0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLy8gUGFyc2UgZWFjaCBsaW5lIGludG8gYW4gYXJyYXlcbiAgY29uc3QgbGluZXMgPSBzdGRvdXQudHJpbSgpLnNwbGl0KCdcXG4nKTtcblxuICAvLyBPbmUgc2luZ2xlIHN0cmluZywganVzdCByZXR1cm4gdGhlIHN0cmluZ1xuICBpZiAobGluZXMubGVuZ3RoID09PSAxICYmICFsaW5lc1swXS5pbmNsdWRlcygnfCcpKSB7XG4gICAgcmV0dXJuIFtsaW5lc1swXV07XG4gIH1cblxuICBjb25zdCByZXN1bHRzID0gW107XG4gIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgIC8vIFRoZSBwcm9wZXJ0aWVzIGFyZSBzcGxpdCB1cCBieSBwaXBlcyBhbmQgZWFjaCBwcm9wZXJ0eVxuICAgIC8vIGhhcyB0aGUgZm9ybWF0IFwiU29tZSBLZXkgOiBTb21lIFZhbHVlXCJcbiAgICBjb25zdCBwcm9wZXJ0aWVzID0gbGluZS5zcGxpdCgnfCcpO1xuXG4gICAgLy8gUGFyc2UgZWFjaCBwcm9wZXJ0eVxuICAgIGNvbnN0IG91dHB1dCA9IHt9O1xuICAgIGxldCBlbnRyeUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcGVydGllcykge1xuICAgICAgaWYgKGVudHJ5SW5kZXggPT09IDApIHtcbiAgICAgICAgLy8gVGhlIGZpcnN0IHByb3BlcnR5IG9ubHkgY29udGFpbnMgb25lIHN0cmluZyB0aGF0IGNvbnRhaW5zXG4gICAgICAgIC8vIHRoZSB0ZXN0IG5hbWUgKGUuZy46ICdYQ1Rlc3RlckFwcFVJVGVzdHMgLSBYQ1Rlc3RlckFwcFVJVGVzdHMuWENUZXN0ZXJBcHBVSVRlc3RzL3Rlc3RFeGFtcGxlJylcbiAgICAgICAgb3V0cHV0LnRlc3ROYW1lID0gcHJvcC50cmltKCk7XG4gICAgICB9IGVsc2UgaWYgKHByb3AudHJpbSgpLnN0YXJ0c1dpdGgoJ0xvY2F0aW9uJykpIHtcbiAgICAgICAgLy8gVGhlIExvY2F0aW9uIHByb3BlcnR5IGhhcyBhIHZhbHVlIHRoYXQgY29tZXMgYWZ0ZXIgJ0xvY2F0aW9uJyB3aXRob3V0IGNvbG9uLlxuICAgICAgICAvLyBlLmcuIExvY2F0aW9uIC9wYXRoL3RvL1hDVGVzdGVyQXBwVUlUZXN0cy9YQ1Rlc3RlckFwcFVJVGVzdHMuc3dpZnQ6MzZcbiAgICAgICAgb3V0cHV0LmxvY2F0aW9uID0gcHJvcC5zdWJzdHJpbmcocHJvcC5pbmRleE9mKCdMb2NhdGlvbicpICsgOCkudHJpbSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IFtrZXksIHZhbHVlXSA9IHByb3Auc3BsaXQoJzonKTtcbiAgICAgICAgb3V0cHV0W3BhcnNlS2V5KGtleS50cmltKCkpXSA9IHBhcnNlVmFsdWUodmFsdWUgPyB2YWx1ZS50cmltKCkgOiAnJyk7XG4gICAgICB9XG4gICAgICBlbnRyeUluZGV4Kys7XG4gICAgfVxuXG4gICAgLy8ga2VlcCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAgLy8gb2xkIHBhdHRlcm46IFhDVGVzdGVyQXBwVUlUZXN0cyAtIFhDVGVzdGVyQXBwVUlUZXN0cy5YQ1Rlc3RlckFwcFVJVGVzdHMvdGVzdEV4YW1wbGUgfCBQYXNzZWQ6IFRydWUgfCBDcmFzaGVkOiBGYWxzZSB8IER1cmF0aW9uOiAxLjQ4NSB8IEZhaWx1cmUgbWVzc2FnZTogIHwgTG9jYXRpb24gOjBcbiAgICAvLyBsYXRlc3QgcGF0dGVybjogWENUZXN0ZXJBcHBVSVRlc3RzIC0gWENUZXN0ZXJBcHBVSVRlc3RzLlhDVGVzdGVyQXBwVUlUZXN0cy90ZXN0RXhhbXBsZSB8IFN0YXR1czogcGFzc2VkIHwgRHVyYXRpb246IDEuOTI1NTc4OTUxODM1NjMyM1xuICAgIGlmICghb3V0cHV0LnBhc3NlZCkge1xuICAgICAgb3V0cHV0LnBhc3NlZCA9IG91dHB1dC5zdGF0dXMgPT09ICdwYXNzZWQnO1xuICAgICAgb3V0cHV0LmNyYXNoZWQgPSBvdXRwdXQuc3RhdHVzID09PSAnY3Jhc2hlZCc7XG4gICAgfSBlbHNlIGlmICghb3V0cHV0LnN0YXR1cykge1xuICAgICAgaWYgKG91dHB1dC5wYXNzZWQpIHtcbiAgICAgICAgb3V0cHV0LnN0YXR1cyA9ICdwYXNzZWQnO1xuICAgICAgfSBlbHNlIGlmIChvdXRwdXQuY3Jhc2hlZCkge1xuICAgICAgICBvdXRwdXQuc3RhdHVzID0gJ2NyYXNoZWQnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LnN0YXR1cyA9ICdmYWlsZWQnO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCB0aGlzIGxpbmUgdG8gdGhlIHJlc3VsdHNcbiAgICByZXN1bHRzLnB1c2gob3V0cHV0KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBSdW5YQ1VJVGVzdFJlc3BvbnNlXG4gKlxuICogQHByb3BlcnR5IHtBcnJheTxYQ1Rlc3RSZXN1bHQ+fSByZXN1bHRzIFRoZSByZXN1bHRzIG9mIGFsbCB0aGUgdGVzdHMgd2l0aCBpbmZvcm1hdGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IGNvZGUgVGhlIGV4aXQgY29kZSBvZiB0aGUgcHJvY2Vzc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHNpZ25hbCBUaGUgc2lnbmFsIHRoYXQgdGVybWluYXRlZCB0aGUgcHJvY2VzcyAob3IgbnVsbCkgKGUuZy46IFNJR1RFUk0pXG4gKlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUnVuWENVSVRlc3RPcHRpb25zXG4gKlxuICogQHByb3BlcnR5IHshc3RyaW5nfSB0ZXN0UnVubmVyQnVuZGxlSWQgVGVzdCBhcHAgYnVuZGxlIChlLmcuOiAnaW8uYXBwaXVtLlhDVGVzdGVyQXBwVUlUZXN0cy54Y3RydW5uZXInKVxuICogQHByb3BlcnR5IHshc3RyaW5nfSBhcHBVbmRlclRlc3RCdW5kbGVJZCBBcHAtdW5kZXItdGVzdCBidW5kbGVcbiAqIEBwcm9wZXJ0eSB7IXN0cmluZ30geGNUZXN0QnVuZGxlSUQgeGN0ZXN0IGJ1bmRsZSBpZFxuICogQHByb3BlcnR5IHtzdHJpbmd9IHRlc3RUeXBlIFt1aV0gWEMgdGVzdCB0eXBlLiAnYXBwJywgJ3VpJywgb3IgJ2xvZ2ljJ1xuICogQHByb3BlcnR5IHtvYmplY3R9IGVudiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgcGFzc2VkIHRvIHRlc3RcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8U3RyaW5nPn0gYXJncyBMYXVuY2ggYXJndW1lbnRzIHRvIHN0YXJ0IHRoZSB0ZXN0IHdpdGggKHNlZSBodHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi94Y3Rlc3QveGN1aWFwcGxpY2F0aW9uLzE1MDA0NzctbGF1bmNoYXJndW1lbnRzIGZvciByZWZlcmVuY2UpXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZW91dCBbMzYwMDAwXSBUaW1lb3V0IGlmIHNlc3Npb24gZG9lc24ndCBjb21wbGV0ZSBhZnRlciBnaXZlbiB0aW1lIChpbiBtaWxsaXNlY29uZHMpXG4gKi9cblxuXG4vKipcbiAqIEB0eXBlZGVmIHtFcnJvcn0gWENVSVRlc3RFcnJvclxuICpcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb2RlIFN1YnByb2Nlc3MgZXhpdCBjb2RlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2lnbmFsIFRoZSBzaWduYWwgKFNJRyopIHRoYXQgY2F1c2VkIHRoZSBwcm9jZXNzIHRvIGZhaWxcbiAqIEBwcm9wZXJ0eSB7IUFycmF5PFhDVGVzdFJlc3VsdD59IHJlc3VsdHMgVGhlIG91dHB1dCBvZiB0aGUgZmFpbGVkIHRlc3QgKGlmIHRoZXJlIGlzIG91dHB1dClcbiAqL1xuXG4vKipcbiAqIFJ1biBhbiBYQ1Rlc3QuIExhdW5jaGVzIGEgc3VicHJvY2VzcyB0aGF0IHJ1bnMgdGhlIFhDIFRlc3QgYW5kIGJsb2Nrc1xuICogdW50aWwgaXQgaXMgY29tcGxldGUuIFBhcnNlcyB0aGUgc3Rkb3V0IG9mIHRoZSBwcm9jZXNzIGFuZCByZXR1cm5zXG4gKiByZXN1bHQgYXMgYW4gYXJyYXlcbiAqXG4gKiBTZWUgaHR0cHM6Ly9mYmlkYi5pby9kb2NzL3Rlc3RfZXhlY3V0aW9uIGZvciByZWZlcmVuY2VcbiAqXG4gKiBAcGFyYW0ge1J1blhDVUlUZXN0T3B0aW9uc30gcnVuWENVSVRlc3RPcHRpb25zXG4gKiBAdGhyb3dzIHtYQ1VJVGVzdEVycm9yfSBFcnJvciB0aHJvd24gaWYgc3VicHJvY2VzcyByZXR1cm5zIG5vbi16ZXJvIGV4aXQgY29kZVxuICogQHJldHVybnMge1J1blhDVUlUZXN0UmVzcG9uc2V9XG4gKi9cbmNvbW1hbmRzLm1vYmlsZVJ1blhDVGVzdCA9IGFzeW5jIGZ1bmN0aW9uIHJ1blhDVGVzdCAoe1xuICB0ZXN0UnVubmVyQnVuZGxlSWQsXG4gIGFwcFVuZGVyVGVzdEJ1bmRsZUlkLFxuICB4Y3Rlc3RCdW5kbGVJZCxcbiAgdGVzdFR5cGUgPSAndWknLFxuICBlbnYsXG4gIGFyZ3MsXG4gIHRpbWVvdXQgPSBYQ1RFU1RfVElNRU9VVCxcbn0pIHtcbiAgY29uc3Qgc3VicHJvYyA9IGF3YWl0IGFzc2VydElEQih0aGlzLm9wdHMpLnJ1blhDVUlUZXN0KFxuICAgICAgICB0ZXN0UnVubmVyQnVuZGxlSWQsIGFwcFVuZGVyVGVzdEJ1bmRsZUlkLCB4Y3Rlc3RCdW5kbGVJZCwge2VudiwgYXJncywgdGVzdFR5cGV9LFxuICApO1xuICByZXR1cm4gYXdhaXQgbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCBtb3N0UmVjZW50TG9nT2JqZWN0ID0gbnVsbDtcbiAgICBsZXQgeGN0ZXN0VGltZW91dDtcbiAgICBsZXQgbGFzdEVycm9yTWVzc2FnZSA9IG51bGw7XG4gICAgaWYgKHRpbWVvdXQgPiAwKSB7XG4gICAgICB4Y3Rlc3RUaW1lb3V0ID0gc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4gcmVqZWN0KG5ldyBlcnJvcnMuVGltZW91dEVycm9yKGBUaW1lZCBvdXQgYWZ0ZXIgJyR7dGltZW91dH1tcycgd2FpdGluZyBmb3IgWENUZXN0IHRvIGNvbXBsZXRlYCkpLFxuICAgICAgICB0aW1lb3V0XG4gICAgICApO1xuICAgIH1cblxuICAgIHN1YnByb2Mub24oJ291dHB1dCcsIChzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgaWYgKHN0ZG91dCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG1vc3RSZWNlbnRMb2dPYmplY3QgPSBwYXJzZVhDVGVzdFN0ZG91dChzdGRvdXQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAvLyBGYWlscyBpZiBsb2cgcGFyc2luZyBmYWlscy5cbiAgICAgICAgICAvLyBUaGlzIGlzIGluIGNhc2UgSURCIGNoYW5nZXMgdGhlIHdheSB0aGF0IGxvZ3MgYXJlIGZvcm1hdHRlZCBhbmRcbiAgICAgICAgICAvLyBpdCBicmVha3MgJ3BhcnNlWENUZXN0U3Rkb3V0Jy4gSWYgdGhhdCBoYXBwZW5zIHdlIHN0aWxsIHdhbnQgdGhlIHByb2Nlc3NcbiAgICAgICAgICAvLyB0byBmaW5pc2hcbiAgICAgICAgICB0aGlzLmxvZy53YXJuKGBGYWlsZWQgdG8gcGFyc2UgbG9ncyBmcm9tIHRlc3Qgb3V0cHV0OiAnJHtzdGRvdXR9J2ApO1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGVyci5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHN0ZGVycikge1xuICAgICAgICBsYXN0RXJyb3JNZXNzYWdlID0gc3RkZXJyO1xuICAgICAgfVxuXG4gICAgICBzdGRvdXQgJiYgeGN0ZXN0TG9nLmluZm8oc3Rkb3V0KTtcbiAgICAgIHN0ZGVyciAmJiB4Y3Rlc3RMb2cuZXJyb3Ioc3RkZXJyKTtcbiAgICB9KTtcblxuICAgIHN1YnByb2Mub24oJ2V4aXQnLCAoY29kZSwgc2lnbmFsKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoeGN0ZXN0VGltZW91dCk7XG4gICAgICBpZiAoY29kZSAhPT0gMCkge1xuICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IobGFzdEVycm9yTWVzc2FnZSB8fCBtb3N0UmVjZW50TG9nT2JqZWN0KTtcbiAgICAgICAgZXJyLmNvZGUgPSBjb2RlO1xuICAgICAgICBpZiAoc2lnbmFsICE9IG51bGwpIHtcbiAgICAgICAgICBlcnIuc2lnbmFsID0gc2lnbmFsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtb3N0UmVjZW50TG9nT2JqZWN0KSB7XG4gICAgICAgICAgZXJyLnJlc3VsdCA9IG1vc3RSZWNlbnRMb2dPYmplY3Q7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZSh7XG4gICAgICAgIGNvZGUsIHNpZ25hbCwgcmVzdWx0czogbW9zdFJlY2VudExvZ09iamVjdCwgcGFzc2VkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBJbnN0YWxsWENUZXN0QnVuZGxlT3B0c1xuICpcbiAqIEBwcm9wZXJ0eSB7eGN0ZXN0QXBwfSB4Y3Rlc3RCdW5kbGUgUGF0aCBvZiB0aGUgWENUZXN0IGFwcCAoVVJMIG9yIC5hcHApXG4gKi9cblxuLyoqXG4gKiBJbnN0YWxsIGFuIFhDVGVzdEJ1bmRsZVxuICpcbiAqIEBwYXJhbSB7SW5zdGFsbFhDVGVzdEJ1bmRsZU9wdHMhfSBvcHRzIEluc3RhbGwgeGN0ZXN0IGJ1bmRsZSBvcHRzXG4gKi9cbmNvbW1hbmRzLm1vYmlsZUluc3RhbGxYQ1Rlc3RCdW5kbGUgPSBhc3luYyBmdW5jdGlvbiBpbnN0YWxsWENUZXN0QnVuZGxlIChvcHRzKSB7XG4gIGNvbnN0IHsgeGN0ZXN0QXBwIH0gPSBvcHRzO1xuICBpZiAoIV8uaXNTdHJpbmcoeGN0ZXN0QXBwKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IoYCd4Y3Rlc3RBcHAnIGlzIGEgcmVxdWlyZWQgcGFyYW1ldGVyIGZvciAnaW5zdGFsbFhDVGVzdEJ1bmRsZScgYW5kIGAgK1xuICAgICAgYG11c3QgYmUgYSBzdHJpbmcuIEZvdW5kICcke3hjdGVzdEFwcH0nYCk7XG4gIH1cbiAgeGN0ZXN0TG9nLmluZm8oYEluc3RhbGxpbmcgYnVuZGxlICcke3hjdGVzdEFwcH0nYCk7XG4gIGNvbnN0IGlkYiA9IGFzc2VydElEQih0aGlzLm9wdHMpO1xuICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmhlbHBlcnMuY29uZmlndXJlQXBwKHhjdGVzdEFwcCwgJy54Y3Rlc3QnKTtcbiAgYXdhaXQgaWRiLmluc3RhbGxYQ1Rlc3RCdW5kbGUocmVzKTtcbn07XG5cbi8qKlxuICogTGlzdCBYQ1Rlc3QgYnVuZGxlcyB0aGF0IGFyZSBpbnN0YWxsZWQgb24gZGV2aWNlXG4gKlxuICogQHJldHVybnMge0FycmF5PHN0cmluZz59IExpc3Qgb2YgWENUZXN0IGJ1bmRsZXMgKGUuZy46IFwiWENUZXN0ZXJBcHBVSVRlc3RzLlhDVGVzdGVyQXBwVUlUZXN0cy90ZXN0TGF1bmNoUGVyZm9ybWFuY2VcIilcbiAqL1xuY29tbWFuZHMubW9iaWxlTGlzdFhDVGVzdEJ1bmRsZXMgPSBhc3luYyBmdW5jdGlvbiBsaXN0WENUZXN0c0luVGVzdEJ1bmRsZSAoKSB7XG4gIHJldHVybiBhd2FpdCBhc3NlcnRJREIodGhpcy5vcHRzKS5saXN0WENUZXN0QnVuZGxlcygpO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBMaXN0WENUZXN0c09wdHNcbiAqXG4gKiBAcHJvcGVydHkgeyFzdHJpbmd9IGJ1bmRsZSBCdW5kbGUgSUQgb2YgdGhlIFhDVGVzdFxuICovXG5cbi8qKlxuICogTGlzdCBYQ1Rlc3RzIGluIGEgdGVzdCBidW5kbGVcbiAqXG4gKiBAcGFyYW0geyFMaXN0WENUZXN0c09wdHN9IG9wdHMgWENUZXN0IGxpc3Qgb3B0aW9uc1xuICpcbiAqIEByZXR1cm5zIHtBcnJheTxzdHJpbmc+fSBUaGUgbGlzdCBvZiB4Y3Rlc3RzIGluIHRoZSB0ZXN0IGJ1bmRsZVxuICogICAgKGUuZy46IFsgJ1hDVGVzdGVyQXBwVUlUZXN0cy5YQ1Rlc3RlckFwcFVJVGVzdHMvdGVzdEV4YW1wbGUnLFxuICAgICAgICAgICAgICAgICdYQ1Rlc3RlckFwcFVJVGVzdHMuWENUZXN0ZXJBcHBVSVRlc3RzL3Rlc3RMYXVuY2hQZXJmb3JtYW5jZScgXSApXG4gKi9cbmNvbW1hbmRzLm1vYmlsZUxpc3RYQ1Rlc3RzSW5UZXN0QnVuZGxlID0gYXN5bmMgZnVuY3Rpb24gbGlzdFhDVGVzdHNJblRlc3RCdW5kbGUgKG9wdHMpIHtcbiAgY29uc3QgeyBidW5kbGUgfSA9IG9wdHM7XG4gIGlmICghXy5pc1N0cmluZyhidW5kbGUpKSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihgJ2J1bmRsZScgaXMgYSByZXF1aXJlZCBwYXJhbWV0ZXIgZm9yICdsaXN0WENUZXN0c0luVGVzdEJ1bmRsZScgYW5kIGAgK1xuICAgICAgYG11c3QgYmUgYSBzdHJpbmcuIEZvdW5kICcke2J1bmRsZX0nYCk7XG4gIH1cbiAgY29uc3QgaWRiID0gYXNzZXJ0SURCKHRoaXMub3B0cyk7XG4gIHJldHVybiBhd2FpdCBpZGIubGlzdFhDVGVzdHNJblRlc3RCdW5kbGUoYnVuZGxlKTtcbn07XG5cbk9iamVjdC5hc3NpZ24oY29tbWFuZHMpO1xuZXhwb3J0IHsgY29tbWFuZHMgfTtcbmV4cG9ydCBkZWZhdWx0IGNvbW1hbmRzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFHQSxNQUFNQSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQUM7QUFFcEIsTUFBTUMsY0FBYyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSTtBQUVyQyxNQUFNQyxTQUFTLEdBQUdDLGVBQU0sQ0FBQ0MsU0FBUyxDQUFDLFFBQVEsQ0FBQztBQU9yQyxTQUFTQyxTQUFTLENBQUVDLElBQUksRUFBRTtFQUFBO0VBQy9CLElBQUksa0JBQUNBLElBQUksQ0FBQ0MsTUFBTSx5Q0FBWCxhQUFhQyxHQUFHLEtBQUksQ0FBQ0YsSUFBSSxDQUFDRyxhQUFhLEVBQUU7SUFDNUMsTUFBTSxJQUFJQyxLQUFLLENBQUUsZ0ZBQStFLEdBQzdGLDhEQUE2RCxDQUFD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
@@ -1 +1 @@
1
- {"version":3,"file":"xctest.js","names":["commands","XCTEST_TIMEOUT","xctestLog","logger","getLogger","assertIDB","opts","device","idb","launchWithIDB","Error","parseXCTestStdout","stdout","parseKey","name","words","split","out","word","substr","toUpperCase","toLowerCase","parseValue","value","isNaN","_","isString","indexOf","parseFloat","parseInt","lines","trim","length","includes","results","line","properties","output","entryIndex","prop","testName","key","push","mobileRunXCTest","runXCTest","testRunnerBundleId","appUnderTestBundleId","xctestBundleId","testType","env","args","timeout","subproc","runXCUITest","B","resolve","reject","mostRecentLogObject","xctestTimeout","setTimeout","on","stderr","err","log","warn","debug","stack","info","error","code","signal","clearTimeout","result","passed","mobileInstallXCTestBundle","installXCTestBundle","xctestApp","errors","InvalidArgumentError","res","helpers","configureApp","mobileListXCTestBundles","listXCTestsInTestBundle","listXCTestBundles","mobileListXCTestsInTestBundle","bundle","Object","assign"],"sources":["../../../lib/commands/xctest.js"],"sourcesContent":["import B from 'bluebird';\nimport { logger } from 'appium/support';\nimport _ from 'lodash';\nimport { errors } from 'appium/driver';\n\n\nconst commands = {};\n\nconst XCTEST_TIMEOUT = 60 * 60 * 1000; // 60 minute timeout\n\nconst xctestLog = logger.getLogger('XCTest');\n\n/**\n * Asserts that IDB is present and that launchWithIDB was used\n *\n * @param {object} opts Opts object from the driver instance\n */\nexport function assertIDB (opts) {\n if (!opts.device?.idb || !opts.launchWithIDB) {\n throw new Error(`To use XCTest runner, IDB (https://github.com/facebook/idb) must be installed ` +\n `and sessions must be run with the \"launchWithIDB\" capability`);\n }\n return opts.device.idb;\n}\n\n\n/**\n * @typedef {Object} XCTestResult\n *\n * @property {string} testName Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')\n * @property {boolean} passed Did the tests pass?\n * @property {boolean} crashed Did the tests crash?\n * @property {number} duration How long did the tests take (in seconds)\n * @property {string} failureMessage Failure message (if applicable)\n * @property {number} location The geolocation of the tests (if applicable)\n */\n\n/**\n * Parse the stdout of XC test log\n * @param {string} stdout A line of standard out from `idb xctest run ...`\n * @returns {Array<XCTestResult>} results The final output of the XCTest run\n */\nexport function parseXCTestStdout (stdout) {\n // Parses a 'key' into JSON format\n function parseKey (name) {\n const words = name.split(' ');\n let out = '';\n for (const word of words) {\n out += word.substr(0, 1).toUpperCase() + word.substr(1);\n }\n return out.substr(0, 1).toLowerCase() + out.substr(1);\n }\n\n // Parses a 'value' into JSON format\n function parseValue (value) {\n value = value || '';\n switch (value.toLowerCase()) {\n case 'true': return true;\n case 'false': return false;\n case '': return null;\n default: break;\n }\n if (!isNaN(value)) {\n if (!_.isString(value)) {\n return 0;\n } else if (value.indexOf('.') > 0) {\n return parseFloat(value);\n }\n return parseInt(value, 10);\n }\n }\n if (!stdout) {\n return [];\n }\n\n // Parse each line into an array\n const lines = stdout.trim().split('\\n');\n\n // One single string, just return the string\n if (lines.length === 1 && !lines[0].includes('|')) {\n return [lines[0]];\n }\n\n const results = [];\n for (const line of lines) {\n // The properties are split up by pipes and each property\n // has the format \"Some Key : Some Value\"\n const properties = line.split('|');\n\n // Parse each property\n const output = {};\n let entryIndex = 0;\n for (const prop of properties) {\n if (entryIndex === 0) {\n // The first property only contains one string that contains\n // the test name (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')\n output.testName = prop.trim();\n } else {\n\n let [key, value] = prop.split(':');\n output[parseKey(key.trim())] = parseValue(value ? value.trim() : '');\n }\n entryIndex++;\n }\n // Add this line to the results\n results.push(output);\n }\n return results;\n}\n\n/**\n * @typedef {Object} RunXCUITestResponse\n *\n * @property {Array<XCTestResult>} results The results of all the tests with information\n * @property {number} code The exit code of the process\n * @property {string} signal The signal that terminated the process (or null) (e.g.: SIGTERM)\n *\n */\n\n/**\n * @typedef {Object} RunXCUITestOptions\n *\n * @property {!string} testRunnerBundleId Test app bundle (e.g.: 'io.appium.XCTesterAppUITests.xctrunner')\n * @property {!string} appUnderTestBundleId App-under-test bundle\n * @property {!string} xcTestBundleID xctest bundle id\n * @property {string} testType [ui] XC test type. 'app', 'ui', or 'logic'\n * @property {object} env Environment variables passed to test\n * @property {Array<String>} args Launch arguments to start the test with (see https://developer.apple.com/documentation/xctest/xcuiapplication/1500477-launcharguments for reference)\n * @property {number} timeout [360000] Timeout if session doesn't complete after given time (in milliseconds)\n */\n\n\n/**\n * @typedef {Error} XCUITestError\n *\n * @property {number} code Subprocess exit code\n * @property {string} signal The signal (SIG*) that caused the process to fail\n * @property {!Array<XCTestResult>} results The output of the failed test (if there is output)\n */\n\n/**\n * Run an XCTest. Launches a subprocess that runs the XC Test and blocks\n * until it is complete. Parses the stdout of the process and returns\n * result as an array\n *\n * See https://fbidb.io/docs/test_execution for reference\n *\n * @param {RunXCUITestOptions} runXCUITestOptions\n * @throws {XCUITestError} Error thrown if subprocess returns non-zero exit code\n * @returns {RunXCUITestResponse}\n */\ncommands.mobileRunXCTest = async function runXCTest ({\n testRunnerBundleId,\n appUnderTestBundleId,\n xctestBundleId,\n testType = 'ui',\n env,\n args,\n timeout = XCTEST_TIMEOUT,\n}) {\n const subproc = await assertIDB(this.opts).runXCUITest(\n testRunnerBundleId, appUnderTestBundleId, xctestBundleId, {env, args, testType},\n );\n return await new B((resolve, reject) => {\n let mostRecentLogObject = null;\n let xctestTimeout;\n if (timeout > 0) {\n xctestTimeout = setTimeout(\n () => reject(`Timed out after '${timeout}ms' waiting for XCTest to complete`),\n timeout\n );\n }\n\n subproc.on('output', (stdout, stderr) => {\n if (stdout) {\n try {\n mostRecentLogObject = parseXCTestStdout(stdout);\n } catch (err) {\n // Fails if log parsing fails.\n // This is in case IDB changes the way that logs are formatted and\n // it breaks 'parseXCTestStdout'. If that happens we still want the process\n // to finish\n this.log.warn(`Failed to parse logs from test output: '${stdout}'`);\n this.log.debug(err.stack);\n }\n }\n stdout && xctestLog.info(stdout);\n stderr && xctestLog.error(stderr);\n });\n\n subproc.on('exit', (code, signal) => {\n clearTimeout(xctestTimeout);\n if (code !== 0) {\n const err = new Error(mostRecentLogObject);\n err.code = code;\n if (signal != null) {\n err.signal = signal;\n }\n if (mostRecentLogObject) {\n err.result = mostRecentLogObject;\n }\n return reject(err);\n }\n resolve({\n code, signal, results: mostRecentLogObject, passed: true,\n });\n });\n });\n};\n\n/**\n * @typedef {Object} InstallXCTestBundleOpts\n *\n * @property {xctestApp} xctestBundle Path of the XCTest app (URL or .app)\n */\n\n/**\n * Install an XCTestBundle\n *\n * @param {InstallXCTestBundleOpts!} opts Install xctest bundle opts\n */\ncommands.mobileInstallXCTestBundle = async function installXCTestBundle (opts) {\n const { xctestApp } = opts;\n if (!_.isString(xctestApp)) {\n throw new errors.InvalidArgumentError(`'xctestApp' is a required parameter for 'installXCTestBundle' and ` +\n `must be a string. Found '${xctestApp}'`);\n }\n xctestLog.info(`Installing bundle '${xctestApp}'`);\n const idb = assertIDB(this.opts);\n const res = await this.helpers.configureApp(xctestApp, '.xctest');\n await idb.installXCTestBundle(res);\n};\n\n/**\n * List XCTest bundles that are installed on device\n *\n * @returns {Array<string>} List of XCTest bundles (e.g.: \"XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance\")\n */\ncommands.mobileListXCTestBundles = async function listXCTestsInTestBundle () {\n return await assertIDB(this.opts).listXCTestBundles();\n};\n\n/**\n * @typedef {Object} ListXCTestsOpts\n *\n * @property {!string} bundle Bundle ID of the XCTest\n */\n\n/**\n * List XCTests in a test bundle\n *\n * @param {!ListXCTestsOpts} opts XCTest list options\n *\n * @returns {Array<string>} The list of xctests in the test bundle\n * (e.g.: [ 'XCTesterAppUITests.XCTesterAppUITests/testExample',\n 'XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance' ] )\n */\ncommands.mobileListXCTestsInTestBundle = async function listXCTestsInTestBundle (opts) {\n const { bundle } = opts;\n if (!_.isString(bundle)) {\n throw new errors.InvalidArgumentError(`'bundle' is a required parameter for 'listXCTestsInTestBundle' and ` +\n `must be a string. Found '${bundle}'`);\n }\n const idb = assertIDB(this.opts);\n return await idb.listXCTestsInTestBundle(bundle);\n};\n\nObject.assign(commands);\nexport { commands };\nexport default commands;\n"],"mappings":"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"}
1
+ {"version":3,"file":"xctest.js","names":["commands","XCTEST_TIMEOUT","xctestLog","logger","getLogger","assertIDB","opts","device","idb","launchWithIDB","Error","parseXCTestStdout","stdout","parseKey","name","words","split","out","word","substr","toUpperCase","toLowerCase","parseValue","value","isNaN","_","isString","indexOf","parseFloat","parseInt","lines","trim","length","includes","results","line","properties","output","entryIndex","prop","testName","startsWith","location","substring","key","passed","status","crashed","push","mobileRunXCTest","runXCTest","testRunnerBundleId","appUnderTestBundleId","xctestBundleId","testType","env","args","timeout","subproc","runXCUITest","B","resolve","reject","mostRecentLogObject","xctestTimeout","lastErrorMessage","setTimeout","errors","TimeoutError","on","stderr","err","log","warn","debug","stack","info","error","code","signal","clearTimeout","result","mobileInstallXCTestBundle","installXCTestBundle","xctestApp","InvalidArgumentError","res","helpers","configureApp","mobileListXCTestBundles","listXCTestsInTestBundle","listXCTestBundles","mobileListXCTestsInTestBundle","bundle","Object","assign"],"sources":["../../../lib/commands/xctest.js"],"sourcesContent":["import B from 'bluebird';\nimport { logger } from 'appium/support';\nimport _ from 'lodash';\nimport { errors } from 'appium/driver';\n\n\nconst commands = {};\n\nconst XCTEST_TIMEOUT = 60 * 60 * 1000; // 60 minute timeout\n\nconst xctestLog = logger.getLogger('XCTest');\n\n/**\n * Asserts that IDB is present and that launchWithIDB was used\n *\n * @param {object} opts Opts object from the driver instance\n */\nexport function assertIDB (opts) {\n if (!opts.device?.idb || !opts.launchWithIDB) {\n throw new Error(`To use XCTest runner, IDB (https://github.com/facebook/idb) must be installed ` +\n `and sessions must be run with the \"launchWithIDB\" capability`);\n }\n return opts.device.idb;\n}\n\n\n/**\n * @typedef {Object} XCTestResult\n *\n * @property {string} testName Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')\n * @property {boolean} passed Did the tests pass?\n * @property {boolean} crashed Did the tests crash?\n * @property {string} status Test result status (e.g.: 'passed', 'failed', 'crashed')\n * @property {number} duration How long did the tests take (in seconds)\n * @property {string} failureMessage Failure message (if applicable)\n * @property {number} location The geolocation of the tests (if applicable)\n */\n\n/**\n * Parse the stdout of XC test log\n * @param {string} stdout A line of standard out from `idb xctest run ...`\n * @returns {Array<XCTestResult>} results The final output of the XCTest run\n */\nexport function parseXCTestStdout (stdout) {\n // Parses a 'key' into JSON format\n function parseKey (name) {\n const words = name.split(' ');\n let out = '';\n for (const word of words) {\n out += word.substr(0, 1).toUpperCase() + word.substr(1);\n }\n return out.substr(0, 1).toLowerCase() + out.substr(1);\n }\n\n // Parses a 'value' into JSON format\n function parseValue (value) {\n value = value || '';\n switch (value.toLowerCase()) {\n case 'true': return true;\n case 'false': return false;\n case '': return null;\n default: break;\n }\n if (!isNaN(value)) {\n if (!_.isString(value)) {\n return 0;\n } else if (value.indexOf('.') > 0) {\n return parseFloat(value);\n }\n return parseInt(value, 10);\n }\n return value;\n }\n if (!stdout) {\n return [];\n }\n\n // Parse each line into an array\n const lines = stdout.trim().split('\\n');\n\n // One single string, just return the string\n if (lines.length === 1 && !lines[0].includes('|')) {\n return [lines[0]];\n }\n\n const results = [];\n for (const line of lines) {\n // The properties are split up by pipes and each property\n // has the format \"Some Key : Some Value\"\n const properties = line.split('|');\n\n // Parse each property\n const output = {};\n let entryIndex = 0;\n for (const prop of properties) {\n if (entryIndex === 0) {\n // The first property only contains one string that contains\n // the test name (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')\n output.testName = prop.trim();\n } else if (prop.trim().startsWith('Location')) {\n // The Location property has a value that comes after 'Location' without colon.\n // e.g. Location /path/to/XCTesterAppUITests/XCTesterAppUITests.swift:36\n output.location = prop.substring(prop.indexOf('Location') + 8).trim();\n } else {\n let [key, value] = prop.split(':');\n output[parseKey(key.trim())] = parseValue(value ? value.trim() : '');\n }\n entryIndex++;\n }\n\n // keep backward compatibility\n // old pattern: XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample | Passed: True | Crashed: False | Duration: 1.485 | Failure message: | Location :0\n // latest pattern: XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample | Status: passed | Duration: 1.9255789518356323\n if (!output.passed) {\n output.passed = output.status === 'passed';\n output.crashed = output.status === 'crashed';\n } else if (!output.status) {\n if (output.passed) {\n output.status = 'passed';\n } else if (output.crashed) {\n output.status = 'crashed';\n } else {\n output.status = 'failed';\n }\n }\n\n // Add this line to the results\n results.push(output);\n }\n return results;\n}\n\n/**\n * @typedef {Object} RunXCUITestResponse\n *\n * @property {Array<XCTestResult>} results The results of all the tests with information\n * @property {number} code The exit code of the process\n * @property {string} signal The signal that terminated the process (or null) (e.g.: SIGTERM)\n *\n */\n\n/**\n * @typedef {Object} RunXCUITestOptions\n *\n * @property {!string} testRunnerBundleId Test app bundle (e.g.: 'io.appium.XCTesterAppUITests.xctrunner')\n * @property {!string} appUnderTestBundleId App-under-test bundle\n * @property {!string} xcTestBundleID xctest bundle id\n * @property {string} testType [ui] XC test type. 'app', 'ui', or 'logic'\n * @property {object} env Environment variables passed to test\n * @property {Array<String>} args Launch arguments to start the test with (see https://developer.apple.com/documentation/xctest/xcuiapplication/1500477-launcharguments for reference)\n * @property {number} timeout [360000] Timeout if session doesn't complete after given time (in milliseconds)\n */\n\n\n/**\n * @typedef {Error} XCUITestError\n *\n * @property {number} code Subprocess exit code\n * @property {string} signal The signal (SIG*) that caused the process to fail\n * @property {!Array<XCTestResult>} results The output of the failed test (if there is output)\n */\n\n/**\n * Run an XCTest. Launches a subprocess that runs the XC Test and blocks\n * until it is complete. Parses the stdout of the process and returns\n * result as an array\n *\n * See https://fbidb.io/docs/test_execution for reference\n *\n * @param {RunXCUITestOptions} runXCUITestOptions\n * @throws {XCUITestError} Error thrown if subprocess returns non-zero exit code\n * @returns {RunXCUITestResponse}\n */\ncommands.mobileRunXCTest = async function runXCTest ({\n testRunnerBundleId,\n appUnderTestBundleId,\n xctestBundleId,\n testType = 'ui',\n env,\n args,\n timeout = XCTEST_TIMEOUT,\n}) {\n const subproc = await assertIDB(this.opts).runXCUITest(\n testRunnerBundleId, appUnderTestBundleId, xctestBundleId, {env, args, testType},\n );\n return await new B((resolve, reject) => {\n let mostRecentLogObject = null;\n let xctestTimeout;\n let lastErrorMessage = null;\n if (timeout > 0) {\n xctestTimeout = setTimeout(\n () => reject(new errors.TimeoutError(`Timed out after '${timeout}ms' waiting for XCTest to complete`)),\n timeout\n );\n }\n\n subproc.on('output', (stdout, stderr) => {\n if (stdout) {\n try {\n mostRecentLogObject = parseXCTestStdout(stdout);\n } catch (err) {\n // Fails if log parsing fails.\n // This is in case IDB changes the way that logs are formatted and\n // it breaks 'parseXCTestStdout'. If that happens we still want the process\n // to finish\n this.log.warn(`Failed to parse logs from test output: '${stdout}'`);\n this.log.debug(err.stack);\n }\n }\n\n if (stderr) {\n lastErrorMessage = stderr;\n }\n\n stdout && xctestLog.info(stdout);\n stderr && xctestLog.error(stderr);\n });\n\n subproc.on('exit', (code, signal) => {\n clearTimeout(xctestTimeout);\n if (code !== 0) {\n const err = new Error(lastErrorMessage || mostRecentLogObject);\n err.code = code;\n if (signal != null) {\n err.signal = signal;\n }\n if (mostRecentLogObject) {\n err.result = mostRecentLogObject;\n }\n return reject(err);\n }\n resolve({\n code, signal, results: mostRecentLogObject, passed: true,\n });\n });\n });\n};\n\n/**\n * @typedef {Object} InstallXCTestBundleOpts\n *\n * @property {xctestApp} xctestBundle Path of the XCTest app (URL or .app)\n */\n\n/**\n * Install an XCTestBundle\n *\n * @param {InstallXCTestBundleOpts!} opts Install xctest bundle opts\n */\ncommands.mobileInstallXCTestBundle = async function installXCTestBundle (opts) {\n const { xctestApp } = opts;\n if (!_.isString(xctestApp)) {\n throw new errors.InvalidArgumentError(`'xctestApp' is a required parameter for 'installXCTestBundle' and ` +\n `must be a string. Found '${xctestApp}'`);\n }\n xctestLog.info(`Installing bundle '${xctestApp}'`);\n const idb = assertIDB(this.opts);\n const res = await this.helpers.configureApp(xctestApp, '.xctest');\n await idb.installXCTestBundle(res);\n};\n\n/**\n * List XCTest bundles that are installed on device\n *\n * @returns {Array<string>} List of XCTest bundles (e.g.: \"XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance\")\n */\ncommands.mobileListXCTestBundles = async function listXCTestsInTestBundle () {\n return await assertIDB(this.opts).listXCTestBundles();\n};\n\n/**\n * @typedef {Object} ListXCTestsOpts\n *\n * @property {!string} bundle Bundle ID of the XCTest\n */\n\n/**\n * List XCTests in a test bundle\n *\n * @param {!ListXCTestsOpts} opts XCTest list options\n *\n * @returns {Array<string>} The list of xctests in the test bundle\n * (e.g.: [ 'XCTesterAppUITests.XCTesterAppUITests/testExample',\n 'XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance' ] )\n */\ncommands.mobileListXCTestsInTestBundle = async function listXCTestsInTestBundle (opts) {\n const { bundle } = opts;\n if (!_.isString(bundle)) {\n throw new errors.InvalidArgumentError(`'bundle' is a required parameter for 'listXCTestsInTestBundle' and ` +\n `must be a string. Found '${bundle}'`);\n }\n const idb = assertIDB(this.opts);\n return await idb.listXCTestsInTestBundle(bundle);\n};\n\nObject.assign(commands);\nexport { commands };\nexport default commands;\n"],"mappings":"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"}
@@ -39,7 +39,7 @@ commands.mobileSetAppearance = async function mobileSetAppearance (opts = {}) {
39
39
  }
40
40
  }
41
41
  try {
42
- return void (await this.proxyCommand('/wda/device/appearance', 'POST', {name: style}));
42
+ return void (await this.proxyCommand('/wda/device/appearance', 'POST', {name: style}, false));
43
43
  } catch (e) {
44
44
  this.log.debug(e.stack);
45
45
  }
@@ -30,6 +30,7 @@ export function assertIDB (opts) {
30
30
  * @property {string} testName Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')
31
31
  * @property {boolean} passed Did the tests pass?
32
32
  * @property {boolean} crashed Did the tests crash?
33
+ * @property {string} status Test result status (e.g.: 'passed', 'failed', 'crashed')
33
34
  * @property {number} duration How long did the tests take (in seconds)
34
35
  * @property {string} failureMessage Failure message (if applicable)
35
36
  * @property {number} location The geolocation of the tests (if applicable)
@@ -68,6 +69,7 @@ export function parseXCTestStdout (stdout) {
68
69
  }
69
70
  return parseInt(value, 10);
70
71
  }
72
+ return value;
71
73
  }
72
74
  if (!stdout) {
73
75
  return [];
@@ -95,13 +97,33 @@ export function parseXCTestStdout (stdout) {
95
97
  // The first property only contains one string that contains
96
98
  // the test name (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')
97
99
  output.testName = prop.trim();
100
+ } else if (prop.trim().startsWith('Location')) {
101
+ // The Location property has a value that comes after 'Location' without colon.
102
+ // e.g. Location /path/to/XCTesterAppUITests/XCTesterAppUITests.swift:36
103
+ output.location = prop.substring(prop.indexOf('Location') + 8).trim();
98
104
  } else {
99
-
100
105
  let [key, value] = prop.split(':');
101
106
  output[parseKey(key.trim())] = parseValue(value ? value.trim() : '');
102
107
  }
103
108
  entryIndex++;
104
109
  }
110
+
111
+ // keep backward compatibility
112
+ // old pattern: XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample | Passed: True | Crashed: False | Duration: 1.485 | Failure message: | Location :0
113
+ // latest pattern: XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample | Status: passed | Duration: 1.9255789518356323
114
+ if (!output.passed) {
115
+ output.passed = output.status === 'passed';
116
+ output.crashed = output.status === 'crashed';
117
+ } else if (!output.status) {
118
+ if (output.passed) {
119
+ output.status = 'passed';
120
+ } else if (output.crashed) {
121
+ output.status = 'crashed';
122
+ } else {
123
+ output.status = 'failed';
124
+ }
125
+ }
126
+
105
127
  // Add this line to the results
106
128
  results.push(output);
107
129
  }
@@ -164,9 +186,10 @@ commands.mobileRunXCTest = async function runXCTest ({
164
186
  return await new B((resolve, reject) => {
165
187
  let mostRecentLogObject = null;
166
188
  let xctestTimeout;
189
+ let lastErrorMessage = null;
167
190
  if (timeout > 0) {
168
191
  xctestTimeout = setTimeout(
169
- () => reject(`Timed out after '${timeout}ms' waiting for XCTest to complete`),
192
+ () => reject(new errors.TimeoutError(`Timed out after '${timeout}ms' waiting for XCTest to complete`)),
170
193
  timeout
171
194
  );
172
195
  }
@@ -184,6 +207,11 @@ commands.mobileRunXCTest = async function runXCTest ({
184
207
  this.log.debug(err.stack);
185
208
  }
186
209
  }
210
+
211
+ if (stderr) {
212
+ lastErrorMessage = stderr;
213
+ }
214
+
187
215
  stdout && xctestLog.info(stdout);
188
216
  stderr && xctestLog.error(stderr);
189
217
  });
@@ -191,7 +219,7 @@ commands.mobileRunXCTest = async function runXCTest ({
191
219
  subproc.on('exit', (code, signal) => {
192
220
  clearTimeout(xctestTimeout);
193
221
  if (code !== 0) {
194
- const err = new Error(mostRecentLogObject);
222
+ const err = new Error(lastErrorMessage || mostRecentLogObject);
195
223
  err.code = code;
196
224
  if (signal != null) {
197
225
  err.signal = signal;