Search code examples
javascriptjasmineprotractorbddcucumberjs

How can I use Jasmine with CucumberJS?


How can I use jasmine with cucumberjs ?

I tried this solution from https://stackoverflow.com/a/30763260/5453732

But I have always this error : TypeError: this.expect(...).toBe is not a function at World. (/myApp/tests/e2e/steps/main.step.js:33:79)

Line 39 :

this.expect(element(by.css('[data-el="' + field + '"]')).isPresent()).toBe(true);

app/modules/user/tests/e2e/user.feature

#user.feature

Feature: Login feature
  As a user
  I want authenticate my account

  Scenario: Authentication success
    Given I am on "#/" page
    Given I check if "navbar-menu-user-module" is visible
    Given I wait "3" seconds

/tests/e2e/steps/main.step.js

module.exports = function () {

    this.World = require("../support/world.js").World;

    this.path = '#/';

    this.Given(/^I am on "?([^"]*)"? page$/, function (arg1, callback) {
        browser.get(arg1);
        callback();
    });

    this.Given(/^I wait "?([^"]*)"? seconds$/, function (arg1, callback) {
        browser.sleep(3000);
        callback();
    });

    this.Given(/^I check if "?([^"]*)"? is visible$/, function (field, callback) {
        this.expect(element(by.css('[data-el="' + field + '"]')).isPresent()).toBe(true);
        callback();
    });
};

/tests/e2e/support/world.js

var World, chai, chaiAsPromised;
chai = require('chai');
chaiAsPromised = require('chai-as-promised');

World = function World(callback) {
    chai.use(chaiAsPromised);
    this.expect = chai.expect;
    callback();
}

module.exports.World = World;

protractor.conf.js

/* protractor.conf.js */
exports.config = {
  directConnect: true,

  seleniumServerJar: 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.48.2.jar',

  specs: [
      'app/modules/user/tests/e2e/*.feature'
  ],

  getPageTimeout: 30000,

  capabilities: {
    'browserName': 'chrome',
    version: '',
    platform: 'ANY'
  },

  onPrepare: function() {
      var width = 1024, height = 800;

      browser.get('#/');
      browser.driver.manage().window().setSize(width, height);
  },

  framework: 'cucumber',

  cucumberOpts: {
    require: [
        'tests/e2e/steps/main.step.js'
    ],
    format: 'pretty', // or summary
    keepAlive: false
  },

  onCleanUp: function() {}

};

and my html :

<a data-el="navbar-menu-user-module" href="./#/user">User Module</a>

package.json

{
  "name": "myApp",
  "version": "1.0.0",
  "description": "myApp",
  "dependencies": {
  },
  "devDependencies": {
    "chai": "^3.3.0",
    "chai-as-promised": "^5.1.0",
    "jasmine-core": "~2.3.4",
    ...
    "protractor": "^2.5.1",
    "selenium-server": "^2.48.2",
    "selenium-standalone": "^4.7.0",
    "selenium-webdriver": "^2.48.0",
  }
}

Solution

  • The key thing to remember is that CucumberJS and Jasmine are mutually exclusive. You can only use Jasmine's expect's in conjunction with the Jasmine framework. toBe() is a function that is provided by Jasmine's expect, which doesn't exist in your framework. That is why you are receiving the error you described.

    Since you are using CucumberJS to structure your test you need to use a separate assertion library, the most popular one being Chai. You'll need to use a function provided by Chai for your assertion. In your case you'll probably want to use the equal() function. Also remember that Protractor's isPresent() function returns a promise, so you'll want to use the eventually chain provided by chai-as-promised. All together, the following assertion:

    this.expect(element(by.css('[data-el="' + field + '"]')).isPresent()).toBe(true);
    

    should be changed to:

    this.expect(element(by.css('[data-el="' + field + '"]')).isPresent()).to.eventually.equal(true);