UNPKG

argus-eyes

Version:

A lightweight commandline tool for visual regression testing of UI components.

197 lines (171 loc) 7.17 kB
var argLoader = require('./argumentLoader'); var util = require('../util'); /** * Expose module functions */ module.exports = { getUserConfig }; /** * Returns the user config object * * @typedef {{ * sizes: String[], * pages: { name: String, url: String, components: String[] }[], * components: { name: String, selector: String, ignore: String[] }[] * }} UserConfig * @throws {Error} * @returns {UserConfig} */ function getUserConfig() { var config = argLoader.getConfig(); if (!util.fileExists(config.config)) { throw new Error('Config file not found: ' + config.config); } try { var userConfig = require(config.config); } catch (e) { throw new Error(util.format("Could not load config file '%s' (Incorrect JSON?): ", config.config)); } // This function throws on error validateUserConfig(userConfig); // Slugify page and component identifiers userConfig = slugifyUserConfig(userConfig); return userConfig; } /** * Validate user config into app config object * * @private * @param {UserConfig} userConfig * @returns {Boolean} */ function validateUserConfig(userConfig) { // Validate phantomjs flags config if (typeof userConfig['phantomjs-flags'] !== 'undefined') { if (!Array.isArray(userConfig['phantomjs-flags'])) { throw new Error('Config: phantomjs-flags must be an array of strings!'); } userConfig['phantomjs-flags'].forEach(flag => { if (typeof flag !== 'string') { throw new Error('Config: phantomjs-flags must be an array of strings!'); } }); } // Validate credentials if (typeof userConfig.credentials !== 'undefined') { if (typeof userConfig.credentials !== 'string' || userConfig.credentials.length < 3) { throw new Error('Config: credentials must be a string!'); } var credentials = userConfig.credentials.split(':'); if (credentials.length !== 2) { throw new Error('Config: credentials must be a correctly formatted string!'); } } // Validate sizes if (!Array.isArray(userConfig.sizes) || userConfig.sizes.length < 1) { throw new Error('Config: No sizes found!'); } userConfig.sizes.forEach(size => { if (typeof size !== 'string') { throw new Error('Config: All sizes need to be a string!'); } var sizes = size.split('x').map(x => parseInt(x, 10)); if (sizes.length !== 2 || !(sizes[0] > 0) || !(sizes[1] > 0)) { throw new Error('Config: All sizes need to be a correctly formatted string!'); } }); // Validate pages if (!Array.isArray(userConfig.pages) || userConfig.pages.length < 1) { throw new Error('Config: No pages found!'); } userConfig.pages.forEach(page => { if (!page.name || typeof page.name !== 'string' || !page.url || typeof page.url !== 'string') { throw new Error('Config: All pages need a name and url!'); } if (!Array.isArray(page.components) || !page.components.length) { throw new Error(util.format("Config: Page '%s' needs at least 1 component!", page.name)); } }); // Validate components if (!Array.isArray(userConfig.components) || userConfig.components.length < 1) { throw new Error('Config: No components found!'); } userConfig.components.forEach(component => { if (!component.name || typeof component.name !== 'string' || !component.selector || typeof component.selector !== 'string') { throw new Error('Config: All components need a name and selector!'); } if (typeof component.ignore !== 'undefined' && (!Array.isArray(component.ignore) || !component.ignore.length)) { throw new Error(util.format("Config: Component '%s' has an invalid ignore list!", component.name)); } }); // Validate all referenced components actually exist var components = userConfig.components.map(c => c.name); userConfig.pages.forEach(page => { page.components.forEach(component => { if (!~components.indexOf(component)) { throw new Error(util.format("Config: Component '%s' not found in page '%s'", component, page.name)); } }); }); // Validate all wait-for-script levels if (typeof userConfig['wait-for-script'] !== 'undefined' && typeof userConfig['wait-for-script'] !== 'string') { throw new Error('Config: wait-for-script must be a valid JavaScript string!'); } userConfig.pages.forEach(page => { if (typeof page['wait-for-script'] !== 'undefined' && typeof page['wait-for-script'] !== 'string') { throw new Error(util.format("Config: Page '%s' has an invalid wait-for-script!", page.name)); } }); userConfig.components.forEach(component => { if (typeof component['wait-for-script'] !== 'undefined' && typeof component['wait-for-script'] !== 'string') { throw new Error(util.format("Config: Component '%s' has an invalid wait-for-script!", component.name)); } }); // Validate all wait-for-delay levels if (typeof userConfig['wait-for-delay'] !== 'undefined' && typeof userConfig['wait-for-delay'] !== 'number') { throw new Error('Config: wait-for-delay must be a valid JavaScript number!'); } userConfig.pages.forEach(page => { if (typeof page['wait-for-delay'] !== 'undefined' && typeof page['wait-for-delay'] !== 'number') { throw new Error(util.format("Config: Page '%s' has an invalid wait-for-delay!", page.name)); } }); userConfig.components.forEach(component => { if (typeof component['wait-for-delay'] !== 'undefined' && typeof component['wait-for-delay'] !== 'number') { throw new Error(util.format("Config: Component '%s' has an invalid wait-for-delay!", component.name)); } }); // Throw 'removed' errors for finished-when var msg = 'Config: finished-when was renamed to wait-for-script in v0.6.0, please update your config'; if (typeof userConfig['finished-when'] !== 'undefined') { throw new Error(msg); } userConfig.pages.forEach(page => { if (typeof page['finished-when'] !== 'undefined') { throw new Error(msg); } }); userConfig.components.forEach(component => { if (typeof component['finished-when'] !== 'undefined') { throw new Error(msg); } }); return true; } /** * Slugify page and component identifiers * * @param {UserConfig} userConfig * @returns {UserConfig} */ function slugifyUserConfig(userConfig) { userConfig.pages = userConfig.pages.map(page => { page.name = util.slugify(page.name); page.components = page.components.map(componentName => util.slugify(componentName)); return page; }); userConfig.components = userConfig.components.map(component => { component.name = util.slugify(component.name); return component; }); return userConfig; }