Ionic V2 beta.4+ Unit Tests Fail if importing Platform or IONIC_DIRECTIVES


#1

We’ve been working on a couple of apps and have had unit tests covering most of our components. Everythign was good on ionic@2.0.0-beta.3, but after upgrading (4, or 6) we get errors running our unit tests on anything that imports either of the items below in their import chain:

Platform from ionic-angular
IONIC_DIRECTIVES from ionic-angular

The error looks like a polyfill issue, but we have had a working spec-bundle that provides all the required polyfills for PhantomJS, and calls the angular2 setBaseTestProviders.

The error we see:

TypeError: 'undefined' is not an object (near '...stAnimationFrame')])['bind'](window);...')

Our spec-bundle.js:

/*
 * When testing with webpack and ES6, we have to do some extra
 * things get testing to work right. Because we are gonna write test
 * in ES6 to, we have to compile those as well. That's handled in
 * wallaby.js with the karma-webpack plugin. This is the entry
 * file for webpack test. Just like webpack will create a bundle.js
 * file for our client, when we run test, it well compile and bundle them
 * all here.
*/
Error.stackTraceLimit = Infinity;

require('core-js');

// Typescript emit helpers polyfill
require('ts-helpers');
require("es6-shim");

require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/jasmine-patch');

require('rxjs/Rx');

var testing = require('angular2/testing');
var browser = require('angular2/platform/testing/browser');

testing.setBaseTestProviders(
  browser.TEST_BROWSER_PLATFORM_PROVIDERS,
  browser.TEST_BROWSER_APPLICATION_PROVIDERS
);

#2

Since IONIC_DIRECTIVES is not required anymore for any custom components underneath a @Page, we can remove those imports, but the {Platform} imports still cause an issue.


#3

I have been trying to track this down all afternoon again. It was definitely introduced in ionic-angular@2.0.0-beta.4. Leaving all other dependencies upgraded, I can rollback to ionic-angular@2.0.0-beta.3 and unit tests pass. As soon as I npm install beta 4 or higher, they begin failing. The line that fails appears to be in one of the polyfills or Zone:

exports.raf = (window[window['Zone']['__symbol__']('requestAnimationFrame')] || window[window['Zone']['__symbol__']('webkitRequestAnimationFrame')])['bind'](window);

This fails running tests via wallaby or karma (both use PhantomJS)

I’m just trying to figure out what was introduced in beta.4 that causes this to break. I’m not convinced it’s the IONIC_DIRECTIVES or Platform imports causing the problem at this point, but something deeper in ionic that is breaking the zone RAF override in PhantomJS.

The app runs fine either way in the browser so I know my webpack config is good. If I rollback to beta.3 tests all pass again, so I know my wallaby and karma configs are good.

Node Version: 5.0.0 (npm 3.8.8)
OS: Windows 7 64-bit
PhantomJS Version: 1.9.20


#4

I have tracked this down to a change in the util/dom.ts file back in the beta.4 release. I have submitted a PR here: PR for to patch the issue

If anyone else needs to patch this before it’s fixed in the next release, you can:

  1. install the latest beta version
  2. in node_modules/ionic-angular/util/dom.js make the following change:

replace line 24:

exports.raf = (window[window['Zone']['__symbol__']('requestAnimationFrame')] || window[window['Zone']['__symbol__']('webkitRequestAnimationFrame')])['bind'](window);

with:

exports.raf = function() {
    var originalRaf = (window[window['Zone']['__symbol__']('requestAnimationFrame')] || window[window['Zone']['__symbol__']('webkitRequestAnimationFrame')]);
    if(originalRaf !== undefined){
        return originalRaf.bind(window);
    }else{
        return window.requestAnimationFrame.bind(window);
    }
}();