@wdio/config
Version:
A helper utility to parse and validate WebdriverIO options
99 lines (98 loc) • 3.79 kB
JavaScript
import decamelize from 'decamelize';
export const validObjectOrArray = (object) => (Array.isArray(object) && object.length > 0) ||
(typeof object === 'object' && Object.keys(object).length > 0);
/**
* remove line numbers from file path, ex:
* `/foo:9` or `c:\bar:14:5`
* @param {string} filePath path to spec file
* @returns {string}
*/
export function removeLineNumbers(filePath) {
const matcher = filePath.match(/:\d+(:\d+$|$)/);
if (matcher) {
filePath = filePath.substring(0, matcher.index);
}
return filePath;
}
/**
* does spec file path contain Cucumber's line number, ex
* `/foo/bar:9` or `c:\bar\foo:14:5`
* @param {string|string[]} spec
*/
export function isCucumberFeatureWithLineNumber(spec) {
const specs = Array.isArray(spec) ? spec : [spec];
return specs.some((s) => s.match(/:\d+(:\d+$|$)/));
}
export function isCloudCapability(caps) {
return Boolean(caps && (caps['bstack:options'] || caps['sauce:options'] || caps['tb:options']));
}
/**
* validates configurations based on default values
* @param {Object} defaults object describing all allowed properties
* @param {Object} options option to check against
* @return {Object} validated config enriched with default values
*/
export function validateConfig(defaults, options, keysToKeep = []) {
const params = {};
for (const [name, expectedOption] of Object.entries(defaults)) {
/**
* check if options is given
*/
if (typeof options[name] === 'undefined' && !expectedOption.default && expectedOption.required) {
throw new Error(`Required option "${name.toString()}" is missing`);
}
if (typeof options[name] === 'undefined' && expectedOption.default) {
params[name] = expectedOption.default;
}
if (typeof options[name] !== 'undefined') {
const optValue = options[name];
if (typeof optValue !== expectedOption.type) {
throw new Error(`Expected option "${name.toString()}" to be type of ${expectedOption.type} but was ${typeof options[name]}`);
}
if (typeof expectedOption.validate === 'function') {
try {
expectedOption.validate(optValue);
}
catch (e) {
throw new Error(`Type check for option "${name.toString()}" failed: ${e.message}`);
}
}
if (typeof optValue === 'string' && expectedOption.match && !optValue.match(expectedOption.match)) {
throw new Error(`Option "${name.toString()}" doesn't match expected values: ${expectedOption.match}`);
}
params[name] = options[name];
}
}
for (const [name, option] of Object.entries(options)) {
/**
* keep keys from source object if desired
*/
if (keysToKeep.includes(name)) {
params[name] = option;
}
}
return params;
}
export function objectToEnv(params) {
/**
* apply all config options as environment variables
*/
for (const [key, value] of Object.entries(params || {})) {
const envKey = decamelize(key).toUpperCase();
if (Array.isArray(value)) {
process.env[envKey] = value.join(',');
}
else if (typeof value === 'boolean' && value) {
process.env[envKey] = '1';
}
else if (value instanceof RegExp) {
process.env[envKey] = value.toString();
}
else if (typeof value === 'object') {
process.env[envKey] = JSON.stringify(value);
}
else if (value && typeof value.toString === 'function') {
process.env[envKey] = value.toString();
}
}
}