Scenario: Whenever user sign in using incorrect credentials, a bootstrap modal appears for 1-2 second with message "sorry, incorrect credentials". Below is the HTML of the modal.
<div class="modal-content">
<div class="modal-body note-error text-center ng-binding"> Sorry, invalid credentials! </div>
</div>
I need to verify if the expected error text is equal to actual error text.
My code
PageObject.js
var errorModal = element(by.css('.modal-body.note-error.text-center.ng-binding'));
this.getErrorText = function(){
var until = protractor.ExpectedConditions;
browser.wait(until.textToBePresentInElement(errorModal, "Sorry, invalid credentials!"), 3000, "Not able to find");
return errorModal.getText();
};
Spec.js
expect(Login_Page.getErrorText()).toMatch('Sorry, invalid credentials!');
Output
Message: Expected '' to match 'Sorry, invalid credentials!'.
I dont know why this wait is not working.
I have found the rootCause of the problem after taking a look at your [app]. The error modal you are looking for always exists in
dom
- That meansisPresent()
will always return a true. But it is visible only for 1 or 2 secs on invalid input - That meansisDisplayed()
will returntrue
for those only few secondsThe side effect of this is the return value of
getText()
. It returns only visible innerText. Check the below extract from official documentationThats the reason you are seeing an empty value from
getText()
I suggest a work-around where you extract the innerText by
browser.executeScript()
replace
return errorModal.getText()
withreturn browser.executeScript('return arguments[0].textContent',errorModal)
and you should be all goodLet me know if this works
This is the answer contributed by pittgoose as a part of https://github.com/angular/protractor/issues/4030. I just thought to share over here
Ok, before every webdriver action protractor performs browser.waitForAngular() which waits for all angular scripts to finish running before performing the next action. In this case I believe protractor is waiting for the popup modal to disappear before it performs its search.
Also, I just proved my theory because when I added browser.waitForAngularEnabled(false) before the browser.wait(...) the test passed. Ex:
This would not be an issue with Selenium Webdriver api since it doesn't wait for Angular to load.