All files / webdriverio/src/commands/browser debug.js

100% Statements 18/18
100% Branches 8/8
100% Functions 3/3
100% Lines 17/17

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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112                                                                        5x 5x         5x   1x 1x           1x           4x         4x           4x 4x 4x 1x     3x 1x 1x       2x                                                         4x    
 
/**
 *
 * This command helps you to debug your integration tests. It stops the running browser and gives
 * you time to jump into it and check the state of your application (e.g. using dev tools).
 * Your terminal transforms into a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
 * interface that will allow you to try out certain commands, find elements and test actions on
 * them.
 *
 * [![WebdriverIO REPL](https://webdriver.io/img/repl.gif)](https://webdriver.io/img/repl.gif)
 *
 * If you run the WDIO testrunner make sure you increase the timeout property of the test framework
 * you are using (e.g. Mocha or Jasmine) in order to prevent test termination due to a test timeout.
 * Also avoid executing the command with multiple capabilities running at the same time.
 *
 * <iframe width="560" height="315" src="https://www.youtube.com/embed/xWwP-3B_YyE" frameborder="0" allowfullscreen></iframe>
 *
 * <example>
    :debug.js
    it('should demonstrate the debug command', () => {
        $('#input').setValue('FOO')
        browser.debug() // jumping into the browser and change value of #input to 'BAR'
        const value = $('#input').getValue()
        console.log(value) // outputs: "BAR"
    })
 * </example>
 *
 * @alias browser.debug
 * @type utility
 *
 */
 
import serializeError from 'serialize-error'
import WDIORepl from '@wdio/repl'
 
export default function debug(commandTimeout = 5000) {
    const repl = new WDIORepl()
    const { introMessage } = WDIORepl
 
    /**
     * run repl in standalone mode
     */
    if (!process.env.WDIO_WORKER) {
        // eslint-disable-next-line
        console.log(WDIORepl.introMessage)
        const context = {
            browser: this,
            driver: this,
            $: ::this.$,
            $$: ::this.$$
        }
        return repl.start(context)
    }
 
    /**
     * register worker process as debugger target
     */
    process._debugProcess(process.pid)
 
    /**
     * initialise repl in testrunner
     */
    process.send({
        origin: 'debugger',
        name: 'start',
        params: { commandTimeout, introMessage }
    })
 
    let commandResolve = /* istanbul ignore next */ () => {}
    process.on('message', (m) => {
        if (m.origin !== 'debugger') {
            return
        }
 
        if (m.name === 'stop') {
            process._debugEnd(process.pid)
            return commandResolve()
        }
 
        /* istanbul ignore if */
        if (m.name === 'eval') {
            repl.eval(m.content.cmd, global, null, (e, result) => {
                if (e) {
                    process.send({
                        origin: 'debugger',
                        name: 'result',
                        params: {
                            error: true,
                            ...serializeError(e)
                        }
                    })
                }
 
                /**
                 * try to do some smart serializations
                 */
                if (typeof result === 'function') {
                    result = `[Function: ${result.name}]`
                }
 
                process.send({
                    origin: 'debugger',
                    name: 'result',
                    params: { result }
                })
            })
        }
    })
 
    return new Promise((resolve) => (commandResolve = resolve))
}