Svelte Kit using Testing Library not recognising href value

19 views Asked by At

I am setting up some tests for a Svelte Kit project using Testing Library which are checking for the presence of HTML elements and subsequent values. At the moment I am writing these tests for my application, looking for specific <a> tags and checking they contain an href with a given value.

The problem I am having is that whilst tests work against elements which do not not display a text value (Twitter links with icons), they do not work against text values. For example, this elements and associated test work fine. I have used aria-label to give the test suite a target.

  <a aria-label="Follow us on Twitter" class="icon-item bg-white text-twitter" href="https://twitter.com/Foo" target="_blank" rel="noreferrer">
    <span class="fa-brands fa-twitter"></span>
  </a>


test('footer contains Twitter link', async () => {
    render(Footer);
    const link = screen.getByRole('link', { name: 'Follow us on Twitter' });
    expect(link).toHaveProperty("href", "https://twitter.com/Foo");
});

But this combination do not.

      <div class="col ps-lg-6 ps-xl-8">
        <div class="row mt-5 mt-lg-0">
          <div class="col-6 col-md-3">
            <h5 class="text-uppercase text-white opacity-85 mb-3">Company</h5>
            <ul class="list-unstyled">
              <li class="mb-1">
                <a class="link-600" href="/services">Services</a>
              </li>
              <li class="mb-1">
                <a class="link-600" href="/about">About</a>
              </li>
              <li class="mb-1">
                <a class="link-600" href="/blog">Blog</a>
              </li>
              <li class="mb-1">
                <a class="link-600" href="/contact">Contact</a>
              </li>
            </ul>
          </div>
...SNIP...
            </ul>
          </div>
        </div>
      </div>

Test case

test("footer contains a link to '/services'", async () => {
    render(Footer);
    const link = screen.getByRole('link', { name: 'Services' });
    expect(link).toHaveProperty("href", "/services");
});

What I don't understand is why the matching to Services won't work. When I set this line in the test suite and break on expect(), the value of a is true.

let a = link.hasAttribute("href")

When I change it to a non-existent value, I get the following output from the test suite.

FAIL  src/lib/components/footer.test.js > footer contains a link to '/services'
TestingLibraryElementError: Unable to find an accessible element with the role "link" and name "Servicesa"

Here are the accessible roles:

  heading:

  Name "Our Mission":
  <h5
    class="text-uppercase text-white opacity-85 mb-3 s-1erdp_PvG-Jl"
  />

 ...SNIP...

  --------------------------------------------------
  link:

...SNIP...

  Name "Follow us on Twitter":
  <a
    aria-label="Follow us on Twitter"
    class="icon-item bg-white text-twitter s-1erdp_PvG-Jl"
    href="https://twitter.com/Foo"
    rel="noreferrer"
    target="_blank"
  />

  Name "Services":
  <a
    class="link-600 s-1erdp_PvG-Jl"
    href="/services"
  />

What am I missing here about this test case that is making it break?

1

There are 1 answers

0
3therk1ll On

If anybody else has this issue, I resolved it by access the href separately with getAttribute() and comparing the value with expect().

test("footer contains a link to '/services'", async () => {
    render(Footer);
    const link = screen.getByRole('link', { name: 'Services' });
    expect(link.getAttribute("href")).toEqual("/services")
});