Skip to content

Instantly share code, notes, and snippets.

@rpelizzi
Last active December 16, 2015 19:30
Show Gist options
  • Save rpelizzi/5485917 to your computer and use it in GitHub Desktop.
Save rpelizzi/5485917 to your computer and use it in GitHub Desktop.
Stateful serialized end-to-end testing for ZappaJS
request = require 'request'
_ = require 'underscore'
# API (to be used with mocha):
# it `will rock`, zappaTest [f1, f2, f3] to use a new agent
# or
# it 'will rock', zappaTest agent [f1, f2, f3] to import an existing agent
# The functions share a context that they can use to communicate, but the
# member `@next` is specific to each invocation and will be overwritten at
# each step.
# @new_agent: Creates a new request agent with a separate set of cookies.
# @agent: Every zappaTest starts with one agent.
# @error: Shorthand to fail with a message and a stacktrace
# @done: Skips all remaining steps and concludes the test.
# @next: It can either be used to serialize (err, res) callbacks from the
# request library, or to serialize code blocks. In the former case, it populates
# the shared context with @err and @res (and possibly @res.json). In the latter
# case, it accepts an object of properties to populate the next shared context.
new_agent = -> request.defaults
jar: request.jar()
zappaTest = (agent, steps) ->
if not steps?
steps = agent
agent = new_agent()
(done) ->
ctx =
new_agent: new_agent
error: (s) -> done new Error s
done: done
agent: agent
ctx_steps = _.map steps, (f) ->
(next) ->
->
ctx.next = (errobj, res) ->
if res? # response callback serialization
try res.json = JSON.parse res.body
_.extend ctx, {err: errobj, res: res}
else # block serialization
errobj ?= {}
_.extend ctx, errobj
next()
f.apply ctx
do _.foldr ctx_steps, ((prev, cur) -> cur prev), done
module.exports = zappaTest
# simple example
it 'should fail to login twice (wrong and missing credentials)', zappaTest [
->
@agent.post basePath + '/login',
form:
username: 'foo'
password: 'bar'
@next
->
@res.statusCode.should.equal 401
@next()
->
@agent.post basePath + '/login',
form:
password: 'admin'
email: 'admin@ric.com'
@next
->
@res.statusCode.should.equal 401
@next()
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment