All files / webdriver/src command.js

100% Statements 34/34
95.65% Branches 22/23
100% Functions 7/7
100% Lines 31/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92        5x     1830x   1830x 19x 19x               20x 19x 19x         20x 19x 1x 4x     1x                     18x 14x   14x       3x 1x     2x                     11x 4x 4x           7x     16x 16x 16x 16x 16x 15x         16x 16x        
import logger from '@wdio/logger'
import WebDriverRequest from './request'
import { isValidParameter, getArgumentType, commandCallStructure } from './utils'
 
const log = logger('webdriver')
 
export default function (method, endpointUri, commandInfo) {
    const { command, ref, parameters, variables = [], isHubCommand = false } = commandInfo
 
    return function (...args) {
        let endpoint = endpointUri // clone endpointUri in case we change it
        const commandParams = [...variables.map((v) => Object.assign(v, {
            /**
             * url variables are:
             */
            required: true, // always required as they are part of the endpoint
            type: 'string'  // have to be always type of string
        })), ...parameters]
 
        const commandUsage = `${command}(${commandParams.map((p) => p.name).join(', ')})`
        const moreInfo = `\n\nFor more info see ${ref}\n`
        const body = {}
 
        /**
         * parameter check
         */
        const minAllowedParams = commandParams.filter((param) => param.required).length
        if (args.length < minAllowedParams || args.length > commandParams.length) {
            const parameterDescription = commandParams.length
                ? `\n\nProperty Description:\n${commandParams.map((p) => `  "${p.name}" (${p.type}): ${p.description}`).join('\n')}`
                : ''
 
            throw new Error(
                `Wrong parameters applied for ${command}\n` +
                `Usage: ${commandUsage}` +
                parameterDescription +
                moreInfo
            )
        }
 
        /**
         * parameter type check
         */
        for (const [i, arg] of Object.entries(args)) {
            const commandParam = commandParams[i]
 
            if (!isValidParameter(arg, commandParam.type)) {
                /**
                 * ignore if argument is not required
                 */
                if (typeof arg === 'undefined' && !commandParam.required) {
                    continue
                }
 
                throw new Error(
                    `Malformed type for "${commandParam.name}" parameter of command ${command}\n` +
                    `Expected: ${commandParam.type}\n` +
                    `Actual: ${getArgumentType(arg)}` +
                    moreInfo
                )
            }
 
            /**
             * inject url variables
             */
            if (i < variables.length) {
                endpoint = endpoint.replace(`:${commandParams[i].name}`, arg)
                continue
            }
 
            /**
             * rest of args are part of body payload
             */
            body[commandParams[i].name] = arg
        }
 
        const request = new WebDriverRequest(method, endpoint, body, isHubCommand)
        this.emit('command', { method, endpoint, body })
        log.info('COMMAND', commandCallStructure(command, args))
        return request.makeRequest(this.options, this.sessionId).then((result) => {
            if (result.value != null) {
                log.info('RESULT', command.toLowerCase().includes('screenshot')
                    && typeof result.value === 'string' && result.value.length > 64
                    ? `${result.value.substr(0, 61)}...` : result.value)
            }
 
            this.emit('result', { method, endpoint, body, result })
            return result.value
        })
    }
}