0

We (my team) is building design system which consists of number web-components (e.g button, link etc) using lit-elements. Design system comes with spec definition which is documented on our documentation site. We want test CSS class properties applied on the web-components.

We can partially test those using window.getComputedStyle() as follows :-

it('test CSS class properties',()=>{
    const element = document.querySelector('selector');
    const styles = window.getComputedStyle(element );
    const content_property = style.getPropertyValue('justify-content');
    expect(content_property).toEqual('space-between');
});

Here comes the problem, when it renders in the browser, computed style property is different than it is defined in the style-sheet. e.g width:100% which becomes width:1366px (the length of the container).

Right now we are testing only one web-component at time in headless browser which means no CSS overrides.

Is there anyway to compute styles the same way the browser does using JavaScript method/API? So we can have computed CSS class property ahead of time and we can compare it with browser's computed style property.

The ugly way of doing it is creating a dummy element with same class from spec documentation in the browser and check it's CSS class properties against original web-component's CSS class properties.

Any suggestions appreciated!

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Rahul Raut
  • 623
  • 6
  • 21
  • One way to do that is to implement the spec yourselves exactly how each browser does it, that is you care about each browser's differences and quirks, Other than that, You could manage each property on it's own, for example We all know what `width:100%` means so why not test it against parent's width and so. – Rainbow Jun 29 '20 at 10:44
  • @ZohirSalak there is library available for react, named as "jest-styled-component" which makes you do the same thing, thought there might be a way to do it. – Rahul Raut Jun 29 '20 at 11:14

1 Answers1

1

I tested it by comparing the value provided with computedStyle and the width of the body. If it provides the same value, I changed it to 100%. This way it can be solved by comparisons.

const element = document.querySelector("body");
const styles = window.getComputedStyle(element);
const content_property = styles.getPropertyValue("width") == document.body.clientWidth + 'px' ? '100%' : styles.getPropertyValue("width");
console.log(styles.getPropertyValue("width"));
console.log(content_property);
body {
  width: 100%;
}

Let's say, we have a parent and child div. The same method can determine the percentage width.

const parent = document.querySelector(".parent");
const child = document.querySelector(".child");

const styles = window.getComputedStyle(child);
const content_property = styles.getPropertyValue("width") == document.querySelector(".parent").clientWidth * (20/100) + 'px' ? '20%' : styles.getPropertyValue("width");

console.log(styles.getPropertyValue("width"));
console.log(content_property);
.parent {
  position: relative;
  width: 300px;
  height: 300px;
  background: yellow;
}

.child {
  position: absolute;
  width: 20%;
  height: 100%;
  background: pink;
}
<div class="parent">
  <div class="child"></div>
</div>

I also convert color to hex.

const a = document.querySelector(".a");
const styles = window.getComputedStyle(a);

function rgbToHex(r, g, b) {
  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

const rgbColor = JSON.stringify(styles.color);

let r = parseInt(rgbColor.slice(rgbColor.indexOf("(") + 1, rgbColor.indexOf(",")));
let g = parseInt(rgbColor.slice(rgbColor.indexOf(",") + 1, rgbColor.lastIndexOf(",")));
let b = parseInt(rgbColor.slice(rgbColor.lastIndexOf(",") + 1, rgbColor.lastIndexOf(")")));


console.log(styles.getPropertyValue("color"));
console.log(r);
console.log(g);
console.log(b);

console.log(rgbToHex(r, g, b));
.a {
  color: #761f8c;
}
<div class="a"></div>
doğukan
  • 23,073
  • 13
  • 57
  • 69
  • I am not only testing width or height, there are other properties like color which will be converted into rgba format. How to test that stuff as well? – Rahul Raut Jun 29 '20 at 11:06
  • 1
    there is no way to get exact property value. you can use like this methods. for color, you can convert rgb to hex https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb – doğukan Jun 29 '20 at 11:11
  • 1
    @RahulRaut I also added color solution. – doğukan Jun 29 '20 at 11:27