Search code examples
svgplaywrightplaywright-testreact-native-svg

Using Playwright - how to test SVG image by d values?


In the website I'm automating, there are SVG images with icons. In once scenario, the SVG has a special arrow that points up and right.

<svg class="SecretClass" focusable="false" viewBox="0 0 640 640" aria-hidden="true" style="width: 25px;">
 <path d="M460 190L460 460L615 325L460 190Z"></path>
 <path d="M90 356L90 283L487 283L487 356L90 356Z"></path>
 <path d="M162 356L162 -68L88 -68L88 356L162 356Z"></path>
</svg>

How should I validate these values in such an element?


Solution

  • Seems like a good use case for a non-image snapshot:

    import {expect, test} from "@playwright/test"; // ^1.42.1
    
    const html = `
    <svg class="SecretClass" focusable="false" viewBox="0 0 640 640" aria-hidden="true" style="width: 25px;">
     <path d="M460 190L460 460L615 325L460 190Z"></path>
     <path d="M90 356L90 283L487 283L487 356L90 356Z"></path>
     <path d="M162 356L162 -68L88 -68L88 356L162 356Z"></path>
    </svg>`;
    
    test("SVG has correct content", async ({page}) => {
      await page.setContent(html);
      const svg = await page.locator(".SecretClass").innerHTML();
      expect(svg).toMatchSnapshot("svg.html");
    });
    

    On first run, the assertion will fail because the snapshot doesn't exist. On the second run, it'll pass. Always check snapshots to make sure they're capturing what you expect them to--baking in a bad snapshot is a common way to wind up with a false positive.

    You may also want to use .evaluate(el => el.outerHTML()); instead of .innerHTML if the SVG tag itself matters in the assertion.

    A data-testid attribute, or some other unique icon identifier is also possible. This is a bit less fussy--snapshots are particular and will fail if the order of attributes changes. Screenshot tests are also possible for assertions like this but can be subject to other flavors of false positives.

    Beyond this, it's a good idea to provide a bit more context for your structure and use case, such as the parent elements of this SVG, because using CSS to select is discouraged. You'll generally want to choose based on an aria role.

    If the assertion needs to wait, you can wrap it with .toPass().