2016-04-25 69 views
2

我對TypeScript和Angular2不是很瞭解,我一直在嘗試使用在TypeScript中編寫的步驟來運行黃瓜的功能。但是,在執行steps.ts文件時,出現以下錯誤::: Ionic2/Angular2:CucumberJs +量角器+ TypeScript配置

[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 

看起來好像黃瓜定義沒有被編譯。

這些是我的(相關)的配置:

我的目錄結構是:

/test/ 
|-/features/ 
|-xpto.feature 
|--/step_definitions 
|---xpto.step.ts 

/package.json

{ 
    "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 && 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" 
    } 
} 

/typings.json

{ 
    "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" 
    } 
} 

/protractor.conf.js:

// @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; 
    } 
}; 

而且一個step_definition的一個例子是:

/test/features/step_definitions/signUp.steps.ts

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 =() => { 

    type Callback = cucumber.CallbackStepDefinition; 
    let step = <cucumber.StepDefinitions>this; 
    let index = new SignInPage(); 
    let page = new SignUpPage(); 

    step.Given(/^I am not authenticated$/, (callback:Callback) => { 
    index.openApp(); 
    callback(); 
    }); 

    step.When(/^I go to register$/, (callback:Callback) => { 
    index.signUp(); 
    callback(); 
    }); 

    step.When(/^I fill 'name' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setName(value); 
    callback(); 
    }); 

    step.When(/^I fill 'email' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setEmail(value); 
    callback(); 
    }); 

    step.When(/^I fill 'password' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setPassword(value); 
    callback(); 
    }); 

    step.When(/^I fill 'passwordConfirmation' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setPasswordConfirmation(value); 
    callback(); 
    }); 

    step.When(/^I press 'Sign up'$/, (callback:Callback) => { 
    page.submit(); 
    callback(); 
    }); 

    step.Then(/^the register form is validated '(.*)'$/, (valid:string, callback:Callback) => { 
    let isValid = (valid === 'true'); 
    expect(page.formIsValid()).to.become(isValid).and.notify(callback); 
    }); 
}; 

有什麼,我已經錯過了?

回答

2

真正的伎倆是解決出口報關,因爲這樣:

import {CallbackStepDefinition} from '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 = function() { 

    let index = new SignInPage(); 
    let page = new SignUpPage(); 

    this.When(/^I go to register$/, (callback:CallbackStepDefinition) => { 
    index.signUp(); 
    callback(); 
    }); 

    this.When(/^I set 'name' with '([^"]*)'$/, (name:string, callback:CallbackStepDefinition) => { 
    page.setName(name); 
    callback(); 
    }); 

    this.When(/^I set 'email' with '([^"]*)'$/, (email:string, callback:CallbackStepDefinition) => { 
    page.setEmail(email); 
    callback(); 
    }); 

    this.When(/^I set 'password' with '([^"]*)'$/, (password:string, callback:CallbackStepDefinition) => { 
    page.setPassword(password); 
    callback(); 
    }); 

    this.When(/^I set 'passwordConfirmation' with '([^"]*)'$/, (value:string, callback:CallbackStepDefinition) => { 
    page.setPasswordConfirmation(value); 
    callback(); 
    }); 

    this.When(/^I press 'Sign up'$/, (callback:CallbackStepDefinition) => { 
    page.submit(); 
    callback(); 
    }); 

    this.Then(/^the register form is validated '(.*)'$/, (valid:string, callback:CallbackStepDefinition) => { 
    let isValid = (valid === 'true'); 
    expect(page.formIsValid()).to.become(isValid).and.notify(callback); 
    }); 
}; 

之後,黃瓜開始相應運行。

0

在你protractor.conf.js你可以從你的cucumberOpts刪除編譯器選項

cucumberOpts: { 
    format: 'pretty', 
    require: [ 
     'test/features/step_definitions/**/*.steps.ts' 
    ], 
    //remove this compiler: 'ts:ts-node/register' 
    }, 

其次,你的signUp.steps.ts應該是這個樣子:

let chai = require('chai').use(require('chai-as-promised')); 
let expect = chai.expect; 

import {SignUpPage} from '../pages/signUp.page'; 
import {SignInPage} from '../pages/signIn.page'; 

import Callback = cucumber.CallbackStepDefinition; 

//1. create a class first 
class SignupSteps{ 

    private index:SignInPage = new SignInPage(); 
    private page:SignUpPage = new SignUpPage(); 

    this.Given(/^I am not authenticated$/, (callback:Callback) => { 
    index.openApp(); 
    callback(); 
    }); 

    this.When(/^I go to register$/, (callback:Callback) => { 
    index.signUp(); 
    callback(); 
    }); 

    this.When(/^I fill 'name' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setName(value); 
    callback(); 
    }); 

    this.When(/^I fill 'email' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setEmail(value); 
    callback(); 
    }); 

    this.When(/^I fill 'password' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setPassword(value); 
    callback(); 
    }); 

    this.When(/^I fill 'passwordConfirmation' with '([^"]*)'$/, (value:string, callback:Callback) => { 
    page.setPasswordConfirmation(value); 
    callback(); 
    }); 

    this.When(/^I press 'Sign up'$/, (callback:Callback) => { 
    page.submit(); 
    callback(); 
    }); 

    this.Then(/^the register form is validated '(.*)'$/, (valid:string, callback:Callback) => { 
    let isValid = (valid === 'true'); 
    expect(page.formIsValid()).to.become(isValid).and.notify(callback); 
    }); 
} 

//2. this is really key, expose the class 
export = SignupSteps; 

您還可以使用https://github.com/timjroberts/cucumber-js-tsflow編寫清潔步驟定義

@ see https://github.com/samvloeberghs/protractor-gherkin-cucumberjs-angular2獲得全面實施。

乾杯