All files / webdriverio/src middlewares.js

100% Statements 25/25
100% Branches 6/6
100% Functions 8/8
100% Lines 23/23

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                    276x 36091x 429x 429x 427x   427x 427x           399x 2x 2x 2x     397x   30x 4x 4x 4x   4x   26x                   69x 953x 5x 10x     5x      
 
import refetchElement from './utils/refetchElement'
import implicitWait from './utils/implicitWait'
 
/**
 * This method is an command wrapper for elements that checks if a command is called
 * that wasn't found on the page and automatically waits for it
 *
 * @param  {Function} fn  commandWrap from wdio-sync package (or shim if not running in sync)
 */
export const elementErrorHandler = (fn) => (commandName, commandFn) => {
    return function (...args) {
        return fn(commandName, async () => {
            const element = await implicitWait(this, commandName)
            this.elementId = element.elementId
 
            try {
                const result = await fn(commandName, commandFn).apply(this, args)
 
                /**
                 * assume Safari responses like { error: 'no such element', message: '', stacktrace: '' }
                 * as `stale element reference`
                 */
                if (result && result.error === 'no such element') {
                    const err = new Error()
                    err.name = 'stale element reference'
                    throw err
                }
 
                return result
            } catch (error) {
                if (error.name === 'stale element reference') {
                    const element = await refetchElement(this, commandName)
                    this.elementId = element.elementId
                    this.parent = element.parent
 
                    return await fn(commandName, commandFn).apply(this, args)
                }
                throw error
            }
        }).apply(this)
 
    }
}
 
/**
 * handle single command calls from multiremote instances
 */
export const multiremoteHandler = (wrapCommand) => (commandName) => {
    return wrapCommand(commandName, function (...args) {
        const commandResults = this.instances.map((instanceName) => {
            return this[instanceName][commandName](...args)
        })
 
        return Promise.all(commandResults)
    })
}