UNPKG

folio

Version:

A customizable test framework to build your own test frameworks. Foundation for the [Playwright test runner](https://github.com/microsoft/playwright-test).

247 lines 11.4 kB
"use strict"; /** * Copyright (c) Microsoft Corporation. * * Licensed 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.reporters = void 0; const fstream_ignore_1 = __importDefault(require("fstream-ignore")); const commander = __importStar(require("commander")); const fs = __importStar(require("fs")); const minimatch_1 = __importDefault(require("minimatch")); const path = __importStar(require("path")); const reporter_1 = require("./reporter"); const dot_1 = __importDefault(require("./reporters/dot")); const json_1 = __importDefault(require("./reporters/json")); const junit_1 = __importDefault(require("./reporters/junit")); const line_1 = __importDefault(require("./reporters/line")); const list_1 = __importDefault(require("./reporters/list")); const multiplexer_1 = require("./reporters/multiplexer"); const runner_1 = require("./runner"); const fixtures_1 = require("./fixtures"); const config_1 = require("./config"); exports.reporters = { 'dot': dot_1.default, 'json': json_1.default, 'junit': junit_1.default, 'line': line_1.default, 'list': list_1.default, 'null': reporter_1.EmptyReporter, }; const availableReporters = Object.keys(exports.reporters).map(r => `"${r}"`).join(); const loadProgram = new commander.Command(); addRunnerOptions(loadProgram, true); loadProgram.helpOption(false); loadProgram.action(async (command) => { try { await runTests(command); } catch (e) { console.log(e); process.exit(1); } }); loadProgram.parse(process.argv); async function runTests(command) { fixtures_1.assignConfig(config_1.defaultConfig); let shard; if (command.shard) { const pair = command.shard.split('/').map((t) => parseInt(t, 10)); shard = { current: pair[0] - 1, total: pair[1] }; } const testDir = path.resolve(process.cwd(), command.args[0] || '.'); const reporterList = command.reporter.split(','); const reporterObjects = reporterList.map(c => { if (exports.reporters[c]) return new exports.reporters[c](); try { const p = path.resolve(process.cwd(), c); return new (require(p).default)(); } catch (e) { console.error('Invalid reporter ' + c, e); process.exit(1); } }); if (!fs.existsSync(testDir)) throw new Error(`${testDir} does not exist`); let files; if (fs.statSync(testDir).isDirectory()) files = filterFiles(testDir, await collectFiles(testDir), command.args.slice(1), command.testMatch, command.testIgnore); else files = [testDir]; const reporter = new multiplexer_1.Multiplexer(reporterObjects); const runner = new runner_1.Runner(reporter); const parameterRegistrations = runner.loadFiles(files).parameters; const parameters = {}; for (const param of command.param || []) { const match = param.match(/([^=]+)=(.*)/); const [_, name, value] = match ? match : ['', param, 'true']; if (!parameterRegistrations.has(name)) { console.error(`unknown parameter '${name}'`); process.exit(1); } const registration = parameterRegistrations.get(name); let list = parameters[name]; if (!list) { list = []; parameters[name] = list; } if (typeof registration.defaultValue === 'string') list.push(value); else if (typeof registration.defaultValue === 'number') list.push(parseFloat(value)); else if (typeof registration.defaultValue === 'boolean') list.push(value === 'true'); } if (command.help === undefined) { printParametersHelp([...parameterRegistrations.values()]); process.exit(0); } // Assign config values after runner.loadFiles to set defaults from the command // line. fixtures_1.config.testDir = testDir; if (command.forbidOnly) fixtures_1.config.forbidOnly = true; if (command.globalTimeout) fixtures_1.config.globalTimeout = parseInt(command.globalTimeout, 10); if (command.grep) fixtures_1.config.grep = command.grep; if (command.maxFailures || command.x) fixtures_1.config.maxFailures = command.x ? 1 : parseInt(command.maxFailures, 10); if (command.outputDir) fixtures_1.config.outputDir = command.output; if (command.quiet) fixtures_1.config.quiet = command.quiet; if (command.repeatEach) fixtures_1.config.repeatEach = parseInt(command.repeatEach, 10); if (command.retries) fixtures_1.config.retries = parseInt(command.retries, 10); if (shard) fixtures_1.config.shard = shard; if (command.snapshotDir) fixtures_1.config.snapshotDir = command.snapshotDir; if (command.timeout) fixtures_1.config.timeout = parseInt(command.timeout, 10); if (command.updateSnapshots) fixtures_1.config.updateSnapshots = !!command.updateSnapshots; if (command.workers) fixtures_1.config.workers = parseInt(command.workers, 10); runner.generateTests({ parameters }); if (command.list) { runner.list(); return; } const result = await runner.run(); if (result === 'sigint') process.exit(130); if (result === 'forbid-only') { console.error('====================================='); console.error(' --forbid-only found a focused test.'); console.error('====================================='); process.exit(1); } if (result === 'no-tests') { console.error('================='); console.error(' no tests found.'); console.error('================='); process.exit(1); } process.exit(result === 'failed' ? 1 : 0); } async function collectFiles(testDir) { const list = []; let callback; const result = new Promise(f => callback = f); fstream_ignore_1.default({ path: testDir, ignoreFiles: ['.gitignore'] }) .on('child', (c) => list.push(c.path)) .on('end', () => callback(list)); return result; } function filterFiles(base, files, filters, testMatch, testIgnore) { if (!testIgnore.includes('/') && !testIgnore.includes('\\')) testIgnore = '**/' + testIgnore; if (!testMatch.includes('/') && !testMatch.includes('\\')) testMatch = '**/' + testMatch; return files.filter(file => { file = path.relative(base, file); if (testIgnore && minimatch_1.default(file, testIgnore)) return false; if (testMatch && !minimatch_1.default(file, testMatch)) return false; if (filters.length && !filters.find(filter => file.includes(filter))) return false; return true; }); } function addRunnerOptions(program, param) { program = program .version('Version ' + /** @type {any} */ (require)('../package.json').version) .option('--forbid-only', `Fail if exclusive test(s) encountered (default: ${config_1.defaultConfig.forbidOnly})`) .option('-g, --grep <grep>', `Only run tests matching this string or regexp (default: "${config_1.defaultConfig.grep}")`) .option('--global-timeout <timeout>', `Specify maximum time this test suite can run in milliseconds (default: 0 for unlimited)`) .option('-h, --help', `Display help`) .option('-j, --workers <workers>', `Number of concurrent workers, use 1 to run in single worker (default: number of CPU cores / 2)`) .option('--list', `Only collect all the test and report them`) .option('--max-failures <N>', `Stop after the first N failures (default: ${config_1.defaultConfig.maxFailures})`) .option('--output <outputDir>', `Folder for output artifacts (default: "test-results")`); if (param) program = program.option('-p, --param <name=value...>', `Specify fixture parameter value`); program = program .option('--quiet', `Suppress stdio`) .option('--repeat-each <repeat-each>', `Specify how many times to run the tests (default: ${config_1.defaultConfig.repeatEach})`) .option('--reporter <reporter>', `Specify reporter to use, comma-separated, can be ${availableReporters}`, process.env.CI ? 'dot' : 'line') .option('--retries <retries>', `Specify retry count (default: ${config_1.defaultConfig.retries})`) .option('--shard <shard>', `Shard tests and execute only selected shard, specify in the form "current/all", 1-based, for example "3/5"`) .option('--snapshot-dir <dir>', `Snapshot directory, relative to tests directory (default: "${config_1.defaultConfig.snapshotDir}"`) .option('--test-ignore <pattern>', `Pattern used to ignore test files`, 'node_modules/**') .option('--test-match <pattern>', `Pattern used to find test files`, '**/?(*.)+(spec|test).[jt]s') .option('--timeout <timeout>', `Specify test timeout threshold in milliseconds (default: ${config_1.defaultConfig.timeout})`) .option('-u, --update-snapshots', `Whether to update snapshots with actual results (default: ${config_1.defaultConfig.updateSnapshots})`) .option('-x', `Stop after the first failure`); } function printParametersHelp(parameterRegistrations) { const program = new commander.Command(); for (const registration of parameterRegistrations) { if (typeof registration.defaultValue === 'boolean') program.option(`-p, --param*${registration.name}`, registration.description, registration.defaultValue); else program.option(`-p, --param*${registration.name}=<value>`, registration.description, String(registration.defaultValue)); } addRunnerOptions(program, false); console.log(program.helpInformation().replace(/--param\*/g, '--param ')); } //# sourceMappingURL=cli.js.map