wallabyjs / public

Repository for Wallaby.js questions and issues
http://wallabyjs.com
760 stars 45 forks source link

wallaby.js configuration for Ionic2, Typescript and Browserify #620

Closed masimplo closed 8 years ago

masimplo commented 8 years ago

Issue description or question

I am trying to run wallaby.js for an Ionic2 app that uses Typescript and Browserify instead of Webpack (there is a closed issue that solves it with webpack). The project I am trying to set this up for is identical to https://github.com/lathonez/clicker (which is currently the most popular guideline for writing unit tests on Ionic2) which uses this karma config. I have the following configuration. The most recent error I got (tried many alternatives) was Postprocessor run failure: 'import' and 'export' may appear only with 'sourceType: module'

Wallaby.js configuration file

module.exports = function (w) {
  var wallabify = require('wallabify');
  var wallabyPostprocessor = wallabify({
      entryPatterns: [
        'app/**/*.spec.js'
      ]
    }
  );
  return {
    files: [
      'node_modules/es6-shim/es6-shim.js',        // TypeError: undefined is not a constructor (evaluating 'new exports.Map()')
      'node_modules/reflect-metadata/Reflect.js', // 'Uncaught reflect-metadata shim is required when using class decorators'
      'node_modules/zone.js/dist/zone.js',        // Zone.js dependencies (Zone undefined)
      'node_modules/zone.js/dist/jasmine-patch.js',
      'node_modules/zone.js/dist/async-test.js',
      'node_modules/zone.js/dist/fake-async-test.js',
      {pattern: 'node_modules/reflect-metadata/Reflect.js.map', load: false}, // 404 on the same
      {pattern: 'www/build/**/*.html', load: false},
      {pattern: 'app/**/*.ts', load: false},
      {pattern: 'app/**/*.spec.ts', ignore: true}
    ],
    tests: [
      {pattern: 'app/**/*.spec.ts', load: false}
    ],
    testFramework: 'jasmine',
    //compilers: {
    //  'app/**/*.ts': w.compilers.typeScript()
    //},
    postprocessor: wallabyPostprocessor,
    bootstrap: function (w) {
      window.__moduleBundler.loadTests();
    }
  };
};

Code editor or IDE name and version

WebStorm 2016.1

OS name and version

OSX

ArtemGovorov commented 8 years ago

I have cloned the repo you've referenced https://github.com/lathonez/clicker and tried your config, and haven't got the 'import' and 'export' may appear only with 'sourceType: module' error. I have got few other errors that were easy to fix in the config, so here is the config that works for that project:

module.exports = function (w) {
    var wallabify = require('wallabify');
    var wallabyPostprocessor = wallabify({
            entryPatterns: [
                'test/setup.js',
                'app/**/*.spec.js'
            ]
        }
    );
    return {
        files: [
            {pattern: 'node_modules/es6-shim/es6-shim.js', instrument: false},
            {pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false},
            {pattern: 'node_modules/zone.js/dist/zone.js', instrument: false},
            {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false},
            {pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false},
            {pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false},
            {pattern: 'app/**/*.html', load: false},
            {pattern: 'app/**/*.ts', load: false},
            {pattern: 'test/testUtils.ts', load: false},
            {pattern: 'test/setup.ts', load: false},
            {pattern: 'app/**/*.spec.ts', ignore: true}
        ],
        tests: [
            {pattern: 'app/**/*.spec.ts', load: false}
        ],
        testFramework: 'jasmine',
        middleware: function (app, express) {
            app.use('/build', express.static(require('path').join(w.projectCacheDir, 'app')));
        },
        postprocessor: wallabyPostprocessor,
        bootstrap: function (w) {
            window.__moduleBundler.loadTests();
        }
    };
};

plus test/setup.ts file:

import { ADDITIONAL_TEST_BROWSER_PROVIDERS, TEST_BROWSER_STATIC_PLATFORM_PROVIDERS } from '@angular/platform-browser/testing/browser_static';
import { BROWSER_APP_DYNAMIC_PROVIDERS }                from '@angular/platform-browser-dynamic';
import { resetBaseTestProviders, setBaseTestProviders } from '@angular/core/testing';

resetBaseTestProviders();
setBaseTestProviders(
    TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
    [
        BROWSER_APP_DYNAMIC_PROVIDERS,
        ADDITIONAL_TEST_BROWSER_PROVIDERS,
    ]
);

Changes I have made to your config:

Hope it all makes sense. Let me know if this works for you.

cklanac commented 8 years ago

I getting the same issue as @masimakopoulos. 'import' and 'export' may appear only with 'sourceType: module'

I'm using the same repo https://github.com/lathonez/clicker which has been updated since this issue was originally filed. And I'm on a Mac using VSCode.

Wallaby.js Console output

