Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Jasmine and CucumberJS with Protractor

I'm looking to use Protractor, CucumberJS, and Jasmine for testing my project. How do I use both Jasmine and CucumberJS with Protractor? Here's the project setup I've created:

/path/to/myproj/protractor.conf.js

exports.config = {
  seleniumServerJar: 'node_modules/protractor/selenium/selenium-server-standalone-2.45.0.jar',

  specs: [
    'features/*.feature'
  ],

  baseUrl: 'http://localhost:8080',

  multiCapabilities: [
    {
      'browserName': 'chrome'
    }
  ],

  allScriptsTimeout: 380000,
  getPageTimeout: 20000,

  framework: 'cucumber',

  cucumberOpts: {
    require: 'features/stepDefinitions.js',
    format: 'summary'
  }
};

As you can see, this project uses "cucumber" as the framework. How do I add in the Jasmine framework alongside CucumberJS? Would this be through the Protractor configuration file or someplace else in the code?

/path/to/myproj/features/demo.feature

Feature: Some terse yet descriptive text of what is desired

  Scenario: Some determinable business situation
    Given some precondition

/path/to/myproj/features/stepDefinitions.js

module.exports = function() {
  this.Given(/^some precondition$/, function (callback) {
    expect(true).toEqual(true);
    callback();
  });
};

When this is executed, "expect" is not defined, presumably because Jasmine has not been integrated, and it's expect global along with it. Here's the full error message:

$ $(npm bin)/protractor protractor.conf.js 
Starting selenium standalone server...
[launcher] Running 1 instances of WebDriver
Selenium standalone server started at http://192.168.1.115:59957/wd/hub
(::) failed steps (::)

ReferenceError: expect is not defined
  at World.<anonymous> (/path/to/myproj/features/stepDefinitions.js:3:5)
  at process._tickCallback (node.js:355:11)


Failing scenarios:
/path/to/myproj/features/demo.feature:3 # Scenario: Some determinable business situation

1 scenario (1 failed)
1 step (1 failed)
Shutting down selenium standalone server.
[launcher] 0 instance(s) of WebDriver still running
[launcher] chrome #1 failed 1 test(s)
[launcher] overall: 1 failed spec(s)
[launcher] Process exited with error code 1

/path/to/myproj/package.json

{
  "name": "myproj",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "cucumber": "0.4.9",
    "protractor": "git+https://github.com/angular/protractor.git#0262268fa43b9eefac815d986740efa07bb15818"
  }
}

Note: I'm using a particular commit to the Protractor Git repository in my package.json, because the latest version (2.1.0) has a bug, which prevents integration with CucumberJS.

like image 838
Aristarkh Artemiy Avatar asked Jun 09 '15 19:06

Aristarkh Artemiy


People also ask

Does Protractor use Jasmine?

By default, Protractor uses the Jasmine test framework for its testing interface. This tutorial assumes some familiarity with Jasmine, and we will use version 2.4. This tutorial will set up a test using a local standalone Selenium Server to control browsers.

What is difference between Jasmine and Protractor?

Protractor is best if you followed BDD during development. This is because Protractor supports BDD-based tools like Mocha, Cucumber, and Jasmine. Taking snapshots and comparing them is easy in Protractor. And, to save the best for last—Protractor helps testers run parallel test cases across a number of workstations.


1 Answers

CucumberJS and Jasmine are mutually exclusive; you won't be able to use Jasmine's expects in Cucumber steps. What you have to do instead is load a separate expectation module. I would suggest Chai with the chai-as-promised plugin. (chai-as-promised simplifies the process of writing expectations around promises. Protractor overrides the expect() function in Jasmine to do this for you behind the scenes) Most likely you'll want to do this in your World as that's the easiest way to provide access to it in your Step Definitions. Your World would look something like this:

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;

Then in your Step Definitions file you just load in the World per the CucumberJS documentation and you're Step Definitions will be scoped to provide access to all properties of the World:

module.exports = function() {

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

  this.Given(/^some precondition$/, function (callback) {
    this.expect(true).to.equal(true);
    callback();
  });
};

Now, for some shameless self-promoting: if you're using Protractor with CucumberJS, I would recommend looking at a module I helped build called CukeFarm. It comes preconfigured with a few modules you'll find useful and it provides a number of general Step Definitions that can be used on most any project.

like image 134
Nathan Thompson Avatar answered Oct 16 '22 15:10

Nathan Thompson