SuitestAutomation/suitest-js-api

View on GitHub
lib/validation/jsonSchemas.js

Summary

Maintainability
D
3 days
Test Coverage
A
100%
const {uniq, values} = require('ramda');
const validationKeys = require('../constants/validationKeys');
const {NETWORK_PROP, NETWORK_METHOD} = require('../constants/networkRequest');
const {PROP_COMPARATOR} = require('../constants/comparator');
const {ELEMENT_PROP, VALUE} = require('../constants/element');
const {ELEMENT_PROP_BY_TYPE} = require('./elementPropTypes');
const BORDER_STYLE = require('../constants/borderStyle');
const VIDEO_STATE = require('../constants/videoState');
const VISIBILITY_STATE = require('../constants/visibilityState');
const CONTENT_MODE = require('../constants/contentMode');
const ELEMENT_STATE = require('../constants/elementState');
const TEXT_ALIGNMENT = require('../constants/textAlignment');
const IMAGE_LOAD_STATE = require('../constants/imageLoadState');
const HAD_NO_ERROR = require('../constants/hadNoError');
const TAP_TYPES = require('../constants/tapTypes');
const DIRECTIONS = require('../constants/directions');
const VRC = require('../constants/vrc');
const SCREEN_ORIENTATION = require('../constants/screenOrientation');
const LAUNCH_MODE = require('../constants/launchMode');
const COOKIE_PROP = require('../constants/cookieProp');
const OCR_READ_AS = require('../constants/ocrReadAs');
const OCR_COLOR = require('../constants/ocrColor');
const schemas = {};

const nonNegativeNumber = () => ({
    type: 'number',
    minimum: 0,
});

const positiveNumber = () => ({
    type: 'number',
    exclusiveMinimum: 0,
});

const CONFIG_OVERRIDE_PROPERTIES = {
    'url': {'type': 'string'},
    'suitestify': {'type': 'boolean'},
    'domainList': {
        'type': 'array',
        'items': {'type': 'string'},
    },
    'mapRules': {
        'type': 'array',
        'items': {
            'type': 'object',
            'properties': {
                'methods': {
                    'type': 'array',
                    'items': {'type': 'string'},
                },
                'url': {'type': 'string'},
                'type': {'type': 'string'},
                'toUrl': {'type': 'string'},
            },
        },
    },
    'codeOverrides': {'type': 'object'},
    'configVariables': {
        'type': 'array',
        'items': {
            'type': 'object',
            'properties': {
                'key': {'type': 'string'},
                'value': {'type': 'string'},
            },
            'required': ['key', 'value'],
        },
    },
    'openAppOverrideTest': {
        'type': 'string',
        'format': 'uuid',
    },
};

schemas[validationKeys.CONFIG_OVERRIDE] = {
    'type': 'object',
    'properties': {
        ...CONFIG_OVERRIDE_PROPERTIES,
    },
};

schemas[validationKeys.LAUNCH_MODE] = {
    'type': 'string',
    'enum': Object.values(LAUNCH_MODE),
};

schemas[validationKeys.SET_SCREEN_ORIENTATION] = {
    'type': 'string',
    'enum': Object.values(SCREEN_ORIENTATION),
};

schemas[validationKeys.TAKE_SCREENSHOT] = {
    'type': 'string',
    'enum': ['raw', 'base64'],
};

schemas[validationKeys.UUID] = {
    'type': 'string',
    'format': 'uuid',
};

schemas[validationKeys.OPEN_SESSION] = {
    'type': 'object',
    'required': ['tokenId', 'tokenPassword'],
    'properties': {
        'tokenId': {'type': 'string'},
        'tokenPassword': {'type': 'string'},
    },
};

schemas[validationKeys.STRING] = {
    'type': 'string',
};

schemas[validationKeys.NON_EMPTY_STRING] = {
    'type': 'string',
    'minLength': 1,
};

schemas[validationKeys.ELEMENT_SELECTOR] = {
    'schemaId': validationKeys.ELEMENT_SELECTOR,
    'type': 'object',
    'additionalProperties': false,
    'properties': {
        'apiId': schemas[validationKeys.NON_EMPTY_STRING],
        'css': {'type': 'string'},
        'xpath': {'type': 'string'},
        'attributes': {'type': 'string'},
        'text': {'type': 'string'},
        'linkText': {'type': 'string'},
        'partialLinkText': {'type': 'string'},
        'position': {'type': 'string'},
        'size': {'type': 'string'},
        'color': {'type': 'string'},
        'index': {
            'type': 'integer',
            'exclusiveMinimum': 0,
        },
        'handle': schemas[validationKeys.NON_EMPTY_STRING],
        'active': {'type': 'boolean'},
    },
    'anyOf': [
        {'required': ['css']},
        {'required': ['xpath']},
        {'required': ['attributes']},
        {'required': ['text']},
        {'required': ['linkText']},
        {'required': ['partialLinkText']},
        {'required': ['position']},
        {'required': ['size']},
        {'required': ['color']},
        {'required': ['apiId']},
        {'required': ['handle']},
        {'required': ['active']},
    ],
};

const deviation = {
    'if': {'properties': {'type': {'const': PROP_COMPARATOR.APPROX}}},
    'then': {'type': ['number', 'string']},
    'else': {'const': 'undefined'},
};
const propComparator = {
    'type': 'string',
    'enum': Object.values(PROP_COMPARATOR),
};

const stringComparators = () => ({
    'type': 'string',
    'enum': [
        PROP_COMPARATOR.EQUAL,
        PROP_COMPARATOR.NOT_EQUAL,
        PROP_COMPARATOR.CONTAIN,
        PROP_COMPARATOR.NOT_CONTAIN,
        PROP_COMPARATOR.START,
        PROP_COMPARATOR.NOT_START,
        PROP_COMPARATOR.END,
        PROP_COMPARATOR.NOT_END,
    ],
});

const booleanComparators = () => ({
    'type': 'string',
    'enum': [PROP_COMPARATOR.EQUAL, PROP_COMPARATOR.NOT_EQUAL],
});

schemas[validationKeys.ELEMENT_PROPS] = {
    'schemaId': validationKeys.ELEMENT_PROPS,
    'type': 'array',
    'items': {
        'type': 'object',
        'required': ['name', 'type', 'val'],
        'anyOf': [
            {'properties': {
                'name': {
                    'type': 'string',
                    'enum': Object.values(ELEMENT_PROP),
                },
                'type': propComparator,
                'val': {'const': VALUE.REPO},
                deviation,
            }},
            {'properties': {
                'name': {
                    'type': 'string',
                    'enum': ELEMENT_PROP_BY_TYPE.integer,
                },
                'type': propComparator,
                'val': {'type': ['integer', 'string']},
                deviation,
            }},
            {'properties': {
                'name': {
                    'type': 'string',
                    'enum': ELEMENT_PROP_BY_TYPE.string,
                },
                'type': propComparator,
                'val': {'type': 'string'},
                deviation,
            }},
            {'properties': {
                'name': {'enum': ELEMENT_PROP_BY_TYPE.number},
                'type': propComparator,
                'val': {'type': ['number', 'string']},
                deviation,
            }},
            {'properties': {
                'name': {'enum': ELEMENT_PROP_BY_TYPE.boolean},
                'type': propComparator,
                'val': {'type': 'boolean'},
                deviation,
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.BORDER_STYLE},
                'type': propComparator,
                'val': {'enum': Object.values(BORDER_STYLE)},
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.VIDEO_STATE},
                'type': propComparator,
                'val': {'enum': Object.values(VIDEO_STATE)},
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.VISIBILITY},
                'type': propComparator,
                'val': {'enum': [VISIBILITY_STATE.COLLAPSED, VISIBILITY_STATE.INVISIBLE, VISIBILITY_STATE.VISIBLE]},
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.CONTENT_MODE},
                'type': propComparator,
                'val': {'enum': Object.values(CONTENT_MODE)},
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.STATE},
                'type': propComparator,
                'val': {'enum': Object.values(ELEMENT_STATE)},
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.TEXT_ALIGNMENT},
                'type': propComparator,
                'val': {'enum': Object.values(TEXT_ALIGNMENT)},
            }},
            {'properties': {
                'name': {'const': ELEMENT_PROP.IMAGE_LOAD_STATE},
                'type': propComparator,
                'val': {'enum': Object.values(IMAGE_LOAD_STATE)},
            }},
        ],
    },
};

schemas[validationKeys.ELEMENT_REPO_PROPS] = {
    'type': 'array',
    'items': {
        'type': 'object',
        'required': ['name', 'type', 'val'],
        'additionalProperties': false,
        'properties': {
            'name': {'enum': Object.values(ELEMENT_PROP)},
            'type': propComparator,
            'val': {'const': VALUE.REPO},
            deviation,
        },
    },
};

schemas[validationKeys.REQUEST_MATCHES] = {
    'type': 'array',
    'items': {
        'type': 'object',
        'required': ['name', 'compare', 'val'],
        'anyOf': [
            {'properties': {
                'name': {'type': 'string'},
                'val': {'type': 'string'},
                'compare': propComparator,
            }},
            {'properties': {
                'name': {'const': NETWORK_PROP.METHOD},
                'val': {'enum': Object.values(NETWORK_METHOD)},
                'compare': propComparator,
            }},
            {'properties': {
                'name': {'const': NETWORK_PROP.BODY},
                'val': {'type': 'string'},
                'compare': propComparator,
            }},
        ],
    },
};

schemas[validationKeys.RESPONSE_MATCHES] = {
    'type': 'array',
    'items': {
        'type': 'object',
        'required': ['name', 'compare', 'val'],
        'anyOf': [
            {'properties': {
                'name': {'type': 'string'},
                'val': {'type': 'string'},
                'compare': propComparator,
            }},
            {'properties': {
                'name': {'const': NETWORK_PROP.STATUS},
                'val': {'type': ['number', 'string']},
                'compare': propComparator,
            }},
            {'properties': {
                'name': {'const': NETWORK_PROP.BODY},
                'val': {'type': 'string'},
                'compare': propComparator,
            }},
        ],
    },
};

schemas[validationKeys.TEST_LAUNCHER_TOKEN] = {
    'type': 'object',
    'required': ['tokenId', 'tokenPassword'],
    'properties': {
        'tokenId': {'type': 'string'},
        'tokenPassword': {'type': 'string'},
        'presets': {
            'type': 'object',
            'additionalProperties': {
                'type': 'object',
                'properties': {
                    'device': {
                        'oneOf': [
                            {'type': 'string'},
                            {
                                'type': 'object',
                                'properties': {
                                    'deviceId': {'type': 'string'},
                                },
                                'additionalProperties': false,
                            },
                        ],
                    },
                    'config': {
                        'oneOf': [
                            {'type': 'string'},
                            {
                                'type': 'object',
                                'properties': {
                                    'configId': {'type': 'string'},
                                    ...CONFIG_OVERRIDE_PROPERTIES,
                                },
                            },
                        ],
                    },
                },
            },

        },
        'appConfigId': {'type': 'string'},
        'deviceId': {'type': 'string'},
    },
};

schemas[validationKeys.SESSION_BOOTSTRAP_TOKEN] = {
    'type': 'object',
    'required': ['tokenId'],
    'properties': {
        'tokenId': {'type': 'string'},
        'tokenPassword': {'type': 'string'},
    },
};

schemas[validationKeys.CONFIGURE] = {
    'schemaId': validationKeys.CONFIGURE,
    'type': 'object',
    'additionalProperties': false,
    'properties': {
        'appConfigId': {'type': 'string'},
        'concurrency': {'type': 'number'},
        'overrideConfigFile': {'type': 'string'},
        'configFile': {'type': 'string'},
        'deviceId': {'type': 'string'},
        'disallowCrashReports': {'type': 'boolean'},
        'inspect': {'type': ['number', 'boolean', 'string']}, // --inspect=true evaluates to {inspect: 'true'}
        'inspectBrk': {'type': ['number', 'boolean', 'string']}, // same as above
        'logDir': {'type': 'string'},
        'defaultTimeout': {'type': 'number'},
        'logLevel': {'enum': ['silent', 'normal', 'verbose', 'debug', 'silly']},
        'orgId': {'type': 'string'},
        'repl': {'type': 'boolean'},
        'timestamp': {'type': 'string'},
        'tokenPassword': {'type': 'string'},
        'tokenId': {'type': 'string'},
        'preset': {
            'type': 'array',
            'items': {'type': 'string'},
        },
        'presets': {'type': 'object'},
        'screenshotDir': {'type': 'string'},
        'includeChangelist': {'type': 'boolean'},
        'recordingOption': {'type': 'string'},
        'webhookUrl': {'type': 'string'},
    },
};

schemas[validationKeys.ARRAY_OF_BUTTONS] = {
    'type': 'array',
    'minItems': 1,
    'items': {
        'type': 'string',
        'minLength': 1,
        'enum': uniq(values(VRC)),
    },
};

schemas[validationKeys.HAD_NO_ERROR] = {
    'schemaId': validationKeys.HAD_NO_ERROR,
    'enum': [HAD_NO_ERROR.ALL, HAD_NO_ERROR.CURRENT_URL],
};

schemas[validationKeys.TAP_TYPE] = {
    'schemaId': validationKeys.TAP_TYPE,
    'enum': [TAP_TYPES.SINGLE, TAP_TYPES.DOUBLE, TAP_TYPES.LONG],
};

schemas[validationKeys.DIRECTIONS] = {
    'schemaId': validationKeys.DIRECTIONS,
    'enum': [DIRECTIONS.UP, DIRECTIONS.DOWN, DIRECTIONS.LEFT, DIRECTIONS.RIGHT],
};

schemas[validationKeys.CSS_PROPS] = {
    'schemaId': validationKeys.CSS_PROPS,
    'type': 'array',
    'minItems': 1,
    'items': {
        'type': 'string',
        'minLength': 1,
    },
};

schemas[validationKeys.ELEMENT_HANDLE] = {
    'schemaId': validationKeys.ELEMENT_HANDLE,
    'oneOf': [
        {'type': 'boolean'},
        {
            'type': 'object',
            'properties': {
                'multiple': {
                    'type': 'boolean',
                },
            },
        },
    ],
};

schemas[validationKeys.ELEMENT_ATTRIBUTES] = {
    'schemaId': validationKeys.ELEMENT_ATTRIBUTES,
    'type': 'array',
    'items': {
        'type': 'string',
        'minLength': 1,
    },
};

schemas[validationKeys.COOKIE_PROPS] = {
    'schemaId': validationKeys.COOKIE_PROPS,
    'type': 'array',
    'items': {
        'type': 'object',
        'required': ['property', 'val'],
        'anyOf': [
            {
                'properties': {
                    'property': {
                        'type': 'string',
                        'enum': [COOKIE_PROP.VALUE, COOKIE_PROP.PATH, COOKIE_PROP.DOMAIN],
                    },
                    'val': {'type': 'string'},
                    'type': stringComparators(),
                },
            },
            {
                'properties': {
                    'property': {
                        'type': 'string',
                        'enum': [COOKIE_PROP.HTTP_ONLY, COOKIE_PROP.SECURE],
                    },
                    'val': {'type': 'boolean'},
                    'type': booleanComparators(),
                },
            },
        ],
    },
};

// schema for validating OCR assertion (testLine) comparators
schemas[validationKeys.OCR_COMPARATORS] = {
    'schemaId': validationKeys.OCR_COMPARATORS,
    'type': 'array',
    'items': {
        'type': 'object',
        'dependencies': {
            'type': ['val'],
        },
        'required': ['val'],
        'additionalProperties': false,
        'properties': {
            'val': {'type': 'string'},
            'type': stringComparators(),
            'readAs': {
                'type': 'string',
                'enum': Object.values(OCR_READ_AS),
            },
            'align': {'type': 'boolean'},
            'color': {
                'type': 'string',
                'enum': Object.values(OCR_COLOR),
            },
            'whitelist': schemas[validationKeys.NON_EMPTY_STRING],
            'blacklist': schemas[validationKeys.NON_EMPTY_STRING],
            'region': {
                'type': 'array',
                'items': [
                    {...nonNegativeNumber(), maximum: 100},
                    {...nonNegativeNumber(), maximum: 100},
                    {...positiveNumber(), maximum: 100},
                    {...positiveNumber(), maximum: 100},
                ],
                'minItems': 4,
                'additionalItems': false,
            },
        },
    },
};

// schema for validating OCR query options
schemas[validationKeys.OCR_OPTIONS] = {
    'schemaId': validationKeys.OCR_OPTIONS,
    'type': 'array',
    'items': {
        'type': 'object',
        'required': [],
        'dependencies': {
            'type': ['val'],
        },
        'additionalProperties': false,
        'properties': {
            'val': {'type': 'string'},
            'type': stringComparators(),
            'readAs': {
                'type': 'string',
                'enum': Object.values(OCR_READ_AS),
            },
            'align': {'type': 'boolean'},
            'color': {
                'type': 'string',
                'enum': Object.values(OCR_COLOR),
            },
            'whitelist': schemas[validationKeys.NON_EMPTY_STRING],
            'blacklist': schemas[validationKeys.NON_EMPTY_STRING],
            'region': {
                'type': 'array',
                'items': [
                    {...nonNegativeNumber(), maximum: 100},
                    {...nonNegativeNumber(), maximum: 100},
                    {...positiveNumber(), maximum: 100},
                    {...positiveNumber(), maximum: 100},
                ],
                'minItems': 4,
                'additionalItems': false,
            },
        },
    },
};

Object.freeze(schemas);

module.exports = schemas;