What is the difference between browser.pause() and browser.enterRepl()?

alecxe picture alecxe · Jul 14, 2015 · Viewed 17.1k times · Source

In protractor, there is the browser.pause() function:

Beta (unstable) pause function for debugging webdriver tests. Use browser.pause() in your test to enter the protractor debugger from that point in the control flow.

element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();

And, also, there is a less-known one - browser.enterRepl():

Beta (unstable) enterRepl function for entering the repl loop from any point in the control flow. Use browser.enterRepl() in your test. Does not require changes to the command line (no need to add 'debug').

element(by.id('foo')).click();
browser.enterRepl();
// Execution will stop before the next click action.
element(by.id('bar')).click();

From the provided documentation and examples, it is clear that they both are used for debugging the tests. But, it is not clear, what is the difference between the two.

When should we use pause() and when enterRepl()?

Answer

Michael Radionov picture Michael Radionov · Jul 14, 2015

It's explained in the docs in general, but I'll try to get a bit deeper.

Protractor has two modes for debugging: DebuggerRepl and CommandRepl.

Repl here stands for Read-eval-print-loop which usually means that whatever command you type in, it gets evaluated right away in the current context and you are provided with a result immediately. For example, the console in Chrome Developer Tools is kinda a REPL for Chrome's implementation of JavaScript/DOM, or when you run node in terminal, you get a REPL for Node.js's JavaScript context - you can type commands and get the result.


When you use browser.pause() you are activating DebuggerRepl. It brings you a Repl where you can execute commands of this mode. You usually see this list of commands in the terminal:

press c to continue to the next webdriver command
press d to continue to the next debugger statement
type "repl" to enter interactive mode
type "exit" to break out of interactive mode
press ^C to exit

So you can go to the next WebDriver command using c command or jump to the next browser.pause() statement in your test using d command. They are executed right away as you use them. So this mode basically allows you to jump over page states and explore the result. (Note: this mode provides more commands; they do work, but I'm not sure what is the meaning of their output and if they are useful for a Protractor user at all.)


When you use browser.enterRepl() you are activating CommandRepl mode. It allows you to use Protractor methods which you would use in tests, but in an interactive mode. You get access to element, browser and protractor objects, so you could run for example:

> $('.hello').getText();
> 'World'

It prints you back the result immediately, so it's sort of a sandbox where you can query the DOM on the current page state and see the results.

As you may have noticed, the browser.pause() list of commands has a line:

type "repl" to enter interactive mode

It means that when you are in DebuggerRepl mode, you can execute the repl command to activate CommandRepl mode for the current page state where you've just run browser.pause(), so you can play with DOM as if you've just used browser.enterRepl(). You can go back to DebuggerRepl mode using the exit command. But if you've entered to CommandRepl mode using browser.enterRepl(), you can't switch to DebuggerRepl mode.

Also, CommandRepl mode can be activated with a feature called elementExplorer. It can be used without any written tests; it just opens a URL in CommandRepl mode.


tl;dr

To summarize, I believe that they supposed to be used according to how they are called.

browser.pause() - I want a browser to pause exactly in that place so I can see what's happening on the page. Then, on my command, I want it to jump to the next state so I can see what is happening here. If I need more information for current state, I can run repl and use the Protractor API (browser, element, protractor) to investigate. I can then exit this mode and continue jumping through states.

browser.enterRepl() - I want a browser to pause exactly in that place and let me investigate a page using the Protractor API (browser, element, protractor) right away, and I don't need to be able to jump between states of the page.