0
votes

Need some advice on how to test a window scroll event using vue-test-utils Below is my js

export default {
  created () {
      window.addEventListener('scroll', this.bannerResize);
  },
  methods: {
    topBResize () {
      var header = document.getElementById('topB');
      var pos1 = header.offsetTop;
      var pageYOffset = window.pageYOffset;
      if (pageYOffset > pos1) {
        header.classList.add('sticky');
      } else {
        header.classList.remove('sticky');
      }
    }
  }
}

Below is my unit test using vue-test-utils

import {expect} from 'chai';
import {createLocalVue, shallow} from 'vue-test-utils'

const localVue = createLocalVue()
localVue.use(VueRouter)
localVue.use(Vuex)

const wrapper = shallow(Banner, {
  localVue,
  router,
  attachToDocument: true
})

describe('topB.vue', () => {
  it('topB resize', () => {
    wrapper.setData({ bsize: true })
    const dBanner = wrapper.find('#topB')
    wrapper.trigger('scroll')
    const pageYOffset = 500;
    const pos1 = 200;
    expect(dBanner.classes()).contains('sticky')
  })
})

The test fails when you check if the sticky class is added.

How do I test this method ? I would like to see the sticky class added when window scrolls vertically

Thanks, RD

1

1 Answers

2
votes

You're triggering a scroll event on the div#topB wrapper, but the event listener is on window. JSDom, used by Mocha and Jest, doesn't support the normal JavaScript methods of scrolling window via window.scrollTo/window.scroll, but assuming you mount the test instance with attachToDocument, you can still manually dispatch a scroll event with:

window.dispatchEvent(new CustomEvent('scroll', { detail: 2000 }))

Your event handler would have to parse the event detail for this value and fallback to window.pageYOffset.

// var pageYOffset = window.pageYOffset;
var pageYOffset = !Number.isNaN(e.detail) ? e.detail : window.pageYOffset;

see GitHub repro 1

Alternatively, you can assume the scroll-event handler would be called upon scrolling; and test by running the scroll-event handler (wrapper.vm.topBResize()) directly, and then checking for the expected outcome. You can set window.pageYOffset before running the handler:

window.pageYOffset = 1000;
wrapper.vm.topBResize();
expect(dBanner.classes()).contains('sticky');
wrapper.pageYOffset = 0;

see GitHub repro 2