All files / wdio-sync/src wrapCommand.js

95.24% Statements 20/21
83.33% Branches 5/6
100% Functions 3/3
95.24% Lines 20/21

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                                  6x     6x   6x             6x 6x   4x     6x         6x 4x     2x     6x 6x   6x 6x   6x 6x         6x               6x 5x     1x        
import Future from 'fibers/future'
 
import executeHooksWithArgs from './executeHooksWithArgs'
import { sanitizeErrorMessage } from './utils'
 
/**
 * wraps a function into a Fiber ready context to enable sync execution and hooks
 * @param  {Function}   fn             function to be executed
 * @param  {String}     commandName    name of that function
 * @param  {Function[]} beforeCommand  method to be executed before calling the actual function
 * @param  {Function[]} afterCommand   method to be executed after calling the actual function
 * @return {Function}   actual wrapped function
 */
export default function wrapCommand (commandName, fn) {
    /**
     * helper method that runs the command with before/afterCommand hook
     */
    const runCommand = async function (...args) {
        // save error for getting full stack in case of failure
        // should be before any async calls
        const stackError = new Error()
 
        await executeHooksWithArgs(
            this.options.beforeCommand,
            [commandName, args]
        )
 
        let commandResult
        let commandError
        try {
            commandResult = await fn.apply(this, args)
        } catch (err) {
            commandError = sanitizeErrorMessage(err, stackError)
        }
 
        await executeHooksWithArgs(
            this.options.afterCommand,
            [commandName, args, commandResult, commandError]
        )
 
        if (commandError) {
            throw commandError
        }
 
        return commandResult
    }
 
    return function (...args) {
        const future = new Future()
 
        const result = runCommand.apply(this, args)
        result.then(::future.return, ::future.throw)
 
        try {
            return future.wait()
        } catch (e) {
            /**
             * in case some 3rd party lib rejects without bundling into an error
             */
            Iif (typeof e === 'string') {
                throw new Error(e)
            }
 
            /**
             * in case we run commands where no fiber function was used
             * e.g. when we call deleteSession
             */
            if (e.message.includes('Can\'t wait without a fiber')) {
                return result
            }
 
            throw e
        }
    }
}