How to set or mock element scrollHeight and element clientHeight in testing?

Viewed 930

I have a javascript function which checks if an html

element, el, is a certain size by checking:

function isOverflow(element: string): boolean {
    const el = document.getElementById(element);
    return el.scrollHeight > el.clientHeight
}

I want to test my function. How can I set or mock the scrollHeight and clientHeight?

it('test', () => {
   const el = document.createElement("p")
   el.setAttribute("id", "overflow")

   //How to mock these? This doesn't work "Cannot assign to 'scrollHeight' because it is a read-only property"
   el.clientHeight = 2;
   el.scrollHeight = 1;

   expect(component.isOverflow("overflow")).toBe(true);
  })
2 Answers

Figured it out:

Object.defineProperty(HTMLElement.prototype, 'scrollHeight', { configurable: true, value: 500 })
Object.defineProperty(HTMLElement.prototype, 'clientHeight', { configurable: true, value: 10 })

Since el.clientHeight is a readOnly property, we can't set to it. I think you can use the height and padding to calculate the el.clientHeight, as mentioned in the mdn blog.

Similary, we can calculate for scrollHeight, as it is also a readOnly property.

The scrollHeight value is equal to the minimum height the element would require in order to fit all the content in the viewport without using a vertical scrollbar. The height is measured in the same way as clientHeight: it includes the element's padding, but not its border, margin or horizontal scrollbar (if present). It can also include the height of pseudo-elements such as ::before or ::after. If the element's content can fit without a need for vertical scrollbar, its scrollHeight is equal to clientHeight

var para = document.createElement("P");
para.innerHTML = "This is a paragraph.";

document.getElementById("myDIV").appendChild(para);
var el = document.getElementById("myDIV");
el.style.padding = "10px";
el.style.height = "100px";
console.log(el.clientHeight)
console.log(parseInt(el.style.padding,10) + parseInt(el.style.height,10))
#myDIV {
border: 1px solid  
}
<div id="myDIV">
A DIV element
</div>

Related