Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expect item in array

One of my test expects an error message text to be one of multiple values. Since getText() returns a promise I cannot use toContain() jasmine matcher. The following would not work since protractor (jasminewd under-the-hood) would not resolve a promise in the second part of the matcher, toContain() in this case:

expect(["Unknown Error", "Connection Error"]).toContain(page.errorMessage.getText());

Question: Is there a way to check if an element is in an array with jasmine+protractor where an element is a promise?

In other words, I'm looking for inverse of toContain() so that the expect() would implicitly resolve the promise passed in.


As a workaround, I can explicitly resolve the promise with then():

page.errorMessage.getText().then(function (text) {
    expect(["Unknown Error", "Connection Error"]).toContain(text);
});

I'm not sure if this is the best option. I would also be okay with a solution based on third-parties like jasmine-matchers.


As an example, this kind of assertion exists in Python:

self.assertIn(1, [1, 2, 3, 4]) 
like image 944
alecxe Avatar asked Feb 26 '15 16:02

alecxe


People also ask

What is the difference between expect array and expect arraycontaining?

expect.not.arrayContaining (array) matches a received array which does not contain all of the elements in the expected array. That is, the expected array is not a subset of the received array. It is the inverse of expect.arrayContaining.

How to test if an object appears within an array?

To test if an object appears within an array, the natural first thought is to use toContain as below: This will actually result in a failure. The matcher is comparing two different instances of the object {b: 2} and expecting two references to the exact same object in memory.

What is expect object in expected objects?

expect.objectContaining (object) matches any received object that recursively matches the expected properties. That is, the expected object is a subset of the received object. Therefore, it matches a received object which contains properties that are present in the expected object.

What is the expected value of the array?

The expected value is also known as the expectation, mathematical expectation, EV, or first moment. Given an array, the task is to calculate the expected value of the array.


2 Answers

Looks like you need a custom matcher. Depending on the version of Jasmine you are using:

With Jasmine 1:

this.addMatchers({
    toBeIn: function(expected) {
        var possibilities = Array.isArray(expected) ? expected : [expected];
        return possibilities.indexOf(this.actual) > -1;
    }
});


With Jasmine 2:

this.addMatchers({
    toBeIn: function(util, customEqualityTesters) {
        return {
            compare: function(actual, expected) {
                var possibilities = Array.isArray(expected) ? expected : [expected];
                var passed = possibilities.indexOf(actual) > -1;

                return {
                    pass: passed,
                    message: 'Expected [' + possibilities.join(', ') + ']' + (passed ? ' not' : '') + ' to contain ' + actual
                };
            }
        };
    }
});


You'll have to execute this in the beforeEach section on each of your describe blocks it's going to be used in.

Your expect would look like:

expect(page.errorMessage.getText()).toBeIn(["Unknown Error", "Connection Error"]);
like image 68
Delian Mitankin Avatar answered Nov 08 '22 12:11

Delian Mitankin


The alternative solution is to use .toMatch() matcher with Regular Expressions and specifically a special character | (called "or"), which allows to match only one entry to succeed:

expect(page.errorMessage.getText()).toMatch(/Unknown Error|Connection Error/);
like image 43
Michael Radionov Avatar answered Nov 08 '22 13:11

Michael Radionov