Search code examples
javascriptplaywrightplaywright-test

How to verify that Multiple Images (List of images) are visible using Playwright JavaScript


Locator page.locator('.inner-blocks div.img-block') returns 3 images. I want to verify one by one that all three images are visible on the Page. I am using Page Object Pattern. My page Object class looks like this

Dashboard.js

class dashboardPage{
constructor(page)
{
this.ImageBlocks = page.locator('.inner-blocks div.img-block')
 }
async verifytopSectionThreeBlocks()
{
const totalblocks = await this.ImageBlocks.count()
console.log("total count:"+totalblocks)
for(let i=0;i<totalblocks;i++)
{
   
     return (await this.ImageBlocks.nth(i))
}
}
}
module.exports ={dashboardPage};

And in the test class i am trying to assert that all images are visible.

const result = dashboardpage.verifytopSectionThreeBlocks()
 await expect (result).toBeVisible()

This is giving error. Could anyone point it out and fix what is wrong here.


Solution

  • You can use .all() and a loop:

    import {expect, test} from "@playwright/test"; // ^1.39.0
    
    // sample page to prove example correctness
    const html = `<!DOCTYPE html>
    <html>
    <body>
    <div class="inner-blocks">
      <div class="img-block"></div>
      <div class="img-block"></div>
      <div class="img-block"></div>
    </div>
    <script>
    
    // make the elements visible after 2 seconds
    setTimeout(() => {
      document.querySelectorAll(".img-block").forEach(e => {
        e.textContent = "added";
      });
    }, 2000);
    </script>
    </body>
    </html>`;
    
    test("all image blocks are eventually visible", async ({page}) => {
      await page.setContent(html);
      const imageBlocks = page.locator(".inner-blocks div.img-block");
      await expect(imageBlocks).toHaveCount(3);
    
      for (const imageBlock of await imageBlocks.all()) {
        await expect(imageBlock).toBeVisible();
      }
    });
    

    In a POM:

    // ... same sample HTML and imports
    
    class DashboardPage {
      constructor(page) {
        this.page = page;
        this.imageBlocks = page.locator(".inner-blocks div.img-block");
      }
    
      goto() {
        return this.page.setContent(html); // for testing; replace with goto
      }
    
      get topSectionBlocks() {
        return this.imageBlocks;
      }
    }
    
    // ...
    
    test("3 image blocks are eventually visible", async ({page}) => {
      const dashboard = new DashboardPage(page);
      await dashboard.goto();
      await expect(dashboard.topSectionBlocks).toHaveCount(3);
    
      for (const block of await dashboard.topSectionBlocks.all()) {
        await expect(block).toBeVisible();
      }
    });
    

    A few notes:

    • return ends the function, breaking the loop at the first iteration.
    • Avoid count()/nth().
    • except should be expect.
    • Always format code so it's readable.
    • Class names should always be UpperPascalCase, not camelCase. Similarly, this.ImageBlocks should be camelCase instead of UpperPascalCase, so this.imageBlocks.
    • verifytopSectionThreeBlocks doesn't actually verify anything, just retrieves locators. I'd call it topSectionBlocks or similar.