title: :: Ionic2/Angular2: CucumberJs + Protractor + TypeScript Configuration
body: <p>I'm not really savvy in TypeScript and Angular2 and I've been trying to run the cucumber's features using steps that have been written in TypeScript. However, on executing the steps.ts files, I'm getting the following error:</p>
  
  <pre><code>[launcher] Running 1 instances of WebDriver
  [launcher] Error: TypeError: step.Given is not a function
      at Object.module.exports (/Users/roalcantara/Documents/Tango/tango/test/features/step_definitions/signIn.steps.ts:13:8)
      at /Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/cli/support_code_loader.js:65:25
      at Array.forEach (native)
      at Object.wrapper (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/cli/support_code_loader.js:62:15)
      at Object.initializer (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/cli/support_code_loader.js:24:41)
      at Object.Library (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/support_code/library.js:118:25)
      at Object.getSupportCodeLibrary (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/cli/support_code_loader.js:10:58)
      at Object.getSupportCodeLibrary (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/cli/configuration.js:126:32)
      at Object.getSupportCodeLibrary (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/runtime.js:43:46)
      at Object.start (/Users/roalcantara/Documents/Tango/tango/node_modules/cucumber/lib/cucumber/runtime.js:12:37)
  [launcher] Process exited with error code 100
  </code></pre>
  
  <p>It seems as if the cucumber definitions had not been compiled.</p>
  
  <p>These are my (relevant) configurations:</p>
  
  <p>My directory structure is:</p>
  
  <pre><code>/test/
  |-/features/
  |-xpto.feature
  |--/step_definitions
  |---xpto.step.ts
  </code></pre>
  
  <p>/package.json</p>
  
  <pre><code>{
    "name": "Tango",
    "version": "0.0.1",
    "private": true,
    "devDependencies": {
      "awesome-typescript-loader": "^0.17.0-rc.5",
      "chai": "^3.5.0",
      "chai-as-promised": "^5.3.0",
      "chalk": "^1.1.3",
      "codecov.io": "0.1.6",
      "cucumber": "^0.10.2",
      "cz-conventional-changelog": "^1.1.6",
      "del": "2.2.0",
      "es6-module-loader": "0.17.11",
      "gulp": "3.9.1",
      "gulp-autoprefixer": "^3.1.0",
      "gulp-inline-ng2-template": "^1.1.4",
      "gulp-load-plugins": "1.2.0",
      "gulp-sass": "2.2.0",
      "gulp-sourcemaps": "^1.6.0",
      "gulp-tslint": "^4.3.5",
      "gulp-typescript": "^2.12.1",
      "gulp-util": "^3.0.7",
      "gulp-watch": "4.3.5",
      "ionic-gulp-browserify-typescript": "^1.0.1",
      "ionic-gulp-fonts-copy": "^1.0.0",
      "ionic-gulp-html-copy": "^1.0.0",
      "ionic-gulp-sass-build": "^1.0.0",
      "ionic-gulp-scripts-copy": "^1.0.1",
      "jasmine-core": "2.4.1",
      "jasmine-spec-reporter": "^2.4.0",
      "karma": "0.13.22",
      "karma-chrome-launcher": "^0.2.3",
      "karma-coverage": "0.5.5",
      "karma-jasmine": "0.3.8",
      "karma-mocha-reporter": "^2.0.0",
      "karma-phantomjs-launcher": "1.0.0",
      "nconf": "^0.8.4",
      "phantomjs-prebuilt": "^2.1.7",
      "protractor": "^3.2.2",
      "protractor-cucumber-framework": "^0.5.0",
      "run-sequence": "1.1.5",
      "strip-sourcemap-loader": "0.0.1",
      "systemjs": "0.19.23",
      "traceur": "0.0.102",
      "ts-node": "0.5.5",
      "tslint": "^3.5.0",
      "tslint-eslint-rules": "1.0.1",
      "typescript": "^1.8.10",
      "typings": "^0.7.12"
    },
    "dependencies": {
      "angular2": "2.0.0-beta.13",
      "es6-promise": "3.0.2",
      "es6-shim": "^0.35.0",
      "ionic-angular": "2.0.0-beta.4",
      "ionic-native": "^1.1.0",
      "ionicons": "3.0.0-alpha.3",
      "reflect-metadata": "0.1.2",
      "rxjs": "5.0.0-beta.2",
      "zone.js": "^0.6.11"
    },
    "cordovaPlugins": [
      "cordova-plugin-device",
      "cordova-plugin-console",
      "cordova-plugin-whitelist",
      "cordova-plugin-inappbrowser",
      "cordova-plugin-splashscreen",
      "cordova-plugin-statusbar",
      "cordova-plugin-camera",
      "ionic-plugin-keyboard",
      "onesignal-cordova-plugin",
      "cordova-plugin-file",
      "cordova-plugin-crop"
    ],
    "cordovaPlatforms": [
      "ios",
      "android"
    ],
    "scripts": {
      "build": "gulp --gulpfile test/gulpfile.ts --cwd ./ ionic.build",
      "protractor": "./node_modules/protractor/bin/protractor protractor.conf.js",
      "e2e": "gulp --gulpfile test/gulpfile.ts --cwd ./ test.build.e2e &amp;&amp; npm run protractor",
      "karma": "gulp --gulpfile test/gulpfile.ts --cwd ./ test.karma.debug",
      "postinstall": "typings install",
      "start": "ionic serve",
      "test": "gulp --gulpfile test/gulpfile.ts --cwd ./ test",
      "test.watch": "gulp --gulpfile test/gulpfile.ts --cwd ./ test.watch.build",
      "webdriver-update": "webdriver-manager update"
    }
  }
  </code></pre>
  
  <p>/typings.json</p>
  
  <pre><code>{
    "dependencies": {},
    "devDependencies": {},
    "ambientDependencies": {
      "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160317120654",
      "bluebird": "registry:dt/bluebird#2.0.0+20160319051630",
      "chalk": "registry:dt/chalk#0.4.0+20160317120654",
      "cucumber": "registry:dt/cucumber#0.0.0+20160316171810",
      "del": "registry:dt/del#2.2.0+20160317120654",
      "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654",
      "express": "registry:dt/express#4.0.0+20160317120654",
      "express-serve-static-core": "registry:dt/express-serve-static-core#0.0.0+20160322035842",
      "glob": "registry:dt/glob#5.0.10+20160317120654",
      "gulp": "registry:dt/gulp#3.8.0+20160316155526",
      "gulp-load-plugins": "registry:dt/gulp-load-plugins#0.0.0+20160316155526",
      "gulp-typescript": "registry:dt/gulp-typescript#0.0.0+20160317120654",
      "gulp-util": "registry:dt/gulp-util#3.0.0+20141016163602",
      "jasmine": "registry:dt/jasmine#2.2.0+20160412134438",
      "karma": "registry:dt/karma#0.13.9+20160316155526",
      "log4js": "registry:dt/log4js#0.0.0+20160316155526",
      "mime": "registry:dt/mime#0.0.0+20160316155526",
      "minimatch": "registry:dt/minimatch#2.0.8+20160317120654",
      "node": "registry:dt/node#4.0.0+20160412142033",
      "orchestrator": "registry:dt/orchestrator#0.0.0+20160316155526",
      "q": "registry:dt/q#0.0.0+20160323171452",
      "run-sequence": "registry:dt/run-sequence#0.0.0+20160316155526",
      "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654",
      "serve-static": "registry:dt/serve-static#1.7.1+20160104095738",
      "through2": "registry:dt/through2#2.0.0+20160317120654",
      "vinyl": "registry:dt/vinyl#1.1.0+20160316155526"
    }
  }
  </code></pre>
  
  <p>/protractor.conf.js:</p>
  
  <pre><code>// @AngularClass
  require('ts-node/register');
  var helpers = require('./helpers');
  
  exports.config = {
    /**
     * Angular 2 configuration
     *
     * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching
     * `rootEl`
     *
     */
    useAllAngular2AppRoots: true,
  
    /* LOCALHOST CONFIG */
    seleniumServerJar: "node_modules/protractor/selenium/selenium-server-standalone-2.52.0.jar",
    baseUrl: 'http://localhost:8100',
  
    exclude: [],
  
    allScriptsTimeout: 110000,
  
    framework: 'custom',
    frameworkPath: require.resolve('protractor-cucumber-framework'),
    specs: [
      helpers.root('test/features/**/*.feature')
    ],
    cucumberOpts: {
      format: 'pretty',
      require: [
        'test/features/step_definitions/**/*.steps.ts'
      ],
      compiler: 'ts:ts-node/register'
    },
  
    directConnect: true,
  
    capabilities: {
      'browserName': 'chrome'
    },
  
    onPrepare: function() {
      browser.ignoreSynchronization = false;
    }
  };
  </code></pre>
  
  <p>And an example of one step_definition is:</p>
  
  <p>/test/features/step_definitions/signUp.steps.ts</p>
  
  <pre><code>import cucumber = require('cucumber')
  import {SignUpPage} from '../pages/signUp.page';
  import {SignInPage} from '../pages/signIn.page';
  
  let chai = require('chai').use(require('chai-as-promised'));
  let expect = chai.expect;
  
  export = () =&gt; {
  
    type Callback = cucumber.CallbackStepDefinition;
    let step = &lt;cucumber.StepDefinitions&gt;this;
    let index = new SignInPage();
    let page = new SignUpPage();
  
    step.Given(/^I am not authenticated$/, (callback:Callback) =&gt; {
      index.openApp();
      callback();
    });
  
    step.When(/^I go to register$/, (callback:Callback) =&gt; {
      index.signUp();
      callback();
    });
  
    step.When(/^I fill 'name' with '([^"]*)'$/, (value:string, callback:Callback) =&gt; {
      page.setName(value);
      callback();
    });
  
    step.When(/^I fill 'email' with '([^"]*)'$/, (value:string, callback:Callback) =&gt; {
      page.setEmail(value);
      callback();
    });
  
    step.When(/^I fill 'password' with '([^"]*)'$/, (value:string, callback:Callback) =&gt; {
      page.setPassword(value);
      callback();
    });
  
    step.When(/^I fill 'passwordConfirmation' with '([^"]*)'$/, (value:string, callback:Callback) =&gt; {
      page.setPasswordConfirmation(value);
      callback();
    });
  
    step.When(/^I press 'Sign up'$/, (callback:Callback) =&gt; {
      page.submit();
      callback();
    });
  
    step.Then(/^the register form is validated '(.*)'$/, (valid:string, callback:Callback) =&gt; {
      let isValid = (valid === 'true');
      expect(page.formIsValid()).to.become(isValid).and.notify(callback);
    });
  };
  </code></pre>
  
  <p>Is there anything that I've missed?</p>