Ad

Protractor Async/Await Error: Unhandled Promise Rejection

I'm refactoring my framework with protractor Async/Await to avoid sloppy browser.sleep() all over the code base.

Following are the steps of test followed by code as an example:

Opens ChromeBrowser
Logins with the credentials
Selects a customer
Clicks on "Manage Customer" button.

Could you please help me with below Error:

Report destination:   target\e2e\screenshots\my-report.html
[12:42:21] I/launcher - Running 1 instances of WebDriver
[12:42:21] I/hosted - Using the selenium server at http://127.0.0.1:4444/wd/hub

(node:18208) UnhandledPromiseRejectionWarning: Error: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined.  This could be either because this is a non-angular page or because you
r test involves client-side navigation, which can interfere with Protractor's bootstrapping.  See http://git.io/v4gXM for details"
    at runWaitForAngularScript.then (C:\Users\Ashish\AppData\Roaming\npm\node_modules\protractor\built\browser.js:463:23)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)Error
    at ElementArrayFinder.applyAction_ (C:\Users\Ashish\AppData\Roaming\npm\node_modules\protractor\built\element.js:459:27)
    at ElementArrayFinder.(anonymous function).args [as sendKeys] (C:\Users\Ashish\AppData\Roaming\npm\node_modules\protractor\built\element.js:91:29)
    at ElementFinder.(anonymous function).args [as sendKeys] (C:\Users\Ashish\AppData\Roaming\npm\node_modules\protractor\built\element.js:831:22)
    at customer.cusSelection (C:\Users\Ashish\Documents\Protractor\scripts\CustomerSelection.js:7:50)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
(node:18208) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:18208) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[12:42:25] I/launcher - 0 instance(s) of WebDriver still running
[12:42:25] I/launcher - chrome #01 passed

Below are the Conf.js, Scenario_01.js & corresponding modules for your kind reference:

Conf.js:

var HtmlScreenshotReporter = require('protractor-jasmine2-screenshot-reporter');
var reporter = new HtmlScreenshotReporter({
  dest: 'target/e2e/screenshots',
  filename: 'my-report.html',
  ignoreSkippedSpecs: true,
  reportOnlyFailedSpecs: false,
  captureOnlyFailedSpecs: true  ,
  showSummary: true,
  showQuickLinks: true,
  showConfiguration: true,
  reportTitle: "Protractor Automation Report",
  reportFailedUrl: true,
  inlineImages: true,
});

exports.config = {
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',

suites: {
    Scenario1: './Scenario_01.js', 
},

SELENIUM_PROMISE_MANAGER: false,

capabilities: {
    'shardTestFiles': false,
    'maxInstances': 1,
    'browserName': 'chrome',
    'chromeOptions': {
     'args': ['disable-extensions', 'start-maximized']  //'--headless',
    }
},
allScriptsTimeout: 11000,
getPageTimout: 10000,
restartBrowserBetweenTests: false,
framework: 'jasmine2',
jasmineNodeOpts: {
    onComplete: null,
    isVerbose: true,
    showColors: true, // is True, prints colors to terminal
    includeStackTrace: true,
    defaultTimeoutInterval: 30000, 
    print: function () {}
},
beforeLaunch: function() {
    return new Promise(function(resolve){
    reporter.beforeLaunch(resolve);
    });
},

onPrepare: function () {

    jasmine.getEnv().addReporter(reporter);
    browser.manage().window().maximize();
    browser.manage().timeouts().implicitlyWait(5000);
    jasmine.getEnv().addReporter( new Jasmine2HtmlReporter({savePath: 'target/screenshots'}));
}
};

Scenario_01.js:

describe('Scenario_01', function() {

 var common = require('./scripts/CloseBrowsers.js');    
 var Login = require('./scripts/Login.js'); 
 var customer = require('./scripts/CustomerSelection.js');

 it('Login', function() {
         browser.waitForAngularEnabled(false); 
         Login.login('admin','Adminpwd');
     });

     it('CustomerSelection', function() {
         browser.waitForAngularEnabled(true);
         customer.cusSelection();
     });

afterAll(function(){
    common.closeBrowsers();
});
});

Login.js:

var Login = function() {

     this.login = async function(username, passwordKey){
     await browser.get('http://testwebsite.com/showCust');
     await element(by.name('USER')).sendKeys(username);
     await element(by.name('PASSWORD')).sendKeys(passwordKey);
     await element(by.xpath('/html/body/table/tbody/tr[2]/td/table/tbody/tr/td/table/tbody/tr[3]/td/form/input[9]')).click();
     await element(by.name('YES')).click();
     //browser.sleep(10000);

};
}
module.exports = new Login();

CustomerSelection.js:

var customer = function(){

    this.cusSelection = async function(){

     await element(by.css(['ng-model="selectedChannel.selected"']));
     await element(by.id('customer-auto-complete')).sendKeys('TestCustomer');
     //browser.sleep(500);

     await element.all(by.css('ul[class^="ui-autocomplete"]')).first().click();
    //browser.sleep(1500);
     await element(by.partialButtonText('Manage Customer')).click();
     browser.sleep(10000);      
    };
}
module.exports = new customer();    
Ad

Answer

The error clearly says that promises rejection in CustomerSelection.js is not handled. As per stack trace, await element(by.xpath(...)) is failing to resolve the promise.

The fix for this problem is to have a catch for customer.cusSelection() in Scenario_01.js: & handle the exception there.

By default the return type of every method with an async keyword is a promise. So you should either await on customer.cusSelection() in Scenario_01.js: or use a then-catch clause for assertion.

Something like this -

 it('CustomerSelection', async function() {
     browser.waitForAngularEnabled(true);
     let response = await customer.cusSelection();
 });

 // OR this to catch exceptions.

 it('CustomerSelection', function() {
     browser.waitForAngularEnabled(true);
     customer.cusSelection()
        .then(response => console.log(response))
        .catch(error => console.error(error));
 });

Node.js is moving towards treating unhandled promise rejections similarly to uncaughtException errors in the future.

This means the upcoming node versions will terminate the process whenever it encounters a promise rejection (reference).

Update - Code Snippet for CustomerSelection.js

var customer = function(){

    this.cusSelection = async function(){

    await element(by.css(['ng-model="selectedChannel.selected"']));
    await element(by.id('customer-auto-complete')).sendKeys('TestCustomer');
    //browser.sleep(500);

    // updating this snippet
    // await element.all(by.css('ul[class^="ui-autocomplete"]')).first().click();

    // to following
    let elements = await element.all(by.css('ul[class^="ui-autocomplete"]'));
    elements.first().click();

    //browser.sleep(1500);
    await element(by.partialButtonText('Manage Customer')).click();
    browser.sleep(10000);      
    };
}
module.exports = new customer(); 
Ad
source: stackoverflow.com
Ad