Search code examples
javascripttestingjasmineprotractorjasmine-matchers

Failed expectation: "Expected [ ] to be empty array."


Here is the failing test:

describe("Checking errors", function () {
    var scope = {};

    beforeEach(function () {
        browser.get("/#endpoint");
        browser.waitForAngular();

        scope.page = new MyPage();
    });

    it("should not show any errors", function () {
        expect(scope.page.errors).toBeEmptyArray();
    });
});

where MyPage is a Page Object:

var MyPage = function () {
    this.errors = element.all(by.css("div.error-block b.error"))
        .filter(function (elm) {
            return elm.isDisplayed().then(function (value) {
                return value;
            });
        })
        .map(function (elm) {
            return elm.getText();
        });
};

module.exports = MyPage;

where errors supposed to be an array of visible error texts found on a page.

Here is the error we are getting:

Failures:

  1) Checking errors should not show any errors
   Message:
     Expected [  ] to be empty array.
   Stacktrace:
     Error: Failed expectation

FYI, toBeEmptyArray() matcher is coming from jasmine-matchers third-party.


I've tried to print out the value of scope.page.errors this way:

scope.page.errors.then(function (errors) {
    console.log(errors);
});

And it is printed out as []. Array.isArray(errors) returns true.

From what I see, scope.page.errors is an empty array, but the expectation fails. What I a missing?


Solution

  • the answer is four lines down in the protractor src.

    ElementArrayFinder extends Promise, while jasmine-matchers checks first checks that errors is an actual array exactly how Array.isArray is done , which will return false;

    This is also consistent with expect(scope.page.errors.length).toBe(0) being undefined because promises do not have lengths.

    Just run errors.then on your promise, and test that the argument is [] You've also shown that can be done when you ran scope.page.errors.then