Search code examples
javascripthtmltagsprotractorchildren

Protractor, how to get an image element using the classname of the father


I need to check for all the card-container that I have in my html page, the presence of the related image. I have many image tags in this page, so I can't get the elements only by tag name.

Here my html:

<div class="card-container">
  <div class="images">
      <a href="https://www.example.com/" target="_blank" rel="noopener noreferrer" class="card-image" title="Vet side" data-linktext="Vet's Side:1:" data-contentname="" data-contenttype="image" data-componentname="VetImage" data-is-click-tracking-enabled="true">
        <div class="image-loader" style="height: 258px; display: inline;">
          <picture>
            <source srcset="/path/for/an/image.jpg.image.740.555.high.jpg 1x,/path/for/an/image.jpg.image.1480.1110.high.jpg 2x" media="(min-width: 1025px)">
            <source srcset="/path/for/an/image.jpg.image.1024.768.medium.jpg 1x,/path/for/an/image.jpg.image.2048.1536.medium.jpg 2x" media="(min-width: 768px)">
            <source srcset="/path/for/an/image.jpg.image.375.281.low.jpg 1x,/path/for/an/image.jpg.image.750.563.low.jpg 2x" media="(min-width: 0px)">
            <img src="/path/for/an/image.jpg.image.750.563.low.jpg" class="" alt="">
          </picture>
        </div>
      </a>
  </div>

My stepdefinition.js:

let card_container = element.all(by.css('.card-container'));
      card_container.count().then(function(value){
            let cards_count = value;
            console.log('cards count is: ', cards_count);
      })
      next();

As shown in my step definitions, I can get the number of cards. At the moment I have 4 card-container with the same structure and the same tag inside. I have to check that if I have a card-container, I have a related image too. Can someone help me?

Thank you


Solution

  • You can chain the locator for the image elements within the locator for a particular card. My example here checks if a card has images, but you could adapt it for a container.

    describe('illustrates finding images within cards', function() {
    it('finds all cards and checks for images', function() {
        browser.waitForAngularEnabled(false);
        browser.ignoreSynchronization = true;
        browser.get('https://materializecss.com/cards.html');
        element.all(by.css('.card-container')).each(function(card, index) {
            card.element(by.tagName('img')).isPresent().then(function(present) {
                if(!present) {
                    console.log('The '+index +'th card not display image');
                } 
    
                expect(present).toEqual(true); // use jasmine assertion api
            });
        })
    }, 2 * 60 * 1000); //should always come up within 2 minutes
    }); //end of describe
    

    Because the page with which I tested was not angular, I set that accordingly. The .each does the same thing for each element found by all. Chaining the calls to myElement did not work, so I reget by index and check isPresent() to avoid getting errors when images are not found (also it lets me know if one was found). I'm assuming there is only one image per card. If not, you might want to put in a .first() to avoid messages about how there were many and Protractor used the first.