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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With