问题
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();
回答1:
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();
来源:https://stackoverflow.com/questions/52271294/protractor-async-await-error-unhandled-promise-rejection