UNPKG

selenium-side-runner

Version:
174 lines 8.15 kB
#!/usr/bin/env node "use strict"; // Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const commander_1 = require("commander"); const crypto_1 = __importDefault(require("crypto")); const fs_1 = __importDefault(require("fs")); const merge_1 = __importDefault(require("lodash/fp/merge")); const os_1 = __importDefault(require("os")); const path_1 = __importDefault(require("path")); const resolve_bin_1 = __importDefault(require("resolve-bin")); const util_1 = __importDefault(require("util")); const capabilities_1 = __importDefault(require("./capabilities")); const config_1 = __importDefault(require("./config")); const proxy_1 = __importDefault(require("./proxy")); const metadata = require('../package.json'); const DEFAULT_TIMEOUT = 15000; process.title = metadata.name; const program = new commander_1.Command(); program .usage('[options] your-project-glob-here-*.side [variadic-project-globs-*.side]') .version(metadata.version) .option('--base-url [url]', 'Override the base URL that was set in the IDE') .option('-c, --capabilities [list]', 'Webdriver capabilities') .option('-j, --jest-options [list]', 'Options to configure Jest, wrap in extra quotes to allow shell to process', '""') .option('-s, --server [url]', 'Webdriver remote server') .option('-r, --retries [number]', 'Retry tests N times on failures, thin wrapper on jest.retryTimes', (str) => parseInt(str), 0) .option('-f, --filter [string]', 'Run suites matching name, takes a regex without slashes, eg (^(hello|goodbye).*$)') .option('-w, --max-workers [number]', `Maximum amount of workers that will run your tests, defaults to number of cores`, (str) => parseInt(str)) .option('-t, --timeout [number]', `The maximimum amount of time, in milliseconds, to spend attempting to locate an element. (default: ${DEFAULT_TIMEOUT})`, (str) => parseInt(str), DEFAULT_TIMEOUT) .option('-T, --jest-timeout [number]', `The maximimum amount of time, in milliseconds, to wait for a test to finish. (default: 60000)`, (str) => parseInt(str), 60000) .option('-x, --proxy-type [type]', 'Type of proxy to use (one of: direct, manual, pac, socks, system)') .option('-y, --proxy-options [list]', 'Proxy options to pass, for use with manual, pac and socks proxies') .option('-n, --config-file [filepath]', 'Use specified YAML file for configuration. (default: .side.yml)') .option('-o, --output-directory [directory]', 'Write test results as json to file in specified directory. Name will be based on timestamp.') .option('-z, --screenshot-failure-directory [directory]', 'Write screenshots of failed tests to file in specified directory. Name will be based on test + timestamp.') .option('-f, --force', "Forcibly run the project, regardless of project's version") .option('-d, --debug', 'Print debug logs') .option('-D, --debug-startup', 'Print debug startup logs') .option('-X, --debug-connection-mode', 'Debug driver connection mode'); program.parse(); if (!program.args.length) { program.outputHelp(); // eslint-disable-next-line no-process-exit process.exit(1); } const options = program.opts(); let configuration = { baseUrl: '', capabilities: { browserName: 'chrome', }, debug: options.debug, debugConnectionMode: options.debugConnectionMode, debugStartup: options.debugStartup, filter: options.filter || '.*', force: options.force, maxWorkers: os_1.default.cpus().length, screenshotFailureDirectory: options.screenshotFailureDirectory, // Convert all project paths into absolute paths projects: [], proxyOptions: {}, proxyType: undefined, retries: options.retries, runId: crypto_1.default.randomBytes(16).toString('hex'), path: path_1.default.join(__dirname, '../../'), server: '', jestTimeout: options.jestTimeout, timeout: DEFAULT_TIMEOUT, }; const confPath = options.configFile || '.side.yml'; const configFilePath = path_1.default.isAbsolute(confPath) ? confPath : path_1.default.join(process.cwd(), confPath); try { const configFileSettings = config_1.default.load(configFilePath); configuration = (0, merge_1.default)(configuration, configFileSettings); } catch (e) { const err = e; if (options.configFile || err.code !== 'ENOENT') { console.warn(err); throw new Error('Could not load ' + configFilePath); } } configuration = (0, merge_1.default)(configuration, { baseUrl: options.baseUrl, capabilities: capabilities_1.default.parseString(options.capabilities), debug: options.debug, maxWorkers: options.maxWorkers, // Convert all project paths into absolute paths projects: program.args.map((arg) => { if (path_1.default.isAbsolute(arg)) return arg; return path_1.default.join(process.cwd(), arg); }), proxyType: options.proxyType, proxyOptions: options.proxyType === 'manual' || options.proxyType === 'socks' ? capabilities_1.default.parseString(options.proxyOptions) : options.proxyOptions, server: options.server, timeout: options.timeout, }); if (configuration.proxyType) { const proxy = (0, proxy_1.default)(configuration.proxyType, configuration.proxyOptions); configuration.capabilities.proxy = proxy; } const outputFilename = 'results-' + new Date().toISOString().replace(/:/g, '-') + '.json'; if (options.outputDirectory) { if (!fs_1.default.existsSync(options.outputDirectory)) { fs_1.default.mkdirSync(options.outputDirectory, { recursive: true }); } const outputFile = path_1.default.join(options.outputDirectory, outputFilename); if (!fs_1.default.existsSync(outputFile)) { fs_1.default.writeFileSync(outputFile, ''); } } if (options.screenshotFailureDirectory) { if (!fs_1.default.existsSync(options.screenshotFailureDirectory)) { fs_1.default.mkdirSync(options.screenshotFailureDirectory, { recursive: true }); } } configuration.debugStartup && console.debug('Configuration:', util_1.default.inspect(configuration)); // All the stuff that goes into a big wrapped jest command const jest = 'node ' + resolve_bin_1.default.sync('jest'); const jestArgs = [ '--config=' + path_1.default.join(__dirname, '..', 'runner.jest.config.js'), '--maxConcurrency=' + configuration.maxWorkers, ] .concat(options.outputDirectory ? [ '--json', '--outputFile=' + path_1.default.join(options.outputDirectory, outputFilename), ] : []) .concat(options.jestOptions.slice(1, -1).split(' ').filter(Boolean)) .concat(['--runTestsByPath', path_1.default.join(__dirname, 'main.test.js')]); const jestEnv = { ...process.env, SE_CONFIGURATION: JSON.stringify(configuration), }; configuration.debugStartup && console.debug('Jest command:', jest, jestArgs, jestEnv); (0, child_process_1.spawn)(jest, jestArgs, { cwd: process.cwd(), env: jestEnv, shell: true, stdio: 'inherit', }).on('exit', (code) => { // This is my bin, my process // eslint-disable-next-line no-process-exit process.exit(code); }); //# sourceMappingURL=bin.js.map