New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cuked-zombie

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cuked-zombie

use cucumber and acceptance tests with zombie

  • 2.1.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1
decreased by-92.31%
Maintainers
1
Weekly downloads
 
Created
Source

cuked-zombie Build Status

Use cucumber and zombie in your acceptance tests

Cucumber is the Javascript reference-implementation for Behaviour Driven Development. Cucumber allows you to write acceptance tests at a higher abstraction level than unit tests. Zombie is a headless browser written in node, based on Contextify and JSDOM.

Combined they are the best available system to acceptance test your web-application in a browser.

features

cuked-zombie bridges the small gap between this libraries. It provides an api to infect your native cucumber steps. Infected cucumber steps have new (zombie-)features:

  • chai exceptions (and other) will be automatically converted to cucumber failures
  • you can pass arguments to your infected step definitions
  • a bunch of tools that extend the behaviour of zombie (visiting Pages, sending Cookies, using jQuery from the tested site, etc)
  • an easy integration with CSSTester
  • the stack trace from assertions is shortened

other features:

  • a simple task to run all or just single cucumber steps, filter by expression and filter by tags
  • some convenient functions to manage different hosts your testing environment runs on

installation

NPM

npm install cuked-zombie

(this will install Zombie and cucumber-js as well)

Usage

To use cucumber with zombie you need to infect your step definitions and create an infected world (a world that knows how to invoke zombie(s)).

  1. create a step definitions bootstrap and use it as the only stepDefinition in cucumber
  2. create your infected steps (they are compatible to native cucumber steps)
  3. run cucumber with the bootstrap or use the internal task grunt cucumber

For this example it is assumed that your features are stored in features/something.feature. Your infected step definitions should be stored in files grouped by domain in: tests/js/cucumber/domain-step-definitions.js. For example: tests/js/cucumber/database-step-definitions.js includes all steps dealing with database stuff. Have a look at tests/files/my-blog for a full, working structure.

1. creating a step definitions bootstrap

We need to create a native step definition for cucumber, which then infects the other step definitions and creates a new zombie world.

create the file: tests/js/cucumber/bootstrap.js and fill in:

module.exports = function() {
  var cucumberStep = this;
  var cukedZombie = require('cuked-zombie');

  var infected = cukedZombie.infect(cucumberStep, {
    world: require('../world-config'),
    steps: {
      dir: __dirname
    }
  });
};

with this bootstrap config cuked-zombie will search for all files in __dirname (next to your bootstrap.js) with the glob: *-step-definitions.js. These found step definitions are called "infected" because cuked-zombie adds cool (zombie-)features to them.

infected steps options

dir should be an absolute path name, or something that glob() (from current pwd) and require() will find. So its best to use something relative to __dirname

infected world options

Here are some examples for the world-config,js:

module.exports = {
  cli: // path to your symfony command line interface,
  domains: {
    // os.hostname(): domain
    'my-server-name': 'staging.my-blog.com'
  },
  cookies: [{
    name: 'staging_access',
    value: 'tokenU1V2pUK'
  }]
};

If you don't want to switch per os.hostname() you can provide a domain directly:

  domain: 'staging.my-blog.com'

2. creating an infected step

basically every cucumber step can be an infected step (they are backwards compatible, allthough doomed to die). Goto the tests/js/cucumber directory and create a node module like: database-step-definitions.js. The base content is just like this:

module.exports = function() {

  this.Given(..., function(callback) {

  };
  
}

You can paste the this.Given/When/Then() statements from the cucumber-js runner cli output.

3. running cucumber

The easiest way is to run cucumber with the built in grunt task:

adjust your Gruntfile.js accordingly:

  grunt.loadNpmTasks('cuked-zombie');

  grunt.initConfig({
    'cuked-zombie': {
      options: {
        features: 'features',
        bootstrap: "tests/js/cucumber/bootstrap.js",
        format: "pretty"
      }
    }
  });

The full configuration is optional. The values above are the defaults, so if they match for you, you don't have to call grunt.initConfig.

to run all tests, use:

grunt cucumber

to run just the post.feature and post-admin.feature, use:

grunt cucumber --filter post

to filter the scenarios using @-tags apply tags to your scenarios like this:

  @post
  Scenario: Writing a new post
  ...

  @delete
  Scenario: Delete a post
  ...

  @post
  Scenario: Rename a post
  ...

  Scenario: Edit a post
  ...

Now you can run scenarios with the selected tag(s). For example, you can use

grunt cucumber --tags @post

to run the 1st and the 3rd scenarios. Or

grunt cucumber --tags @post,@delete

to run the first three scenarios.

Debugging

Often its REALLY difficult to see what zombie is doing. Starting with version 2.0.x cuked-zombie has now a better fine-grained debug possibility.
Use node debug for this:

DEBUG=* grunt cucumber

windows:

set DEBUG=*
grunt cucumber

You can use debug like this: DEBUG=*,-fixtures this will include all debug messages except for fixtures

  • fixtures: the output from cuked zombie, when fixtures are loaded (with symfony bridge)
  • cuked-zombie: internals from cuked zombie
  • zombie: all messages from zombie (event loop, etc)
  • requests: shows all http resonses and http requests that zombie does during a test (very useful for debugging ajax)

advanced configuration

You can hook into the infected World on creation like this:

var cukedZombie = require('cuked-zombie');
var infected = cukedZombie.infect(cucumberStep, {
  ...
});

var Browser = cukedZombie.Zombie;
Browser.extend(function(browser) {
  browser.on('authenticate', function(authentication) {
    authentication.username = 'myUser';
    authentication.password = 'myPw';
  });
});

infected.World.prototype.init = function(Browser) {
  // add properties to the available for all steps
  // this refers here the same this, bound to a cucumber step
  this.filled = {}; 
  
  this.myStepHelper = function() {
    // ...
  };
};

simplifying step definitions

Image you have several css selectors, that need to be used in more than one step. I would be a code smell to copy and paste them. So lets write some helper functions. You can use this.fn in an infected step to inject functions in to your steps. You have the same scope as in the step for those helpers.

Lets assume your code in an infected step looks like this:

module.exports = function(expect) {

  this.Then(/^a tab with title "([^"]*)" is added$/, function (label, callback) {
    var tab = this.css('ul.nav-tabs:first').exists()
      .css('li:contains("'+label+'")').exists();
    callback();
  });

  this.When(/^I (activate|select) the tab "([^"]*)"$/, function (nulll, label, callback) {
    // copy and paste from above
    var tab = this.css('ul.nav-tabs:first').exists()
      .css('li:contains("'+label+'")').exists();

    this.util.clickLink(tab.css('a').get(), callback);
  });

After refactoring it should look like this:

module.exports = function(expect) {

  this.fn.findTab = function(label) {
    return this.css('ul.nav-tabs:first').exists()
      .css('li:contains("'+label+'")').exists();
  };

  this.Then(/^a tab with title "([^"]*)" is added$/, function (label, callback) {
    this.findTab(label);
    callback();
  });

  this.When(/^I (activate|select) the tab "([^"]*)"$/, function (nulll, label, callback) {
    var tab = this.findTab(label);

    this.util.clickLink(tab.css('a').get(), callback);
  });

Migration to 2.0.0 from 1.2.x

  • read the changelog for zombie 3.x.x from zombie 2.0.x-alpha
  • use the new troubleshooting debug-mode for cuked zombie

Migration to 1.2.x from 1.0.x and 1.1.x

  • uninstall the grunt-cucumber task from your package.json
  • remove the cucumberjs: { ... } section from your Gruntfile
  • if your features are not in the directory features next to the Gruntfile.js or your bootstrap.js is not in tests\js\cucumber adjust the config-section cuked-zombie in your Gruntfile like explained above

Keywords

FAQs

Package last updated on 09 Nov 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc