Test if each element contains an element with protractor

I want to test if each of the elements .elem1 contain an element .elem2. Tried this but doesn't seem to work as expected:

expect(element.all(by.css('.elem1')).all(by.css('.elem2')).isDisplayed()).toBeTruthy();

Upvotes: 2

Views: 1189

Answers (1)

alecxe
alecxe

Reputation: 473833

How about you compare the number of elem1 elements with the number of elem1 elements having elem2 elements inside:

var elem1count = element.all(by.xpath("//*[contains(@class, 'elem1')]")).count();
var elem1WithElem2count = element.all(by.xpath("//*[contains(@class, 'elem1') and .//*[contains(@class, 'elem2')]]")).count();
elem1WithElem2count.then(function (elem1WithElem2count) {
    expect(elem1count).toEqual(elem1WithElem2count);
});

Yeah, that was kind of ugly.

Similar idea, but using filter():

var elem1count = element.all(by.css(".elem1")).count();
var elem1WithElem2count = element.all(by.css(".elem1")).filter(function (elem1) {
    return elem1.element(by.css('.elem2')).isPresent();
}).count();

elem1WithElem2count.then(function (elem1WithElem2count) {
    expect(elem1count).toEqual(elem1WithElem2count);
});

Or, you can solve it with reduce():

var result = element.all(by.css('.elem1')).reduce(function(acc, elem1) {
    return elem1.element(by.css('.elem2')).isPresent().then(function (isPresent) {
        return acc && isPresent;
    });
}, false);
expect(result).toBe(true);

Here, for each elem1 element we are getting a boolean variable indicating whether an elem2 element is present or not and then reducing all of the booleans into a single boolean.

You may also use each() and have an expect check for every elem1:

element.all(by.css('.elem1')).each(function(elem1) {
    expect(elem1.element(by.css('.elem2')).isPresent()).toBe(true);
});

Upvotes: 2

Related Questions