UNPKG

appium-doctor

Version:

Test environment for fitness to run Appium

134 lines (93 loc) 13.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.OptionalOpencv4nodejsCommandCheck = exports.OptionalMjpegConsumerCommandCheck = exports.OptionalFfmpegCommandCheck = exports.NodeVersionCheck = exports.NodeBinaryCheck = void 0; require("source-map-support/register"); var _utils = require("./utils"); var _teen_process = require("teen_process"); var _doctor = require("./doctor"); var _nodeDetector = _interopRequireDefault(require("./node-detector")); var _appiumSupport = require("appium-support"); var _os = require("os"); require("@colors/colors"); let checks = []; class NodeBinaryCheck extends _doctor.DoctorCheck { async diagnose() { let nodePath = await _nodeDetector.default.detect(); return nodePath ? (0, _utils.ok)(`The Node.js binary was found at: ${nodePath}`) : (0, _utils.nok)('The Node.js binary was NOT found!'); } fix() { return `Manually setup ${'Node.js'.bold}.`; } } exports.NodeBinaryCheck = NodeBinaryCheck; checks.push(new NodeBinaryCheck()); const REQUIRED_NODE_VERSION = '10.0.0'; class NodeVersionCheck extends _doctor.DoctorCheck { async diagnose() { let nodePath = await _nodeDetector.default.detect(); if (!nodePath) { return (0, _utils.nok)('Node is not installed, so no version to check!'); } let { stdout } = await (0, _teen_process.exec)(nodePath, ['--version']); let versionString = stdout.replace('v', '').trim(); try { return _appiumSupport.util.compareVersions(REQUIRED_NODE_VERSION, '<=', versionString) ? (0, _utils.ok)(`Node version is ${versionString}`) : (0, _utils.nok)(`Node version should be at least ${REQUIRED_NODE_VERSION}!`); } catch { return (0, _utils.nok)(`Unable to find node version (version = '${versionString}')`); } } fix() { return `Manually upgrade ${'Node.js'.bold}.`; } } exports.NodeVersionCheck = NodeVersionCheck; checks.push(new NodeVersionCheck()); class OptionalOpencv4nodejsCommandCheck extends _doctor.DoctorCheck { async diagnose() { const packageName = 'opencv4nodejs'; const packageInfo = await (0, _utils.getNpmPackageInfo)(packageName); if (packageInfo) { return (0, _utils.okOptional)(`${packageName} is installed at: ${packageInfo.path}. Installed version is: ${packageInfo.version}`); } return (0, _utils.nokOptional)(`${packageName} cannot be found.`); } async fix() { return `Why ${'opencv4nodejs'.bold} is needed and how to install it: http://appium.io/docs/en/writing-running-appium/image-comparison/`; } } exports.OptionalOpencv4nodejsCommandCheck = OptionalOpencv4nodejsCommandCheck; checks.push(new OptionalOpencv4nodejsCommandCheck()); class OptionalFfmpegCommandCheck extends _doctor.DoctorCheck { async diagnose() { const ffmpegPath = await (0, _utils.resolveExecutablePath)('ffmpeg'); return ffmpegPath ? (0, _utils.okOptional)(`ffmpeg is installed at: ${ffmpegPath}. ${(await (0, _teen_process.exec)('ffmpeg', ['-version'])).stdout.split(_os.EOL)[0]}`) : (0, _utils.nokOptional)('ffmpeg cannot be found'); } async fix() { return `${'ffmpeg'.bold} is needed to record screen features. Please read https://www.ffmpeg.org/ to install it`; } } exports.OptionalFfmpegCommandCheck = OptionalFfmpegCommandCheck; checks.push(new OptionalFfmpegCommandCheck()); class OptionalMjpegConsumerCommandCheck extends _doctor.DoctorCheck { async diagnose() { const packageName = 'mjpeg-consumer'; const packageInfo = await (0, _utils.getNpmPackageInfo)(packageName); if (packageInfo) { return (0, _utils.okOptional)(`${packageName} is installed at: ${packageInfo.path}. Installed version is: ${packageInfo.version}`); } return (0, _utils.nokOptional)(`${packageName} cannot be found.`); } async fix() { return `${'mjpeg-consumer'.bold} module is required to use MJPEG-over-HTTP features. Please install it with 'npm i -g mjpeg-consumer'.`; } } exports.OptionalMjpegConsumerCommandCheck = OptionalMjpegConsumerCommandCheck; checks.push(new OptionalMjpegConsumerCommandCheck()); var _default = checks; exports.default = _default;require('source-map-support').install(); //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliL2dlbmVyYWwuanMiLCJuYW1lcyI6WyJjaGVja3MiLCJOb2RlQmluYXJ5Q2hlY2siLCJEb2N0b3JDaGVjayIsImRpYWdub3NlIiwibm9kZVBhdGgiLCJOb2RlRGV0ZWN0b3IiLCJkZXRlY3QiLCJvayIsIm5vayIsImZpeCIsImJvbGQiLCJwdXNoIiwiUkVRVUlSRURfTk9ERV9WRVJTSU9OIiwiTm9kZVZlcnNpb25DaGVjayIsInN0ZG91dCIsImV4ZWMiLCJ2ZXJzaW9uU3RyaW5nIiwicmVwbGFjZSIsInRyaW0iLCJ1dGlsIiwiY29tcGFyZVZlcnNpb25zIiwiT3B0aW9uYWxPcGVuY3Y0bm9kZWpzQ29tbWFuZENoZWNrIiwicGFja2FnZU5hbWUiLCJwYWNrYWdlSW5mbyIsImdldE5wbVBhY2thZ2VJbmZvIiwib2tPcHRpb25hbCIsInBhdGgiLCJ2ZXJzaW9uIiwibm9rT3B0aW9uYWwiLCJPcHRpb25hbEZmbXBlZ0NvbW1hbmRDaGVjayIsImZmbXBlZ1BhdGgiLCJyZXNvbHZlRXhlY3V0YWJsZVBhdGgiLCJzcGxpdCIsIkVPTCIsIk9wdGlvbmFsTWpwZWdDb25zdW1lckNvbW1hbmRDaGVjayJdLCJzb3VyY2VSb290IjoiLi4vLi4iLCJzb3VyY2VzIjpbImxpYi9nZW5lcmFsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG9rLCBub2ssIG9rT3B0aW9uYWwsIG5va09wdGlvbmFsLCByZXNvbHZlRXhlY3V0YWJsZVBhdGgsIGdldE5wbVBhY2thZ2VJbmZvIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCB7IERvY3RvckNoZWNrIH0gZnJvbSAnLi9kb2N0b3InO1xuaW1wb3J0IE5vZGVEZXRlY3RvciBmcm9tICcuL25vZGUtZGV0ZWN0b3InO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCB7IEVPTCB9IGZyb20gJ29zJztcbmltcG9ydCAnQGNvbG9ycy9jb2xvcnMnO1xuXG5sZXQgY2hlY2tzID0gW107XG5cbi8vIE5vZGUgQmluYXJ5XG5jbGFzcyBOb2RlQmluYXJ5Q2hlY2sgZXh0ZW5kcyBEb2N0b3JDaGVjayB7XG4gIGFzeW5jIGRpYWdub3NlICgpIHtcbiAgICBsZXQgbm9kZVBhdGggPSBhd2FpdCBOb2RlRGV0ZWN0b3IuZGV0ZWN0KCk7XG4gICAgcmV0dXJuIG5vZGVQYXRoID8gb2soYFRoZSBOb2RlLmpzIGJpbmFyeSB3YXMgZm91bmQgYXQ6ICR7bm9kZVBhdGh9YCkgOlxuICAgICAgbm9rKCdUaGUgTm9kZS5qcyBiaW5hcnkgd2FzIE5PVCBmb3VuZCEnKTtcbiAgfVxuXG4gIGZpeCAoKSB7XG4gICAgcmV0dXJuIGBNYW51YWxseSBzZXR1cCAkeydOb2RlLmpzJy5ib2xkfS5gO1xuICB9XG59XG5jaGVja3MucHVzaChuZXcgTm9kZUJpbmFyeUNoZWNrKCkpO1xuXG5jb25zdCBSRVFVSVJFRF9OT0RFX1ZFUlNJT04gPSAnMTAuMC4wJztcblxuLy8gTm9kZSB2ZXJzaW9uXG5jbGFzcyBOb2RlVmVyc2lvbkNoZWNrIGV4dGVuZHMgRG9jdG9yQ2hlY2sge1xuICBhc3luYyBkaWFnbm9zZSAoKSB7XG4gICAgbGV0IG5vZGVQYXRoID0gYXdhaXQgTm9kZURldGVjdG9yLmRldGVjdCgpO1xuICAgIGlmICghbm9kZVBhdGgpIHtcbiAgICAgIHJldHVybiBub2soJ05vZGUgaXMgbm90IGluc3RhbGxlZCwgc28gbm8gdmVyc2lvbiB0byBjaGVjayEnKTtcbiAgICB9XG4gICAgbGV0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYyhub2RlUGF0aCwgWyctLXZlcnNpb24nXSk7XG4gICAgbGV0IHZlcnNpb25TdHJpbmcgPSBzdGRvdXQucmVwbGFjZSgndicsICcnKS50cmltKCk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB1dGlsLmNvbXBhcmVWZXJzaW9ucyhSRVFVSVJFRF9OT0RFX1ZFUlNJT04sICc8PScsIHZlcnNpb25TdHJpbmcpXG4gICAgICAgID8gb2soYE5vZGUgdmVyc2lvbiBpcyAke3ZlcnNpb25TdHJpbmd9YClcbiAgICAgICAgOiBub2soYE5vZGUgdmVyc2lvbiBzaG91bGQgYmUgYXQgbGVhc3QgJHtSRVFVSVJFRF9OT0RFX1ZFUlNJT059IWApO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG5vayhgVW5hYmxlIHRvIGZpbmQgbm9kZSB2ZXJzaW9uICh2ZXJzaW9uID0gJyR7dmVyc2lvblN0cmluZ30nKWApO1xuICAgIH1cbiAgfVxuXG4gIGZpeCAoKSB7XG4gICAgcmV0dXJuIGBNYW51YWxseSB1cGdyYWRlICR7J05vZGUuanMnLmJvbGR9LmA7XG4gIH1cbn1cbmNoZWNrcy5wdXNoKG5ldyBOb2RlVmVyc2lvbkNoZWNrKCkpO1xuXG5jbGFzcyBPcHRpb25hbE9wZW5jdjRub2RlanNDb21tYW5kQ2hlY2sgZXh0ZW5kcyBEb2N0b3JDaGVjayB7XG4gIGFzeW5jIGRpYWdub3NlICgpIHtcbiAgICBjb25zdCBwYWNrYWdlTmFtZSA9ICdvcGVuY3Y0bm9kZWpzJztcbiAgICBjb25zdCBwYWNrYWdlSW5mbyA9IGF3YWl0IGdldE5wbVBhY2thZ2VJbmZvKHBhY2thZ2VOYW1lKTtcblxuICAgIGlmIChwYWNrYWdlSW5mbykge1xuICAgICAgcmV0dXJuIG9rT3B0aW9uYWwoYCR7cGFja2FnZU5hbWV9IGlzIGluc3RhbGxlZCBhdDogJHtwYWNrYWdlSW5mby5wYXRofS4gSW5zdGFsbGVkIHZlcnNpb24gaXM6ICR7cGFja2FnZUluZm8udmVyc2lvbn1gKTtcbiAgICB9XG4gICAgcmV0dXJuIG5va09wdGlvbmFsKGAke3BhY2thZ2VOYW1lfSBjYW5ub3QgYmUgZm91bmQuYCk7XG4gIH1cblxuICBhc3luYyBmaXggKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlcXVpcmUtYXdhaXRcbiAgICByZXR1cm4gYFdoeSAkeydvcGVuY3Y0bm9kZWpzJy5ib2xkfSBpcyBuZWVkZWQgYW5kIGhvdyB0byBpbnN0YWxsIGl0OiBodHRwOi8vYXBwaXVtLmlvL2RvY3MvZW4vd3JpdGluZy1ydW5uaW5nLWFwcGl1bS9pbWFnZS1jb21wYXJpc29uL2A7XG4gIH1cbn1cbmNoZWNrcy5wdXNoKG5ldyBPcHRpb25hbE9wZW5jdjRub2RlanNDb21tYW5kQ2hlY2soKSk7XG5cbmNsYXNzIE9wdGlvbmFsRmZtcGVnQ29tbWFuZENoZWNrIGV4dGVuZHMgRG9jdG9yQ2hlY2sge1xuICBhc3luYyBkaWFnbm9zZSAoKSB7XG4gICAgY29uc3QgZmZtcGVnUGF0aCA9IGF3YWl0IHJlc29sdmVFeGVjdXRhYmxlUGF0aCgnZmZtcGVnJyk7XG4gICAgcmV0dXJuIGZmbXBlZ1BhdGhcbiAgICAgID8gb2tPcHRpb25hbChgZmZtcGVnIGlzIGluc3RhbGxlZCBhdDogJHtmZm1wZWdQYXRofS4gJHsoYXdhaXQgZXhlYygnZmZtcGVnJywgWyctdmVyc2lvbiddKSkuc3Rkb3V0LnNwbGl0KEVPTClbMF19YClcbiAgICAgIDogbm9rT3B0aW9uYWwoJ2ZmbXBlZyBjYW5ub3QgYmUgZm91bmQnKTtcbiAgfVxuXG4gIGFzeW5jIGZpeCAoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgIHJldHVybiBgJHsnZmZtcGVnJy5ib2xkfSBpcyBuZWVkZWQgdG8gcmVjb3JkIHNjcmVlbiBmZWF0dXJlcy4gUGxlYXNlIHJlYWQgaHR0cHM6Ly93d3cuZmZtcGVnLm9yZy8gdG8gaW5zdGFsbCBpdGA7XG4gIH1cbn1cbmNoZWNrcy5wdXNoKG5ldyBPcHRpb25hbEZmbXBlZ0NvbW1hbmRDaGVjaygpKTtcblxuXG5jbGFzcyBPcHRpb25hbE1qcGVnQ29uc3VtZXJDb21tYW5kQ2hlY2sgZXh0ZW5kcyBEb2N0b3JDaGVjayB7XG4gIGFzeW5jIGRpYWdub3NlICgpIHtcbiAgICBjb25zdCBwYWNrYWdlTmFtZSA9ICdtanBlZy1jb25zdW1lcic7XG4gICAgY29uc3QgcGFja2FnZUluZm8gPSBhd2FpdCBnZXROcG1QYWNrYWdlSW5mbyhwYWNrYWdlTmFtZSk7XG5cbiAgICBpZiAocGFja2FnZUluZm8pIHtcbiAgICAgIHJldHVybiBva09wdGlvbmFsKGAke3BhY2thZ2VOYW1lfSBpcyBpbnN0YWxsZWQgYXQ6ICR7cGFja2FnZUluZm8ucGF0aH0uIEluc3RhbGxlZCB2ZXJzaW9uIGlzOiAke3BhY2thZ2VJbmZvLnZlcnNpb259YCk7XG4gICAgfVxuICAgIHJldHVybiBub2tPcHRpb25hbChgJHtwYWNrYWdlTmFtZX0gY2Fubm90IGJlIGZvdW5kLmApO1xuICB9XG5cbiAgYXN5bmMgZml4ICgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgcmV0dXJuIGAkeydtanBlZy1jb25zdW1lcicuYm9sZH0gbW9kdWxlIGlzIHJlcXVpcmVkIHRvIHVzZSBNSlBFRy1vdmVyLUhUVFAgZmVhdHVyZXMuIFBsZWFzZSBpbnN0YWxsIGl0IHdpdGggJ25wbSBpIC1nIG1qcGVnLWNvbnN1bWVyJy5gO1xuICB9XG59XG5jaGVja3MucHVzaChuZXcgT3B0aW9uYWxNanBlZ0NvbnN1bWVyQ29tbWFuZENoZWNrKCkpO1xuXG5cbmV4cG9ydCB7IE5vZGVCaW5hcnlDaGVjaywgTm9kZVZlcnNpb25DaGVjayxcbiAgT3B0aW9uYWxPcGVuY3Y0bm9kZWpzQ29tbWFuZENoZWNrLCBPcHRpb25hbEZmbXBlZ0NvbW1hbmRDaGVjaywgT3B0aW9uYWxNanBlZ0NvbnN1bWVyQ29tbWFuZENoZWNrIH07XG5leHBvcnQgZGVmYXVsdCBjaGVja3M7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsSUFBSUEsTUFBTSxHQUFHLEVBQWI7O0FBR0EsTUFBTUMsZUFBTixTQUE4QkMsbUJBQTlCLENBQTBDO0VBQzFCLE1BQVJDLFFBQVEsR0FBSTtJQUNoQixJQUFJQyxRQUFRLEdBQUcsTUFBTUMscUJBQUEsQ0FBYUMsTUFBYixFQUFyQjtJQUNBLE9BQU9GLFFBQVEsR0FBRyxJQUFBRyxTQUFBLEVBQUksb0NBQW1DSCxR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