Reputation: 5287
I have a directive that conditionally applies CSS classes to the rendered HTML based on calculations from the width of the window. The directive works just fine... if you resize the window on this page, you can see how items are put in the overflow dropdown: http://ngofficeuifabric.com/demos/uifBreadcrumb. The code for the directive's controller is here: https://github.com/ngOfficeUIFabric/ng-officeuifabric/blob/master/src/components/breadcrumb/breadcrumbDirective.ts#L119-L164.
The challenge we're having is writing reliable tests. Within the tests we want to verify that overflow class is added / removed based on the resizing of the window. We've tried numerous ways of doing this with no luck... seems the resize event will fire, but we'll after the test evaluates. We did have this working by setting the value of the window.innerWidth
property, but that's supposed to be readonly.
We've tried setting the value before all tests as the starting point:
beforeAll(() => {
originalWidth = jQuery(document.body).css('width');
jQuery(document.body).css('width', '800px');
jQuery(window).trigger('resize');
});
and then trying a test like this:
it('should not have is-overflow class', () => {
expect(element).not.toHaveClass('is-overflow');
});
This fails because PhantomJS starts at width=400px so the class is added, but in the beforeAll()
we set it to 800px... the resize event handler kicks in well after this test runs & this, throws an error. Even adding delays with setTimeout()
isn't helping (nor is it desirable).
In other tests, we need to resize the browser multiple times to ensure that things are updating as desired.
it('should change breadcrumb count on resize', inject(($window: ng.IWindowService) => {
let startingWidth: string = jQuery(document.body).css('width');
let visibleLinks: JQuery = element.find('.ms-Breadcrumb-list li');
expect(visibleLinks.length).toBe(4);
let overflowLinks: JQuery = element.find('.ms-ContextualMenu li');
expect(overflowLinks.length).toBe(2);
// narrow down window
jQuery(document.body).css('width', '620px'); // must be less than break point
jQuery(window).trigger('resize');
visibleLinks = element.find('.ms-Breadcrumb-list li');
expect(visibleLinks.length).toBe(2);
overflowLinks = element.find('.ms-ContextualMenu li');
expect(overflowLinks.length).toBe(4);
// back to normal
jQuery(document.body).css('width', startingWidth);
jQuery(window).trigger('resize');
visibleLinks = element.find('.ms-Breadcrumb-list li');
expect(visibleLinks.length).toBe(4);
overflowLinks = element.find('.ms-ContextualMenu li');
expect(overflowLinks.length).toBe(2);
}));
Manually testing the directive shows it does exactly what we want, but after adding numerous console.log()
statements, it's clear that the resize event is not firing right away when we try to call it... rather it's delayed to run AFTER the tests have run.
Is there a reliable way to trigger the resize event to run, and complete, from tests?
Upvotes: 1
Views: 936
Reputation: 51
I think resizing and scrolling are not in the perimeter of unit test. it would be easily doable to check those kind of events inside Integration test (i.e with protractor).
For example i had to develop a scroll-to-top thing in one of my project and the only one way to test it was with integration tests.
Upvotes: 1