{
  "name": "zombie",
  "version": "2.0.0-alpha24",
  "description": "Insanely fast, full-stack, headless browser testing using Node.js",
  "homepage": "http://zombie.labnotes.org/",
  "author": {
    "name": "Assaf Arkin",
    "email": "assaf@labnotes.org",
    "url": "http://labnotes.org/"
  },
  "contributors": [
    {
      "name": "Bob Lail",
      "email": "bob.lailfamily@gmail.com",
      "url": "http://boblail.tumblr.com/"
    },
    {
      "name": "Brian McDaniel",
      "url": "https://github.com/brianmcd"
    },
    {
      "name": "Damian Janowski"
    },
    {
      "name": "José Valim",
      "email": "jose.valim@plataformatec.com.br",
      "url": "http://blog.plataformatec.com.br/"
    }
  ],
  "keywords": [
    "test",
    "tests",
    "testing",
    "TDD",
    "spec",
    "specs",
    "BDD",
    "headless",
    "browser",
    "html",
    "html5",
    "dom",
    "css",
    "javascript",
    "integration",
    "ajax",
    "full-stack",
    "DSL"
  ],
  "main": "lib/zombie",
  "scripts": {
    "build": "coffee --bare --compile --output lib/zombie src/zombie/*.coffee",
    "prepublish": "coffee --bare --compile --output lib/zombie src/zombie/*.coffee",
    "postpublish": "rm -rf html man7 lib",
    "test": "./node_modules/.bin/mocha"
  },
  "engines": {
    "node": ">= 0.8.0"
  },
  "dependencies": {
    "eventsource": "0.0.8",
    "html5": "0.3.14",
    "jsdom": "0.8.6",
    "mime": "1.2.11",
    "ms": "0.6.1",
    "q": "0.9.7",
    "request": "2.27.0",
    "tough-cookie": "0.9.15",
    "ws": "0.4.31"
  },
  "devDependencies": {
    "coffee-script": "1.6.3",
    "express": "3.4.0",
    "node-syntaxhighlighter": "0.8.1",
    "mocha": "1.13.0",
    "replay": "1.7.0",
    "requirejs": "2.1.8",
    "robotskirt": "2.7.1"
  },
  "repository": {
    "type": "git",
    "url": "http://github.com/assaf/zombie"
  },
  "bugs": {
    "url": "http://github.com/assaf/zombie/issues"
  },
  "licenses": [
    {
      "type": "MIT",
      "url": "http://github.com/assaf/zombie/blob/master/MIT-LICENSE"
    }
  ],
  "readme": "zombie.js(1) -- Insanely fast, headless full-stack testing using Node.js\n========================================================================\n\n\n## The Bite\n\nIf you're going to write an insanely fast, headless browser, how can you not\ncall it Zombie?  Zombie it is.\n\nZombie.js is a lightweight framework for testing client-side JavaScript code in\na simulated environment.  No browser required.\n\nLet's try to sign up to a page and see what happens:\n\n    var Browser = require(\"zombie\");\n    var assert = require(\"assert\");\n\n    // Load the page from localhost\n    browser = new Browser()\n    browser.visit(\"http://localhost:3000/\", function () {\n\n      // Fill email, password and submit form\n      browser.\n        fill(\"email\", \"zombie@underworld.dead\").\n        fill(\"password\", \"eat-the-living\").\n        pressButton(\"Sign Me Up!\", function() {\n\n          // Form submitted, new page loaded.\n          assert.ok(browser.success);\n          assert.equal(browser.text(\"title\"), \"Welcome To Brains Depot\");\n\n        })\n\n    });\n\nWell, that was easy.\n\n\n## Infection\n\nTo install Zombie.js you need Node.js, NPM, a C++ compiler and Python.\n\nOn OS X start by installing XCode, or use the [OSX GCC\ninstaller](https://github.com/kennethreitz/osx-gcc-installer) (less to\ndownload).\n\nNext, assuming you're using the mighty [Homebrew](http://mxcl.github.com/homebrew/):\n\n    $ brew install node\n    $ node --version\n    v0.6.2\n    $ curl http://npmjs.org/install.sh | sudo sh\n    $ npm --version\n    1.0.106\n    $ npm install zombie\n\nOn Ubuntu try these steps:\n\n    $ sudo apt-get install python-software-properties\n    $ sudo add-apt-repository ppa:chris-lea/node.js\n    $ sudo apt-get update\n    $ sudo apt-get install nodejs nodejs-dev npm\n    $ node --version\n    v0.6.2\n    $ npm --version\n    1.0.106\n    $ npm install zombie\n\nOn Windows you'll need Cygwin to get access to GCC, Python, etc.  [Read\nthis](https://github.com/joyent/node/wiki/Building-node.js-on-Cygwin-(Windows))\nfor detailed instructions and troubleshooting.\n\n\n## Walking\n\nTo start off we're going to need a browser.  A browser maintains state across\nrequests: history, cookies, HTML5 local and session stroage, etc.  A browser\nhas a main window, and typically a document loaded into that window.\n\nYou can create a new `Browser` and point it at a document, either by setting the\n`location` property or calling its `visit` function.  As a shortcut, you can\njust call the `Browser.visit` function with a URL and callback:\n\n    Browser.visit(\"http://localhost:3000/\", function (e, browser) {\n      // The browser argument is an instance of Browser class\n      ...\n    })\n\nThe browser will load the document and if the document includes any scripts,\nalso load and execute these scripts.  It will then process some events, for\nexample, anything your scripts do on page load.  All of that, just like a real\nbrowser, happens asynchronously.\n\nTo wait for the page to fully load and process events, you pass `visit` a\ncallback function.  Zombie will then call your callback with `null`, the browser\nobject, the status code of the last response, and an array of errors (hopefully\nempty).  This is JavaScript, so you don't need to declare all these arguments,\nand in fact can access them as `browser.statusCode` and `browser.errors`.\n\n(Why would the first callback argument be `null`?  It works great when using\nasynchronous testing frameworks like\n[Mocha](http://visionmedia.github.com/mocha/).)\n\n\nZombie also supports promises.  When you call functions like `visit`, `wait` or\n`clickLink` without a callback, you get a\n[promise](http://documentup.com/kriskowal/q/#tutorial).  After the browser is\ndone processing, it either fulfills or rejects the promise.\n\nFor example:\n\n    browser.visit(\"http://localhost:3000/\").\n      then(function() {\n        assert.equal(browser.text(\"H1\"), \"Deferred zombies\");\n      }).\n      fail(function(error) {\n        console.log(\"Oops\", error);\n      });\n\nAnother way to simplify your code is to catch all errors from one place using\nevents, for example:\n\n    browser.on(\"error\", function(error) {\n      console.error(error);\n    })\n    browser.visit(\"http://localhost:3000/\").\n      then(function() {\n        assert.equal(browser.text(\"H1\"), \"Deferred zombies\");\n        // Chaining works by returning a promise here\n        return browser.clickLink(\"Hit me\");\n      }).\n      then(function() {\n        assert.equal(browser.text(\"H1\"), \"Ouch\");\n      });\n\n\nMost errors that occur – resource loading and JavaScript execution – are not\nfatal, so rather the stopping processing, they are collected in\n`browser.errors`.  For example:\n\n    browser.visit(\"http://localhost:3000/\", function () {\n      assert.ok(browser.success);\n      if (browser.error )\n        console.dir(\"Errors reported:\", browser.errors);\n    })\n\nWhenever you want to wait for all events to be processed, just call\n`browser.wait` with a callback.  If you know how long the wait is (e.g.\nanimation or page transition), you can pass a duration (in milliseconds) as the\nfirst argument.  You can also pass a function that would return true when done.\n\nOtherwise, Zombie makes best judgement by waiting for about half a second for\nthe page to load resources (scripts, XHR requests, iframes), process DOM events,\nand fire timeouts events.  It is quite common for pages to fire timeout events\nas they load, e.g. jQuery's `onready`.  Usually these events delay the test by\nno more than a few milliseconds.\n\nRead more [on the Browser API](doc/API.md)\n\n\n## Hunting\n\nThere are several ways you can inspect the contents of a document.  For\nstarters, there's the [DOM API](http://www.w3.org/DOM/DOMTR), which you can use\nto find elements and traverse the document tree.\n\nYou can also use CSS selectors to pick a specific element or node list.\nZombie.js implements the [DOM Selector\nAPI](http://www.w3.org/TR/selectors-api/).  These functions are available from\nevery element, the document, and the `Browser` object itself.\n\nTo get the HTML contents of an element, read its `innerHTML` property.  If you\nwant to include the element itself with its attributes, read the element's\n`outerHTML` property instead.  Alternatively, you can call the `browser.html`\nfunction with a CSS selector and optional context element.  If the function\nselects multiple elements, it will return the combined HTML of them all.\n\nTo see the textual contents of an element, read its `textContent` property.\nAlternatively, you can call the `browser.text` function with a CSS selector and\noptional context element.  If the function selects multiple elements, it will\nreturn the combined text contents of them all.\n\nHere are a few examples for checking the contents of a document:\n\n    // Make sure we have an element with the ID brains.\n    assert.ok(browser.query(\"#brains\"));\n\n    // Make sure body has two elements with the class hand.\n    assert.lengthOf(browser.body.queryAll(\".hand\"), 2);\n\n    // Check the document title.\n    assert.equal(browser.text(\"title\"), \"The Living Dead\");\n\n    // Show me the document contents.\n    console.log(browser.html());\n\n    // Show me the contents of the parts table:\n    console.log(browser.html(\"table.parts\"));\n\nCSS selectors are implemented by Sizzle.js.  In addition to CSS 3 selectors you\nget additional and quite useful extensions, such as `:not(selector)`,\n`[NAME!=VALUE]`, `:contains(TEXT)`, `:first/:last` and so forth.  Check out the\n[Sizzle.js documentation](http://sizzlejs.com/) for more details.\n\nRead more [on the Browser API](doc/API.md) and [CSS selectors](doc/selectors.md)\n\n\n## Feeding\n\nYou're going to want to perform some actions, like clicking links, entering\ntext, submitting forms.  You can certainly do that using the [DOM\nAPI](http://www.w3.org/DOM/DOMTR), or several of the convenience functions we're\ngoing to cover next.\n\nTo click a link on the page, use `clickLink` with selector and callback.  The\nfirst argument can be a CSS selector (see _[Hunting](#hunting)_), the `A` element, or the\ntext contents of the `A` element you want to click.\n\nThe second argument is a callback, which much like the `visit` callback gets\nfired after all events are processed.\n\nLet's see that in action:\n\n    // Now go to the shopping cart page and check that we have\n    // three bodies there.\n    browser.clickLink(\"View Cart\", function(e, browser, status) {\n      assert.lengthOf(browser.queryAll(\"#cart .body\"), 3);\n    });\n\nTo submit a form, use `pressButton`.  The first argument can be a CSS selector,\nthe button/input element. the button name (the value of the `name` argument) or\nthe text that shows on the button.  You can press any `BUTTON` element or\n`INPUT` of type `submit`, `reset` or `button`.  The second argument is a\ncallback, just like `clickLink`.\n\nOf course, before submitting a form, you'll need to fill it with values.  For\ntext fields, use the `fill` function, which takes two arguments: selector and\nthe field value.  This time the selector can be a CSS selector, the input\nelement, the field name (its `name` attribute), or the text that shows on the\nlabel associated with that field.\n\nZombie.js supports text fields, password fields, text areas, and also the new\nHTML5 fields types like email, search and url.\n\nThe `fill` function returns a reference to the browser, so you can chain several\nfunctions together.  Its sibling functions `check` and `uncheck` (for check\nboxes), `choose` (for radio buttons) and `select` (for drop downs) work the same\nway.\n\nLet's combine all of that into one example:\n\n    // Fill in the form and submit.\n    browser.\n      fill(\"Your Name\", \"Arm Biter\").\n      fill(\"Profession\", \"Living dead\").\n      select(\"Born\", \"1968\").\n      uncheck(\"Send me the newsletter\").\n      pressButton(\"Sign me up\", function() {\n\n        // Make sure we got redirected to thank you page.\n        assert.equal(browser.location.pathname, \"/thankyou\");\n\n      });\n\nRead more [on the Browser API](doc/API.md)\n\n\n## Believing\n\nHere are some guidelines for writing tests using Zombie,\n[promises](http://documentup.com/kriskowal/q/) and\n[Mocha](http://visionmedia.github.com/mocha/).\n\nLet's start with a simple example:\n\n    describe(\"visit\", function() {\n      before(function(done) {\n        this.browser = new Browser();\n        this.browser\n          .visit(\"/promises\")\n          .then(done, done);\n      });\n\n      it(\"should load the promises page\", function() {\n        assert.equal(this.browser.location.pathname, \"/promises\");\n      });\n    });\n\nThe call to `visit` returns a promise.  Once the page loads successfully, the\npromise will resolve and call the first callback (`done`) with no arguments.\nThis will run the test and evaluate the assertion.  Success.\n\nIf there's an error, the promise fails and calls the second callback (also\n`done`) with an error.  Calling it with an `Error` argument causes Mocha to fail\nthe test.\n\nNow let's chain promises together:\n\n    browser\n      .visit(\"/promises\") // Step 1, open a page\n      .then(function() {\n        // Step 2, fill-in the form\n        browser.fill(\"Email\", \"armbiter@example.com\");\n        browser.fill(\"Password\", \"b100d\");\n      })\n      .then(function() {\n        // Step 3, resolve the next promise with this value.\n        return \"OK\";\n      })\n      .then(function(value) {\n        // Step 4, previous step got us to resolve with this value.\n        assert.equal(value, \"OK\");\n      })\n      .then(function() {\n        // Step 5, click the button and wait for something to happen\n        // by returning another promise.\n        return browser.pressButton(\"Let me in\");\n      })\n      .then(done, done);\n\nThe first step is easy, it loads a page and returns a promise.  When that\npromise resolves, it calls the function of the second step which fills the two\nform fields.  That step is itself a promise that resolves with no value.\n\nThe third step follows, and here we simply return a value.  As a result, the\nnext promise will resolve with that value, as you can see in the fourth step.\nAnother way to think about it is: step four is chained to a new promise with the\nvalue \"OK\".\n\nOn to step five where we press the button, which submits the form and loads the\nresponse page.  All of that happens after `pressButton`, so we want to wait for\nit before moving to the sixth and last step.\n\nLuckily, `pressButton` - just like `wait` - returns a promise which gets\nfulfilled after the browser is done processing events and loading resources.  By\nreturning this new promise, we cause the next step to wait for this promise to\nresolve.\n\nIn short: the very last step is chained to a new promise returned by\n`pressButton`.  You can use this pattern whenever you need to wait, after\n`visit`, `reload`, `clickLink`, etc.\n\n**Note:** In CoffeeScript a function that doesn't end with explicit `return`\nstatement would return the value of the last statement.  If you're seeing\npromises resolved with unexpected values, you may need to end your function\nwith a `return`.\n\nIn real life the ability to chain promises helps us structure complex scenarios\nout of reusable steps.  Like so:\n\n    browser\n      .visit(\"/promises\")\n      .then( fillInName.bind(browser) )\n      .then( fillInAddress.bind(browser) )\n      .then( fillInCreditCard.bind(browser) )\n      .then(function() {\n        browser.pressButton(\"Buy it!\")\n      })\n      .then(done, done);\n\n**Note:** This usage of `bind` is one way to allow a function defined in another\ncontext to use the `Browser` object available in this context.\n\nLet's talk about error handling.  In promise-land, an error causes the promise\nto be rejected.  However, errors are not re-thrown out of the promise, and so\nthis code will fail silently:\n\n    browser\n      .visit(\"/promises\")\n      .then(function() {\n        // This throws an error, which gets caught and rejects\n        // the promise.\n        assert(false, \"I fail!\");\n      })\n      .then(done);\n\nRejection may not be fun, but you've got to deal with it.\n\nWhen a promise gets rejected, that rejection travels down the chain, so you only\nneed to catch it at the very end.  The examples we started with do that by\ncalling `then` with the same callback for handling the resolved and rejected\ncases.\n\nIf your test case expects an error to happen, write it like this:\n\n    browser\n      .visit(\"/promises\")\n      .then(function() {\n        assert(false, \"I fail!\")\n      })\n      .fail(function(error) {\n        // Error happened, test is done.  Otherwise, done never\n        // gets called and Mocha will fail this test.\n        done();\n      });\n\nAnother way of dealing with errors:\n\n    before(function(done) {\n      this.browser = new Browser();\n      this.browser\n        .visit(\"/no-such-page\")\n        .finally(done);\n    });\n\n    it(\"should report an error\", function() {\n      assert(this.browser.error);\n    })\n\nUnlike `then`, the `finally` callback gets called on either success or failure\nand with no value.\n\nRead more [about promises](http://documentup.com/kriskowal/q/).\n\n\n## Readiness\n\nZombie.js supports the following:\n\n- HTML5 parsing and dealing with tag soups\n- [DOM Level 3](http://www.w3.org/DOM/DOMTR) implementation\n- HTML5 form fields (`search`, `url`, etc)\n- CSS3 Selectors with [some extensions](http://sizzlejs.com/)\n- Cookies and [Web Storage](http://dev.w3.org/html5/webstorage/)\n- `XMLHttpRequest` in all its glory\n- `setTimeout`/`setInterval`\n- `pushState`, `popstate` and `hashchange` events\n- `alert`, `confirm` and `prompt`\n- WebSockets and Server-Sent Events\n\n\n## In The Family\n\n**[capybara-zombie](https://github.com/plataformatec/capybara-zombie)** --\nCapybara driver for zombie.js running on top of node.\n\n**[zombie-jasmine-spike](https://github.com/mileskin/zombie-jasmine-spike)** --\nSpike project for trying out Zombie.js with Jasmine\n\n**[Mocha](http://visionmedia.github.com/mocha/)** -- mocha - simple, flexible,\nfun javascript test framework for node.js & the browser. (BDD, TDD, QUnit styles\nvia interfaces)\n\n**[Mink](https://github.com/Behat/Mink)** -- PHP 5.3 acceptance test framework\nfor web applications\n\n\n## Reporting Glitches\n\n**Step 1:** Run Zombie with debugging turned on, the trace will help figure out\nwhat it's doing. For example:\n\n    Browser.debug = true\n    var browser = new Browser()\n    browser.visit(\"http://thedead\", function() {\n      console.log(status, browser.errors);\n      ...\n    });\n\n**Step 2:** Wait for it to finish processing, then dump the current browser\nstate:\n\n   browser.dump();\n\n**Step 3:** If publicly available, include the URL of the page you're trying to\naccess.  Even better, provide a test script I can run from the Node.js console\n(similar to step 1 above).\n\nRead more [about troubleshooting](troubleshoot)\n\n\n## Giving Back\n\n\n* Find [assaf/zombie on Github](http://github.com/assaf/zombie)\n* Fork the project\n* Add tests\n* Make your changes\n* Send a pull request\n\nRead more [about the guts of Zombie.js](guts) and check out the outstanding\n[to-dos](todo).\n\nFollow announcements, ask questions on [the Google\nGroup](https://groups.google.com/forum/?hl=en#!forum/zombie-js)\n\nGet help on IRC: join [zombie.js on Freenode](irc://irc.freenode.net/zombie.js)\nor [web-based IRC](http://webchat.freenode.net/?channels=zombie-js)\n\n\n## Brains\n\nZombie.js is copyright of [Assaf Arkin](http://labnotes.org), released under the\nMIT License\n\nBlood, sweat and tears of joy:\n\n[Bob Lail boblail](http://boblail.tumblr.com/)\n\n[Brian McDaniel](https://github.com/brianmcd)\n\n[Damian Janowski aka djanowski](https://github.com/djanowski)\n\n[José Valim aka josevalim](http://blog.plataformatec.com.br/)\n\n[Justin Latimer](http://www.justinlatimer.com/)\n\nAnd all the fine people mentioned in [the changelog](changelog).\n\nZombie.js is written in\n[CoffeeScript](http://jashkenas.github.com/coffee-script/) for\n[Node.js](http://nodejs.org/)\n\nDOM emulation by Elijah Insua's [JSDOM](http://jsdom.org/)\n\nHTML5 parsing by Aria Stewart's [HTML5](https://github.com/aredridel/html5)\n\nCSS selectors by John Resig's [Sizzle.js](http://sizzlejs.com/)\n\nXPath support using Google's [AJAXSLT](http://code.google.com/p/ajaxslt/)\n\nJavaScript execution contexts using\n[Contextify](https://github.com/brianmcd/contextify)\n\nHTTP(S) requests using [Request](https://github.com/mikeal/request)\n\nCookie support using [Tough Cookie](https://github.com/goinstant/node-cookie)\n\nPromises support via [Q](http://documentup.com/kriskowal/q/)\n\nMagical Zombie Girl by [Toho Scope](http://www.flickr.com/people/tohoscope/)\n\n\n## See Also\n\n**zombie-api**(7), **zombie-troubleshoot**(7), **zombie-selectors**(7),\n**zombie-changelog**(7), **zombie-todo**(7)\n",
  "readmeFilename": "README.md",
  "_id": "zombie@2.0.0-alpha24",
  "dist": {
    "shasum": "b84ba32329c2f496a46faa020db1663b8a658d5a"
  },
  "_from": "zombie@*",
  "_resolved": "https://registry.npmjs.org/zombie/-/zombie-2.0.0-alpha24.tgz"
}
