Skip to content
This repository
Newer
Older
100644 539 lines (389 sloc) 18.548 kb
92ab4345 »
2010-12-28 Added documentation page for CSS selectors.
1 zombie.js(1) -- Insanely fast, headless full-stack testing using Node.js
2 ========================================================================
8f851ca6 »
2010-12-27 Added troublehsooting guide.
3
650947c9 »
2010-12-21 Fixed documentation link.
4
f35b8e2a »
2010-12-21 First documentation you can actually use.
5 ## The Bite
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
6
671b1be1 »
2012-05-10 Narrower page is easier to edit.
7 If you're going to write an insanely fast, headless browser, how can you not
8 call it Zombie? Zombie it is.
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
9
671b1be1 »
2012-05-10 Narrower page is easier to edit.
10 Zombie.js is a lightweight framework for testing client-side JavaScript code in
11 a simulated environment. No browser required.
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
12
f35b8e2a »
2010-12-21 First documentation you can actually use.
13 Let's try to sign up to a page and see what happens:
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
14
39f70ed1 »
2011-12-16 `Zombie` and `Browser` are no longer distinct namespaces. What you
15 var Browser = require("zombie");
51c04016 »
2010-12-31 Fixed TOC, PDF header and added require("assert") to examples.
16 var assert = require("assert");
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
17
f35b8e2a »
2010-12-21 First documentation you can actually use.
18 // Load the page from localhost
39f70ed1 »
2011-12-16 `Zombie` and `Browser` are no longer distinct namespaces. What you
19 browser = new Browser()
20 browser.visit("http://localhost:3000/", function () {
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
21
f35b8e2a »
2010-12-21 First documentation you can actually use.
22 // Fill email, password and submit form
d9892e82 »
2011-12-28 docs: 'ReferenceError: zombie is not defined' in README.md
23 browser.
f35b8e2a »
2010-12-21 First documentation you can actually use.
24 fill("email", "zombie@underworld.dead").
25 fill("password", "eat-the-living").
39f70ed1 »
2011-12-16 `Zombie` and `Browser` are no longer distinct namespaces. What you
26 pressButton("Sign Me Up!", function() {
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
27
f35b8e2a »
2010-12-21 First documentation you can actually use.
28 // Form submitted, new page loaded.
d9892e82 »
2011-12-28 docs: 'ReferenceError: zombie is not defined' in README.md
29 assert.ok(browser.success);
30 assert.equal(browser.text("title"), "Welcome To Brains Depot");
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
31
f35b8e2a »
2010-12-21 First documentation you can actually use.
32 })
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
33
f35b8e2a »
2010-12-21 First documentation you can actually use.
34 });
f050f196 »
2010-12-11 Fixed loading to keep track of outstanding requests, so waiting
35
f35b8e2a »
2010-12-21 First documentation you can actually use.
36 Well, that was easy.
d6803cc1 »
2010-12-20 Starting to work on documentation
37
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
38
87cb065c »
2011-05-05 Adding a basic infection/installation section.
39 ## Infection
40
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
41 To install Zombie.js you need Node.js, NPM, a C++ compiler and Python.
42
671b1be1 »
2012-05-10 Narrower page is easier to edit.
43 On OS X start by installing XCode, or use the [OSX GCC
44 installer](https://github.com/kennethreitz/osx-gcc-installer) (less to
45 download).
ea9ba0be »
2011-09-03 Updated installation instructions for OS X/Windows
46
c4293673 »
2011-12-05 Updated documentation
47 Next, assuming you're using the mighty [Homebrew](http://mxcl.github.com/homebrew/):
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
48
49 $ brew install node
f15cf06c »
2012-02-29 Fixed readme typo
50 $ node --version
1cf9f9d4 »
2011-11-24 Updated installation instructions for Ubuntu.
51 v0.6.2
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
52 $ curl http://npmjs.org/install.sh | sudo sh
53 $ npm --version
1cf9f9d4 »
2011-11-24 Updated installation instructions for Ubuntu.
54 1.0.106
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
55 $ npm install zombie
56
57 On Ubuntu try these steps:
58
1cf9f9d4 »
2011-11-24 Updated installation instructions for Ubuntu.
59 $ sudo apt-get install python-software-properties
60 $ sudo add-apt-repository ppa:chris-lea/node.js
61 $ sudo apt-get update
62 $ sudo apt-get install nodejs nodejs-dev npm
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
63 $ node --version
1cf9f9d4 »
2011-11-24 Updated installation instructions for Ubuntu.
64 v0.6.2
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
65 $ npm --version
1cf9f9d4 »
2011-11-24 Updated installation instructions for Ubuntu.
66 1.0.106
28c7d277 »
2011-12-11 Fix typo in readme
67 $ npm install zombie
099817ad »
2011-07-28 Updated README to explain installation procedure for OS X and Ubuntu.
68
ea9ba0be »
2011-09-03 Updated installation instructions for OS X/Windows
69 On Windows you'll need Cygwin to get access to GCC, Python, etc. [Read
671b1be1 »
2012-05-10 Narrower page is easier to edit.
70 this](https://github.com/joyent/node/wiki/Building-node.js-on-Cygwin-(Windows))
71 for detailed instructions and troubleshooting.
87cb065c »
2011-05-05 Adding a basic infection/installation section.
72
f35b8e2a »
2010-12-21 First documentation you can actually use.
73
2d4a116a »
2010-12-22 Walking, just walking.
74 ## Walking
f35b8e2a »
2010-12-21 First documentation you can actually use.
75
671b1be1 »
2012-05-10 Narrower page is easier to edit.
76 To start off we're going to need a browser. A browser maintains state across
9aa1c430 »
2012-07-14 Minor cleanups in README.md.
77 requests: history, cookies, HTML5 local and session stroage, etc. A browser
671b1be1 »
2012-05-10 Narrower page is easier to edit.
78 has a main window, and typically a document loaded into that window.
f35b8e2a »
2010-12-21 First documentation you can actually use.
79
671b1be1 »
2012-05-10 Narrower page is easier to edit.
80 You can create a new `Browser` and point it at a document, either by setting the
81 `location` property or calling its `visit` function. As a shortcut, you can
82 just call the `Browser.visit` function with a URL and callback:
39f70ed1 »
2011-12-16 `Zombie` and `Browser` are no longer distinct namespaces. What you
83
84 Browser.visit("http://localhost:3000/", function (e, browser) {
85 // The browser argument is an instance of Browser class
86 ...
87 })
2e14582d »
2010-12-22 Added `querySelector` and `querySelectorAll` based on the [DOM
88
671b1be1 »
2012-05-10 Narrower page is easier to edit.
89 The browser will load the document and if the document includes any scripts,
90 also load and execute these scripts. It will then process some events, for
91 example, anything your scripts do on page load. All of that, just like a real
c4293673 »
2011-12-05 Updated documentation
92 browser, happens asynchronously.
2e14582d »
2010-12-22 Added `querySelector` and `querySelectorAll` based on the [DOM
93
671b1be1 »
2012-05-10 Narrower page is easier to edit.
94 To wait for the page to fully load and process events, you pass `visit` a
95 callback function. Zombie will then call your callback with `null`, the browser
96 object, the status code of the last response, and an array of errors (hopefully
97 empty). This is JavaScript, so you don't need to declare all these arguments,
98 and in fact can access them as `browser.statusCode` and `browser.errors`.
ba74cd1f »
2011-12-06 Updated documentation
99
671b1be1 »
2012-05-10 Narrower page is easier to edit.
100 (Why would the first callback argument be `null`? It works great when using
101 asynchronous testing frameworks like
9aa1c430 »
2012-07-14 Minor cleanups in README.md.
102 [Mocha](http://visionmedia.github.com/mocha/).)
ba74cd1f »
2011-12-06 Updated documentation
103
05dbd1c7 »
2011-11-21 Updaded documentation to describe new error handling behavior
104
dadf6639 »
2012-05-10 [Closes #309] Added promises.
105 Zombie also supports promises. When you call functions like `visit`, `wait` or
106 `clickLink` without a callback, you get a
9aa1c430 »
2012-07-14 Minor cleanups in README.md.
107 [promise](http://documentup.com/kriskowal/q/#tutorial). After the browser is
dadf6639 »
2012-05-10 [Closes #309] Added promises.
108 done processing, it either fulfills or rejects the promise.
109
110 For example:
111
112 browser.visit("http://localhost:3000/").
113 then(function() {
114 assert.equal(browser.text("H1"), "Deferred zombies");
115 }).
116 fail(function(error) {
117 console.log("Oops", error);
22000c69 »
2012-05-10 New API for setting authentication credentials.
118 });
dadf6639 »
2012-05-10 [Closes #309] Added promises.
119
120 Another way to simplify your code is to catch all errors from one place using
121 events, for example:
122
123 browser.on("error", function(error) {
124 console.error(error);
125 })
126 browser.visit("http://localhost:3000/").
127 then(function() {
128 assert.equal(browser.text("H1"), "Deferred zombies");
129 // Chaining works by returning a promise here
130 return browser.clickLink("Hit me");
131 }).
132 then(function() {
133 assert.equal(browser.text("H1"), "Ouch");
22000c69 »
2012-05-10 New API for setting authentication credentials.
134 });
dadf6639 »
2012-05-10 [Closes #309] Added promises.
135
136
137 Most errors that occur – resource loading and JavaScript execution – are not
138 fatal, so rather the stopping processing, they are collected in
139 `browser.errors`. For example:
2e14582d »
2010-12-22 Added `querySelector` and `querySelectorAll` based on the [DOM
140
ba74cd1f »
2011-12-06 Updated documentation
141 browser.visit("http://localhost:3000/", function () {
bee403ea »
2011-12-16 [Closes #227] Fixed error in example
142 assert.ok(browser.success);
ba74cd1f »
2011-12-06 Updated documentation
143 if (browser.error )
144 console.dir("Errors reported:", browser.errors);
145 })
2e14582d »
2010-12-22 Added `querySelector` and `querySelectorAll` based on the [DOM
146
671b1be1 »
2012-05-10 Narrower page is easier to edit.
147 Whenever you want to wait for all events to be processed, just call
148 `browser.wait` with a callback. If you know how long the wait is (e.g.
149 animation or page transition), you can pass a duration (in milliseconds) as the
150 first argument. You can also pass a function that would return true when done.
c4293673 »
2011-12-05 Updated documentation
151
671b1be1 »
2012-05-10 Narrower page is easier to edit.
152 Otherwise, Zombie makes best judgement by waiting for about half a second for
153 the page to load resources (scripts, XHR requests, iframes), process DOM events,
154 and fire timeouts events. It is quite common for pages to fire timeout events
155 as they load, e.g. jQuery's `onready`. Usually these events delay the test by
156 no more than a few milliseconds.
2e14582d »
2010-12-22 Added `querySelector` and `querySelectorAll` based on the [DOM
157
8dd13f78 »
2012-04-26 [Closes #310] Deadlink in README
158 Read more [on the Browser API](API)
2decad44 »
2010-12-29 Moved "the guts" to its own page.
159
2e14582d »
2010-12-22 Added `querySelector` and `querySelectorAll` based on the [DOM
160
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
161 ## Hunting
162
671b1be1 »
2012-05-10 Narrower page is easier to edit.
163 There are several ways you can inspect the contents of a document. For
164 starters, there's the [DOM API](http://www.w3.org/DOM/DOMTR), which you can use
165 to find elements and traverse the document tree.
c4293673 »
2011-12-05 Updated documentation
166
671b1be1 »
2012-05-10 Narrower page is easier to edit.
167 You can also use CSS selectors to pick a specific element or node list.
168 Zombie.js implements the [DOM Selector
169 API](http://www.w3.org/TR/selectors-api/). These functions are available from
170 every element, the document, and the `Browser` object itself.
c4293673 »
2011-12-05 Updated documentation
171
671b1be1 »
2012-05-10 Narrower page is easier to edit.
172 To get the HTML contents of an element, read its `innerHTML` property. If you
173 want to include the element itself with its attributes, read the element's
174 `outerHTML` property instead. Alternatively, you can call the `browser.html`
175 function with a CSS selector and optional context element. If the function
176 selects multiple elements, it will return the combined HTML of them all.
c4293673 »
2011-12-05 Updated documentation
177
671b1be1 »
2012-05-10 Narrower page is easier to edit.
178 To see the textual contents of an element, read its `textContent` property.
179 Alternatively, you can call the `browser.text` function with a CSS selector and
180 optional context element. If the function selects multiple elements, it will
181 return the combined text contents of them all.
5234ecf9 »
2010-12-22 Added documentation for using CSS selectors.
182
183 Here are a few examples for checking the contents of a document:
184
185 // Make sure we have an element with the ID brains.
ba74cd1f »
2011-12-06 Updated documentation
186 assert.ok(browser.query("#brains"));
5234ecf9 »
2010-12-22 Added documentation for using CSS selectors.
187
188 // Make sure body has two elements with the class hand.
ba74cd1f »
2011-12-06 Updated documentation
189 assert.lengthOf(browser.body.queryAll(".hand"), 2);
5234ecf9 »
2010-12-22 Added documentation for using CSS selectors.
190
191 // Check the document title.
192 assert.equal(browser.text("title"), "The Living Dead");
193
194 // Show me the document contents.
195 console.log(browser.html());
196
197 // Show me the contents of the parts table:
198 console.log(browser.html("table.parts"));
199
671b1be1 »
2012-05-10 Narrower page is easier to edit.
200 CSS selectors are implemented by Sizzle.js. In addition to CSS 3 selectors you
201 get additional and quite useful extensions, such as `:not(selector)`,
202 `[NAME!=VALUE]`, `:contains(TEXT)`, `:first/:last` and so forth. Check out the
203 [Sizzle.js documentation](https://github.com/jeresig/sizzle/wiki) for more
204 details.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
205
8dd13f78 »
2012-04-26 [Closes #310] Deadlink in README
206 Read more [on the Browser API](API) and [CSS selectors](selectors)
2decad44 »
2010-12-29 Moved "the guts" to its own page.
207
208
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
209 ## Feeding
210
671b1be1 »
2012-05-10 Narrower page is easier to edit.
211 You're going to want to perform some actions, like clicking links, entering
212 text, submitting forms. You can certainly do that using the [DOM
213 API](http://www.w3.org/DOM/DOMTR), or several of the convenience functions we're
214 going to cover next.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
215
671b1be1 »
2012-05-10 Narrower page is easier to edit.
216 To click a link on the page, use `clickLink` with selector and callback. The
9aa1c430 »
2012-07-14 Minor cleanups in README.md.
217 first argument can be a CSS selector (see _[Hunting](#hunting)_), the `A` element, or the
671b1be1 »
2012-05-10 Narrower page is easier to edit.
218 text contents of the `A` element you want to click.
9778d9e2 »
2011-01-13 The `visit`, `clickLink` and `pressButton` methods now pass three
219
671b1be1 »
2012-05-10 Narrower page is easier to edit.
220 The second argument is a callback, which much like the `visit` callback gets
221 fired after all events are processed.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
222
223 Let's see that in action:
224
225 // Now go to the shopping cart page and check that we have
226 // three bodies there.
ba74cd1f »
2011-12-06 Updated documentation
227 browser.clickLink("View Cart", function(e, browser, status) {
228 assert.lengthOf(browser.queryAll("#cart .body"), 3);
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
229 });
230
671b1be1 »
2012-05-10 Narrower page is easier to edit.
231 To submit a form, use `pressButton`. The first argument can be a CSS selector,
232 the button/input element. the button name (the value of the `name` argument) or
233 the text that shows on the button. You can press any `BUTTON` element or
234 `INPUT` of type `submit`, `reset` or `button`. The second argument is a
235 callback, just like `clickLink`.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
236
671b1be1 »
2012-05-10 Narrower page is easier to edit.
237 Of course, before submitting a form, you'll need to fill it with values. For
238 text fields, use the `fill` function, which takes two arguments: selector and
239 the field value. This time the selector can be a CSS selector, the input
240 element, the field name (its `name` attribute), or the text that shows on the
241 label associated with that field.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
242
671b1be1 »
2012-05-10 Narrower page is easier to edit.
243 Zombie.js supports text fields, password fields, text areas, and also the new
9aa1c430 »
2012-07-14 Minor cleanups in README.md.
244 HTML5 fields types like email, search and url.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
245
671b1be1 »
2012-05-10 Narrower page is easier to edit.
246 The `fill` function returns a reference to the browser, so you can chain several
247 functions together. Its sibling functions `check` and `uncheck` (for check
248 boxes), `choose` (for radio buttons) and `select` (for drop downs) work the same
249 way.
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
250
251 Let's combine all of that into one example:
252
253 // Fill in the form and submit.
254 browser.
255 fill("Your Name", "Arm Biter").
256 fill("Profession", "Living dead").
d96f211b »
2011-02-09 Correct some typos.
257 select("Born", "1968").
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
258 uncheck("Send me the newsletter").
39f70ed1 »
2011-12-16 `Zombie` and `Browser` are no longer distinct namespaces. What you
259 pressButton("Sign me up", function() {
ba74cd1f »
2011-12-06 Updated documentation
260
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
261 // Make sure we got redirected to thank you page.
ba74cd1f »
2011-12-06 Updated documentation
262 assert.equal(browser.location.pathname, "/thankyou");
263
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
264 });
265
8dd13f78 »
2012-04-26 [Closes #310] Deadlink in README
266 Read more [on the Browser API](API)
2decad44 »
2010-12-29 Moved "the guts" to its own page.
267
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
268
f890e6fb »
2012-05-22 Added documentation on how to use promises.
269 ## Believing
270
271 Here are some guidelines for writing tests using Zombie,
272 [promises](http://documentup.com/kriskowal/q/) and
273 [Mocha](http://visionmedia.github.com/mocha/).
274
275 Let's start with a simple example:
276
277 describe("visit", function() {
278 before(function(done) {
c1ce1491 »
2012-05-26 Some improvements to the docs.
279 this.browser = new Browser();
280 this.browser
f890e6fb »
2012-05-22 Added documentation on how to use promises.
281 .visit("/promises")
282 .then(done, done);
283 });
284
285 it("should load the promises page", function() {
c1ce1491 »
2012-05-26 Some improvements to the docs.
286 assert.equal(this.browser.location.pathname, "/promises");
f890e6fb »
2012-05-22 Added documentation on how to use promises.
287 });
288 });
289
290 The call to `visit` returns a promise. Once the page loads successfully, the
c1ce1491 »
2012-05-26 Some improvements to the docs.
291 promise will resolve and call the first callback (`done`) with no arguments.
292 This will run the test and evaluate the assertion. Success.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
293
c1ce1491 »
2012-05-26 Some improvements to the docs.
294 If there's an error, the promise fails and calls the second callback (also
295 `done`) with an error. Calling it with an `Error` argument causes Mocha to fail
296 the test.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
297
dd87736d »
2012-06-04 Clean up documentation to match blog post.
298 Now let's chain promises together:
f890e6fb »
2012-05-22 Added documentation on how to use promises.
299
300 browser
301 .visit("/promises") // Step 1, open a page
302 .then(function() {
dd87736d »
2012-06-04 Clean up documentation to match blog post.
303 // Step 2, fill-in the form
f890e6fb »
2012-05-22 Added documentation on how to use promises.
304 browser.fill("Email", "armbiter@example.com");
305 browser.fill("Password", "b100d");
306 })
307 .then(function() {
308 // Step 3, resolve the next promise with this value.
309 return "OK";
310 })
311 .then(function(value) {
312 // Step 4, previous step got us to resolve with this value.
313 assert.equal(value, "OK");
314 })
315 .then(function() {
316 // Step 5, click the button and wait for something to happen
317 // by returning another promise.
318 return browser.pressButton("Let me in");
319 })
320 .then(done, done);
321
322 The first step is easy, it loads a page and returns a promise. When that
dd87736d »
2012-06-04 Clean up documentation to match blog post.
323 promise resolves, it calls the function of the second step which fills the two
324 form fields. That step is itself a promise that resolves with no value.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
325
326 The third step follows, and here we simply return a value. As a result, the
c1ce1491 »
2012-05-26 Some improvements to the docs.
327 next promise will resolve with that value, as you can see in the fourth step.
328 Another way to think about it is: step four is chained to a new promise with the
329 value "OK".
f890e6fb »
2012-05-22 Added documentation on how to use promises.
330
c1ce1491 »
2012-05-26 Some improvements to the docs.
331 On to step five where we press the button, which submits the form and loads the
332 response page. All of that happens after `pressButton`, so we want to wait for
dd87736d »
2012-06-04 Clean up documentation to match blog post.
333 it before moving to the sixth and last step.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
334
335 Luckily, `pressButton` - just like `wait` - returns a promise which gets
336 fulfilled after the browser is done processing events and loading resources. By
dd87736d »
2012-06-04 Clean up documentation to match blog post.
337 returning this new promise, we cause the next step to wait for this promise to
338 resolve.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
339
dd87736d »
2012-06-04 Clean up documentation to match blog post.
340 In short: the very last step is chained to a new promise returned by
341 `pressButton`. You can use this pattern whenever you need to wait, after
342 `visit`, `reload`, `clickLink`, etc.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
343
dd87736d »
2012-06-04 Clean up documentation to match blog post.
344 **Note:** In CoffeeScript a function that doesn't end with explicit `return`
c1ce1491 »
2012-05-26 Some improvements to the docs.
345 statement would return the value of the last statement. If you're seeing
dd87736d »
2012-06-04 Clean up documentation to match blog post.
346 promises resolved with unexpected values, you may need to end your function
347 with a `return`.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
348
dd87736d »
2012-06-04 Clean up documentation to match blog post.
349 In real life the ability to chain promises helps us structure complex scenarios
350 out of reusable steps. Like so:
f890e6fb »
2012-05-22 Added documentation on how to use promises.
351
352 browser
353 .visit("/promises")
354 .then( fillInName.bind(browser) )
355 .then( fillInAddress.bind(browser) )
356 .then( fillInCreditCard.bind(browser) )
357 .then(function() {
358 browser.pressButton("Buy it!")
359 })
360 .then(done, done);
361
dd87736d »
2012-06-04 Clean up documentation to match blog post.
362 **Note:** This usage of `bind` is one way to allow a function defined in another
363 context to use the `Browser` object available in this context.
c1ce1491 »
2012-05-26 Some improvements to the docs.
364
dd87736d »
2012-06-04 Clean up documentation to match blog post.
365 Let's talk about error handling. In promise-land, an error causes the promise
366 to be rejected. However, errors are not re-thrown out of the promise, and so
367 this code will fail silently:
f890e6fb »
2012-05-22 Added documentation on how to use promises.
368
369 browser
370 .visit("/promises")
371 .then(function() {
c1ce1491 »
2012-05-26 Some improvements to the docs.
372 // This throws an error, which gets caught and rejects
373 // the promise.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
374 assert(false, "I fail!");
375 })
376 .then(done);
377
dd87736d »
2012-06-04 Clean up documentation to match blog post.
378 Rejection may not be fun, but you've got to deal with it.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
379
dd87736d »
2012-06-04 Clean up documentation to match blog post.
380 When a promise gets rejected, that rejection travels down the chain, so you only
381 need to catch it at the very end. The examples we started with do that by
382 calling `then` with the same callback for handling the resolved and rejected
383 cases.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
384
dd87736d »
2012-06-04 Clean up documentation to match blog post.
385 If your test case expects an error to happen, write it like this:
f890e6fb »
2012-05-22 Added documentation on how to use promises.
386
387 browser
388 .visit("/promises")
389 .then(function() {
c1ce1491 »
2012-05-26 Some improvements to the docs.
390 assert(false, "I fail!")
f890e6fb »
2012-05-22 Added documentation on how to use promises.
391 })
392 .fail(function(error) {
c1ce1491 »
2012-05-26 Some improvements to the docs.
393 // Error happened, test is done. Otherwise, done never
dd87736d »
2012-06-04 Clean up documentation to match blog post.
394 // gets called and Mocha will fail this test.
f890e6fb »
2012-05-22 Added documentation on how to use promises.
395 done();
396 });
397
c1ce1491 »
2012-05-26 Some improvements to the docs.
398 Another way of dealing with errors:
399
400 before(function(done) {
dd87736d »
2012-06-04 Clean up documentation to match blog post.
401 this.browser = new Browser();
402 this.browser
c1ce1491 »
2012-05-26 Some improvements to the docs.
403 .visit("/no-such-page")
404 .finally(done);
405 });
406
407 it("should report an error", function() {
dd87736d »
2012-06-04 Clean up documentation to match blog post.
408 assert(this.browser.error);
c1ce1491 »
2012-05-26 Some improvements to the docs.
409 })
410
dd87736d »
2012-06-04 Clean up documentation to match blog post.
411 Unlike `then`, the `finally` callback gets called on either success or failure
412 and with no value.
c1ce1491 »
2012-05-26 Some improvements to the docs.
413
f890e6fb »
2012-05-22 Added documentation on how to use promises.
414 Read more [about promises](http://documentup.com/kriskowal/q/).
415
416
fc74a5a1 »
2010-12-27 Added list of supported features.
417 ## Readiness
418
419 Zombie.js supports the following:
420
19a9ffb8 »
2010-12-28 Updated README with new feature.
421 - HTML5 parsing and dealing with tag soups
fc74a5a1 »
2010-12-27 Added list of supported features.
422 - [DOM Level 3](http://www.w3.org/DOM/DOMTR) implementation
423 - HTML5 form fields (`search`, `url`, etc)
d96f211b »
2011-02-09 Correct some typos.
424 - CSS3 Selectors with [some extensions](http://sizzlejs.com/)
fc74a5a1 »
2010-12-27 Added list of supported features.
425 - Cookies and [Web Storage](http://dev.w3.org/html5/webstorage/)
19a9ffb8 »
2010-12-28 Updated README with new feature.
426 - `XMLHttpRequest` in all its glory
c4293673 »
2011-12-05 Updated documentation
427 - `setTimeout`/`setInterval`
19a9ffb8 »
2010-12-28 Updated README with new feature.
428 - `pushState`, `popstate` and `hashchange` events
444f0957 »
2011-01-13 Added IRC reference in documentation/site.
429 - `alert`, `confirm` and `prompt`
46c7c005 »
2012-04-25 Added support for EventSource (SSE)
430 - WebSockets and Server-Sent Events
fc74a5a1 »
2010-12-27 Added list of supported features.
431
432
b3de181a »
2011-01-14 Added links to related projects.
433 ## In The Family
434
671b1be1 »
2012-05-10 Narrower page is easier to edit.
435 **[capybara-zombie](https://github.com/plataformatec/capybara-zombie)** --
436 Capybara driver for zombie.js running on top of node.
b3de181a »
2011-01-14 Added links to related projects.
437
671b1be1 »
2012-05-10 Narrower page is easier to edit.
438 **[zombie-jasmine-spike](https://github.com/mileskin/zombie-jasmine-spike)** --
439 Spike project for trying out Zombie.js with Jasmine
b3de181a »
2011-01-14 Added links to related projects.
440
f890e6fb »
2012-05-22 Added documentation on how to use promises.
441 **[Mocha](http://visionmedia.github.com/mocha/)** -- mocha - simple, flexible,
671b1be1 »
2012-05-10 Narrower page is easier to edit.
442 fun javascript test framework for node.js & the browser. (BDD, TDD, QUnit styles
443 via interfaces)
fb3375be »
2011-09-01 Upgraded to JSDOM 0.2.4
444
671b1be1 »
2012-05-10 Narrower page is easier to edit.
445 **[Mink](https://github.com/Behat/Mink)** -- PHP 5.3 acceptance test framework
446 for web applications
fb3375be »
2011-09-01 Upgraded to JSDOM 0.2.4
447
b3de181a »
2011-01-14 Added links to related projects.
448
88d23644 »
2010-12-29 Browser now has a property called `debug` that you can set to
449 ## Reporting Glitches
450
671b1be1 »
2012-05-10 Narrower page is easier to edit.
451 **Step 1:** Run Zombie with debugging turned on, the trace will help figure out
452 what it's doing. For example:
88d23644 »
2010-12-29 Browser now has a property called `debug` that you can set to
453
39f70ed1 »
2011-12-16 `Zombie` and `Browser` are no longer distinct namespaces. What you
454 Browser.debug = true
455 var browser = new Browser()
456 browser.visit("http://thedead", function() {
ba74cd1f »
2011-12-06 Updated documentation
457 console.log(status, browser.errors);
2d291fe6 »
2011-01-31 Whitespace.
458 ...
88d23644 »
2010-12-29 Browser now has a property called `debug` that you can set to
459 });
460
671b1be1 »
2012-05-10 Narrower page is easier to edit.
461 **Step 2:** Wait for it to finish processing, then dump the current browser
462 state:
88d23644 »
2010-12-29 Browser now has a property called `debug` that you can set to
463
ba74cd1f »
2011-12-06 Updated documentation
464 browser.dump();
88d23644 »
2010-12-29 Browser now has a property called `debug` that you can set to
465
671b1be1 »
2012-05-10 Narrower page is easier to edit.
466 **Step 3:** If publicly available, include the URL of the page you're trying to
467 access. Even better, provide a test script I can run from the Node.js console
468 (similar to step 1 above).
88d23644 »
2010-12-29 Browser now has a property called `debug` that you can set to
469
43b4c33e »
2011-01-10 Fixed Web site links to not require .html.
470 Read more [about troubleshooting](troubleshoot)
2f9b7ee6 »
2010-12-21 First NPM release.
471
472
2d55b465 »
2010-12-22 You can now use `pressButton` with inputs of type button and reset
473 ## Giving Back
f050f196 »
2010-12-11 Fixed loading to keep track of outstanding requests, so waiting
474
444f0957 »
2011-01-13 Added IRC reference in documentation/site.
475
2f9b7ee6 »
2010-12-21 First NPM release.
476 * Find [assaf/zombie on Github](http://github.com/assaf/zombie)
477 * Fork the project
478 * Add tests
479 * Make your changes
480 * Send a pull request
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
481
671b1be1 »
2012-05-10 Narrower page is easier to edit.
482 Read more [about the guts of Zombie.js](guts) and check out the outstanding
483 [to-dos](todo).
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
484
671b1be1 »
2012-05-10 Narrower page is easier to edit.
485 Follow announcements, ask questions on [the Google
486 Group](https://groups.google.com/forum/?hl=en#!forum/zombie-js)
d39328fc »
2011-01-18 Added link to mailing list.
487
671b1be1 »
2012-05-10 Narrower page is easier to edit.
488 Get help on IRC: join [zombie.js on Freenode](irc://irc.freenode.net/zombie.js)
489 or [web-based IRC](http://webchat.freenode.net/?channels=zombie-js)
444f0957 »
2011-01-13 Added IRC reference in documentation/site.
490
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
491
f35b8e2a »
2010-12-21 First documentation you can actually use.
492 ## Brains
41ee2f29 »
2010-12-09 Fixed test suite so vows command just works.
493
671b1be1 »
2012-05-10 Narrower page is easier to edit.
494 Zombie.js is copyright of [Assaf Arkin](http://labnotes.org), released under the
495 MIT License
d6803cc1 »
2010-12-20 Starting to work on documentation
496
ae07a369 »
2011-02-02 Listing collaborators in README.
497 Blood, sweat and tears of joy:
498
c6ee7449 »
2012-01-04 Added Justin Latimer and Brian McDaniel to README credits
499 [Bob Lail boblail](http://boblail.tumblr.com/)
500
501 [Brian McDaniel](https://github.com/brianmcd)
502
ae07a369 »
2011-02-02 Listing collaborators in README.
503 [Damian Janowski aka djanowski](https://github.com/djanowski)
504
505 [José Valim aka josevalim](http://blog.plataformatec.com.br/)
506
c6ee7449 »
2012-01-04 Added Justin Latimer and Brian McDaniel to README credits
507 [Justin Latimer](http://www.justinlatimer.com/)
ae07a369 »
2011-02-02 Listing collaborators in README.
508
509 And all the fine people mentioned in [the changelog](changelog).
8750a5e4 »
2011-01-12 Added credits linking to Github contribution page.
510
671b1be1 »
2012-05-10 Narrower page is easier to edit.
511 Zombie.js is written in
512 [CoffeeScript](http://jashkenas.github.com/coffee-script/) for
513 [Node.js](http://nodejs.org/)
3c40783f »
2010-12-11 Added browser/window.select using Sizzle.js.
514
71ad9f8a »
2010-12-30 Added magical zombie girl and PDF.
515 DOM emulation by Elijah Insua's [JSDOM](http://jsdom.org/)
2decad44 »
2010-12-29 Moved "the guts" to its own page.
516
71ad9f8a »
2010-12-30 Added magical zombie girl and PDF.
517 HTML5 parsing by Aria Stewart's [HTML5](https://github.com/aredridel/html5)
2decad44 »
2010-12-29 Moved "the guts" to its own page.
518
71ad9f8a »
2010-12-30 Added magical zombie girl and PDF.
519 CSS selectors by John Resig's [Sizzle.js](http://sizzlejs.com/)
520
d7275cc0 »
2010-12-31 Add documentation for browser.css and browser.xpath.
521 XPath support using Google's [AJAXSLT](http://code.google.com/p/ajaxslt/)
522
671b1be1 »
2012-05-10 Narrower page is easier to edit.
523 JavaScript execution contexts using
524 [Contextify](https://github.com/brianmcd/contextify)
ddbe77d0 »
2011-12-13 Added Brian McDaniel (contextify) to contributor list
525
fdbfde86 »
2012-04-25 By popular demand: proxy!
526 HTTP(S) requests using [Request](https://github.com/mikeal/request)
527
acaccf4a »
2012-04-26 Only testing for Node 0.6
528 Cookie support using [Tough Cookie](https://github.com/goinstant/node-cookie)
529
f890e6fb »
2012-05-22 Added documentation on how to use promises.
530 Promises support via [Q](http://documentup.com/kriskowal/q/)
dadf6639 »
2012-05-10 [Closes #309] Added promises.
531
71ad9f8a »
2010-12-30 Added magical zombie girl and PDF.
532 Magical Zombie Girl by [Toho Scope](http://www.flickr.com/people/tohoscope/)
f35b8e2a »
2010-12-21 First documentation you can actually use.
533
534
535 ## See Also
536
671b1be1 »
2012-05-10 Narrower page is easier to edit.
537 **zombie-api**(7), **zombie-troubleshoot**(7), **zombie-selectors**(7),
538 **zombie-changelog**(7), **zombie-todo**(7)
Something went wrong with that request. Please try again.