Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
masimplo opened this issue May 30, 2016 · 6 comments
Closed

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

masimplo opened this issue May 30, 2016 · 6 comments

Comments

@masimplo
Copy link

masimplo commented May 30, 2016

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
Copy link
Member

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:

  • Created and added to the files list the test/setup.ts file. Karma has this code in the app/app.spec.ts and because it runs specs in alphabetical order one after another in a single sandbox, it works (if you remove the file, it stops working). Wallaby runs test files in a few sandboxes to make it faster, so instead of relying on some spec to set it up for others, I put it in the test/setup.ts and added it to the entryPatterns list.
  • Added the instrument: false flag to libraries to avoid unnecessary instrumentation.
  • Added the test/testUtils.ts to the files list because a couple of specs import the file.
  • Switched the 'www/build/**/*.html' pattern to 'app/**/*.html' one and added the middleware function to map /build (that components are referencing to load HTML templates) to /app. This is not a requirement, just tells wallaby to serve you HTML files from app folder when requested from /build, so that you don't have to build anything before (or during) wallaby runs (when you change your HTML for example).

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

@cklanac
Copy link

cklanac commented Jul 22, 2016

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
Copy link

cklanac commented Jul 22, 2016

(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
Copy link

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 (marcoturi/ionic-boilerplate@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
Copy link
Member

@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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants