How to simulate window scrolling in a Angular Unit Test?
Had the same issue recently. For the scrolling to work, you will need to set some dimensions on the body tag, so the window can be scrolled.
var scrollEvent = document.createEvent( 'CustomEvent' ); // MUST be 'CustomEvent'
scrollEvent.initCustomEvent( 'scroll', false, false, null );
var expectedLeft = 123;
var expectedTop = 456;
mockWindow.document.body.style.minHeight = '9000px';
mockWindow.document.body.style.minWidth = '9000px';
mockWindow.scrollTo( expectedLeft, expectedTop );
mockWindow.dispatchEvent( scrollEvent );
Unfortunately this does not work in PhantomJS.
If you are running your tests on Travis CI, you can also use Chrome by adding the following to your .travis.yml
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
And a custom Chrome launcher in your karma config:
module.exports = function(config) {
var configuration = {
// ... your default content
// This is the new content for your travis-ci configuration test
// Custom launcher for Travis-CI
customLaunchers: {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true
};
if(process.env.TRAVIS){
configuration.browsers = ['Chrome_travis_ci'];
}
config.set( configuration );
};
user1906437
Updated on June 07, 2022Comments
-
user1906437 almost 2 years
How can you simulate or mock window scrolling in a Jasmine Unit Test and or set a window.pageYOffset property?
I am using Angular 1.3, Jasmine 2.1 + Karma 0.12.28 and PhantomJS 1.9.12
This is my directive:
'use strict'; (function () { angular .module('myApp') .directive('scrollNews', scrollNews); function scrollNews(){ var directive = { restrict: 'A', scope: false, link: link }; return directive; function link(scope, element) { scope.limit = 2; //add one to the limit scope.loadMore = function() { scope.limit += 1; }; var raw = element[0]; angular.element(window).on('scroll', function () { var scrollFrontier = this.pageYOffset + 800; // when scrollFrontier has reached raw.scrollHeight, run loadMore() if (scrollFrontier >= raw.scrollHeight) { scope.loadMore(); // run the function scope.$digest(); // update the HTML } }); } } })();
And this is my testSpec:
describe('Directive: scroll news', function(){ var element, $scope, $window; beforeEach(module('myApp')); beforeEach(inject(function($compile, $rootScope, _$window_){ $scope = $rootScope; $window = _$window_; element = angular.element('<div scroll-news></div>'); $compile(element)($scope); $scope.$digest(); })); it('should have a limit of 2 when no scrolling have occurred', function(){ expect($scope.limit).toBe(2); }); it('should add one to the limit with loadMore function', function(){ $scope.loadMore(); expect($scope.limit).toBe(3); }); it('should run loadMore() when scrolling has reached a specific height', function(){ element.scrollHeight = 1400; var spy = spyOn($window, 'scrollTo'); $window.scrollTo(0, 1400); expect(spy).toHaveBeenCalled(); expect($scope.limit).toBe(3); // Logs: Expected 2 to be 3. - so loadMore() have not called }); });
I want to simulate or mock a window scroll event to the element.scrollHeight, because if these two reaches the same height my directive runs the loadMore() function. But how can I make unit test of that?
Btw the directive works fine in production :)