appium-doctor
Version:
Test environment for fitness to run Appium
439 lines (365 loc) • 45 kB
JavaScript
require('source-map-support').install();
;
var _Promise = require('babel-runtime/core-js/promise')['default'];
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
var _this = this;
var _libDoctor = require('../lib/doctor');
var _chai = require('chai');
var _chai2 = _interopRequireDefault(_chai);
var _appiumTestSupport = require('appium-test-support');
var _libLogger = require('../lib/logger');
var _libLogger2 = _interopRequireDefault(_libLogger);
_chai2['default'].should();
var P = _Promise;
describe('doctor', function () {
it('register', function () {
var doctor = new _libDoctor.Doctor();
doctor.checks.should.have.length(0);
doctor.register(new _libDoctor.DoctorCheck());
doctor.checks.should.have.length(1);
doctor.register([new _libDoctor.DoctorCheck(), new _libDoctor.DoctorCheck()]);
doctor.checks.should.have.length(3);
});
function configure() {
var doctor = new _libDoctor.Doctor();
var checks = [new _libDoctor.DoctorCheck(), new _libDoctor.DoctorCheck(), new _libDoctor.DoctorCheck()];
doctor.register(checks);
return { doctor: doctor, checks: checks };
}
describe('diagnose', (0, _appiumTestSupport.withMocks)({}, function (mocks, S) {
it('should detect all issues', function callee$2$0() {
var logStub, _configure, doctor, checks;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
_configure = configure();
doctor = _configure.doctor;
checks = _configure.checks;
mocks.checks = checks.map(function (check) {
return S.sandbox.mock(check);
});
mocks.checks[0].expects('diagnose').once().returns({ ok: true, message: "All Good!" });
mocks.checks[1].expects('diagnose').once().returns({ ok: false, message: "Oh No!" });
mocks.checks[2].expects('diagnose').once().returns({ ok: false, message: "Oh No!" });
context$3$0.next = 10;
return _regeneratorRuntime.awrap(doctor.diagnose());
case 10:
(0, _appiumTestSupport.verify)(mocks);
doctor.toFix.should.have.length(2);
logStub.output.should.equal(['info: ### Diagnostic starting ###', 'info: ✔ All Good!', 'warn: ✖ Oh No!', 'warn: ✖ Oh No!', 'info: ### Diagnostic completed, 2 fixes needed. ###', 'info: '].join('\n'));
case 13:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('reportSuccess', (0, _appiumTestSupport.withMocks)({}, function (mocks, S) {
var doctor = new _libDoctor.Doctor();
it('should report success when no fixes are needed', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
doctor.toFix = [];
context$3$0.next = 4;
return _regeneratorRuntime.awrap(doctor.reportSuccess());
case 4:
context$3$0.sent.should.equal(true);
logStub.output.should.equal(['info: Everything looks good, bye!', 'info: '].join('\n'));
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should return false when fixes are needed', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
doctor.toFix = [{}];
context$3$0.next = 3;
return _regeneratorRuntime.awrap(doctor.reportSuccess());
case 3:
context$3$0.sent.should.equal(false);
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('reportManualFixes', (0, _appiumTestSupport.withMocks)({}, function (mocks, S) {
var doctor = new _libDoctor.Doctor();
it('should ask for manual fixes to be applied', function callee$2$0() {
var logStub, i, m;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
doctor.toFix = [{ error: 'Oh no this need to be manually fixed.', check: new _libDoctor.DoctorCheck() }, { error: 'Oh no this is an autofix.', check: new _libDoctor.DoctorCheck({ autofix: true }) }, { error: 'Oh no this also need to be manually fixed.', check: new _libDoctor.DoctorCheck() }, { error: 'Oh no this also need to be manually fixed.', check: new _libDoctor.DoctorCheck() }];
for (i = 0; i < doctor.toFix.length; i++) {
m = S.sandbox.mock(doctor.toFix[i].check);
if (doctor.toFix[i].check.autofix) {
m.expects('fix').never();
} else {
m.expects('fix').once().returns(P.resolve('Manual fix for ' + i + ' is do something.'));
}
}
context$3$0.next = 5;
return _regeneratorRuntime.awrap(doctor.reportManualFixes());
case 5:
context$3$0.sent.should.equal(true);
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: ### Manual Fixes Needed ###', 'info: The configuration cannot be automatically fixed, please do the following first:', 'warn: - Manual fix for 0 is do something.', 'warn: - Manual fix for 2 is do something.', 'warn: - Manual fix for 3 is do something.', 'info: ###', 'info: ', 'info: Bye, run appium-doctor again when all manual fixes have been applied!', 'info: '].join('\n'));
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should return false when there is no manual fix', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
doctor.toFix = [{ error: 'Oh no!', check: new _libDoctor.DoctorCheck({ autofix: true }) }];
context$3$0.next = 3;
return _regeneratorRuntime.awrap(doctor.reportManualFixes());
case 3:
context$3$0.sent.should.equal(false);
case 4:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('runAutoFix', (0, _appiumTestSupport.withMocks)({}, function (mocks, S) {
var doctor = new _libDoctor.Doctor();
var fix = {
error: 'Something wrong!',
check: {
fix: function fix() {},
diagnose: function diagnose() {}
}
};
it('fix - success', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.check = S.sandbox.mock(fix.check);
mocks.check.expects('fix').once();
mocks.check.expects('diagnose').once().returns(P.resolve({
ok: true, message: 'It worked' }));
context$3$0.next = 6;
return _regeneratorRuntime.awrap(doctor.runAutoFix(fix));
case 6:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: ### Fixing: Something wrong! ###', 'info: Checking if this was fixed:', 'info: ✔ It worked', 'info: ### Fix was successfully applied ###'].join('\n'));
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix - skipped', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.check = S.sandbox.mock(fix.check);
mocks.check.expects('fix').once().throws(new _libDoctor.FixSkippedError());
context$3$0.next = 5;
return _regeneratorRuntime.awrap(doctor.runAutoFix(fix));
case 5:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: ### Fixing: Something wrong! ###', 'info: ### Skipped fix ###'].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix - crash', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.check = S.sandbox.mock(fix.check);
mocks.check.expects('fix').once().throws(new Error('Oh No!'));
context$3$0.next = 5;
return _regeneratorRuntime.awrap(doctor.runAutoFix(fix));
case 5:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: ### Fixing: Something wrong! ###', 'warn: Error: Oh No!', 'info: ### Fix did not succeed ###'].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('fix - didn\'t fix', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
mocks.check = S.sandbox.mock(fix.check);
mocks.check.expects('fix').once();
mocks.check.expects('diagnose').once().returns(P.resolve({
ok: false, message: 'Still Weird!' }));
context$3$0.next = 6;
return _regeneratorRuntime.awrap(doctor.runAutoFix(fix));
case 6:
(0, _appiumTestSupport.verify)(mocks);
logStub.output.should.equal(['info: ### Fixing: Something wrong! ###', 'info: Checking if this was fixed:', 'info: ✖ Still Weird!', 'info: ### Fix was applied but issue remains ###'].join('\n'));
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('runAutoFixes', (0, _appiumTestSupport.withSandbox)({}, function (S) {
var doctor = new _libDoctor.Doctor();
it('success', function callee$2$0() {
var logStub;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
doctor.toFix = [{ error: 'Oh no.', check: new _libDoctor.DoctorCheck({ autofix: true }) }, { error: 'Oh no.', check: new _libDoctor.DoctorCheck({ autofix: true }) }, { error: 'Oh no.', check: new _libDoctor.DoctorCheck({ autofix: true }) }];
S.sandbox.stub(doctor, 'runAutoFix', function (f) {
_libLogger2['default'].info('Autofix log go there.');
f.fixed = true;
});
context$3$0.next = 5;
return _regeneratorRuntime.awrap(doctor.runAutoFixes());
case 5:
doctor.runAutoFix.calledThrice.should.be.ok;
logStub.output.should.equal(['info: Autofix log go there.', 'info: ', 'info: Autofix log go there.', 'info: ', 'info: Autofix log go there.', 'info: ', 'info: Bye, all issues have been fixed!', 'info: '].join('\n'));
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('failure', function callee$2$0() {
var logStub, succeed;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
logStub = (0, _appiumTestSupport.stubLog)(S.sandbox, _libLogger2['default'], { stripColors: true });
doctor.toFix = [{ error: 'Oh no.', check: new _libDoctor.DoctorCheck({ autofix: true }) }, { error: 'Oh no.', check: new _libDoctor.DoctorCheck({ autofix: true }) }, { error: 'Oh no.', check: new _libDoctor.DoctorCheck({ autofix: true }) }];
succeed = false;
S.sandbox.stub(doctor, 'runAutoFix', function (f) {
if (succeed) {
_libLogger2['default'].info('succeeded, Autofix log go there.');
f.fixed = true;
} else {
_libLogger2['default'].warn('failed, Autofix log go there.');
}
succeed = !succeed;
});
context$3$0.next = 6;
return _regeneratorRuntime.awrap(doctor.runAutoFixes());
case 6:
doctor.runAutoFix.calledThrice.should.be.ok;
logStub.output.should.equal(['warn: failed, Autofix log go there.', 'info: ', 'info: succeeded, Autofix log go there.', 'info: ', 'warn: failed, Autofix log go there.', 'info: ', 'info: Bye, a few issues remain, fix manually and/or rerun appium-doctor!', 'info: '].join('\n'));
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('run', (0, _appiumTestSupport.withMocks)({}, function (mocks, S) {
var doctor = new _libDoctor.Doctor();
it('should work', function callee$2$0() {
var _doctor;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
context$3$0.prev = 0;
_doctor = new _libDoctor.Doctor();
context$3$0.next = 4;
return _regeneratorRuntime.awrap(_doctor.run());
case 4:
context$3$0.next = 8;
break;
case 6:
context$3$0.prev = 6;
context$3$0.t0 = context$3$0['catch'](0);
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this, [[0, 6]]);
});
it('should report success', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.doctor = S.sandbox.mock(doctor);
mocks.doctor.expects('diagnose').once();
mocks.doctor.expects('reportSuccess').once().returns(true);
mocks.doctor.expects('reportManualFixes').never();
mocks.doctor.expects('runAutoFixes').never();
context$3$0.next = 7;
return _regeneratorRuntime.awrap(doctor.run());
case 7:
(0, _appiumTestSupport.verify)(mocks);
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should report manual fixes', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.doctor = S.sandbox.mock(doctor);
mocks.doctor.expects('diagnose').once();
mocks.doctor.expects('reportSuccess').once().returns(false);
mocks.doctor.expects('reportManualFixes').once().returns(true);
mocks.doctor.expects('runAutoFixes').never();
context$3$0.next = 7;
return _regeneratorRuntime.awrap(doctor.run());
case 7:
(0, _appiumTestSupport.verify)(mocks);
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should run autofixes', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.doctor = S.sandbox.mock(doctor);
mocks.doctor.expects('diagnose').once();
mocks.doctor.expects('reportSuccess').once().returns(false);
mocks.doctor.expects('reportManualFixes').once().returns(false);
mocks.doctor.expects('runAutoFixes').once();
context$3$0.next = 7;
return _regeneratorRuntime.awrap(doctor.run());
case 7:
(0, _appiumTestSupport.verify)(mocks);
case 8:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
});
//# sourceMappingURL=data:application/json;base64,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c0JBQXNCLEVBQUU7Ozs7QUFDekIsaUJBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdEMsaUJBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3hDLGlCQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUQsaUJBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2hFLGlCQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQzs7NkNBQ3RDLE1BQU0sQ0FBQyxHQUFHLEVBQUU7OztBQUNsQiwyQ0FBTyxLQUFLLENBQUMsQ0FBQzs7Ozs7OztLQUNmLENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQyxDQUFDO0NBQ0wsQ0FBQyxDQUFDIiwiZmlsZSI6InRlc3QvZG9jdG9yLXNwZWNzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJhbnNwaWxlOm1vY2hhXG5cbmltcG9ydCB7IERvY3RvciwgRG9jdG9yQ2hlY2ssIEZpeFNraXBwZWRFcnJvciB9IGZyb20gJy4uL2xpYi9kb2N0b3InO1xuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgeyB3aXRoU2FuZGJveCwgd2l0aE1vY2tzLCB2ZXJpZnksIHN0dWJMb2cgfSBmcm9tICdhcHBpdW0tdGVzdC1zdXBwb3J0JztcbmltcG9ydCBsb2cgZnJvbSAnLi4vbGliL2xvZ2dlcic7XG5cbmNoYWkuc2hvdWxkKCk7XG5sZXQgUCA9IFByb21pc2U7XG5cbmRlc2NyaWJlKCdkb2N0b3InLCAoKSA9PiB7XG5cbiAgaXQoJ3JlZ2lzdGVyJywgKCkgPT4ge1xuICAgIGxldCBkb2N0b3IgPSBuZXcgRG9jdG9yKCk7XG4gICAgZG9jdG9yLmNoZWNrcy5zaG91bGQuaGF2ZS5sZW5ndGgoMCk7XG4gICAgZG9jdG9yLnJlZ2lzdGVyKG5ldyBEb2N0b3JDaGVjaygpKTtcbiAgICBkb2N0b3IuY2hlY2tzLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICBkb2N0b3IucmVnaXN0ZXIoW25ldyBEb2N0b3JDaGVjaygpLCBuZXcgRG9jdG9yQ2hlY2soKV0pO1xuICAgIGRvY3Rvci5jaGVja3Muc2hvdWxkLmhhdmUubGVuZ3RoKDMpO1xuICB9KTtcblxuICBmdW5jdGlvbiBjb25maWd1cmUoKSB7XG4gICAgbGV0IGRvY3RvciA9IG5ldyBEb2N0b3IoKTtcbiAgICBsZXQgY2hlY2tzID0gW25ldyBEb2N0b3JDaGVjaygpLCBuZXcgRG9jdG9yQ2hlY2soKSwgbmV3IERvY3RvckNoZWNrKCldO1xuICAgIGRvY3Rvci5yZWdpc3RlcihjaGVja3MpO1xuICAgIHJldHVybiB7ZG9jdG9yLCBjaGVja3N9O1xuICB9XG5cbiAgZGVzY3JpYmUoJ2RpYWdub3NlJywgd2l0aE1vY2tzKHt9LCAobW9ja3MsIFMpID0+IHtcbiAgICBpdCgnc2hvdWxkIGRldGVjdCBhbGwgaXNzdWVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IGxvZ1N0dWIgPSBzdHViTG9nKFMuc2FuZGJveCwgbG9nLCB7c3RyaXBDb2xvcnM6IHRydWV9KTtcbiAgICAgIGxldCB7ZG9jdG9yLCBjaGVja3N9ID0gY29uZmlndXJlKCk7XG4gICAgICBtb2Nrcy5jaGVja3MgPSBjaGVja3MubWFwKChjaGVjaykgPT4geyByZXR1cm4gUy5zYW5kYm94Lm1vY2soY2hlY2spOyB9KTtcbiAgICAgIG1vY2tzLmNoZWNrc1swXS5leHBlY3RzKCdkaWFnbm9zZScpLm9uY2UoKS5yZXR1cm5zKHtvazogdHJ1ZSwgbWVzc2FnZTogXCJBbGwgR29vZCFcIn0pO1xuICAgICAgbW9ja3MuY2hlY2tzWzFdLmV4cGVjdHMoJ2RpYWdub3NlJykub25jZSgpLnJldHVybnMoe29rOiBmYWxzZSwgbWVzc2FnZTogXCJPaCBObyFcIn0pO1xuICAgICAgbW9ja3MuY2hlY2tzWzJdLmV4cGVjdHMoJ2RpYWdub3NlJykub25jZSgpLnJldHVybnMoe29rOiBmYWxzZSwgbWVzc2FnZTogXCJPaCBObyFcIn0pO1xuICAgICAgYXdhaXQgZG9jdG9yLmRpYWdub3NlKCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgZG9jdG9yLnRvRml4LnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICAgIGxvZ1N0dWIub3V0cHV0LnNob3VsZC5lcXVhbChbXG4gICAgICAgICdpbmZvOiAjIyMgRGlhZ25vc3RpYyBzdGFydGluZyAjIyMnLFxuICAgICAgICAnaW5mbzogIOKclCBBbGwgR29vZCEnLFxuICAgICAgICAnd2FybjogIOKcliBPaCBObyEnLFxuICAgICAgICAnd2FybjogIOKcliBPaCBObyEnLFxuICAgICAgICAnaW5mbzogIyMjIERpYWdub3N0aWMgY29tcGxldGVkLCAyIGZpeGVzIG5lZWRlZC4gIyMjJyxcbiAgICAgICAgJ2luZm86ICdcbiAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuICB9KSk7XG5cbiAgZGVzY3JpYmUoJ3JlcG9ydFN1Y2Nlc3MnLCB3aXRoTW9ja3Moe30sKG1vY2tzLCBTKSA9PiB7XG4gICAgbGV0IGRvY3RvciA9IG5ldyBEb2N0b3IoKTtcbiAgICBpdCgnc2hvdWxkIHJlcG9ydCBzdWNjZXNzIHdoZW4gbm8gZml4ZXMgYXJlIG5lZWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2dTdHViID0gc3R1YkxvZyhTLnNhbmRib3gsIGxvZywge3N0cmlwQ29sb3JzOiB0cnVlfSk7XG4gICAgICBkb2N0b3IudG9GaXggPSBbXTtcbiAgICAgIChhd2FpdCBkb2N0b3IucmVwb3J0U3VjY2VzcygpKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBsb2dTdHViLm91dHB1dC5zaG91bGQuZXF1YWwoW1xuICAgICAgICAnaW5mbzogRXZlcnl0aGluZyBsb29rcyBnb29kLCBieWUhJyxcbiAgICAgICAgJ2luZm86ICdcbiAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiBmaXhlcyBhcmUgbmVlZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgZG9jdG9yLnRvRml4ID0gW3t9XTtcbiAgICAgIChhd2FpdCBkb2N0b3IucmVwb3J0U3VjY2VzcygpKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuICB9KSk7XG5cbiAgZGVzY3JpYmUoJ3JlcG9ydE1hbnVhbEZpeGVzJywgd2l0aE1vY2tzKHt9LChtb2NrcywgUykgPT4ge1xuICAgIGxldCBkb2N0b3IgPSBuZXcgRG9jdG9yKCk7XG4gICAgaXQoJ3Nob3VsZCBhc2sgZm9yIG1hbnVhbCBmaXhlcyB0byBiZSBhcHBsaWVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IGxvZ1N0dWIgPSBzdHViTG9nKFMuc2FuZGJveCwgbG9nLCB7c3RyaXBDb2xvcnM6IHRydWV9KTtcbiAgICAgIGRvY3Rvci50b0ZpeCA9IFtcbiAgICAgICAge2Vycm9yOiAnT2ggbm8gdGhpcyBuZWVkIHRvIGJlIG1hbnVhbGx5IGZpeGVkLicsIGNoZWNrOiBuZXcgRG9jdG9yQ2hlY2soKX0sXG4gICAgICAgIHtlcnJvcjogJ09oIG5vIHRoaXMgaXMgYW4gYXV0b2ZpeC4nLCBjaGVjazogbmV3IERvY3RvckNoZWNrKHthdXRvZml4OiB0cnVlfSl9LFxuICAgICAgICB7ZXJyb3I6ICdPaCBubyB0aGlzIGFsc28gbmVlZCB0byBiZSBtYW51YWxseSBmaXhlZC4nLCBjaGVjazogbmV3IERvY3RvckNoZWNrKCl9LFxuICAgICAgICB7ZXJyb3I6ICdPaCBubyB0aGlzIGFsc28gbmVlZCB0byBiZSBtYW51YWxseSBmaXhlZC4nLCBjaGVjazogbmV3IERvY3RvckNoZWNrKCl9LFxuICAgICAgXTtcbiAgICAgIGZvcihsZXQgaT0wOyBpPGRvY3Rvci50b0ZpeC5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgbSA9IFMuc2FuZGJveC5tb2NrKGRvY3Rvci50b0ZpeFtpXS5jaGVjayk7XG4gICAgICAgIGlmKGRvY3Rvci50b0ZpeFtpXS5jaGVjay5hdXRvZml4KSB7XG4gICAgICAgICAgbS5leHBlY3RzKCdmaXgnKS5uZXZlcigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG0uZXhwZWN0cygnZml4Jykub25jZSgpLnJldHVybnMoUC5yZXNvbHZlKGBNYW51YWwgZml4IGZvciAke2l9IGlzIGRvIHNvbWV0aGluZy5gKSk7XG4gICAgICAgfVxuICAgICAgfVxuICAgICAgKGF3YWl0IGRvY3Rvci5yZXBvcnRNYW51YWxGaXhlcygpKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgbG9nU3R1Yi5vdXRwdXQuc2hvdWxkLmVxdWFsKFtcbiAgICAgICAgJ2luZm86ICMjIyBNYW51YWwgRml4ZXMgTmVlZGVkICMjIycsXG4gICAgICAgICdpbmZvOiBUaGUgY29uZmlndXJhdGlvbiBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBmaXhlZCwgcGxlYXNlIGRvIHRoZSBmb2xsb3dpbmcgZmlyc3Q6JyxcbiAgICAgICAgJ3dhcm46IC0gTWFudWFsIGZpeCBmb3IgMCBpcyBkbyBzb21ldGhpbmcuJyxcbiAgICAgICAgJ3dhcm46IC0gTWFudWFsIGZpeCBmb3IgMiBpcyBkbyBzb21ldGhpbmcuJyxcbiAgICAgICAgJ3dhcm46IC0gTWFudWFsIGZpeCBmb3IgMyBpcyBkbyBzb21ldGhpbmcuJyxcbiAgICAgICAgJ2luZm86ICMjIycsXG4gICAgICAgICdpbmZvOiAnLFxuICAgICAgICAnaW5mbzogQnllLCBydW4gYXBwaXVtLWRvY3RvciBhZ2FpbiB3aGVuIGFsbCBtYW51YWwgZml4ZXMgaGF2ZSBiZWVuIGFwcGxpZWQhJyxcbiAgICAgICAgJ2luZm86ICdcbiAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiB0aGVyZSBpcyBubyBtYW51YWwgZml4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgZG9jdG9yLnRvRml4ID0gW3tlcnJvcjogJ09oIG5vIScsIGNoZWNrOiBuZXcgRG9jdG9yQ2hlY2soe2F1dG9maXg6IHRydWV9KSB9XTtcbiAgICAgIChhd2FpdCBkb2N0b3IucmVwb3J0TWFudWFsRml4ZXMoKSkuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcbiAgfSkpO1xuXG4gIGRlc2NyaWJlKCdydW5BdXRvRml4JywgIHdpdGhNb2Nrcyh7fSwgKG1vY2tzLCBTKSA9PiB7XG4gICAgbGV0IGRvY3RvciA9IG5ldyBEb2N0b3IoKTtcbiAgICBsZXQgZml4ID0ge1xuICAgICAgZXJyb3I6ICdTb21ldGhpbmcgd3JvbmchJyxcbiAgICAgIGNoZWNrOiB7XG4gICAgICAgIGZpeDogKCkgPT4ge30sXG4gICAgICAgIGRpYWdub3NlOiAoKSA9PiB7fVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpdCgnZml4IC0gc3VjY2VzcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2dTdHViID0gc3R1YkxvZyhTLnNhbmRib3gsIGxvZywge3N0cmlwQ29sb3JzOiB0cnVlfSk7XG4gICAgICBtb2Nrcy5jaGVjayA9IFMuc2FuZGJveC5tb2NrKGZpeC5jaGVjayk7XG4gICAgICBtb2Nrcy5jaGVjay5leHBlY3RzKCdmaXgnKS5vbmNlKCk7XG4gICAgICBtb2Nrcy5jaGVjay5leHBlY3RzKCdkaWFnbm9zZScpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSh7XG4gICAgICAgIG9rOiB0cnVlLCBtZXNzYWdlOiAnSXQgd29ya2VkJ30pKTtcbiAgICAgIGF3YWl0IGRvY3Rvci5ydW5BdXRvRml4KGZpeCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgbG9nU3R1Yi5vdXRwdXQuc2hvdWxkLmVxdWFsKFtcbiAgICAgICAgJ2luZm86ICMjIyBGaXhpbmc6IFNvbWV0aGluZyB3cm9uZyEgIyMjJyxcbiAgICAgICAgJ2luZm86IENoZWNraW5nIGlmIHRoaXMgd2FzIGZpeGVkOicsXG4gICAgICAgICdpbmZvOiAg4pyUIEl0IHdvcmtlZCcsXG4gICAgICAgICdpbmZvOiAjIyMgRml4IHdhcyBzdWNjZXNzZnVsbHkgYXBwbGllZCAjIyMnXG4gICAgICBdLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcblxuICAgIGl0KCdmaXggLSBza2lwcGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IGxvZ1N0dWIgPSBzdHViTG9nKFMuc2FuZGJveCwgbG9nLCB7c3RyaXBDb2xvcnM6IHRydWV9KTtcbiAgICAgIG1vY2tzLmNoZWNrID0gUy5zYW5kYm94Lm1vY2soZml4LmNoZWNrKTtcbiAgICAgIG1vY2tzLmNoZWNrLmV4cGVjdHMoJ2ZpeCcpLm9uY2UoKS50aHJvd3MobmV3IEZpeFNraXBwZWRFcnJvcigpKTtcbiAgICAgIGF3YWl0IGRvY3Rvci5ydW5BdXRvRml4KGZpeCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgbG9nU3R1Yi5vdXRwdXQuc2hvdWxkLmVxdWFsKFtcbiAgICAgICAgJ2luZm86ICMjIyBGaXhpbmc6IFNvbWV0aGluZyB3cm9uZyEgIyMjJyxcbiAgICAgICAgJ2luZm86ICMjIyBTa2lwcGVkIGZpeCAjIyMnLFxuICAgICAgXS5qb2luKCdcXG4nKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZml4IC0gY3Jhc2gnLCBhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgbG9nU3R1YiA9IHN0dWJMb2coUy5zYW5kYm94LCBsb2csIHtzdHJpcENvbG9yczogdHJ1ZX0pO1xuICAgICAgbW9ja3MuY2hlY2sgPSBTLnNhbmRib3gubW9jayhmaXguY2hlY2spO1xuICAgICAgbW9ja3MuY2hlY2suZXhwZWN0cygnZml4Jykub25jZSgpLnRocm93cyhuZXcgRXJyb3IoJ09oIE5vIScpKTtcbiAgICAgIGF3YWl0IGRvY3Rvci5ydW5BdXRvRml4KGZpeCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgICAgbG9nU3R1Yi5vdXRwdXQuc2hvdWxkLmVxdWFsKFtcbiAgICAgICAgJ2luZm86ICMjIyBGaXhpbmc6IFNvbWV0aGluZyB3cm9uZyEgIyMjJyxcbiAgICAgICAgJ3dhcm46IEVycm9yOiBPaCBObyEnLFxuICAgICAgICAnaW5mbzogIyMjIEZpeCBkaWQgbm90IHN1Y2NlZWQgIyMjJyxcbiAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZpeCAtIGRpZG5cXCd0IGZpeCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2dTdHViID0gc3R1YkxvZyhTLnNhbmRib3gsIGxvZywge3N0cmlwQ29sb3JzOiB0cnVlfSk7XG4gICAgICBtb2Nrcy5jaGVjayA9IFMuc2FuZGJveC5tb2NrKGZpeC5jaGVjayk7XG4gICAgICBtb2Nrcy5jaGVjay5leHBlY3RzKCdmaXgnKS5vbmNlKCk7XG4gICAgICBtb2Nrcy5jaGVjay5leHBlY3RzKCdkaWFnbm9zZScpLm9uY2UoKS5yZXR1cm5zKFAucmVzb2x2ZSh7XG4gICAgICAgIG9rOiBmYWxzZSwgbWVzc2FnZTogJ1N0aWxsIFdlaXJkISd9KSk7XG4gICAgICBhd2FpdCBkb2N0b3IucnVuQXV0b0ZpeChmaXgpO1xuICAgICAgdmVyaWZ5KG1vY2tzKTtcbiAgICAgIGxvZ1N0dWIub3V0cHV0LnNob3VsZC5lcXVhbChbXG4gICAgICAgICdpbmZvOiAjIyMgRml4aW5nOiBTb21ldGhpbmcgd3JvbmchICMjIycsXG4gICAgICAgICdpbmZvOiBDaGVja2luZyBpZiB0aGlzIHdhcyBmaXhlZDonLFxuICAgICAgICAnaW5mbzogIOKcliBTdGlsbCBXZWlyZCEnLFxuICAgICAgICAnaW5mbzogIyMjIEZpeCB3YXMgYXBwbGllZCBidXQgaXNzdWUgcmVtYWlucyAjIyMnXG4gICAgICBdLmpvaW4oJ1xcbicpKTtcbiAgICB9KTtcbiAgfSkpO1xuXG4gIGRlc2NyaWJlKCdydW5BdXRvRml4ZXMnLCAgd2l0aFNhbmRib3goe30sIChTKSA9PiB7XG4gICAgbGV0IGRvY3RvciA9IG5ldyBEb2N0b3IoKTtcbiAgICBpdCgnc3VjY2VzcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2dTdHViID0gc3R1YkxvZyhTLnNhbmRib3gsIGxvZywge3N0cmlwQ29sb3JzOiB0cnVlfSk7XG4gICAgICBkb2N0b3IudG9GaXggPSBbXG4gICAgICAgIHtlcnJvcjogJ09oIG5vLicsIGNoZWNrOiBuZXcgRG9jdG9yQ2hlY2soe2F1dG9maXg6IHRydWV9KX0sXG4gICAgICAgIHtlcnJvcjogJ09oIG5vLicsIGNoZWNrOiBuZXcgRG9jdG9yQ2hlY2soe2F1dG9maXg6IHRydWV9KX0sXG4gICAgICAgIHtlcnJvcjogJ09oIG5vLicsIGNoZWNrOiBuZXcgRG9jdG9yQ2hlY2soe2F1dG9maXg6IHRydWV9KX0sXG4gICAgICBdO1xuICAgICAgUy5zYW5kYm94LnN0dWIoZG9jdG9yLCAncnVuQXV0b0ZpeCcsIChmKSA9PiB7XG4gICAgICAgIGxvZy5pbmZvKCdBdXRvZml4IGxvZyBnbyB0aGVyZS4nKTtcbiAgICAgICAgZi5maXhlZCA9IHRydWU7XG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGRvY3Rvci5ydW5BdXRvRml4ZXMoKTtcbiAgICAgIGRvY3Rvci5ydW5BdXRvRml4LmNhbGxlZFRocmljZS5zaG91bGQuYmUub2s7XG4gICAgICBsb2dTdHViLm91dHB1dC5zaG91bGQuZXF1YWwoW1xuICAgICAgICAnaW5mbzogQXV0b2ZpeCBsb2cgZ28gdGhlcmUuJyxcbiAgICAgICAgJ2luZm86ICcsXG4gICAgICAgICdpbmZvOiBBdXRvZml4IGxvZyBnbyB0aGVyZS4nLFxuICAgICAgICAnaW5mbzogJyxcbiAgICAgICAgJ2luZm86IEF1dG9maXggbG9nIGdvIHRoZXJlLicsXG4gICAgICAgICdpbmZvOiAnLFxuICAgICAgICAnaW5mbzogQnllLCBhbGwgaXNzdWVzIGhhdmUgYmVlbiBmaXhlZCEnLFxuICAgICAgICAnaW5mbzogJyxcbiAgICAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZhaWx1cmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgbG9nU3R1YiA9IHN0dWJMb2coUy5zYW5kYm94LCBsb2csIHtzdHJpcENvbG9yczogdHJ1ZX0pO1xuICAgICAgZG9jdG9yLnRvRml4ID0gW1xuICAgICAgICB7ZXJyb3I6ICdPaCBuby4nLCBjaGVjazogbmV3IERvY3RvckNoZWNrKHthdXRvZml4OiB0cnVlfSl9LFxuICAgICAgICB7ZXJyb3I6ICdPaCBuby4nLCBjaGVjazogbmV3IERvY3RvckNoZWNrKHthdXRvZml4OiB0cnVlfSl9LFxuICAgICAgICB7ZXJyb3I6ICdPaCBuby4nLCBjaGVjazogbmV3IERvY3RvckNoZWNrKHthdXRvZml4OiB0cnVlfSl9LFxuICAgICAgXTtcbiAgICAgIGxldCBzdWNjZWVkID0gZmFsc2U7XG4gICAgICBTLnNhbmRib3guc3R1Yihkb2N0b3IsICdydW5BdXRvRml4JywgKGYpID0+IHtcbiAgICAgICAgaWYoc3VjY2VlZCkge1xuICAgICAgICAgIGxvZy5pbmZvKCdzdWNjZWVkZWQsIEF1dG9maXggbG9nIGdvIHRoZXJlLicpO1xuICAgICAgICAgIGYuZml4ZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvZy53YXJuKCdmYWlsZWQsIEF1dG9maXggbG9nIGdvIHRoZXJlLicpO1xuICAgICAgICB9XG4gICAgICAgIHN1Y2NlZWQgPSAhc3VjY2VlZDtcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgZG9jdG9yLnJ1bkF1dG9GaXhlcygpO1xuICAgICAgZG9jdG9yLnJ1bkF1dG9GaXguY2FsbGVkVGhyaWNlLnNob3VsZC5iZS5vaztcbiAgICAgIGxvZ1N0dWIub3V0cHV0LnNob3VsZC5lcXVhbChbXG4gICAgICAgICd3YXJuOiBmYWlsZWQsIEF1dG9maXggbG9nIGdvIHRoZXJlLicsXG4gICAgICAgICdpbmZvOiAnLFxuICAgICAgICAnaW5mbzogc3VjY2VlZGVkLCBBdXRvZml4IGxvZyBnbyB0aGVyZS4nLFxuICAgICAgICAnaW5mbzogJyxcbiAgICAgICAgJ3dhcm46IGZhaWxlZCwgQXV0b2ZpeCBsb2cgZ28gdGhlcmUuJyxcbiAgICAgICAgJ2luZm86ICcsXG4gICAgICAgICdpbmZvOiBCeWUsIGEgZmV3IGlzc3VlcyByZW1haW4sIGZpeCBtYW51YWxseSBhbmQvb3IgcmVydW4gYXBwaXVtLWRvY3RvciEnLFxuICAgICAgICAnaW5mbzogJyxcbiAgICAgICAgIF0uam9pbignXFxuJykpO1xuICAgIH0pO1xuICB9KSk7XG5cbiAgZGVzY3JpYmUoJ3J1bicsICB3aXRoTW9ja3Moe30sIChtb2NrcywgUykgPT4ge1xuICAgIGxldCBkb2N0b3IgPSBuZXcgRG9jdG9yKCk7XG4gICAgaXQoJ3Nob3VsZCB3b3JrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IGRvY3RvciA9IG5ldyBEb2N0b3IoKTtcbiAgICAgICAgYXdhaXQgZG9jdG9yLnJ1bigpO1xuICAgICAgfSBjYXRjaChlcnIpIHtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHJlcG9ydCBzdWNjZXNzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja3MuZG9jdG9yID0gUy5zYW5kYm94Lm1vY2soZG9jdG9yKTtcbiAgICAgIG1vY2tzLmRvY3Rvci5leHBlY3RzKCdkaWFnbm9zZScpLm9uY2UoKTtcbiAgICAgIG1vY2tzLmRvY3Rvci5leHBlY3RzKCdyZXBvcnRTdWNjZXNzJykub25jZSgpLnJldHVybnModHJ1ZSk7XG4gICAgICBtb2Nrcy5kb2N0b3IuZXhwZWN0cygncmVwb3J0TWFudWFsRml4ZXMnKS5uZXZlcigpO1xuICAgICAgbW9ja3MuZG9jdG9yLmV4cGVjdHMoJ3J1bkF1dG9GaXhlcycpLm5ldmVyKCk7XG4gICAgICBhd2FpdCBkb2N0b3IucnVuKCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcmVwb3J0IG1hbnVhbCBmaXhlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmRvY3RvciA9IFMuc2FuZGJveC5tb2NrKGRvY3Rvcik7XG4gICAgICBtb2Nrcy5kb2N0b3IuZXhwZWN0cygnZGlhZ25vc2UnKS5vbmNlKCk7XG4gICAgICBtb2Nrcy5kb2N0b3IuZXhwZWN0cygncmVwb3J0U3VjY2VzcycpLm9uY2UoKS5yZXR1cm5zKGZhbHNlKTtcbiAgICAgIG1vY2tzLmRvY3Rvci5leHBlY3RzKCdyZXBvcnRNYW51YWxGaXhlcycpLm9uY2UoKS5yZXR1cm5zKHRydWUpO1xuICAgICAgbW9ja3MuZG9jdG9yLmV4cGVjdHMoJ3J1bkF1dG9GaXhlcycpLm5ldmVyKCk7XG4gICAgICBhd2FpdCBkb2N0b3IucnVuKCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcnVuIGF1dG9maXhlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIG1vY2tzLmRvY3RvciA9IFMuc2FuZGJveC5tb2NrKGRvY3Rvcik7XG4gICAgICBtb2Nrcy5kb2N0b3IuZXhwZWN0cygnZGlhZ25vc2UnKS5vbmNlKCk7XG4gICAgICBtb2Nrcy5kb2N0b3IuZXhwZWN0cygncmVwb3J0U3VjY2VzcycpLm9uY2UoKS5yZXR1cm5zKGZhbHNlKTtcbiAgICAgIG1vY2tzLmRvY3Rvci5leHBlY3RzKCdyZXBvcnRNYW51YWxGaXhlcycpLm9uY2UoKS5yZXR1cm5zKGZhbHNlKTtcbiAgICAgIG1vY2tzLmRvY3Rvci5leHBlY3RzKCdydW5BdXRvRml4ZXMnKS5vbmNlKCk7XG4gICAgICBhd2FpdCBkb2N0b3IucnVuKCk7XG4gICAgICB2ZXJpZnkobW9ja3MpO1xuICAgIH0pO1xuICB9KSk7XG59KTtcbiJdfQ==