Search code examples
testingember.jsqunit

In qunit, how to query the scrollbar height or detect if a scroll bar is present on an element?


I'm writing tests for my Ember components. One of the more delicate issues is getting a specific element to scroll while not generating scroll bars elsewhere.

I'm trying to write a test that will tell me when my scrolling setup becomes broken. I've tried a variety of syntaxes and strategies. get doesn't work as scrollHeight is not a property. The qunit accessors don't have a get property value. qunit hasProperty lets me detect if a property has a specific value, but not if it's over or under or any comparison to another property.

    const scrollElement = assert.dom('[data-test-user-list-ul-element]');
    var hasVerticalScrollbar = scrollElement.get('scrollHeight') > scrollElement.get('clientHeight');
    assert.true(hasVerticalScrollbar);

UPDATE TO SHOW WORKING ANSWER:

    const element = find('[data-test-user-list-ul-element]');
    const isThereADifference = element.scrollHeight - element.clientHeight;
    assert.true(isThereADifference > 0);

HOW TO TEST THE BODY ELEMENT FOR NO SCROLL BARS:

    const element = this.element;
    const isThereADifference = element.scrollHeight - element.clientHeight;
    assert.true(isThereADifference === 0);

graphic showing desired item to test


Solution

  • you're very close!!

    assert.dom doesn't return an element, and elements and don't have a get property, so you probably want to look at scrollHeight and clientHeight directly:

    For example in My ember-primitives project, I calculate the scroll-top position like this:

    function getTop(element?: Element | null | undefined) {
      assert('Could not find scroller', element);
    
      return element.scrollHeight - element.clientHeight;
    }
    

    so you could define a hasScrollBar like this:

    function hasScrollbar(element?: Element | null | undefined) {
      assert(`Can't check if a scrollbar exists on an element, if the element doesn't exist`, element);
    
      return element.scrollHeight === element.clientHeight;
    }
    

    Here is an example set of tests for working with scroll position.


    Using @ember/test-helpers, you can confidently acquire the element via selector (ignoring elements outside of your test container) via

    import { find } from '@ember/test-helpers';
    
    // ...
    
    const scrollElement = find('[data-test-user-list-ul-element]');
    
    // ...
    
    assert.true(hasScrollbar(scrollElement), 'element has a scrollbar');
    

    References: