Skip to content

Commit

Permalink
Finish Cucumber.js example (fixes #8)
Browse files Browse the repository at this point in the history
The example test suite is now in `examples/cucumber`. Run it like so:
    make cucumber.js
  • Loading branch information
Lon Ingram committed Aug 30, 2012
1 parent ea2ef55 commit 41fd5b9
Show file tree
Hide file tree
Showing 13 changed files with 230 additions and 163 deletions.
16 changes: 14 additions & 2 deletions Makefile
Expand Up @@ -7,11 +7,13 @@ NODE_MODULES = $(PWD)/node_modules
# XXX: below may be a bit too clever
PID_FILE := $(PWD)/$(shell echo ".test-server-pid.$$RANDOM")

test:
fixture-server:
@cd tests/fixtures ; \
$(NODE_MODULES)/.bin/http-server -s -p $(TEST_PORT) & \
echo "$$!" > $(PID_FILE) ; \
cd $(PWD)

test: fixture-server
@$(NODE_MODULES)/.bin/mocha tests/test --recursive \
--globals define \
--timeout $(TEST_TIMEOUT) --slow $(TEST_SLOW) \
Expand All @@ -20,4 +22,14 @@ test:
kill -9 `cat $(PID_FILE)` ; rm $(PID_FILE) ; \
exit $$STATUS

.PHONY: test
cucumber.js: fixture-server
@TEST_PORT=$(TEST_PORT) $(NODE_MODULES)/.bin/cucumber.js \
-f pretty \
examples/cucumber/features \
--require examples/cucumber/features/steps \
--require examples/cucumber/features/support ; \
STATUS=$$? ; \
kill -9 `cat $(PID_FILE)` ; rm $(PID_FILE) ; \
exit $$STATUS

.PHONY: test fixture-server cucumber.js
14 changes: 10 additions & 4 deletions README.md
Expand Up @@ -62,15 +62,21 @@ var spooky = new Spooky({
});
```

A minimal example can be found in `examples`.
A minimal example can be found in the repo under `examples`. Run it like this:

``` shell
$ node examples/hello.js
```

See `tests/util/hooks.js` for an example of how to use SpookyJS with [Mocha](http://visionmedia.github.com/mocha).
A small example [Cucumber.js](https://github.com/cucumber/cucumber-js/) test suite can be found in the repo under `examples/cucumber`. To run the suite:

See `tests/features/` for an example using SpookyJS with Cucumber.js.
``` shell
$ make cucumber.js
```

You may change the port that the fixture server runs on by setting the `TEST_PORT` make parameter.

See the tests for an example of how to use SpookyJS with [Mocha](http://visionmedia.github.com/mocha).

## Development

Expand All @@ -82,7 +88,7 @@ SpookyJS includes a suite of unit tests, driven by [Mocha](http://visionmedia.gi
$ make test
```

The following parameters are supported (defaults are in parentheses):
The following make parameters are supported (defaults are in parentheses):

* `TEST_REPORTER` the [Mocha reporter](http://visionmedia.github.com/mocha/#reporters) to use (dot)
* `TEST_PORT` the port to run the fixture web server on (8080)
Expand Down
20 changes: 20 additions & 0 deletions examples/cucumber/features/navigation.feature
@@ -0,0 +1,20 @@
Feature: Navigation
As a SpookyJS user
I would like to use the navigation API

Scenario: Back
Given I go to "/1.html"
And I go to "/2.html"
And I go to "/3.html"
When I go back
Then I should be on "2\.html"
And run

Scenario: Forward
Given I go to "/1.html"
And I go to "/2.html"
And I go to "/3.html"
And I go back
When I go forward
Then I should be on "3\.html"
And run
38 changes: 38 additions & 0 deletions examples/cucumber/features/steps/navigation.js
@@ -0,0 +1,38 @@
module.exports = function () {
this.World = require('../support/world.js').World;

function go(url, callback) {
this.spooky.thenOpen(this.baseUrl + url);
callback();
}

function goBack(callback) {
this.spooky.back();
callback();
}

function goForward(callback) {
this.spooky.forward();
callback();
}

this.Given('I go to "$url"', go);
this.When('I go to "$url"', go);

this.Given('I go back', goBack);
this.When('I go back', goBack);

this.Given('I go forward', goForward);
this.When('I go forward', goForward);

this.Then('I should be on "$url"', function shouldBeOn(url, callback) {
this.spooky.then([{
url: url
}, function () {
this.echo(this.getCurrentUrl());
this.test.assertUrlMatch(new RegExp(url));
}]);
callback();
});
};

23 changes: 23 additions & 0 deletions examples/cucumber/features/steps/run.js
@@ -0,0 +1,23 @@
module.exports = function () {
this.World = require('../support/world.js').World;

this.Then('run', function (callback) {
var world = this;

this.spooky.then(function () {
this.emit('tests.complete', this.test.testResults);
});

this.spooky.once('tests.complete', (function (results) {
if (results.failed) {
callback.fail(results.failures.map(function (failure) {
return 'Failed: ' + failure.message;
}).join('\n'));
} else {
callback();
}
}).bind(this));

this.spooky.run();
});
};
Expand Up @@ -3,4 +3,9 @@ module.exports = function () {
this.spooky.start();
callback();
});

this.After(function (callback) {
this.spooky.destroy();
callback();
});
};
82 changes: 82 additions & 0 deletions examples/cucumber/features/support/world.js
@@ -0,0 +1,82 @@
var util = require('util');
var Spooky = require('../../../../lib/spooky');

var World = function World(callback) {
var spooky;
var world = this;

this.baseUrl = 'http://localhost:' + process.env.TEST_PORT;

try {
spooky = world.spooky = new Spooky({
casper: {
verbose: true,
logLevel: 'debug'
},
child: {
port: 8081,
spooky_lib: './node_modules',
script: './lib/bootstrap.js'
}
}, onCreated);
} catch (e) {
console.dir(e)
console.trace('Spooky.listen failed');
}

//spooky.debug = true;

// track errors
spooky.errors = [];
spooky.on('error', function (error) {
error = error.data ? error.data : error;
spooky.errors.push(error);
if (spooky.debug) {
console.error('spooky error', util.inspect(error));
}
});

spooky.console = [];
spooky.on('console', function (line) {
spooky.console.push(line);
if (spooky.debug) {
console.log(line);
}
});

spooky.on('log', function (entry) {
if (!spooky.debug) { return; }
var message = entry.message;
var event = (message.event || '').toLowerCase();

if (event === 'request') {
console.log('%s: %s %s',
spooky.options.port, message.method, message.request.url);
console.log(' Headers: %s',
util.inspect(message.request.headers));
console.log(' Payload: %s',
util.inspect(JSON.parse(message.request.post)));
} else if (event === 'response') {
console.log('%s: %s %s',
spooky.options.port, message.code,
util.inspect(JSON.parse(message.body)));
} else {
console.log(spooky.options.port + ':');
console.dir(entry);
}
});

function onCreated(err, error, response) {
if (err) {
throw err;
} else if (error) {
console.dir(error);
throw new Error('Failed to initialize context.spooky: ' +
error.code + ' - ' + error.message);
}

callback(world);
}
};

module.exports.World = World;
38 changes: 38 additions & 0 deletions examples/cucumber/steps/navigation.js
@@ -0,0 +1,38 @@
module.exports = function () {
var expect = require('expect.js');
this.World = require('../support/world.js').World;

this.Given('I go to "$path"', function (path, callback) {
this.spooky.thenOpen(this.testUrl + path);
callback();
});

this.Given('I go back', function (callback) {
this.spooky.back();
callback();
});

this.Given('I go forward', function (callback) {
this.spooky.forward();
callback();
});

this.When('I go back', function (callback) {
this.spooky.back();
callback();
});

this.When('I go forward', function (callback) {
this.spooky.forward();
callback();
});

this.Then('I should be on "$path"', function (path, callback) {
this.spooky.then([{
url: this.testUrl + path
}, function () {
this.test.assert(this.getCurrentUrl() === url);
}]);
callback();
});
};
15 changes: 0 additions & 15 deletions tests/features/errors.feature

This file was deleted.

9 changes: 0 additions & 9 deletions tests/features/steps/call.js

This file was deleted.

24 changes: 0 additions & 24 deletions tests/features/steps/errors.js

This file was deleted.

8 changes: 0 additions & 8 deletions tests/features/steps/run.js

This file was deleted.

0 comments on commit 41fd5b9

Please sign in to comment.