Best Python code snippet using tox_python
browser-options.js
Source:browser-options.js
1'use strict';2const _ = require('lodash');3const Config = require('lib/config');4const defaults = require('lib/config/defaults');5describe('config browser-options', () => {6 const sandbox = sinon.sandbox.create();7 const mkBrowser_ = (opts) => {8 return _.defaults(opts || {}, {9 desiredCapabilities: {}10 });11 };12 const createConfig = () => Config.create(defaults.config);13 beforeEach(() => sandbox.stub(Config, 'read').returns({}));14 afterEach(() => sandbox.restore());15 describe('desiredCapabilities', () => {16 describe('should throw error if desiredCapabilities', () => {17 it('is missing', () => {18 const readConfig = {19 browsers: {20 b1: {}21 }22 };23 Config.read.returns(readConfig);24 assert.throws(() => createConfig(), Error, 'Each browser must have "desiredCapabilities" option');25 });26 it('is not an object or null', () => {27 const readConfig = {28 browsers: {29 b1: {30 desiredCapabilities: 'chrome'31 }32 }33 };34 Config.read.returns(readConfig);35 assert.throws(() => createConfig(), Error, '"desiredCapabilities" must be an object');36 });37 });38 it('should set desiredCapabilities', () => {39 const readConfig = {40 browsers: {41 b1: {42 desiredCapabilities: {43 browserName: 'yabro'44 }45 }46 }47 };48 Config.read.returns(readConfig);49 const config = createConfig();50 assert.deepEqual(config.browsers.b1.desiredCapabilities, {browserName: 'yabro'});51 });52 });53 describe('baseUrl', () => {54 it('should throw error if baseUrl is not a string', () => {55 const readConfig = {56 browsers: {57 b1: mkBrowser_({baseUrl: ['Array']})58 }59 };60 Config.read.returns(readConfig);61 assert.throws(() => createConfig(), Error, '"baseUrl" must be a string');62 });63 it('should set baseUrl to all browsers', () => {64 const baseUrl = 'http://default.com';65 const readConfig = {66 baseUrl,67 browsers: {68 b1: mkBrowser_(),69 b2: mkBrowser_()70 }71 };72 Config.read.returns(readConfig);73 const config = createConfig();74 assert.equal(config.browsers.b1.baseUrl, baseUrl);75 assert.equal(config.browsers.b2.baseUrl, baseUrl);76 });77 it('should override baseUrl option if protocol is set', () => {78 const baseUrl = 'http://default.com';79 const readConfig = {80 baseUrl,81 browsers: {82 b1: mkBrowser_(),83 b2: mkBrowser_({baseUrl: 'http://foo.com'})84 }85 };86 Config.read.returns(readConfig);87 const config = createConfig();88 assert.equal(config.browsers.b1.baseUrl, baseUrl);89 assert.equal(config.browsers.b2.baseUrl, 'http://foo.com');90 });91 it('should resolve baseUrl option relative to top level baseUrl', () => {92 const baseUrl = 'http://default.com';93 const readConfig = {94 baseUrl,95 browsers: {96 b1: mkBrowser_(),97 b2: mkBrowser_({baseUrl: '/test'})98 }99 };100 Config.read.returns(readConfig);101 const config = createConfig();102 assert.equal(config.browsers.b1.baseUrl, baseUrl);103 assert.equal(config.browsers.b2.baseUrl, 'http://default.com/test');104 });105 it('should resolve baseUrl option relative to top level baseUrl with path', () => {106 const baseUrl = 'http://default.com/search/';107 const readConfig = {108 baseUrl,109 browsers: {110 b1: mkBrowser_(),111 b2: mkBrowser_({baseUrl: '/test'})112 }113 };114 Config.read.returns(readConfig);115 const config = createConfig();116 assert.equal(config.browsers.b1.baseUrl, baseUrl);117 assert.equal(config.browsers.b2.baseUrl, 'http://default.com/search/test');118 });119 });120 describe('gridUrl', () => {121 it('should throw error if gridUrl is not a string', () => {122 const readConfig = {123 browsers: {124 b1: mkBrowser_({gridUrl: /regExp/})125 }126 };127 Config.read.returns(readConfig);128 assert.throws(() => createConfig(), Error, '"gridUrl" must be a string');129 });130 it('should set gridUrl to all browsers', () => {131 const gridUrl = 'http://default.com';132 const readConfig = {133 gridUrl,134 browsers: {135 b1: mkBrowser_(),136 b2: mkBrowser_()137 }138 };139 Config.read.returns(readConfig);140 const config = createConfig();141 assert.equal(config.browsers.b1.gridUrl, gridUrl);142 assert.equal(config.browsers.b2.gridUrl, gridUrl);143 });144 it('should override gridUrl option', () => {145 const gridUrl = 'http://default.com';146 const readConfig = {147 gridUrl,148 browsers: {149 b1: mkBrowser_(),150 b2: mkBrowser_({gridUrl: 'http://bar.com'})151 }152 };153 Config.read.returns(readConfig);154 const config = createConfig();155 assert.equal(config.browsers.b1.gridUrl, gridUrl);156 assert.equal(config.browsers.b2.gridUrl, 'http://bar.com');157 });158 });159 describe('automationProtocol', () => {160 it('should throw an error if option value is not string', () => {161 const readConfig = {162 browsers: {163 b1: mkBrowser_({automationProtocol: {not: 'string'}})164 }165 };166 Config.read.returns(readConfig);167 assert.throws(() => createConfig(), Error, /"automationProtocol" must be a string/);168 });169 it('should throw an error if option value is not "webdriver" or "devtools"', () => {170 const readConfig = {171 browsers: {172 b1: mkBrowser_({automationProtocol: 'foo bar'})173 }174 };175 Config.read.returns(readConfig);176 assert.throws(() => createConfig(), Error, /"automationProtocol" must be "webdriver" or "devtools"/);177 });178 describe('should not throw an error if option value is', () => {179 ['webdriver', 'devtools'].forEach((value) => {180 it(`${value}`, () => {181 const readConfig = {182 browsers: {183 b1: mkBrowser_({automationProtocol: value})184 }185 };186 Config.read.returns(readConfig);187 assert.doesNotThrow(() => createConfig());188 });189 });190 });191 it('should set a default value if it is not set in config', () => {192 const readConfig = {193 browsers: {194 b1: mkBrowser_()195 }196 };197 Config.read.returns(readConfig);198 const config = createConfig();199 assert.equal(config.automationProtocol, defaults.automationProtocol);200 });201 it('should override option for browser', () => {202 const readConfig = {203 automationProtocol: 'webdriver',204 browsers: {205 b1: mkBrowser_(),206 b2: mkBrowser_({automationProtocol: 'devtools'})207 }208 };209 Config.read.returns(readConfig);210 const config = createConfig();211 assert.equal(config.browsers.b1.automationProtocol, 'webdriver');212 assert.equal(config.browsers.b2.automationProtocol, 'devtools');213 });214 });215 describe('sessionEnvFlags', () => {216 it('should throw an error if option value is not an object', () => {217 const readConfig = {218 browsers: {219 b1: mkBrowser_({sessionEnvFlags: 'string'})220 }221 };222 Config.read.returns(readConfig);223 assert.throws(() => createConfig(), Error, /"sessionEnvFlags" must be an object/);224 });225 it('should throw an error if option value is not available', () => {226 const readConfig = {227 browsers: {228 b1: mkBrowser_({sessionEnvFlags: {a: 'b'}})229 }230 };231 Config.read.returns(readConfig);232 assert.throws(() => createConfig(), Error, /keys of "sessionEnvFlags" must be one of:/);233 });234 it('should throw an error if value inside available option is not boolean', () => {235 const readConfig = {236 browsers: {237 b1: mkBrowser_({sessionEnvFlags: {isW3C: 'string'}})238 }239 };240 Config.read.returns(readConfig);241 assert.throws(() => createConfig(), Error, /values of "sessionEnvFlags" must be boolean/);242 });243 describe('should not throw an error if option key is', () => {244 ['isW3C', 'isChrome', 'isMobile', 'isIOS', 'isAndroid', 'isSauce', 'isSeleniumStandalone'].forEach((key) => {245 it(`"${key}" and value is boolean`, () => {246 const readConfig = {247 browsers: {248 b1: mkBrowser_({sessionEnvFlags: {[key]: true}})249 }250 };251 Config.read.returns(readConfig);252 assert.doesNotThrow(() => createConfig());253 });254 });255 });256 it('should set a default value if it is not set in config', () => {257 const readConfig = {258 browsers: {259 b1: mkBrowser_()260 }261 };262 Config.read.returns(readConfig);263 const config = createConfig();264 assert.deepEqual(config.sessionEnvFlags, defaults.sessionEnvFlags);265 });266 it('should override option for browser', () => {267 const readConfig = {268 sessionEnvFlags: {isW3C: true},269 browsers: {270 b1: mkBrowser_(),271 b2: mkBrowser_({sessionEnvFlags: {isW3C: false}})272 }273 };274 Config.read.returns(readConfig);275 const config = createConfig();276 assert.deepEqual(config.browsers.b1.sessionEnvFlags, {isW3C: true});277 assert.deepEqual(config.browsers.b2.sessionEnvFlags, {isW3C: false});278 });279 });280 describe('prepareBrowser', () => {281 it('should throw error if prepareBrowser is not a null or function', () => {282 const readConfig = {283 browsers: {284 b1: mkBrowser_({prepareBrowser: 'String'})285 }286 };287 Config.read.returns(readConfig);288 assert.throws(() => createConfig(), Error, '"prepareBrowser" must be a function');289 });290 it('should set prepareBrowser to all browsers', () => {291 const prepareBrowser = () => {};292 const readConfig = {293 prepareBrowser,294 browsers: {295 b1: mkBrowser_(),296 b2: mkBrowser_()297 }298 };299 Config.read.returns(readConfig);300 const config = createConfig();301 assert.equal(config.browsers.b1.prepareBrowser, prepareBrowser);302 assert.equal(config.browsers.b2.prepareBrowser, prepareBrowser);303 });304 it('should override prepareBrowser option', () => {305 const prepareBrowser = () => {};306 const newFunc = () => {};307 const readConfig = {308 prepareBrowser,309 browsers: {310 b1: mkBrowser_(),311 b2: mkBrowser_({prepareBrowser: newFunc})312 }313 };314 Config.read.returns(readConfig);315 const config = createConfig();316 assert.equal(config.browsers.b1.prepareBrowser, prepareBrowser);317 assert.equal(config.browsers.b2.prepareBrowser, newFunc);318 });319 });320 describe('screenshotsDir', () => {321 it('should set a default screenshotsDir option if it is not set in config', () => {322 const config = createConfig();323 assert.equal(config.screenshotsDir, defaults.screenshotsDir);324 });325 it('should throw an error if a value is not a string or function', () => {326 const readConfig = {327 browsers: {328 b1: mkBrowser_({screenshotsDir: ['Array']})329 }330 };331 Config.read.returns(readConfig);332 assert.throws(() => createConfig(), Error, '"screenshotsDir" must be a string or function');333 });334 it('should does not throw if a value is a function', () => {335 const readConfig = {336 screenshotsDir: () => {},337 browsers: {338 b1: mkBrowser_()339 }340 };341 Config.read.returns(readConfig);342 assert.doesNotThrow(createConfig);343 });344 it('should set screenshotsDir option to all browsers', () => {345 const screenshotsDir = '/some/dir';346 const readConfig = {347 screenshotsDir,348 browsers: {349 b1: mkBrowser_(),350 b2: mkBrowser_()351 }352 };353 Config.read.returns(readConfig);354 const config = createConfig();355 assert.equal(config.browsers.b1.screenshotsDir, '/some/dir');356 assert.equal(config.browsers.b2.screenshotsDir, '/some/dir');357 });358 it('should override screenshotsDir option per browser', () => {359 const screenshotsDir = '/some/dir';360 const readConfig = {361 screenshotsDir,362 browsers: {363 b1: mkBrowser_(),364 b2: mkBrowser_({screenshotsDir: '/screens'})365 }366 };367 Config.read.returns(readConfig);368 const config = createConfig();369 assert.equal(config.browsers.b1.screenshotsDir, '/some/dir');370 assert.equal(config.browsers.b2.screenshotsDir, '/screens');371 });372 });373 ['sessionsPerBrowser', 'waitTimeout'].forEach((option) => {374 describe(`${option}`, () => {375 describe(`should throw error if ${option}`, () => {376 it('is not a number', () => {377 const readConfig = {378 browsers: {379 b1: mkBrowser_({[option]: '10'})380 }381 };382 Config.read.returns(readConfig);383 assert.throws(() => createConfig(), Error, `"${option}" must be a positive integer`);384 });385 it('is negative number', () => {386 const readConfig = {387 browsers: {388 b1: mkBrowser_({[option]: -5})389 }390 };391 Config.read.returns(readConfig);392 assert.throws(() => createConfig(), Error, `"${option}" must be a positive integer`);393 });394 it('is float number', () => {395 const readConfig = {396 browsers: {397 b1: mkBrowser_({[option]: 15.5})398 }399 };400 Config.read.returns(readConfig);401 assert.throws(() => createConfig(), Error, `"${option}" must be a positive integer`);402 });403 });404 it(`should set ${option} to all browsers`, () => {405 const readConfig = {406 [option]: 666,407 browsers: {408 b1: mkBrowser_(),409 b2: mkBrowser_()410 }411 };412 Config.read.returns(readConfig);413 const config = createConfig();414 assert.equal(config.browsers.b1[option], 666);415 assert.equal(config.browsers.b2[option], 666);416 });417 it(`should override ${option} option`, () => {418 const readConfig = {419 [option]: 666,420 browsers: {421 b1: mkBrowser_(),422 b2: mkBrowser_(_.set({}, option, 13))423 }424 };425 Config.read.returns(readConfig);426 const config = createConfig();427 assert.equal(config.browsers.b1[option], 666);428 assert.equal(config.browsers.b2[option], 13);429 });430 });431 });432 describe('testsPerSession', () => {433 describe('should throw error if "testsPerSession"', () => {434 it('is not a number', () => {435 const readConfig = {436 browsers: {437 b1: mkBrowser_({testsPerSession: '10'})438 }439 };440 Config.read.returns(readConfig);441 assert.throws(() => createConfig(), Error, '"testsPerSession" must be a positive integer or Infinity');442 });443 it('is a negative number', () => {444 const readConfig = {445 browsers: {446 b1: mkBrowser_({testsPerSession: -5})447 }448 };449 Config.read.returns(readConfig);450 assert.throws(() => createConfig(), Error, '"testsPerSession" must be a positive integer or Infinity');451 });452 it('is a float number', () => {453 const readConfig = {454 browsers: {455 b1: mkBrowser_({testsPerSession: 15.5})456 }457 };458 Config.read.returns(readConfig);459 assert.throws(() => createConfig(), Error, '"testsPerSession" must be a positive integer or Infinity');460 });461 });462 it('should set "testsPerSession" to all browsers', () => {463 const readConfig = {464 testsPerSession: 666,465 browsers: {466 b1: mkBrowser_(),467 b2: mkBrowser_()468 }469 };470 Config.read.returns(readConfig);471 const config = createConfig();472 assert.equal(config.browsers.b1.testsPerSession, 666);473 assert.equal(config.browsers.b2.testsPerSession, 666);474 });475 it('should override "testsPerSession option"', () => {476 const readConfig = {477 testsPerSession: 666,478 browsers: {479 b1: mkBrowser_(),480 b2: mkBrowser_({testsPerSession: 13})481 }482 };483 Config.read.returns(readConfig);484 const config = createConfig();485 assert.equal(config.browsers.b1.testsPerSession, 666);486 assert.equal(config.browsers.b2.testsPerSession, 13);487 });488 });489 [490 'retry', 'httpTimeout', 'sessionRequestTimeout', 'sessionQuitTimeout',491 'screenshotOnRejectTimeout', 'screenshotDelay', 'pageLoadTimeout', 'testTimeout', 'urlHttpTimeout'492 ].forEach((option) => {493 describe(`${option}`, () => {494 it(`should throw error if ${option} is not a number`, () => {495 const readConfig = {496 browsers: {497 b1: mkBrowser_(_.set({}, option, '100500'))498 }499 };500 Config.read.returns(readConfig);501 assert.throws(() => createConfig(), Error, `"${option}" must be a non-negative integer`);502 });503 it(`should throw error if ${option} is negative`, () => {504 const readConfig = {505 browsers: {506 b1: mkBrowser_(_.set({}, option, -7))507 }508 };509 Config.read.returns(readConfig);510 assert.throws(() => createConfig(), Error, `"${option}" must be a non-negative integer`);511 });512 it(`should set ${option} option to all browsers`, () => {513 const readConfig = {514 [option]: 100500,515 browsers: {516 b1: mkBrowser_(),517 b2: mkBrowser_()518 }519 };520 Config.read.returns(readConfig);521 const config = createConfig();522 assert.equal(config.browsers.b1[option], 100500);523 assert.equal(config.browsers.b2[option], 100500);524 });525 it(`should override ${option} option`, () => {526 const readConfig = {527 [option]: 100500,528 browsers: {529 b1: mkBrowser_(),530 b2: mkBrowser_(_.set({}, option, 500100))531 }532 };533 Config.read.returns(readConfig);534 const config = createConfig();535 assert.equal(config.browsers.b1[option], 100500);536 assert.equal(config.browsers.b2[option], 500100);537 });538 });539 });540 describe('meta', () => {541 it('should throw error if "meta" is not a object', () => {542 const readConfig = {543 browsers: {544 b1: mkBrowser_({meta: 'meta-string'})545 }546 };547 Config.read.returns(readConfig);548 assert.throws(() => createConfig(), Error, '"meta" must be an object');549 });550 it('should set null by default', () => {551 const readConfig = {552 browsers: {553 b1: mkBrowser_({})554 }555 };556 Config.read.returns(readConfig);557 const config = createConfig();558 assert.equal(config.browsers.b1.meta, null);559 });560 it('should set provided value', () => {561 const readConfig = {562 browsers: {563 b1: mkBrowser_({meta: {k1: 'v1', k2: 'v2'}})564 }565 };566 Config.read.returns(readConfig);567 const config = createConfig();568 assert.deepEqual(config.browsers.b1.meta, {k1: 'v1', k2: 'v2'});569 });570 });571 describe('windowSize', () => {572 describe('should throw error if "windowSize" is', () => {573 it('not object, string or null', () => {574 const readConfig = {575 browsers: {576 b1: mkBrowser_({windowSize: 1})577 }578 };579 Config.read.returns(readConfig);580 assert.throws(() => createConfig(), Error, '"windowSize" must be string, object or null');581 });582 it('object without "width" or "height" keys', () => {583 const readConfig = {584 browsers: {585 b1: mkBrowser_({windowSize: {width: 1}})586 }587 };588 Config.read.returns(readConfig);589 assert.throws(() => createConfig(), Error, '"windowSize" must be an object with "width" and "height" keys');590 });591 it('object with "width" or "height" keys that are not numbers', () => {592 const readConfig = {593 browsers: {594 b1: mkBrowser_({windowSize: {width: 1, height: '2'}})595 }596 };597 Config.read.returns(readConfig);598 assert.throws(() => createConfig(), Error, '"windowSize" must be an object with "width" and "height" keys');599 });600 it('string with wrong pattern', () => {601 const readConfig = {602 browsers: {603 b1: mkBrowser_({windowSize: 'some_size'})604 }605 };606 Config.read.returns(readConfig);607 assert.throws(() => createConfig(), Error, '"windowSize" should have form of <width>x<height> (i.e. 1600x1200)');608 });609 });610 it('should be "null" by default', () => {611 const readConfig = {612 browsers: {613 b1: mkBrowser_()614 }615 };616 Config.read.returns(readConfig);617 const config = createConfig();618 assert.equal(config.browsers.b1.windowSize, null);619 });620 it('should accept string value', () => {621 const readConfig = {622 browsers: {623 b1: mkBrowser_({windowSize: '1x2'})624 }625 };626 Config.read.returns(readConfig);627 const config = createConfig();628 assert.deepEqual(config.browsers.b1.windowSize, {width: 1, height: 2});629 });630 it('should pass object with "width" and "height" keys as is', () => {631 const size = {width: 1, height: 2, check: true};632 const readConfig = {633 browsers: {634 b1: mkBrowser_({windowSize: size})635 }636 };637 Config.read.returns(readConfig);638 const config = createConfig();639 assert.deepEqual(config.browsers.b1.windowSize, size);640 });641 it('should set option to all browsers', () => {642 const readConfig = {643 windowSize: '1x2',644 browsers: {645 b1: mkBrowser_(),646 b2: mkBrowser_()647 }648 };649 Config.read.returns(readConfig);650 const config = createConfig();651 assert.deepEqual(config.browsers.b1.windowSize, {width: 1, height: 2});652 assert.deepEqual(config.browsers.b2.windowSize, {width: 1, height: 2});653 });654 it('should override option for browser', () => {655 const readConfig = {656 windowSize: '1x2',657 browsers: {658 b1: mkBrowser_(),659 b2: mkBrowser_({windowSize: '5x5'})660 }661 };662 Config.read.returns(readConfig);663 const config = createConfig();664 assert.deepEqual(config.browsers.b1.windowSize, {width: 1, height: 2});665 assert.deepEqual(config.browsers.b2.windowSize, {width: 5, height: 5});666 });667 });668 ['tolerance', 'antialiasingTolerance'].forEach((option) => {669 describe(`${option}`, () => {670 describe('should throw an error', () => {671 it('if value is not number', () => {672 const readConfig = {673 browsers: {674 b1: mkBrowser_({[option]: []})675 }676 };677 Config.read.returns(readConfig);678 assert.throws(() => createConfig(), Error, `"${option}" must be a number`);679 });680 it('if value is negative', () => {681 const readConfig = {682 browsers: {683 b1: mkBrowser_({[option]: -1})684 }685 };686 Config.read.returns(readConfig);687 assert.throws(() => createConfig(), Error, `"${option}" must be non-negative`);688 });689 });690 it('should set a default value if it is not set in config', () => {691 const readConfig = {692 browsers: {693 b1: mkBrowser_()694 }695 };696 Config.read.returns(readConfig);697 const config = createConfig();698 assert.equal(config[option], defaults[option]);699 });700 it('should does not throw if value is 0', () => {701 const readConfig = {702 browsers: {703 b1: mkBrowser_({[option]: 0})704 }705 };706 Config.read.returns(readConfig);707 assert.doesNotThrow(createConfig);708 });709 it('should override option for browser', () => {710 const readConfig = {711 [option]: 100,712 browsers: {713 b1: mkBrowser_(),714 b2: mkBrowser_({[option]: 200})715 }716 };717 Config.read.returns(readConfig);718 const config = createConfig();719 assert.deepEqual(config.browsers.b1[option], 100);720 assert.deepEqual(config.browsers.b2[option], 200);721 });722 });723 });724 describe('buildDiffOpts', () => {725 it('should throw error if "buildDiffOpts" is not a object', () => {726 const readConfig = {727 browsers: {728 b1: mkBrowser_({buildDiffOpts: 'some-string'})729 }730 };731 Config.read.returns(readConfig);732 assert.throws(() => createConfig(), Error, '"buildDiffOpts" must be an object');733 });734 ['ignoreAntialiasing', 'ignoreCaret'].forEach((option) => {735 it(`should set "${option}" to "true" by default`, () => {736 const readConfig = {737 browsers: {738 b1: mkBrowser_({})739 }740 };741 Config.read.returns(readConfig);742 const config = createConfig();743 assert.equal(config.browsers.b1.buildDiffOpts[option], true);744 });745 });746 it('should set provided value', () => {747 const readConfig = {748 browsers: {749 b1: mkBrowser_({buildDiffOpts: {k1: 'v1', k2: 'v2'}})750 }751 };752 Config.read.returns(readConfig);753 const config = createConfig();754 assert.deepEqual(config.browsers.b1.buildDiffOpts, {k1: 'v1', k2: 'v2'});755 });756 });757 describe('assertViewOpts', () => {758 it('should throw error if "assertViewOpts" is not an object', () => {759 const readConfig = {760 browsers: {761 b1: mkBrowser_({assertViewOpts: 'some-string'})762 }763 };764 Config.read.returns(readConfig);765 assert.throws(() => createConfig(), Error, '"assertViewOpts" must be an object');766 });767 ['ignoreElements', 'captureElementFromTop', 'allowViewportOverflow'].forEach((option) => {768 it(`should set "${option}" option to default value if it is not set in config`, () => {769 const readConfig = {770 browsers: {771 b1: mkBrowser_()772 }773 };774 Config.read.returns(readConfig);775 const config = createConfig();776 assert.deepEqual(config.browsers.b1.assertViewOpts[option], defaults.assertViewOpts[option]);777 });778 it(`should overridde only "${option}" and use others from defaults`, () => {779 const readConfig = {780 browsers: {781 b1: mkBrowser_({assertViewOpts: {[option]: 100500}})782 }783 };784 Config.read.returns(readConfig);785 const config = createConfig();786 assert.deepEqual(config.browsers.b1.assertViewOpts, {...defaults.assertViewOpts, [option]: 100500});787 });788 });789 it('should set provided values and use others from defaults', () => {790 const readConfig = {791 browsers: {792 b1: mkBrowser_({assertViewOpts: {k1: 'v1', k2: 'v2'}})793 }794 };795 Config.read.returns(readConfig);796 const config = createConfig();797 assert.deepEqual(config.browsers.b1.assertViewOpts, {...defaults.assertViewOpts, k1: 'v1', k2: 'v2'});798 });799 });800 [801 'calibrate',802 'screenshotOnReject',803 'compositeImage',804 'resetCursor',805 'strictTestsOrder',806 'saveHistory',807 'waitOrientationChange'808 ].forEach((option) => {809 describe(option, () => {810 it('should throw an error if value is not a boolean', () => {811 const readConfig = _.set({}, 'browsers.b1', mkBrowser_({[option]: 'foo'}));812 Config.read.returns(readConfig);813 assert.throws(() => createConfig(), Error, `"${option}" must be a boolean`);814 });815 it('should set a default value if it is not set in config', () => {816 const readConfig = _.set({}, 'browsers.b1', mkBrowser_());817 Config.read.returns(readConfig);818 const config = createConfig();819 assert.equal(config[option], defaults[option]);820 });821 it('should override option for browser', () => {822 const readConfig = {823 [option]: false,824 browsers: {825 b1: mkBrowser_(),826 b2: mkBrowser_({[option]: true})827 }828 };829 Config.read.returns(readConfig);830 const config = createConfig();831 assert.isFalse(config.browsers.b1[option]);832 assert.isTrue(config.browsers.b2[option]);833 });834 });835 });836 describe('screenshotMode', () => {837 it('should throw an error if option is not a string', () => {838 const readConfig = {839 browsers: {840 b1: mkBrowser_({screenshotMode: {not: 'string'}})841 }842 };843 Config.read.returns(readConfig);844 assert.throws(() => createConfig(), Error, /"screenshotMode" must be a string/);845 });846 it('should throw an error if option value is not "fullpage", "viewport" or "auto"', () => {847 const readConfig = {848 browsers: {849 b1: mkBrowser_({screenshotMode: 'foo bar'})850 }851 };852 Config.read.returns(readConfig);853 assert.throws(() => createConfig(), Error, /"screenshotMode" must be "fullpage", "viewport" or "auto"/);854 });855 describe('should not throw an error if option value is', () => {856 ['fullpage', 'viewport', 'auto'].forEach((value) => {857 it(`${value}`, () => {858 const readConfig = {859 browsers: {860 b1: mkBrowser_({screenshotMode: value})861 }862 };863 Config.read.returns(readConfig);864 assert.doesNotThrow(() => createConfig());865 });866 });867 });868 it('should set a default value if it is not set in config', () => {869 const readConfig = {870 browsers: {871 b1: mkBrowser_()872 }873 };874 Config.read.returns(readConfig);875 const config = createConfig();876 assert.equal(config.screenshotMode, defaults.screenshotMode);877 });878 it('should override option for browser', () => {879 const readConfig = {880 screenshotMode: 'fullpage',881 browsers: {882 b1: mkBrowser_(),883 b2: mkBrowser_({screenshotMode: 'viewport'})884 }885 };886 Config.read.returns(readConfig);887 const config = createConfig();888 assert.equal(config.browsers.b1.screenshotMode, 'fullpage');889 assert.equal(config.browsers.b2.screenshotMode, 'viewport');890 });891 describe('on android browser', () => {892 it('should set mode to \'viewport\' by default', () => {893 const readConfig = {894 browsers: {895 b1: mkBrowser_({896 desiredCapabilities: {897 platformName: 'android'898 }899 })900 }901 };902 Config.read.returns(readConfig);903 const config = createConfig();904 assert.equal(config.browsers.b1.screenshotMode, 'viewport');905 });906 it('should preserve manually set mode', () => {907 const readConfig = {908 browsers: {909 b1: mkBrowser_({910 desiredCapabilities: {911 platformName: 'android'912 },913 screenshotMode: 'fullpage'914 })915 }916 };917 Config.read.returns(readConfig);918 const config = createConfig();919 assert.equal(config.browsers.b1.screenshotMode, 'fullpage');920 });921 });922 });923 describe('orientation', () => {924 it('should throw an error if option value is not string', () => {925 const readConfig = {926 browsers: {927 b1: mkBrowser_({orientation: {not: 'string'}})928 }929 };930 Config.read.returns(readConfig);931 assert.throws(() => createConfig(), Error, /"orientation" must be a string/);932 });933 it('should throw an error if option value is not "landscape" or "portrait"', () => {934 const readConfig = {935 browsers: {936 b1: mkBrowser_({orientation: 'foo bar'})937 }938 };939 Config.read.returns(readConfig);940 assert.throws(() => createConfig(), Error, /"orientation" must be "landscape" or "portrait"/);941 });942 describe('should not throw an error if option value is', () => {943 ['landscape', 'portrait'].forEach((value) => {944 it(`${value}`, () => {945 const readConfig = {946 browsers: {947 b1: mkBrowser_({orientation: value})948 }949 };950 Config.read.returns(readConfig);951 assert.doesNotThrow(() => createConfig());952 });953 });954 });955 it('should set a default value if it is not set in config', () => {956 const readConfig = {957 browsers: {958 b1: mkBrowser_()959 }960 };961 Config.read.returns(readConfig);962 const config = createConfig();963 assert.equal(config.orientation, defaults.orientation);964 });965 it('should override option for browser', () => {966 const readConfig = {967 orientation: 'landscape',968 browsers: {969 b1: mkBrowser_(),970 b2: mkBrowser_({orientation: 'portrait'})971 }972 };973 Config.read.returns(readConfig);974 const config = createConfig();975 assert.equal(config.browsers.b1.orientation, 'landscape');976 assert.equal(config.browsers.b2.orientation, 'portrait');977 });978 });979 ['outputDir', 'user', 'key', 'region'].forEach((option) => {980 describe(option, () => {981 it('should throw an error if value is not a null or string', () => {982 const readConfig = _.set({}, 'browsers.b1', mkBrowser_({[option]: {some: 'object'}}));983 Config.read.returns(readConfig);984 assert.throws(() => createConfig(), Error, `"${option}" must be a string`);985 });986 it('should set a default value if it is not set in config', () => {987 const readConfig = _.set({}, 'browsers.b1', mkBrowser_());988 Config.read.returns(readConfig);989 const config = createConfig();990 assert.equal(config[option], defaults[option]);991 });992 it('should override option for browser', () => {993 const readConfig = {994 [option]: 'init-string',995 browsers: {996 b1: mkBrowser_(),997 b2: mkBrowser_({[option]: 'new-string'})998 }999 };1000 Config.read.returns(readConfig);1001 const config = createConfig();1002 assert.equal(config.browsers.b1[option], 'init-string');1003 assert.equal(config.browsers.b2[option], 'new-string');1004 });1005 });1006 });1007 ['agent', 'headers'].forEach((option) => {1008 describe(option, () => {1009 it(`should throw error if "${option}" is not an object`, () => {1010 const readConfig = _.set({}, 'browsers.b1', mkBrowser_({[option]: 'string'}));1011 Config.read.returns(readConfig);1012 assert.throws(() => createConfig(), Error, `"${option}" must be an object`);1013 });1014 it('should set a default value if it is not set in config', () => {1015 const readConfig = _.set({}, 'browsers.b1', mkBrowser_());1016 Config.read.returns(readConfig);1017 const config = createConfig();1018 assert.equal(config[option], defaults[option]);1019 });1020 it('should set provided value', () => {1021 const readConfig = _.set({}, 'browsers.b1', mkBrowser_({[option]: {k1: 'v1', k2: 'v2'}}));1022 Config.read.returns(readConfig);1023 const config = createConfig();1024 assert.deepEqual(config.browsers.b1[option], {k1: 'v1', k2: 'v2'});1025 });1026 });1027 });1028 ['transformRequest', 'transformResponse'].forEach((option) => {1029 describe(option, () => {1030 it(`should throw error if ${option} is not a null or function`, () => {1031 const readConfig = _.set({}, 'browsers.b1', mkBrowser_({[option]: 'string'}));1032 Config.read.returns(readConfig);1033 assert.throws(() => createConfig(), Error, `"${option}" must be a function`);1034 });1035 it('should set a default value if it is not set in config', () => {1036 const readConfig = _.set({}, 'browsers.b1', mkBrowser_());1037 Config.read.returns(readConfig);1038 const config = createConfig();1039 assert.equal(config[option], defaults[option]);1040 });1041 it(`should override ${option} option`, () => {1042 const optionFn = () => { };1043 const newOptionFn = () => { };1044 const readConfig = {1045 [option]: optionFn,1046 browsers: {1047 b1: mkBrowser_(),1048 b2: mkBrowser_({[option]: newOptionFn})1049 }1050 };1051 Config.read.returns(readConfig);1052 const config = createConfig();1053 assert.equal(config.browsers.b1[option], optionFn);1054 assert.equal(config.browsers.b2[option], newOptionFn);1055 });1056 });1057 });1058 ['strictSSL', 'headless'].forEach((option) => {1059 describe(option, () => {1060 it(`should throw error if ${option} is not a null or boolean`, () => {1061 const readConfig = _.set({}, 'browsers.b1', mkBrowser_({[option]: 'string'}));1062 Config.read.returns(readConfig);1063 assert.throws(() => createConfig(), Error, `"${option}" must be a boolean`);1064 });1065 it('should set a default value if it is not set in config', () => {1066 const readConfig = _.set({}, 'browsers.b1', mkBrowser_());1067 Config.read.returns(readConfig);1068 const config = createConfig();1069 assert.equal(config[option], defaults[option]);1070 });1071 it(`should override ${option} option`, () => {1072 const readConfig = {1073 [option]: false,1074 browsers: {1075 b1: mkBrowser_(),1076 b2: mkBrowser_({[option]: true})1077 }1078 };1079 Config.read.returns(readConfig);1080 const config = createConfig();1081 assert.isFalse(config.browsers.b1[option]);1082 assert.isTrue(config.browsers.b2[option]);1083 });1084 });1085 });...
options.js
Source:options.js
1'use strict';2const _ = require('lodash');3const Config = require('lib/config');4const defaults = require('lib/config/defaults');5const parser = require('lib/config/options');6describe('config options', () => {7 const sandbox = sinon.sandbox.create();8 const createConfig = () => Config.create(defaults.config);9 const parse_ = (opts) => parser(_.defaults(opts, {env: {}, argv: []}));10 beforeEach(() => sandbox.stub(Config, 'read').returns({}));11 afterEach(() => sandbox.restore());12 describe('system', () => {13 describe('debug', () => {14 it('should throw error if debug is not a boolean', () => {15 const readConfig = _.set({}, 'system.debug', 'String');16 Config.read.returns(readConfig);17 assert.throws(() => createConfig(), Error, '"debug" must be a boolean');18 });19 it('should set default debug option if it does not set in config file', () => {20 const config = createConfig();21 assert.equal(config.system.debug, defaults.debug);22 });23 it('should override debug option', () => {24 const readConfig = _.set({}, 'system.debug', true);25 Config.read.returns(readConfig);26 const config = createConfig();27 assert.equal(config.system.debug, true);28 });29 });30 describe('mochaOpts', () => {31 it('should throw error if mochaOpts is not a null or object', () => {32 const readConfig = _.set({}, 'system.mochaOpts', ['Array']);33 Config.read.returns(readConfig);34 assert.throws(() => createConfig(), Error, '"mochaOpts" must be an object');35 });36 it('should set default mochaOpts option if it does not set in config file', () => {37 const config = createConfig();38 assert.deepEqual(config.system.mochaOpts, defaults.mochaOpts);39 });40 it('should override mochaOpts option', () => {41 const readConfig = _.set({}, 'system.mochaOpts.grep', /test/);42 Config.read.returns(readConfig);43 const config = createConfig();44 assert.deepEqual(config.system.mochaOpts.grep, /test/);45 });46 it('should parse mochaOpts option from environment', () => {47 const result = parse_({48 options: {system: {mochaOpts: {}}},49 env: {'hermione_system_mocha_opts': '{"some": "opts"}'}50 });51 assert.deepEqual(result.system.mochaOpts, {some: 'opts'});52 });53 it('should parse mochaOpts options from cli', () => {54 const result = parse_({55 options: {system: {mochaOpts: {}}},56 argv: ['--system-mocha-opts', '{"some": "opts"}']57 });58 assert.deepEqual(result.system.mochaOpts, {some: 'opts'});59 });60 });61 describe('ctx', () => {62 it('should be empty by default', () => {63 const config = createConfig();64 assert.deepEqual(config.system.ctx, {});65 });66 it('should override ctx option', () => {67 const readConfig = _.set({}, 'system.ctx', {some: 'ctx'});68 Config.read.returns(readConfig);69 const config = createConfig();70 assert.deepEqual(config.system.ctx, {some: 'ctx'});71 });72 });73 describe('patternsOnReject', () => {74 it('should be empty by default', () => {75 const config = createConfig();76 assert.deepEqual(config.system.patternsOnReject, []);77 });78 it('should throw error if "patternsOnReject" is not an array', () => {79 const readConfig = _.set({}, 'system.patternsOnReject', {});80 Config.read.returns(readConfig);81 assert.throws(() => createConfig(), Error, '"patternsOnReject" must be an array');82 });83 it('should override "patternsOnReject" option', () => {84 const readConfig = _.set({}, 'system.patternsOnReject', ['some-pattern']);85 Config.read.returns(readConfig);86 const config = createConfig();87 assert.deepEqual(config.system.patternsOnReject, ['some-pattern']);88 });89 it('should parse "patternsOnReject" option from environment', () => {90 const result = parse_({91 options: {system: {patternsOnReject: []}},92 env: {'hermione_system_patterns_on_reject': '["some-pattern"]'}93 });94 assert.deepEqual(result.system.patternsOnReject, ['some-pattern']);95 });96 it('should parse "patternsOnReject" options from cli', () => {97 const result = parse_({98 options: {system: {patternsOnReject: []}},99 argv: ['--system-patterns-on-reject', '["some-pattern"]']100 });101 assert.deepEqual(result.system.patternsOnReject, ['some-pattern']);102 });103 });104 describe('workers', () => {105 it('should throw in case of not positive integer', () => {106 [0, -1, 'string', {foo: 'bar'}].forEach((workers) => {107 Config.read.returns({system: {workers}});108 assert.throws(() => createConfig(), '"workers" must be a positive integer');109 });110 });111 it('should equal one by default', () => {112 const config = createConfig();113 assert.equal(config.system.workers, 1);114 });115 it('should be overridden from a config', () => {116 Config.read.returns({system: {workers: 100500}});117 const config = createConfig();118 assert.equal(config.system.workers, 100500);119 });120 });121 describe('diffColor', () => {122 it('should be #ff00ff by default', () => {123 const config = createConfig();124 assert.deepEqual(config.system.diffColor, '#ff00ff');125 });126 it('should override diffColor option', () => {127 const readConfig = _.set({}, 'system.diffColor', '#f5f5f5');128 Config.read.returns(readConfig);129 const config = createConfig();130 assert.equal(config.system.diffColor, '#f5f5f5');131 });132 it('should throw an error if option is not a string', () => {133 const readConfig = _.set({}, 'system.diffColor', 1);134 Config.read.returns(readConfig);135 assert.throws(() => createConfig(), Error, '"diffColor" must be a string');136 });137 it('should throw an error if option is not a hexadecimal value', () => {138 const readConfig = _.set({}, 'system.diffColor', '#gggggg');139 Config.read.returns(readConfig);140 assert.throws(() => createConfig(), Error, /"diffColor" must be a hexadecimal/);141 });142 });143 describe('tempDir', () => {144 it('should set default option if it does not set in config file', () => {145 const config = createConfig();146 assert.deepEqual(config.system.tempDir, defaults.tempDir);147 });148 it('should override tempDir option', () => {149 const readConfig = _.set({}, 'system.tempDir', '/def/path');150 Config.read.returns(readConfig);151 const config = createConfig();152 assert.equal(config.system.tempDir, '/def/path');153 });154 it('should throw an error if option is not a string', () => {155 const readConfig = _.set({}, 'system.tempDir', 1);156 Config.read.returns(readConfig);157 assert.throws(() => createConfig(), Error, '"tempDir" must be a string');158 });159 });160 describe('parallelLimit', () => {161 it('should throw error in case of not positive integer', () => {162 [0, -1, '10', 10.15, {foo: 'bar'}].forEach((parallelLimit) => {163 Config.read.returns({system: {parallelLimit}});164 assert.throws(() => createConfig(), '"parallelLimit" must be a positive integer');165 });166 });167 it('should be able to pass value is Infinity', () => {168 Config.read.returns({system: {parallelLimit: Infinity}});169 const config = createConfig();170 assert.equal(config.system.parallelLimit, Infinity);171 });172 it('should set default parallelLimit option if it does not set in config file', () => {173 const config = createConfig();174 assert.equal(config.system.parallelLimit, defaults.parallelLimit);175 });176 it('should be overridden from a config', () => {177 Config.read.returns({system: {parallelLimit: 5}});178 const config = createConfig();179 assert.equal(config.system.parallelLimit, 5);180 });181 it('should parse option from environment', () => {182 const result = parse_({183 options: {system: {mochaOpts: {}}},184 env: {'hermione_system_parallel_limit': 10}185 });186 assert.equal(result.system.parallelLimit, 10);187 });188 it('should parse option from cli', () => {189 const result = parse_({190 options: {system: {parallelLimit: 1}},191 argv: ['--system-parallel-limit', 15]192 });193 assert.equal(result.system.parallelLimit, 15);194 });195 });196 describe('fileExtensions', () => {197 it('should set default extension', () => {198 const config = createConfig();199 assert.deepEqual(config.system.fileExtensions, defaults.fileExtensions);200 });201 describe('should throw error if "fileExtensions" option', () => {202 it('is not an array', () => {203 const value = {};204 const readConfig = _.set({}, 'system.fileExtensions', value);205 Config.read.returns(readConfig);206 assert.throws(() => createConfig(), Error, `"fileExtensions" must be an array of strings but got ${JSON.stringify(value)}`);207 });208 it('is not an array of strings', () => {209 const value = ['string', 100500];210 const readConfig = _.set({}, 'system.fileExtensions', value);211 Config.read.returns(readConfig);212 assert.throws(() => createConfig(), Error, `fileExtensions" must be an array of strings but got ${JSON.stringify(value)}`);213 });214 it('has strings that do not start with dot symbol', () => {215 const value = ['.foo', 'bar'];216 const readConfig = _.set({}, 'system.fileExtensions', value);217 Config.read.returns(readConfig);218 assert.throws(() => createConfig(), Error, `Each extension from "fileExtensions" must start with dot symbol but got ${JSON.stringify(value)}`);219 });220 });221 it('should set "fileExtensions" option', () => {222 const fileExtensions = ['.foo', '.bar'];223 const readConfig = _.set({}, 'system.fileExtensions', fileExtensions);224 Config.read.returns(readConfig);225 const config = createConfig();226 assert.deepEqual(config.system.fileExtensions, fileExtensions);227 });228 });229 });230 describe('prepareEnvironment', () => {231 it('should throw error if prepareEnvironment is not a null or function', () => {232 const readConfig = {prepareEnvironment: 'String'};233 Config.read.returns(readConfig);234 assert.throws(() => createConfig(), Error, '"prepareEnvironment" must be a function');235 });236 it('should set default prepareEnvironment option if it does not set in config file', () => {237 const config = createConfig();238 assert.equal(config.prepareEnvironment, defaults.prepareEnvironment);239 });240 it('should override prepareEnvironment option', () => {241 const newFunc = () => {};242 const readConfig = {prepareEnvironment: newFunc};243 Config.read.returns(readConfig);244 const config = createConfig();245 assert.deepEqual(config.prepareEnvironment, newFunc);246 });247 });248 describe('plugins', () => {249 it('should parse boolean value from environment', () => {250 const result = parse_({251 options: {plugins: {foo: {}}},252 env: {'hermione_plugins_foo': 'true'}253 });254 assert.strictEqual(result.plugins.foo, true);255 });256 it('should parse object value from environment', () => {257 const result = parse_({258 options: {plugins: {foo: {}}},259 env: {'hermione_plugins_foo': '{"opt": 1}'}260 });261 assert.deepEqual(result.plugins.foo, {opt: 1});262 });263 it('should throw error on invalid values from environment', () => {264 assert.throws(265 () => parse_({266 options: {plugins: {foo: {}}},267 env: {'hermione_plugins_foo': '{key: 1}'}268 }),269 'a value must be a primitive type'270 );271 });272 it('should parse boolean value from cli', () => {273 const result = parse_({274 options: {plugins: {foo: {}}},275 argv: ['--plugins-foo', 'true']276 });277 assert.strictEqual(result.plugins.foo, true);278 });279 it('should parse object value from cli', () => {280 const result = parse_({281 options: {plugins: {foo: {}}},282 argv: ['--plugins-foo', '{"opt": 1}']283 });284 assert.deepEqual(result.plugins.foo, {opt: 1});285 });286 it('should throw error on invalid values from cli', () => {287 assert.throws(288 () => parse_({289 options: {plugins: {foo: {}}},290 argv: ['--plugins-foo', '{key: 1}']291 }),292 'a value must be a primitive type'293 );294 });295 });296 describe('shouldRetry', () => {297 it('should throw error if shouldRetry is not a function', () => {298 const readConfig = _.set({}, 'shouldRetry', 'shouldRetry');299 Config.read.returns(readConfig);300 assert.throws(() => createConfig(), Error, '"shouldRetry" must be a function');301 });302 it('should set default shouldRetry option if it does not set in config file', () => {303 const config = createConfig();304 assert.equal(config.shouldRetry, null);305 });306 it('should override shouldRetry option', () => {307 const shouldRetry = () => {};308 const readConfig = _.set({}, 'shouldRetry', shouldRetry);309 Config.read.returns(readConfig);310 const config = createConfig();311 assert.equal(config.shouldRetry, shouldRetry);312 });313 });...
executeService.js
Source:executeService.js
1const { exec } = require('child_process');2const { offDeviceFromSmartThings } = require('./smartthings');3const { logger } = require('./logger');4const { saveConfig } = require('./env');5const lastMessage = {6};7const lockRequest = {8 locked: false,9 data: 0,10 weight: -1,11};12setTimeout(() => {13 if (lockRequest.locked) {14 if ((Date.now() - lockRequest.data) > 1000 * 60 * 5) {15 console.log('force unlocked');16 lockRequest.locked = false;17 lockRequest.data = 0;18 lockRequest.weight = -1;19 }20 }21}, 3000);22const messageResponse = {23 batteryWarning: (messageId) => (messageId ? Number(messageId) : null),24 battery: (messageId) => (messageId && messageId > 0 ? messageId : null),25 theftStatus: (messageId) => (messageId ? Number(messageId) : null),26 preaccont: (messageId) => (messageId ? Number(messageId) : null),27 errACinfo: (messageId) => messageId,28 errCHGinfo: (messageId) => messageId,29 errTimerinfo: (messageId) => messageId,30};31async function smartthingsOffDevice(deviceId, readConfig) {32 const { smartthings } = readConfig;33 if (smartthings.useSmartthings) {34 const status = await offDeviceFromSmartThings(35 smartthings.shard,36 smartthings.appId,37 smartthings.appSecret,38 deviceId,39 );40 return status;41 }42 return null;43}44const actionToCommands = {45 forceUpdate: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} update`,46 hvac: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} hvac| grep operating`,47 doors: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} lockstatus| grep Doors`,48 battery: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} battery | grep "Battery level"`,49 charging: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} chargestatus | grep "Charge status"`,50 airconOn: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} aircon on`,51 airconOff: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} aircon off`,52 headlightsOn: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} headlights on`,53 headlightsOff: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} headlights off`,54 parkinglightsOn: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} parkinglights on`,55 parkinglightsOff: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} parkinglights off`,56 cooling10Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode cool 10`,57 cooling20Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode cool 20`,58 cooling30Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode cool 30`,59 windscreen10Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode windscreen 10`,60 windscreen20Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode windscreen 20`,61 windscreen30Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode windscreen 30`,62 heating10Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode heat 10`,63 heating20Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode heat 20`,64 heating30Mins: (readConfig, device) => `phevctl ${device.modelYear && device.modelYear !== 'any' ? `--car-model=${device.modelYear}` : ''} ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} acmode heat 30`,65 batteryWarning: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} warning| grep "Warning message"`,66 errACinfo: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} airconerror| grep "air conditioning"`,67 errCHGinfo: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} chargeerror| grep charge`,68 errTimerinfo: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} aircontimererror| grep "air conditioning timer"`,69 theftStatus: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} theftstatus| grep "theft alarm"`,70 preaccont: (readConfig) => `phevctl ${readConfig.macAddress ? `-m "${readConfig.macAddress}"` : ''} preaccont| grep "Pre air conditioning control"`,71 evseSlow: () => 'slowCharge.sh',72 evseFastCharge: () => 'fastCharge.sh',73 evseDisableCharge: () => 'disableCharge.sh',74 reboot: () => 'reboot',75 halt: () => 'halt',76 upgrade: () => 'nohup npm i smartthings-phevctl -g >/dev/null 2>1 &',77 shutdown2H: (readConfig) => {78 // eslint-disable-next-line no-param-reassign79 readConfig.upsMaxTimeHours = '2';80 saveConfig(readConfig);81 return null;82 },83 shutdown5H: (readConfig) => {84 // eslint-disable-next-line no-param-reassign85 readConfig.upsMaxTimeHours = '5';86 saveConfig(readConfig);87 return null;88 },89 shutdown8H: (readConfig) => {90 // eslint-disable-next-line no-param-reassign91 readConfig.upsMaxTimeHours = '8';92 saveConfig(readConfig);93 return null;94 },95 shutdown1D: (readConfig) => {96 // eslint-disable-next-line no-param-reassign97 readConfig.upsMaxTimeHours = '24';98 saveConfig(readConfig);99 return null;100 },101 shutdown2D: (readConfig) => {102 // eslint-disable-next-line no-param-reassign103 readConfig.upsMaxTimeHours = '48';104 saveConfig(readConfig);105 return null;106 },107};108const transformResponse = {109 battery: (response, config) => {110 logger.info(`battery response = ${response}`);111 let resp = {};112 if (response) {113 try {114 resp = JSON.parse(response);115 } catch (e) {116 logger.warn(e);117 }118 return { value: (resp['Battery level'] * (config.batteryFactory || 1.0)).toFixed(0), value2: resp.heater };119 }120 return null;121 },122 charging: (response) => response.replace(/[^0-9]/g, ''),123 batteryWarning: (response) => response.replace(/[^0-9]/g, ''),124 theftStatus: (response) => response.replace(/[^0-9]/g, ''),125 errACinfo: (response) => response.includes('air conditioning error'),126 preaccont: (response) => response.replace(/[^0-9]/g, ''),127 errCHGinfo: (response) => response.includes('charge error'),128 errTimerinfo: (response) => response.includes('air conditioning timer error'),129 doors: (response) => {130 logger.info(`response "${response}"`);131 if (response.includes('Doors are Locked')) {132 return 1;133 } if (response === 'Doors are UnLocked \n') {134 return 0;135 }136 return -1;137 },138 hvac: (response) => {139 logger.info(`hvac response = ${response}`);140 let resp = {};141 if (response) {142 try {143 resp = JSON.parse(response);144 } catch (e) {145 logger.warn(e);146 }147 }148 return { value: resp.operating, value2: resp.mode };149 },150};151function sleep(ms) {152 return new Promise((resolve) => {153 setTimeout(resolve, ms);154 });155}156function execute0(device, readConfig) {157 return new Promise((resolve) => {158 const command = actionToCommands[device.actionId](readConfig, device);159 if (!command) {160 resolve({ code: 0, output: null });161 return;162 }163 logger.info(`run command ${command}`);164 let scriptOutput = '';165 const child = exec(command);166 let answered = false;167 child.stdout.on('data', (data) => {168 logger.info(`stdout: ${data}`);169 scriptOutput += data.toString();170 });171 child.stderr.on('data', (data) => {172 logger.error(`stderr: ${data}`);173 });174 child.on('close', (code) => {175 logger.info(`closing code: ${code}`);176 const output = transformResponse[device.actionId];177 answered = true;178 resolve({ code, output: (output ? output(scriptOutput, readConfig) : null) });179 });180 // Kill after "x" milliseconds181 setTimeout(() => {182 child.kill();183 if (!answered) {184 logger.info(`${device.id} force killed`);185 const output = transformResponse[device.actionId];186 resolve({ code: -1, output: (output ? output(scriptOutput, readConfig) : null) });187 }188 }, readConfig.smartthings.timeout);189 });190}191function killAll() {192 return new Promise((resolve) => {193 logger.info('run command killall phevctl');194 const child = exec('killall phevctl');195 child.on('close', (code) => {196 resolve(code);197 });198 });199}200function restartApplication() {201 return new Promise((resolve) => {202 logger.info('run command pm2 restart smartthings-phevctl');203 const child = exec('pm2 restart smartthings-phevctl');204 child.stdout.on('data', (data) => {205 logger.info(`stdout: ${data}`);206 });207 child.stderr.on('data', (data) => {208 logger.error(`stderr: ${data}`);209 });210 child.on('close', (code) => {211 logger.info(`closing code: ${code}`);212 resolve(code);213 });214 // Kill after "x" milliseconds215 setTimeout(() => {216 child.kill();217 logger.info('restart force killed');218 resolve(-1);219 }, 10000);220 });221}222async function execute(device, readConfig) {223 if (lockRequest.weight < 3) {224 lockRequest.weight = 3;225 }226 while (lockRequest.weight <= 3 && lockRequest.locked) {227 await sleep(2000);228 }229 lockRequest.weight = 3;230 lockRequest.locked = true;231 lockRequest.data = Date.now();232 try {233 try {234 if (!device.direct) {235 await smartthingsOffDevice(device.id, readConfig);236 }237 } catch (e) {238 logger.error('Smartthing off device error', e);239 }240 await killAll();241 let res = await execute0(device, readConfig);242 if (res.code !== 0) {243 await sleep(6000);244 await killAll();245 res = await execute0(device, readConfig);246 }247 if (res.code === 0) {248 return res.output;249 }250 } catch (e) {251 logger.error(e.message, e);252 } finally {253 lockRequest.locked = false;254 lockRequest.weight = -1;255 }256 return null;257}258async function forceUpdate(readConfig) {259 if (lockRequest.weight < 2) {260 lockRequest.weight = 2;261 }262 while (lockRequest.weight <= 2 && lockRequest.locked) {263 await sleep(2000);264 }265 lockRequest.weight = 2;266 lockRequest.locked = true;267 lockRequest.data = Date.now();268 try {269 const device = {270 id: 'forceUpdate',271 actionId: 'forceUpdate',272 };273 await killAll();274 let res = await execute0(device, readConfig);275 if (res.code !== 0) {276 await sleep(6000);277 await killAll();278 res = await execute0(device, readConfig);279 }280 if (res.code === 0) {281 return res.output;282 }283 } catch (e) {284 logger.error(e.message, e);285 } finally {286 lockRequest.locked = false;287 lockRequest.weight = -1;288 }289 return null;290}291async function getNotificationByActionId(actionId, readConfig) {292 if (lockRequest.weight < 1) {293 lockRequest.weight = 1;294 }295 while (lockRequest.weight <= 1 && lockRequest.locked) {296 await sleep(2000);297 }298 lockRequest.weight = 1;299 lockRequest.locked = true;300 lockRequest.data = Date.now();301 try {302 const device = {303 id: actionId,304 actionId,305 };306 await killAll();307 let res = await execute0(device, readConfig);308 if (res.code !== 0) {309 await sleep(3000);310 await killAll();311 res = await execute0(device, readConfig);312 }313 if (res.code === 0) {314 const messageId = res.output;315 if (messageId === lastMessage[actionId]) {316 return null;317 }318 const value = messageId.value2 === 0 || messageId.value2319 ? messageId.value2320 : messageId;321 lastMessage[actionId] = value;322 return messageResponse[actionId](value);323 }324 } catch (e) {325 logger.error(e.message, e);326 } finally {327 lockRequest.locked = false;328 lockRequest.weight = -1;329 }330 return null;331}332async function execute1(deviceId, readConfig) {333 const device = readConfig.smartthings.devices.find((d) => d.id === deviceId);334 if (device) {335 return execute(device, readConfig);336 }337 return null;338}339async function execute2(deviceId, action2, readConfig) {340 const device = readConfig.smartthings.devices.find((d) => d.id === deviceId);341 if (device) {342 const value = await execute(device, readConfig);343 const device2 = JSON.parse(JSON.stringify(device));344 device2.actionId = action2;345 const value2 = await execute(device2, readConfig);346 return { value, value2 };347 }348 return null;349}350module.exports.restartApplication = restartApplication;351module.exports.executeAction = execute1;352module.exports.executeAction2 = execute2;353module.exports.executeActionDirect = execute;354module.exports.forceUpdate = forceUpdate;355module.exports.killAll = killAll;356module.exports.sleep = sleep;...
fontMeasurements.js
Source:fontMeasurements.js
1/*---------------------------------------------------------------------------------------------2 * Copyright (c) Microsoft Corporation. All rights reserved.3 * Licensed under the MIT License. See License.txt in the project root for license information.4 *--------------------------------------------------------------------------------------------*/5import * as browser from '../../../base/browser/browser.js';6import { Emitter } from '../../../base/common/event.js';7import { Disposable } from '../../../base/common/lifecycle.js';8import { CharWidthRequest, readCharWidths } from './charWidthReader.js';9import { EditorFontLigatures } from '../../common/config/editorOptions.js';10import { FontInfo } from '../../common/config/fontInfo.js';11class FontMeasurementsImpl extends Disposable {12 constructor() {13 super();14 this._onDidChange = this._register(new Emitter());15 this.onDidChange = this._onDidChange.event;16 this._cache = new FontMeasurementsCache();17 this._evictUntrustedReadingsTimeout = -1;18 }19 dispose() {20 if (this._evictUntrustedReadingsTimeout !== -1) {21 window.clearTimeout(this._evictUntrustedReadingsTimeout);22 this._evictUntrustedReadingsTimeout = -1;23 }24 super.dispose();25 }26 /**27 * Clear all cached font information and trigger a change event.28 */29 clearAllFontInfos() {30 this._cache = new FontMeasurementsCache();31 this._onDidChange.fire();32 }33 _writeToCache(item, value) {34 this._cache.put(item, value);35 if (!value.isTrusted && this._evictUntrustedReadingsTimeout === -1) {36 // Try reading again after some time37 this._evictUntrustedReadingsTimeout = window.setTimeout(() => {38 this._evictUntrustedReadingsTimeout = -1;39 this._evictUntrustedReadings();40 }, 5000);41 }42 }43 _evictUntrustedReadings() {44 const values = this._cache.getValues();45 let somethingRemoved = false;46 for (const item of values) {47 if (!item.isTrusted) {48 somethingRemoved = true;49 this._cache.remove(item);50 }51 }52 if (somethingRemoved) {53 this._onDidChange.fire();54 }55 }56 /**57 * Read font information.58 */59 readFontInfo(bareFontInfo) {60 if (!this._cache.has(bareFontInfo)) {61 let readConfig = this._actualReadFontInfo(bareFontInfo);62 if (readConfig.typicalHalfwidthCharacterWidth <= 2 || readConfig.typicalFullwidthCharacterWidth <= 2 || readConfig.spaceWidth <= 2 || readConfig.maxDigitWidth <= 2) {63 // Hey, it's Bug 14341 ... we couldn't read64 readConfig = new FontInfo({65 pixelRatio: browser.PixelRatio.value,66 fontFamily: readConfig.fontFamily,67 fontWeight: readConfig.fontWeight,68 fontSize: readConfig.fontSize,69 fontFeatureSettings: readConfig.fontFeatureSettings,70 lineHeight: readConfig.lineHeight,71 letterSpacing: readConfig.letterSpacing,72 isMonospace: readConfig.isMonospace,73 typicalHalfwidthCharacterWidth: Math.max(readConfig.typicalHalfwidthCharacterWidth, 5),74 typicalFullwidthCharacterWidth: Math.max(readConfig.typicalFullwidthCharacterWidth, 5),75 canUseHalfwidthRightwardsArrow: readConfig.canUseHalfwidthRightwardsArrow,76 spaceWidth: Math.max(readConfig.spaceWidth, 5),77 middotWidth: Math.max(readConfig.middotWidth, 5),78 wsmiddotWidth: Math.max(readConfig.wsmiddotWidth, 5),79 maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5),80 }, false);81 }82 this._writeToCache(bareFontInfo, readConfig);83 }84 return this._cache.get(bareFontInfo);85 }86 _createRequest(chr, type, all, monospace) {87 const result = new CharWidthRequest(chr, type);88 all.push(result);89 if (monospace) {90 monospace.push(result);91 }92 return result;93 }94 _actualReadFontInfo(bareFontInfo) {95 const all = [];96 const monospace = [];97 const typicalHalfwidthCharacter = this._createRequest('n', 0 /* Regular */, all, monospace);98 const typicalFullwidthCharacter = this._createRequest('\uff4d', 0 /* Regular */, all, null);99 const space = this._createRequest(' ', 0 /* Regular */, all, monospace);100 const digit0 = this._createRequest('0', 0 /* Regular */, all, monospace);101 const digit1 = this._createRequest('1', 0 /* Regular */, all, monospace);102 const digit2 = this._createRequest('2', 0 /* Regular */, all, monospace);103 const digit3 = this._createRequest('3', 0 /* Regular */, all, monospace);104 const digit4 = this._createRequest('4', 0 /* Regular */, all, monospace);105 const digit5 = this._createRequest('5', 0 /* Regular */, all, monospace);106 const digit6 = this._createRequest('6', 0 /* Regular */, all, monospace);107 const digit7 = this._createRequest('7', 0 /* Regular */, all, monospace);108 const digit8 = this._createRequest('8', 0 /* Regular */, all, monospace);109 const digit9 = this._createRequest('9', 0 /* Regular */, all, monospace);110 // monospace test: used for whitespace rendering111 const rightwardsArrow = this._createRequest('â', 0 /* Regular */, all, monospace);112 const halfwidthRightwardsArrow = this._createRequest('ï¿«', 0 /* Regular */, all, null);113 // U+00B7 - MIDDLE DOT114 const middot = this._createRequest('·', 0 /* Regular */, all, monospace);115 // U+2E31 - WORD SEPARATOR MIDDLE DOT116 const wsmiddotWidth = this._createRequest(String.fromCharCode(0x2E31), 0 /* Regular */, all, null);117 // monospace test: some characters118 const monospaceTestChars = '|/-_ilm%';119 for (let i = 0, len = monospaceTestChars.length; i < len; i++) {120 this._createRequest(monospaceTestChars.charAt(i), 0 /* Regular */, all, monospace);121 this._createRequest(monospaceTestChars.charAt(i), 1 /* Italic */, all, monospace);122 this._createRequest(monospaceTestChars.charAt(i), 2 /* Bold */, all, monospace);123 }124 readCharWidths(bareFontInfo, all);125 const maxDigitWidth = Math.max(digit0.width, digit1.width, digit2.width, digit3.width, digit4.width, digit5.width, digit6.width, digit7.width, digit8.width, digit9.width);126 let isMonospace = (bareFontInfo.fontFeatureSettings === EditorFontLigatures.OFF);127 const referenceWidth = monospace[0].width;128 for (let i = 1, len = monospace.length; isMonospace && i < len; i++) {129 const diff = referenceWidth - monospace[i].width;130 if (diff < -0.001 || diff > 0.001) {131 isMonospace = false;132 break;133 }134 }135 let canUseHalfwidthRightwardsArrow = true;136 if (isMonospace && halfwidthRightwardsArrow.width !== referenceWidth) {137 // using a halfwidth rightwards arrow would break monospace...138 canUseHalfwidthRightwardsArrow = false;139 }140 if (halfwidthRightwardsArrow.width > rightwardsArrow.width) {141 // using a halfwidth rightwards arrow would paint a larger arrow than a regular rightwards arrow142 canUseHalfwidthRightwardsArrow = false;143 }144 return new FontInfo({145 pixelRatio: browser.PixelRatio.value,146 fontFamily: bareFontInfo.fontFamily,147 fontWeight: bareFontInfo.fontWeight,148 fontSize: bareFontInfo.fontSize,149 fontFeatureSettings: bareFontInfo.fontFeatureSettings,150 lineHeight: bareFontInfo.lineHeight,151 letterSpacing: bareFontInfo.letterSpacing,152 isMonospace: isMonospace,153 typicalHalfwidthCharacterWidth: typicalHalfwidthCharacter.width,154 typicalFullwidthCharacterWidth: typicalFullwidthCharacter.width,155 canUseHalfwidthRightwardsArrow: canUseHalfwidthRightwardsArrow,156 spaceWidth: space.width,157 middotWidth: middot.width,158 wsmiddotWidth: wsmiddotWidth.width,159 maxDigitWidth: maxDigitWidth160 }, true);161 }162}163class FontMeasurementsCache {164 constructor() {165 this._keys = Object.create(null);166 this._values = Object.create(null);167 }168 has(item) {169 const itemId = item.getId();170 return !!this._values[itemId];171 }172 get(item) {173 const itemId = item.getId();174 return this._values[itemId];175 }176 put(item, value) {177 const itemId = item.getId();178 this._keys[itemId] = item;179 this._values[itemId] = value;180 }181 remove(item) {182 const itemId = item.getId();183 delete this._keys[itemId];184 delete this._values[itemId];185 }186 getValues() {187 return Object.keys(this._keys).map(id => this._values[id]);188 }189}...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!