webdriverio-automation
Version:
WebdriverIO-Automation android ios project
548 lines (536 loc) • 61.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
require("source-map-support/register");
var _capabilities = require("../../lib/basedriver/capabilities");
var _chai = _interopRequireDefault(require("chai"));
var _chaiAsPromised = _interopRequireDefault(require("chai-as-promised"));
var _lodash = _interopRequireDefault(require("lodash"));
var _desiredCaps = require("../../lib/basedriver/desired-caps");
_chai.default.use(_chaiAsPromised.default);
const should = _chai.default.should();
describe('caps', function () {
describe('#validateCaps', function () {
it('returns invalid argument error if "capability" is not a JSON object (1)', function () {
for (let arg of [undefined, null, 1, true, 'string']) {
(function () {
(0, _capabilities.validateCaps)(arg);
}).should.throw(/must be a JSON object/);
}
});
it('returns result {} by default if caps is empty object and no constraints provided (2)', function () {
(0, _capabilities.validateCaps)({}).should.deep.equal({});
});
describe('throws errors if constraints are not met', function () {
it('returns invalid argument error if "present" constraint not met on property', function () {
(() => (0, _capabilities.validateCaps)({}, {
foo: {
presence: true
}
})).should.throw(/'foo' can't be blank/);
});
it('returns the capability that was passed in if "skipPresenceConstraint" is false', function () {
(0, _capabilities.validateCaps)({}, {
foo: {
presence: true
}
}, {
skipPresenceConstraint: true
}).should.deep.equal({});
});
it('returns invalid argument error if "isString" constraint not met on property', function () {
(() => (0, _capabilities.validateCaps)({
foo: 1
}, {
foo: {
isString: true
}
})).should.throw(/'foo' must be of type string/);
});
it('returns invalid argument error if "isNumber" constraint not met on property', function () {
(() => (0, _capabilities.validateCaps)({
foo: 'bar'
}, {
foo: {
isNumber: true
}
})).should.throw(/'foo' must be of type number/);
});
it('returns invalid argument error if "isBoolean" constraint not met on property', function () {
(() => (0, _capabilities.validateCaps)({
foo: 'bar'
}, {
foo: {
isBoolean: true
}
})).should.throw(/'foo' must be of type boolean/);
});
it('returns invalid argument error if "inclusion" constraint not met on property', function () {
(() => (0, _capabilities.validateCaps)({
foo: '3'
}, {
foo: {
inclusionCaseInsensitive: ['1', '2']
}
})).should.throw(/'foo' 3 not part of 1,2/);
});
it('returns invalid argument error if "inclusionCaseInsensitive" constraint not met on property', function () {
(() => (0, _capabilities.validateCaps)({
foo: 'a'
}, {
foo: {
inclusion: ['A', 'B', 'C']
}
})).should.throw(/'foo' a is not included in the list/);
});
});
it('should not throw errors if constraints are met', function () {
let caps = {
number: 1,
string: 'string',
present: 'present',
extra: 'extra'
};
let constraints = {
number: {
isNumber: true
},
string: {
isString: true
},
present: {
presence: true
},
notPresent: {
presence: false
}
};
(0, _capabilities.validateCaps)(caps, constraints).should.deep.equal(caps);
});
});
describe('#mergeCaps', function () {
it('returns a result that is {} by default (1)', function () {
(0, _capabilities.mergeCaps)().should.deep.equal({});
});
it('returns a result that matches primary by default (2, 3)', function () {
(0, _capabilities.mergeCaps)({
hello: 'world'
}).should.deep.equal({
hello: 'world'
});
});
it('returns invalid argument error if primary and secondary have matching properties (4)', function () {
(() => (0, _capabilities.mergeCaps)({
hello: 'world'
}, {
hello: 'whirl'
})).should.throw(/property 'hello' should not exist on both primary [\w\W]* and secondary [\w\W]*/);
});
it('returns a result with keys from primary and secondary together', function () {
let primary = {
a: 'a',
b: 'b'
};
let secondary = {
c: 'c',
d: 'd'
};
(0, _capabilities.mergeCaps)(primary, secondary).should.deep.equal({
a: 'a',
b: 'b',
c: 'c',
d: 'd'
});
});
});
describe('#parseCaps', function () {
let caps;
beforeEach(function () {
caps = {};
});
it('should return invalid argument if no caps object provided', function () {
(() => (0, _capabilities.parseCaps)()).should.throw(/must be a JSON object/);
});
it('sets "requiredCaps" to property named "alwaysMatch" (2)', function () {
caps.alwaysMatch = {
hello: 'world'
};
(0, _capabilities.parseCaps)(caps).requiredCaps.should.deep.equal(caps.alwaysMatch);
});
it('sets "requiredCaps" to empty JSON object if "alwaysMatch" is not an object (2.1)', function () {
(0, _capabilities.parseCaps)(caps).requiredCaps.should.deep.equal({});
});
it('returns invalid argument error if "requiredCaps" don\'t match "constraints" (2.2)', function () {
caps.alwaysMatch = {
foo: 1
};
(() => (0, _capabilities.parseCaps)(caps, {
foo: {
isString: true
}
})).should.throw(/'foo' must be of type string/);
});
it('sets "allFirstMatchCaps" to property named "firstMatch" (3)', function () {
(0, _capabilities.parseCaps)({}, [{}]).allFirstMatchCaps.should.deep.equal([{}]);
});
it('sets "allFirstMatchCaps" to [{}] if "firstMatch" is undefined (3.1)', function () {
(0, _capabilities.parseCaps)({}).allFirstMatchCaps.should.deep.equal([{}]);
});
it('returns invalid argument error if "firstMatch" is not an array and is not undefined (3.2)', function () {
for (let arg of [null, 1, true, 'string']) {
caps.firstMatch = arg;
(function () {
(0, _capabilities.parseCaps)(caps);
}).should.throw(/must be a JSON array or undefined/);
}
});
it('has "validatedFirstMatchCaps" property that is empty by default if no valid firstMatch caps were found (4)', function () {
(0, _capabilities.parseCaps)(caps, {
foo: {
presence: true
}
}).validatedFirstMatchCaps.should.deep.equal([]);
});
describe('returns a "validatedFirstMatchCaps" array (5)', function () {
it('that equals "firstMatch" if firstMatch is one empty object and there are no constraints', function () {
caps.firstMatch = [{}];
(0, _capabilities.parseCaps)(caps).validatedFirstMatchCaps.should.deep.equal(caps.firstMatch);
});
it('returns "null" matchedCaps if nothing matches', function () {
caps.firstMatch = [{}];
should.equal((0, _capabilities.parseCaps)(caps, {
foo: {
presence: true
}
}).matchedCaps, null);
});
it(`should return capabilities if presence constraint is matched in at least one of the 'firstMatch' capabilities objects`, function () {
caps.alwaysMatch = {
foo: 'bar'
};
caps.firstMatch = [{
hello: 'world'
}, {
goodbye: 'world'
}];
(0, _capabilities.parseCaps)(caps, {
goodbye: {
presence: true
}
}).matchedCaps.should.deep.equal({
foo: 'bar',
goodbye: 'world'
});
});
it(`throws invalid argument if presence constraint is not met on any capabilities`, function () {
caps.alwaysMatch = {
foo: 'bar'
};
caps.firstMatch = [{
hello: 'world'
}, {
goodbye: 'world'
}];
should.equal((0, _capabilities.parseCaps)(caps, {
someAttribute: {
presence: true
}
}).matchedCaps, null);
});
it('that equals firstMatch if firstMatch contains two objects that pass the provided constraints', function () {
caps.alwaysMatch = {
foo: 'bar'
};
caps.firstMatch = [{
foo: 'bar1'
}, {
foo: 'bar2'
}];
let constraints = {
foo: {
presence: true,
isString: true
}
};
(0, _capabilities.parseCaps)(caps, constraints).validatedFirstMatchCaps.should.deep.equal(caps.firstMatch);
});
it('returns invalid argument error if the firstMatch[2] is not an object', function () {
caps.alwaysMatch = 'Not an object and not undefined';
caps.firstMatch = [{
foo: 'bar'
}, 'foo'];
(() => (0, _capabilities.parseCaps)(caps, {})).should.throw(/must be a JSON object/);
});
});
describe('returns a matchedCaps object (6)', function () {
beforeEach(function () {
caps.alwaysMatch = {
hello: 'world'
};
});
it('which is same as alwaysMatch if firstMatch array is not provided', function () {
(0, _capabilities.parseCaps)(caps).matchedCaps.should.deep.equal({
hello: 'world'
});
});
it('merges caps together', function () {
caps.firstMatch = [{
foo: 'bar'
}];
(0, _capabilities.parseCaps)(caps).matchedCaps.should.deep.equal({
hello: 'world',
foo: 'bar'
});
});
it('with merged caps', function () {
caps.firstMatch = [{
hello: 'bar',
foo: 'foo'
}, {
foo: 'bar'
}];
(0, _capabilities.parseCaps)(caps).matchedCaps.should.deep.equal({
hello: 'world',
foo: 'bar'
});
});
});
});
describe('#processCaps', function () {
it('should return "alwaysMatch" if "firstMatch" and "constraints" were not provided', function () {
(0, _capabilities.processCapabilities)({}).should.deep.equal({});
});
it('should return merged caps', function () {
(0, _capabilities.processCapabilities)({
alwaysMatch: {
hello: 'world'
},
firstMatch: [{
foo: 'bar'
}]
}).should.deep.equal({
hello: 'world',
foo: 'bar'
});
});
it('should strip out the "appium:" prefix for non-standard capabilities', function () {
(0, _capabilities.processCapabilities)({
alwaysMatch: {
'appium:hello': 'world'
},
firstMatch: [{
'appium:foo': 'bar'
}]
}).should.deep.equal({
hello: 'world',
foo: 'bar'
});
});
it('should throw an exception if a standard capability (https://www.w3.org/TR/webdriver/#dfn-table-of-standard-capabilities) is prefixed', function () {
(() => (0, _capabilities.processCapabilities)({
alwaysMatch: {
'appium:platformName': 'Whatevz'
},
firstMatch: [{
'appium:browserName': 'Anything'
}]
})).should.throw(/standard capabilities/);
});
it('should not throw an exception if presence constraint is not met on a firstMatch capability', function () {
const caps = (0, _capabilities.processCapabilities)({
alwaysMatch: {
'platformName': 'Fake',
'appium:fakeCap': 'foobar'
},
firstMatch: [{
'foo': 'bar'
}]
}, {
platformName: {
presence: true
},
fakeCap: {
presence: true
}
});
caps.platformName.should.equal('Fake');
caps.fakeCap.should.equal('foobar');
caps.foo.should.equal('bar');
});
it('should throw an exception if no matching caps were found', function () {
(() => (0, _capabilities.processCapabilities)({
alwaysMatch: {
'platformName': 'Fake',
'appium:fakeCap': 'foobar'
},
firstMatch: [{
'foo': 'bar'
}]
}, {
platformName: {
presence: true
},
fakeCap: {
presence: true
},
missingCap: {
presence: true
}
})).should.throw(/'missingCap' can't be blank/);
});
describe('validate Appium constraints', function () {
let constraints = { ..._desiredCaps.desiredCapabilityConstraints
};
let matchingCaps = {
'platformName': 'Fake',
'automationName': 'Fake',
'deviceName': 'Fake'
};
let caps;
it('should validate when alwaysMatch has the proper caps', function () {
caps = {
alwaysMatch: matchingCaps,
firstMatch: [{}]
};
(0, _capabilities.processCapabilities)(caps, constraints).should.deep.equal(matchingCaps);
});
it('should validate when firstMatch[0] has the proper caps', function () {
caps = {
alwaysMatch: {},
firstMatch: [matchingCaps]
};
(0, _capabilities.processCapabilities)(caps, constraints).should.deep.equal(matchingCaps);
});
it('should validate when alwaysMatch and firstMatch[0] have the proper caps when merged together', function () {
caps = {
alwaysMatch: _lodash.default.omit(matchingCaps, ['deviceName']),
firstMatch: [{
'appium:deviceName': 'Fake'
}]
};
(0, _capabilities.processCapabilities)(caps, constraints).should.deep.equal(matchingCaps);
});
it('should validate when automationName is omitted', function () {
caps = {
alwaysMatch: _lodash.default.omit(matchingCaps, ['automationName'])
};
(0, _capabilities.processCapabilities)(caps, constraints).should.deep.equal(_lodash.default.omit(matchingCaps, 'automationName'));
});
it('should pass if first element in "firstMatch" does validate and second element does not', function () {
caps = {
alwaysMatch: {},
firstMatch: [matchingCaps, {
badCaps: 'badCaps'
}]
};
(0, _capabilities.processCapabilities)(caps, constraints).should.deep.equal(matchingCaps);
});
it('should pass if first element in "firstMatch" does not validate and second element does', function () {
caps = {
alwaysMatch: {},
firstMatch: [{
badCaps: 'badCaps'
}, matchingCaps]
};
(0, _capabilities.processCapabilities)(caps, constraints).should.deep.equal(matchingCaps);
});
it('should fail when deviceName is blank', function () {
caps = {
alwaysMatch: _lodash.default.omit(matchingCaps, ['deviceName'])
};
(() => (0, _capabilities.processCapabilities)(caps, constraints)).should.throw(/'deviceName' can't be blank/);
});
it('should fail when bad parameters are passed in more than one firstMatch capability', function () {
caps = {
alwaysMatch: {},
firstMatch: [{
bad: 'params'
}, {
more: 'bad-params'
}]
};
(() => (0, _capabilities.processCapabilities)(caps, constraints)).should.throw(/Could not find matching capabilities/);
});
});
});
describe('.findNonPrefixedCaps', function () {
it('should find alwaysMatch caps with no prefix', function () {
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch: {
'non-standard': 'dummy'
}
}).should.eql(['non-standard']);
});
it('should not find a standard cap in alwaysMatch', function () {
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch: {
'platformName': 'Any'
}
}).should.eql([]);
});
it('should find firstMatch caps with no prefix', function () {
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch: {},
firstMatch: [{
'non-standard': 'dummy'
}]
}).should.eql(['non-standard']);
});
it('should not find a standard cap in prefix', function () {
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch: {},
firstMatch: [{
'platformName': 'Any'
}]
}).should.eql([]);
});
it('should find firstMatch caps in second item of firstMatch array', function () {
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch: {},
firstMatch: [{}, {
'non-standard': 'dummy'
}]
}).should.eql(['non-standard']);
});
it('should remove duplicates from alwaysMatch and firstMatch', function () {
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch: {
'non-standard': 'something'
},
firstMatch: [{
'non-standard': 'dummy'
}]
}).should.eql(['non-standard']);
});
it('should remove duplicates from firstMatch', function () {
(0, _capabilities.findNonPrefixedCaps)({
firstMatch: [{
'non-standard': 'dummy'
}, {
'non-standard': 'dummy 2'
}]
}).should.eql(['non-standard']);
});
it('should remove duplicates and keep standard capabilities', function () {
const alwaysMatch = {
platformName: 'Fake',
nonStandardOne: 'non-standard',
nonStandardTwo: 'non-standard'
};
const firstMatch = [{
nonStandardThree: 'non-standard',
nonStandardFour: 'non-standard',
browserName: 'FakeBrowser'
}, {
nonStandardThree: 'non-standard',
nonStandardFour: 'non-standard',
nonStandardFive: 'non-standard',
browserVersion: 'whateva'
}];
(0, _capabilities.findNonPrefixedCaps)({
alwaysMatch,
firstMatch
}).should.eql(['nonStandardOne', 'nonStandardTwo', 'nonStandardThree', 'nonStandardFour', 'nonStandardFive']);
});
});
});require('source-map-support').install();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvYmFzZWRyaXZlci9jYXBhYmlsaXRpZXMtc3BlY3MuanMiXSwibmFtZXMiOlsiY2hhaSIsInVzZSIsImNoYWlBc1Byb21pc2VkIiwic2hvdWxkIiwiZGVzY3JpYmUiLCJpdCIsImFyZyIsInVuZGVmaW5lZCIsInRocm93IiwiZGVlcCIsImVxdWFsIiwiZm9vIiwicHJlc2VuY2UiLCJza2lwUHJlc2VuY2VDb25zdHJhaW50IiwiaXNTdHJpbmciLCJpc051bWJlciIsImlzQm9vbGVhbiIsImluY2x1c2lvbkNhc2VJbnNlbnNpdGl2ZSIsImluY2x1c2lvbiIsImNhcHMiLCJudW1iZXIiLCJzdHJpbmciLCJwcmVzZW50IiwiZXh0cmEiLCJjb25zdHJhaW50cyIsIm5vdFByZXNlbnQiLCJoZWxsbyIsInByaW1hcnkiLCJhIiwiYiIsInNlY29uZGFyeSIsImMiLCJkIiwiYmVmb3JlRWFjaCIsImFsd2F5c01hdGNoIiwicmVxdWlyZWRDYXBzIiwiYWxsRmlyc3RNYXRjaENhcHMiLCJmaXJzdE1hdGNoIiwidmFsaWRhdGVkRmlyc3RNYXRjaENhcHMiLCJtYXRjaGVkQ2FwcyIsImdvb2RieWUiLCJzb21lQXR0cmlidXRlIiwicGxhdGZvcm1OYW1lIiwiZmFrZUNhcCIsIm1pc3NpbmdDYXAiLCJkZXNpcmVkQ2FwYWJpbGl0eUNvbnN0cmFpbnRzIiwibWF0Y2hpbmdDYXBzIiwiXyIsIm9taXQiLCJiYWRDYXBzIiwiYmFkIiwibW9yZSIsImVxbCIsIm5vblN0YW5kYXJkT25lIiwibm9uU3RhbmRhcmRUd28iLCJub25TdGFuZGFyZFRocmVlIiwibm9uU3RhbmRhcmRGb3VyIiwiYnJvd3Nlck5hbWUiLCJub25TdGFuZGFyZEZpdmUiLCJicm93c2VyVmVyc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUFBLGNBQUtDLEdBQUwsQ0FBU0MsdUJBQVQ7O0FBQ0EsTUFBTUMsTUFBTSxHQUFHSCxjQUFLRyxNQUFMLEVB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QUF0RCxDQUEwRCxDQUFDLGdCQUFELEVBQW1CLGdCQUFuQixFQUFxQyxrQkFBckMsRUFBeUQsaUJBQXpELEVBQTRFLGlCQUE1RSxDQUExRDtBQUNELEtBWEMsQ0FBRjtBQVlELEdBcERPLENBQVI7QUFxREQsQ0FoYU8sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHBhcnNlQ2FwcywgdmFsaWRhdGVDYXBzLCBtZXJnZUNhcHMsIHByb2Nlc3NDYXBhYmlsaXRpZXMsIGZpbmROb25QcmVmaXhlZENhcHMgfSBmcm9tICcuLi8uLi9saWIvYmFzZWRyaXZlci9jYXBhYmlsaXRpZXMnO1xuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZGVzaXJlZENhcGFiaWxpdHlDb25zdHJhaW50cyB9IGZyb20gJy4uLy4uL2xpYi9iYXNlZHJpdmVyL2Rlc2lyZWQtY2Fwcyc7XG5cbmNoYWkudXNlKGNoYWlBc1Byb21pc2VkKTtcbmNvbnN0IHNob3VsZCA9IGNoYWkuc2hvdWxkKCk7XG5cbmRlc2NyaWJlKCdjYXBzJywgZnVuY3Rpb24gKCkge1xuXG4gIC8vIFRlc3RzIGJhc2VkIG9uOiBodHRwczovL3d3dy53My5vcmcvVFIvd2ViZHJpdmVyLyNkZm4tdmFsaWRhdGUtY2Fwc1xuICBkZXNjcmliZSgnI3ZhbGlkYXRlQ2FwcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgncmV0dXJucyBpbnZhbGlkIGFyZ3VtZW50IGVycm9yIGlmIFwiY2FwYWJpbGl0eVwiIGlzIG5vdCBhIEpTT04gb2JqZWN0ICgxKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGZvciAobGV0IGFyZyBvZiBbdW5kZWZpbmVkLCBudWxsLCAxLCB0cnVlLCAnc3RyaW5nJ10pIHtcbiAgICAgICAgKGZ1bmN0aW9uICgpIHsgdmFsaWRhdGVDYXBzKGFyZyk7IH0pLnNob3VsZC50aHJvdygvbXVzdCBiZSBhIEpTT04gb2JqZWN0Lyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyByZXN1bHQge30gYnkgZGVmYXVsdCBpZiBjYXBzIGlzIGVtcHR5IG9iamVjdCBhbmQgbm8gY29uc3RyYWludHMgcHJvdmlkZWQgKDIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgdmFsaWRhdGVDYXBzKHt9KS5zaG91bGQuZGVlcC5lcXVhbCh7fSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndGhyb3dzIGVycm9ycyBpZiBjb25zdHJhaW50cyBhcmUgbm90IG1ldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdyZXR1cm5zIGludmFsaWQgYXJndW1lbnQgZXJyb3IgaWYgXCJwcmVzZW50XCIgY29uc3RyYWludCBub3QgbWV0IG9uIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAoKCkgPT4gdmFsaWRhdGVDYXBzKHt9LCB7Zm9vOiB7cHJlc2VuY2U6IHRydWV9fSkpLnNob3VsZC50aHJvdygvJ2ZvbycgY2FuJ3QgYmUgYmxhbmsvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmV0dXJucyB0aGUgY2FwYWJpbGl0eSB0aGF0IHdhcyBwYXNzZWQgaW4gaWYgXCJza2lwUHJlc2VuY2VDb25zdHJhaW50XCIgaXMgZmFsc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhbGlkYXRlQ2Fwcyh7fSwge2Zvbzoge3ByZXNlbmNlOiB0cnVlfX0sIHtza2lwUHJlc2VuY2VDb25zdHJhaW50OiB0cnVlfSkuc2hvdWxkLmRlZXAuZXF1YWwoe30pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdyZXR1cm5zIGludmFsaWQgYXJndW1lbnQgZXJyb3IgaWYgXCJpc1N0cmluZ1wiIGNvbnN0cmFpbnQgbm90IG1ldCBvbiBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKCgpID0+IHZhbGlkYXRlQ2Fwcyh7Zm9vOiAxfSwge2Zvbzoge2lzU3RyaW5nOiB0cnVlfX0pKS5zaG91bGQudGhyb3coLydmb28nIG11c3QgYmUgb2YgdHlwZSBzdHJpbmcvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmV0dXJucyBpbnZhbGlkIGFyZ3VtZW50IGVycm9yIGlmIFwiaXNOdW1iZXJcIiBjb25zdHJhaW50IG5vdCBtZXQgb24gcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICgoKSA9PiB2YWxpZGF0ZUNhcHMoe2ZvbzogJ2Jhcid9LCB7Zm9vOiB7aXNOdW1iZXI6IHRydWV9fSkpLnNob3VsZC50aHJvdygvJ2ZvbycgbXVzdCBiZSBvZiB0eXBlIG51bWJlci8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdyZXR1cm5zIGludmFsaWQgYXJndW1lbnQgZXJyb3IgaWYgXCJpc0Jvb2xlYW5cIiBjb25zdHJhaW50IG5vdCBtZXQgb24gcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICgoKSA9PiB2YWxpZGF0ZUNhcHMoe2ZvbzogJ2Jhcid9LCB7Zm9vOiB7aXNCb29sZWFuOiB0cnVlfX0pKS5zaG91bGQudGhyb3coLydmb28nIG11c3QgYmUgb2YgdHlwZSBib29sZWFuLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3JldHVybnMgaW52YWxpZCBhcmd1bWVudCBlcnJvciBpZiBcImluY2x1c2lvblwiIGNvbnN0cmFpbnQgbm90IG1ldCBvbiBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKCgpID0+IHZhbGlkYXRlQ2Fwcyh7Zm9vOiAnMyd9LCB7Zm9vOiB7aW5jbHVzaW9uQ2FzZUluc2Vuc2l0aXZlOiBbJzEnLCAnMiddfX0pKS5zaG91bGQudGhyb3coLydmb28nIDMgbm90IHBhcnQgb2YgMSwyLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3JldHVybnMgaW52YWxpZCBhcmd1bWVudCBlcnJvciBpZiBcImluY2x1c2lvbkNhc2VJbnNlbnNpdGl2ZVwiIGNvbnN0cmFpbnQgbm90IG1ldCBvbiBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKCgpID0+IHZhbGlkYXRlQ2Fwcyh7Zm9vOiAnYSd9LCB7Zm9vOiB7aW5jbHVzaW9uOiBbJ0EnLCAnQicsICdDJ119fSkpLnNob3VsZC50aHJvdygvJ2ZvbycgYSBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIGxpc3QvKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgZXJyb3JzIGlmIGNvbnN0cmFpbnRzIGFyZSBtZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgY2FwcyA9IHtcbiAgICAgICAgbnVtYmVyOiAxLFxuICAgICAgICBzdHJpbmc6ICdzdHJpbmcnLFxuICAgICAgICBwcmVzZW50OiAncHJlc2VudCcsXG4gICAgICAgIGV4dHJhOiAnZXh0cmEnLFxuICAgICAgfTtcblxuICAgICAgbGV0IGNvbnN0cmFpbnRzID0ge1xuICAgICAgICBudW1iZXI6IHtpc051bWJlcjogdHJ1ZX0sXG4gICAgICAgIHN0cmluZzoge2lzU3RyaW5nOiB0cnVlfSxcbiAgICAgICAgcHJlc2VudDoge3ByZXNlbmNlOiB0cnVlfSxcbiAgICAgICAgbm90UHJlc2VudDoge3ByZXNlbmNlOiBmYWxzZX0sXG4gICAgICB9O1xuXG4gICAgICB2YWxpZGF0ZUNhcHMoY2FwcywgY29uc3RyYWludHMpLnNob3VsZC5kZWVwLmVxdWFsKGNhcHMpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBUZXN0cyBiYXNlZCBvbjogaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYmRyaXZlci8jZGZuLW1lcmdpbmctY2Fwc1xuICBkZXNjcmliZSgnI21lcmdlQ2FwcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgncmV0dXJucyBhIHJlc3VsdCB0aGF0IGlzIHt9IGJ5IGRlZmF1bHQgKDEpJywgZnVuY3Rpb24gKCkge1xuICAgICAgbWVyZ2VDYXBzKCkuc2hvdWxkLmRlZXAuZXF1YWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JldHVybnMgYSByZXN1bHQgdGhhdCBtYXRjaGVzIHByaW1hcnkgYnkgZGVmYXVsdCAoMiwgMyknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBtZXJnZUNhcHMoe2hlbGxvOiAnd29ybGQnfSkuc2hvdWxkLmRlZXAuZXF1YWwoe2hlbGxvOiAnd29ybGQnfSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyBpbnZhbGlkIGFyZ3VtZW50IGVycm9yIGlmIHByaW1hcnkgYW5kIHNlY29uZGFyeSBoYXZlIG1hdGNoaW5nIHByb3BlcnRpZXMgKDQpJywgZnVuY3Rpb24gKCkge1xuICAgICAgKCgpID0+IG1lcmdlQ2Fwcyh7aGVsbG86ICd3b3JsZCd9LCB7aGVsbG86ICd3aGlybCd9KSkuc2hvdWxkLnRocm93KC9wcm9wZXJ0eSAnaGVsbG8nIHNob3VsZCBub3QgZXhpc3Qgb24gYm90aCBwcmltYXJ5IFtcXHdcXFddKiBhbmQgc2Vjb25kYXJ5IFtcXHdcXFddKi8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JldHVybnMgYSByZXN1bHQgd2l0aCBrZXlzIGZyb20gcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHRvZ2V0aGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHByaW1hcnkgPSB7XG4gICAgICAgIGE6ICdhJyxcbiAgICAgICAgYjogJ2InLFxuICAgICAgfTtcbiAgICAgIGxldCBzZWNvbmRhcnkgPSB7XG4gICAgICAgIGM6ICdjJyxcbiAgICAgICAgZDogJ2QnLFxuICAgICAgfTtcbiAgICAgIG1lcmdlQ2FwcyhwcmltYXJ5LCBzZWNvbmRhcnkpLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgYTogJ2EnLCBiOiAnYicsIGM6ICdjJywgZDogJ2QnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFRlc3RzIGJhc2VkIG9uOiBodHRwczovL3d3dy53My5vcmcvVFIvd2ViZHJpdmVyLyNwcm9jZXNzaW5nLWNhcHNcbiAgZGVzY3JpYmUoJyNwYXJzZUNhcHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGNhcHM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNhcHMgPSB7fTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGludmFsaWQgYXJndW1lbnQgaWYgbm8gY2FwcyBvYmplY3QgcHJvdmlkZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAoKCkgPT4gcGFyc2VDYXBzKCkpLnNob3VsZC50aHJvdygvbXVzdCBiZSBhIEpTT04gb2JqZWN0Lyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2V0cyBcInJlcXVpcmVkQ2Fwc1wiIHRvIHByb3BlcnR5IG5hbWVkIFwiYWx3YXlzTWF0Y2hcIiAoMiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjYXBzLmFsd2F5c01hdGNoID0ge2hlbGxvOiAnd29ybGQnfTtcbiAgICAgIHBhcnNlQ2FwcyhjYXBzKS5yZXF1aXJlZENhcHMuc2hvdWxkLmRlZXAuZXF1YWwoY2Fwcy5hbHdheXNNYXRjaCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2V0cyBcInJlcXVpcmVkQ2Fwc1wiIHRvIGVtcHR5IEpTT04gb2JqZWN0IGlmIFwiYWx3YXlzTWF0Y2hcIiBpcyBub3QgYW4gb2JqZWN0ICgyLjEpJywgZnVuY3Rpb24gKCkge1xuICAgICAgcGFyc2VDYXBzKGNhcHMpLnJlcXVpcmVkQ2Fwcy5zaG91bGQuZGVlcC5lcXVhbCh7fSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyBpbnZhbGlkIGFyZ3VtZW50IGVycm9yIGlmIFwicmVxdWlyZWRDYXBzXCIgZG9uXFwndCBtYXRjaCBcImNvbnN0cmFpbnRzXCIgKDIuMiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjYXBzLmFsd2F5c01hdGNoID0ge2ZvbzogMX07XG4gICAgICAoKCkgPT4gcGFyc2VDYXBzKGNhcHMsIHtmb286IHtpc1N0cmluZzogdHJ1ZX19KSkuc2hvdWxkLnRocm93KC8nZm9vJyBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2V0cyBcImFsbEZpcnN0TWF0Y2hDYXBzXCIgdG8gcHJvcGVydHkgbmFtZWQgXCJmaXJzdE1hdGNoXCIgKDMpJywgZnVuY3Rpb24gKCkge1xuICAgICAgcGFyc2VDYXBzKHt9LCBbe31dKS5hbGxGaXJzdE1hdGNoQ2Fwcy5zaG91bGQuZGVlcC5lcXVhbChbe31dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZXRzIFwiYWxsRmlyc3RNYXRjaENhcHNcIiB0byBbe31dIGlmIFwiZmlyc3RNYXRjaFwiIGlzIHVuZGVmaW5lZCAoMy4xKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHBhcnNlQ2Fwcyh7fSkuYWxsRmlyc3RNYXRjaENhcHMuc2hvdWxkLmRlZXAuZXF1YWwoW3t9XSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyBpbnZhbGlkIGFyZ3VtZW50IGVycm9yIGlmIFwiZmlyc3RNYXRjaFwiIGlzIG5vdCBhbiBhcnJheSBhbmQgaXMgbm90IHVuZGVmaW5lZCAoMy4yKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGZvciAobGV0IGFyZyBvZiBbbnVsbCwgMSwgdHJ1ZSwgJ3N0cmluZyddKSB7XG4gICAgICAgIGNhcHMuZmlyc3RNYXRjaCA9IGFyZztcbiAgICAgICAgKGZ1bmN0aW9uICgpIHsgcGFyc2VDYXBzKGNhcHMpOyB9KS5zaG91bGQudGhyb3coL211c3QgYmUgYSBKU09OIGFycmF5IG9yIHVuZGVmaW5lZC8pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ2hhcyBcInZhbGlkYXRlZEZpcnN0TWF0Y2hDYXBzXCIgcHJvcGVydHkgdGhhdCBpcyBlbXB0eSBieSBkZWZhdWx0IGlmIG5vIHZhbGlkIGZpcnN0TWF0Y2ggY2FwcyB3ZXJlIGZvdW5kICg0KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHBhcnNlQ2FwcyhjYXBzLCB7Zm9vOiB7cHJlc2VuY2U6IHRydWV9fSkudmFsaWRhdGVkRmlyc3RNYXRjaENhcHMuc2hvdWxkLmRlZXAuZXF1YWwoW10pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3JldHVybnMgYSBcInZhbGlkYXRlZEZpcnN0TWF0Y2hDYXBzXCIgYXJyYXkgKDUpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3RoYXQgZXF1YWxzIFwiZmlyc3RNYXRjaFwiIGlmIGZpcnN0TWF0Y2ggaXMgb25lIGVtcHR5IG9iamVjdCBhbmQgdGhlcmUgYXJlIG5vIGNvbnN0cmFpbnRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjYXBzLmZpcnN0TWF0Y2ggPSBbe31dO1xuICAgICAgICBwYXJzZUNhcHMoY2FwcykudmFsaWRhdGVkRmlyc3RNYXRjaENhcHMuc2hvdWxkLmRlZXAuZXF1YWwoY2Fwcy5maXJzdE1hdGNoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmV0dXJucyBcIm51bGxcIiBtYXRjaGVkQ2FwcyBpZiBub3RoaW5nIG1hdGNoZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhcHMuZmlyc3RNYXRjaCA9IFt7fV07XG4gICAgICAgIHNob3VsZC5lcXVhbChwYXJzZUNhcHMoY2Fwcywge2Zvbzoge3ByZXNlbmNlOiB0cnVlfX0pLm1hdGNoZWRDYXBzLCBudWxsKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgc2hvdWxkIHJldHVybiBjYXBhYmlsaXRpZXMgaWYgcHJlc2VuY2UgY29uc3RyYWludCBpcyBtYXRjaGVkIGluIGF0IGxlYXN0IG9uZSBvZiB0aGUgJ2ZpcnN0TWF0Y2gnIGNhcGFiaWxpdGllcyBvYmplY3RzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjYXBzLmFsd2F5c01hdGNoID0ge1xuICAgICAgICAgIGZvbzogJ2JhcicsXG4gICAgICAgIH07XG4gICAgICAgIGNhcHMuZmlyc3RNYXRjaCA9IFt7XG4gICAgICAgICAgaGVsbG86ICd3b3JsZCcsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBnb29kYnllOiAnd29ybGQnLFxuICAgICAgICB9XTtcbiAgICAgICAgcGFyc2VDYXBzKGNhcHMsIHtnb29kYnllOiB7cHJlc2VuY2U6IHRydWV9fSkubWF0Y2hlZENhcHMuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICAgIGZvbzogJ2JhcicsXG4gICAgICAgICAgZ29vZGJ5ZTogJ3dvcmxkJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHRocm93cyBpbnZhbGlkIGFyZ3VtZW50IGlmIHByZXNlbmNlIGNvbnN0cmFpbnQgaXMgbm90IG1ldCBvbiBhbnkgY2FwYWJpbGl0aWVzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjYXBzLmFsd2F5c01hdGNoID0ge1xuICAgICAgICAgIGZvbzogJ2JhcicsXG4gICAgICAgIH07XG4gICAgICAgIGNhcHMuZmlyc3RNYXRjaCA9IFt7XG4gICAgICAgICAgaGVsbG86ICd3b3JsZCcsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBnb29kYnllOiAnd29ybGQnLFxuICAgICAgICB9XTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHBhcnNlQ2FwcyhjYXBzLCB7c29tZUF0dHJpYnV0ZToge3ByZXNlbmNlOiB0cnVlfX0pLm1hdGNoZWRDYXBzLCBudWxsKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgndGhhdCBlcXVhbHMgZmlyc3RNYXRjaCBpZiBmaXJzdE1hdGNoIGNvbnRhaW5zIHR3byBvYmplY3RzIHRoYXQgcGFzcyB0aGUgcHJvdmlkZWQgY29uc3RyYWludHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhcHMuYWx3YXlzTWF0Y2ggPSB7XG4gICAgICAgICAgZm9vOiAnYmFyJ1xuICAgICAgICB9O1xuICAgICAgICBjYXBzLmZpcnN0TWF0Y2ggPSBbXG4gICAgICAgICAge2ZvbzogJ2JhcjEnfSxcbiAgICAgICAgICB7Zm9vOiAnYmFyMid9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGxldCBjb25zdHJhaW50cyA9IHtcbiAgICAgICAgICBmb286IHtcbiAgICAgICAgICAgIHByZXNlbmNlOiB0cnVlLFxuICAgICAgICAgICAgaXNTdHJpbmc6IHRydWUsXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHBhcnNlQ2FwcyhjYXBzLCBjb25zdHJhaW50cykudmFsaWRhdGVkRmlyc3RNYXRjaENhcHMuc2hvdWxkLmRlZXAuZXF1YWwoY2Fwcy5maXJzdE1hdGNoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmV0dXJucyBpbnZhbGlkIGFyZ3VtZW50IGVycm9yIGlmIHRoZSBmaXJzdE1hdGNoWzJdIGlzIG5vdCBhbiBvYmplY3QnLCBmdW5