Thursday, September 21Be an Automation Engineer

Debugging Protractor Tests

Most of the editors use node debugger to debug a node.js code.

Protractor has extended node debugger for debugging test scripts. We need to debug tests from Terminal. Also, we can execute additional statements in the debugging mode. This is quite a fantastic feature which will be more helpful for testers to debug protractor tests.

Lets start debugging a protractor failing test.
In the below failing_spec.js spec, protractor tries to identify an element with locator by.binding('Nmmmmmmm'). But http://angularjs.org page has no element with specified locator.

describe('Suite for protractor debugger',function(){
    it('Failing spec',function(){
        browser.get("http://angularjs.org");
        element(by.model('yourName')).sendKeys('Vijay');
        //Element doesn't exist
        var welcomeText = element(by.binding('Nmmmmmmm')).getText();
        expect('Hello '+welcomeText+'!').toEqual('Hello Vijay!')
    });
}); 

If we run the above spec, it will fail with NoSuchElementError. So we need to debug the spec to find out the root cause.

So, we can debug the above spec in 2 ways.

  • browser.pause()
  • browser.debugger()

Lets see how to use browser.pause(). Before start debugging the test script we need to increase the script timeout and framework timeouts in your config file as shown below.

exports.config = {
    capabilities: {
        'directConnect': true,
        'browserName': 'chrome'
    },
    framework: 'jasmine',
    specs: ['./specs/failing_spec.js'],
    allScriptsTimeout: 999999,
    jasmineNodeOpts: {
        defaultTimeoutInterval: 999999
    },
    onPrepare: function () {
        browser.manage().window().maximize();
        browser.manage().timeouts().implicitlyWait(5000);
    }
};

allScriptsTimeout: allScriptsTimeout will set the asynchronous script execution timeout in the test. By default it is 11 sec. We have set to 999999 in the above config file.
defaultTimeoutInterval: For every it block in jasmine there is 30 sec default timeout interval. We have increased it to 999999.

1. browser.pause() :

Before executing the above test we need to add browser.pause() code in failing_spec.js file.

describe('Suite for protractor debugger',function(){
    it('Failing spec',function(){
        browser.get("http://angularjs.org");
        browser.pause();
        element(by.model('yourName')).sendKeys('Vijay');
        //Element doesn't exist
        var welcomeText = element(by.binding('Nmmmmmmm')).getText();
        expect('Hello '+welcomeText+'!').toEqual('Hello Vijay!')
    });
}); 

Run the above spec from command line.

protractor config.js

Observe that debugger starts after launching angularjs.org.

[15:22:06] I/protractor - Encountered browser.pause(). Attaching debugger...
Starting debugger agent.
Debugger listening on 127.0.0.1:5858
ControlFlow::816
| TaskQueue::291
| | (pending) Task::308
| | | TaskQueue::381
| | | | (blocked) Task::441<>
| | Task::310
wd-debug> 

The cursor stops at wd-debug> as shown above.

We have the below options in debug mode.

  1. c: If we type c and hit enter, protractor will execute immediate next step in it’s control flow.

  2. repl: To enter interactive mode we can enter ‘repl’ in terminal. Interactive mode will be helpful to execute protractor statements at run time(Ex: element(by.binding(‘yourName’)).getText()). The result of the executed command will be sent back to terminal.

Continue to use c until you find failing statement.

In our example, the error causing statement is element(by.binding(‘Nmmmmmmm’)).getText(). So we need to use correct locator.

The correct identifier we need to use is by.binding(‘yourName’).

You can also check if our new locator is working. Just enter repl in the debugger terminal and test your new code like below.

wd-debug> repl
> element(by.binding('yourName')).getText()
Hello Vijay!
> 

Enter Ctrl+c to come out of stop debugging.

2. browser.debugger() :

The procedure for debugging using browser.debugger() is same as browser.pause(). The only difference is

  1. Add browser.debugger() in your script instead of browser.pause().
    describe('Suite for protractor debugger',function(){
    it('Failing spec',function(){
        browser.get("http://angularjs.org");
        browser.debugger();
        element(by.model('yourName')).sendKeys('Vijay');
        //Element doesn't exist
        var welcomeText = element(by.binding('Nmmmmmmm')).getText();
        expect('Hello '+welcomeText+'!').toEqual('Hello Vijay!')
    });
    }); 
    
  2. Run the protractor tests with debug command line option
protractor debug config.js

We can also debug protractor tests from IDEs like VSCode and Webstorm.

I will soon add a post to explain the debugging from editors

%d bloggers like this: