Wait for toast to disappear in Protractor

2.3k Views Asked by At

Summary

How do I wait for all toasts to disappear when using Protractor for testing an AngularJS webapp?

More details

I have an AngularJS app, that I am testing using Protractor. I am using angular-toastr to show notifications when things happen in the application.

At one point in the tests, I am unable to click a button because a toast is currently blocking the button. The error I get is:

Element is not clickable at point (898, 712). Other element would receive the click: <div id="toast-container" {...}

So I want to wait for the toast to disappear before continuing. Since angular-toastr does not use $timeout, I can not do this with browser.waitForAngular();

So how should I do it?

What am I NOT trying to do?

I am not trying to test the contents of the toast. Right now, I don't care about the toast at all, I just want to click the button that the toast is obscuring.

3

There are 3 best solutions below

0
On

You can wait for the element being not present (or alternatively not displayed):

browser.wait(function () {
    return $('#toast-container').isPresent().then(function (toastPresent) {
        return !toastPresent;
    });
}, 10000);
0
On

I found a starting point in this blog post: http://docsplendid.com/archives/209

I tweaked it a bit to work with toastr, and this is where it ended up:

var hasClicked = false;

browser.wait(function() {
    var deferred = protractor.promise.defer();

    var elements = element.all(by.className('toast'));
    var count = elements.count().then(function (result) {
        // If there are toasts active, click them to hide them faster.
        if (result > 0 && !hasClicked) {
            elements.click();
            hasClicked = true;
        }
        deferred.fulfill(result === 0);
    });

    return deferred.promise;
});
0
On

Not an answer to your quest but you can click on the Toastr message to make it disappear before attempting to click the button being obscured.

element(by.css(".toast-message")).click()