Jest-dom: toHaveStyle doesn't take account of CSS custom properties

Created on 16 Jul 2020  路  6Comments  路  Source: testing-library/jest-dom

  • @testing-library/jest-dom version: 5.1.1
  • node version: 12.16.2
  • npm (or yarn) version: 1.22.4

Relevant code or config:

test.only('failing test', () => {
  const style = document.createElement('style')
  style.innerHTML = `
    div {
      --color: blue;
    }
  `

  const {container} = render(`
    <div>
      Hello world
    </div>
  `)

  document.body.appendChild(style)
  document.body.appendChild(container)

  expect(container).toHaveStyle(`--color: blue`)
})

Problem description:

If you were to run the test above, this would fail because toHaveStyle doesn't take account of CSS custom properties.

Suggested solution:

I think the PR #276 caused this behavior. Indeed, the isSubset function has been changed and doesn't use getPropertyValue anymore (see this line).

It seems a custom property on CSSStyleDeclaration can't be accessed simply using the property key (for example computedStyle['--color']), you explicitely have to use getPropertyValue.

I forked the repo and changed back the isSubset function to use getPropertyValue and things work well. That may be a solution (I assume there's a reason why it's been changed so things may not be so simple).

bug help wanted released

All 6 comments

Indeed, #276 was there for a reason, and unfortunately, we had not been covering in a test the support for these custom properties, which would've flagged this when it was introduced. The reason for #276, you can see it by checking #272, which is pretty serious and un-intuitive.

Anyway, we need to figure out how to support both use-cases. I may be able to dig into this soon, but I'll also mention here @just-boris who flagged #272 and authored the fix, because maybe they have an immediate understanding of what could be needed here.

I see two possible options here:

  1. Bring back the getPropertyValue call, while keeping the property getter:
Object.entries(styles).every(
      ([prop, value]) =>
        computedStyle[prop] === value ||
        computedStyle.getPropertyValue(prop.toLowerCase()) === value,
    )
  1. Use only getPropertyValue and write a custom camelCase to dash-case converter, based on the following code: https://github.com/jsdom/cssstyle/blob/master/lib/parsers.js#L711-L722 (sadly, it is not exported)

Option (1) seems reasonable enough without the extra overhead of the case converter.

BTW @thomlom in the mean time, while this is resolved, you need not have a fork. You can fix the version in your package.json to the one prior to the release of that recent fix.

Option 1 seems good to me too! Tests with a CSS custom property would need to be added of course.

@gnapse, sure! I didn't mean "forked" but "cloned" 馃槃

:tada: This issue has been resolved in version 5.11.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

Was this page helpful?
0 / 5 - 0 ratings