...
[Info] Fri, 22 Jul 2016 19:17:18 GMT wallaby:workers Started run worker instance (immediate) #3
[Info] Fri, 22 Jul 2016 19:17:18 GMT wallaby:workers Started run worker instance (immediate) #5
[Info] Fri, 22 Jul 2016 19:17:19 GMT wallaby:project 'import' and 'export' may appear only with 'sourceType: module'
[Info] Fri, 22 Jul 2016 19:17:19 GMT wallaby:project Test run finished
[Info] Fri, 22 Jul 2016 19:17:19 GMT wallaby:project Test run data re-queued

I've looked at similar issues listed tsify #86 and babelify #103. But their recommendations assume the files are being transpiled in the browser instead of Wallaby's built-in Typescript compiler.

Below are the wallaby.js and app/app.spec.ts files

wallaby.js

module.exports = function (w) {
    var wallabify = require('wallabify');
    var wallabyPostprocessor = wallabify({
        entryPatterns: [
            'test/setup.js',
            'app/**/*.spec.js'
        ]
    }
    );

    return {
        debug: true,
        files: [
            { pattern: 'node_modules/es6-shim/es6-shim.js', instrument: false },
            { pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false },
            { pattern: 'node_modules/zone.js/dist/zone.js', instrument: false },
            { pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false },
            { pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false },
            { pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false },
            { pattern: 'app/**/*.html', load: false },
            { pattern: 'app/**/*.ts', load: false },
            { pattern: 'test/testUtils.ts', load: false },
            { pattern: 'test/diExports.ts', load: false },
            { pattern: 'test/mocks.ts', load: false },
            { pattern: 'test/setup.ts', load: false },
            { pattern: 'app/**/*.spec.ts', ignore: true }
        ],
        tests: [
            { pattern: 'app/**/*.spec.ts', load: false }
        ],
        testFramework: 'jasmine',
        middleware: function (app, express) {
            app.use('/build', express.static(require('path').join(w.projectCacheDir, 'app')));
        },
        postprocessor: wallabyPostprocessor,
        bootstrap: function (w) {
            window.__moduleBundler.loadTests();
        }
    };
};

app/app.spec.ts


import {
  TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS, TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
}                               from '@angular/platform-browser-dynamic/testing';
import { setBaseTestProviders } from '@angular/core/testing';

setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
cklanac commented 8 years ago

(I think) I found the problem... pages/index.ts exports modules using .ts extension.

/app/pages/index.ts

export * from './clickerList/clickerList.ts'; //<== these extensions are the problem
export * from './page2/page2.ts';

So the transpiled version has the extensions hard-coded into the require path. And when Browserify requires the file it loads the .ts version an barfs on the import statements.

~/.vscode/extensions/WallabyJs.wallaby-vscode-1.0.20/projects//instrumented/app/pages/index.js

'use strict';
$_$wp(21);
function __export(m) {
    $_$wf(21);
    for (var p in $_$w(21, 0), m) {
        if ($_$w(21, 1), !exports.hasOwnProperty(p)) {
            $_$w(21, 2), exports[p] = m[p];
        }
    }
}
$_$w(21, 3), __export(require('./clickerList/clickerList.ts')); 
$_$w(21, 4), __export(require('./page2/page2.ts'));
$_$wpe(21);

So, after several hours... it's just a simple fix. Remove the extensions :-)

/app/pages/index.ts

export * from './clickerList/clickerList';
export * from './page2/page2';
murraybauer commented 7 years ago

Hi just purchased Wallaby, but can't get it working for my project!

I'm using the latest clone clicker repo (ionic 3) -> wallaby starts with errors and says 0/0 tests.

I tried to use the config above (the project has changed quite a bit and the additional app.spec.ts file references old angular libraries), but fails with: ​​Error: Missing: SyncTestZoneSpec​​

And your config for the ionic 2 boilerplate project (https://github.com/marcoturi/ionic2-boilerplate/compare/master...wallabyjs:master#diff-df917165808e321c16970c70edfaba6f) errors with: [Error] ​​Postprocessor run failure: Failed to run preprocessors on src/app/app.component.js, Error: Processor must pass a string, an object with code property or an error to done function.​​

Are you please able provide a config that works?

ArtemGovorov commented 7 years ago

@murraybauer I have taken the config described here, and it's working for me after few tweaks. Here is the fork of the clicker with the working wallaby config. It's mostly taken from the config I have referenced, plus I have done small refactoring of TestUtils class that was inside the src/test.ts file with some karma hacks. Wallaby doesn't need those hacks, so I have put the re-used code into the separate testUtils.ts file.

murraybauer commented 7 years ago

Thanks @ArtemGovorov brilliant. All worked perfectly. Appreciate the assistance and speedy reply. Could have not gotten there myself.