UNPKG

11.8 kBMarkdownView Raw
1# Ciao
2
3Ciao is a simple command line utility for testing http(s) requests and generating API documentation.
4
5Scripts are written in coffee-script, however it's important to note that they are interpreted, not executed.
6
7### Basic uptime script:
8
9```coffee-script
10#> Check Google is still running
11host: 'www.google.co.uk'
12
13#? Should have company name
14response.body.should.containEql 'Google'
15```
16
17### HTML test script:
18
19```coffee-script
20#> Twitter home page
21port: 443
22protocol: 'https:'
23host: 'twitter.com'
24
25#? Login form
26$('div.front-signin input#signin-email').length.should.eql 1
27$('div.front-signin input#signin-password').length.should.eql 1
28$('div.front-signin button[type="submit"]').length.should.eql 1
29```
30
31### JSON webservice script:
32
33```coffee-script
34#! Requried Headers
35headers: 'User-Agent': 'Ciao/Client 1.0'
36
37#> Github API call for node.js README
38port: 443
39protocol: 'https:'
40host: 'api.github.com'
41path: '/repos/joyent/node/readme'
42headers: 'Accept': 'application/json'
43
44#? Readme is available on Github
45response.statusCode.should.equal 200
46response.should.have.header 'server', 'GitHub.com'
47
48#? Should be what we are looking for...
49json.sha.should.match /^[a-z0-9]{40}/
50json.should.containEql
51 type: 'file'
52 path: 'README.md'
53 url: 'https://api.github.com/repos/joyent/node/contents/README.md'
54 html_url: 'https://github.com/joyent/node/blob/master/README.md'
55 git_url: 'https://api.github.com/repos/joyent/node/git/blobs/' + json.sha
56```
57
58When you run a script, documentation is produced. eg:
59[Github API Example - Documentation](https://github.com/missinglink/ciao/blob/master/doc/scripts/examples/github-api.md)
60
61---
62
63# Writing Scripts
64
65Ciao uses a special syntax to declare the start and end of code blocks.
66
67Currently 4 interpreter directives are supported:
68
69* `#! before` block, this is merged in to every `request` block.
70* `#> request` block, this is the main http(s) query definition block.
71* `#? assertion` block, this defines a test case which the `result` should conform to.
72* `## junk` block, all code in this block will be ignored by the parser.
73
74Each directive is followed by a single space and a directive title
75
76eg. `#> Contact page is available` defines a `#> request` block with the title `Contact page is available`.
77
78The title is used for reporting & documentation, so the better your titles, the easier life will be for you.
79
80---
81
82# Installing Ciao
83
84To install the most stable `ciao` binary globally on your system via `npm` you can simply:
85
86```bash
87$ [sudo] npm install -g ciao
88$ ciao --help
89```
90
91[![NPM](https://nodei.co/npm/ciao.png?downloads=true&stars=true)](https://nodei.co/npm/ciao)
92
93Note: you will need `node` and `npm` installed first.
94
95The easiest way to install `node.js` is with [nave.sh](https://github.com/isaacs/nave) by executing `[sudo] ./nave.sh usemain 0.10`
96
97---
98
99# Running Scripts
100
101```
102peter@edgy:/var/www/ciao$ ciao --help
103
104 Usage: ciao [options] <file ...>
105
106 Options:
107 -h, --help output usage information
108 -V, --version output the version number
109 -g, --gist [url] load script from github gist
110 -c, --conf [dir] an additional config file to load after ciao.json
111 -s, --silent disable reporters
112 -v, --verbose report full requests and responses on error
113 -d, --documentation [dir] generate documentation in output dir
114```
115
116### Running a single script
117
118```bash
119$ ciao scripts/examples/basic.coffee
120
121 GET http://www.google.co.uk/ scripts/examples/basic.coffee
122 ✓ Status: 200 OK
123
124 GET http://www.google.co.uk/ scripts/examples/basic.coffee
125 ✓ Response.body should contain company name
126```
127
128### Running all scripts in a directory
129
130You can also use ciao on directories to recursively run all scripts.
131
132```bash
133$ ciao scripts/
134```
135
136### Running a gist as a script
137
138You can run remote scripts from github by providing the gist suffix or url.
139
140```bash
141$ ciao --gist missinglink/4678610
142$ ciao --gist https://gist.github.com/missinglink/4678610
143```
144
145Note: The way the gist flag behaves has changed since `0.1.8`, please upgrade if you have issues.
146
147---
148
149# Requests
150
151The ciao request format is the same as that of the `node.js` native http client `http.request`.
152
153All `#> request` blocks have access to an object named `config` which contains all the static configuration properties defined in the ciao config. (as discussed below)
154
155### Request properties
156
157* `host` A domain name or IP address of the server to issue the request to. Defaults to 'www.example.com'.
158* `hostname` To support url.parse() hostname is preferred over host
159* `port` Port of remote server. Defaults to 80.
160* `method` A string specifying the HTTP request method. Defaults to 'GET'.
161* `path` Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'
162* `headers` An object containing request headers.
163* `auth` Basic authentication i.e. 'user:password' to compute an Authorization header.
164* `body` If body is an object then `JSON.stringify` will be run on it before sending.
165
166Full `http.request` reference: http://nodejs.org/api/http.html#http_http_request_options_callback
167
168### Examples
169
170```coffee-script
171#> Post data to a JSON web service
172path: '/blog/article'
173method: 'POST'
174headers:
175 'Accept': 'application/json'
176 'Content-Type': 'application/json'
177body:
178 title: 'My amazing blog post'
179 body: '@todo'
180```
181
182```coffee-script
183#> Get package details from the npm registry
184host: 'registry.npmjs.org'
185path: '/ciao/latest'
186headers: 'Accept': 'application/json'
187
188#? Should have preferGlobal set to true
189json.preferGlobal.should.be.true
190```
191
192---
193
194# Assertions
195
196You can add assertions to your scripts by including `#? assertion` blocks.
197
198Currently `#? assertion` blocks only provide the functionality of the `should` js framework, but I am looking at adding more assertion libraries in the future.
199
200Each test case has access to four objects named `title`, `response`, `json` & `$`.
201
202* `title` is simply the title specified in the interpreter directive (as discussed above)
203* `response` contains 3 properties returned by `http.request`
204 * `body` contains the body of the http(s) response.
205 * `statusCode` contains the status code of the http(s) response.
206 * `headers` contains an array of headers that were returned.
207* `json` the result of parsing the response.body with `JSON.parse` (empty for invalid json).
208* `$` the result of parsing the response.body with `cheerio` (a familiar jQuery-like API).
209
210### Examples
211
212```coffee-script
213#? Test the response code
214response.statusCode.should.equal 200
215
216#? Test a header is set
217response.should.have.header 'server'
218
219#? Test a header value
220response.should.have.header 'server', 'apache'
221
222#? Test body contains string
223response.body.should.containEql 'Bingo Bango Bongo!'
224
225#? Test body contains regex
226response.body.should.match /^[a-z0-9]{40}/
227
228#? Test json object contains properties
229json.should.containEql {
230 id: "10000000000000000000",
231 name: "Bingo Bango Bongo!"
232}
233
234#? Check for a redirect
235response.should.have.header 'location', 'http://www.example.com/'
236```
237
238`should.js` reference: https://github.com/visionmedia/should.js/
239
240### Testing the DOM
241
242Since version `0.1.8` you can test DOM elements in your source using a jQuery-like syntax.
243
244```coffee-script
245#> Wikipedia home page
246host: 'en.wikipedia.org'
247path: '/wiki/Main_Page'
248
249#? Count stylesheets
250$('link[rel="stylesheet"]').length.should.eql 2
251
252#? Page structure
253$('body.mediawiki > div#mw-page-base').length.should.eql 1
254
255#? Check headers are correctly rendered
256$('span.mw-headline').first().text().should.eql "From today's featured article"
257$('span.mw-headline').eq(1).text().should.eql "Did you know..."
258$('span.mw-headline').eq(2).text().should.eql "Today's articles for improvement"
259$('span.mw-headline').eq(3).text().should.eql "In the news"
260$('span.mw-headline').eq(4).text().should.eql "On this day..."
261$('span.mw-headline').last().text().should.eql "Wikipedia languages"
262```
263
264`cheerio` reference: https://github.com/MatthewMueller/cheerio
265
266---
267
268# Project Settings
269
270Ciao looks for a project-wide configuration file called `ciao.json` in your current working directory.
271
272The `defaults` section is merged in to every request that is made, it's useful for specifying global request properties such as `host` and `port`.
273
274The `config` section is useful for storing session tokens or any sort of data you would like available to `#! before` or `#> request` blocks.
275
276Example `ciao.json`
277
278```javascript
279{
280 "defaults": {
281 "host": "www.google.co.uk",
282 "port": 80,
283 "headers": {
284 "User-Agent": "Ciao/Client 1.0"
285 }
286 },
287 "config": {
288 "bingo": "bango"
289 }
290}
291```
292
293## Dynamic Project Settings
294
295If you require your settings to be generated before the test suite runs then you may use a file called `ciao.js` or `ciao.coffee` instead of `ciao.json`.
296
297This is particularly useful for running `fixtures` or any other `local` or `remote` code before your tests start.
298
299Dynamic configurations must export their settings with `module.exports` or an error will be thrown.
300
301Note: This feature was introduced in `0.3.1`, please upgrade if you have issues.
302
303---
304
305# Generate Documentation
306
307Ciao can generate documentation for each `#> request`, the resulting `response` and all `#? assertion` blocks.
308
309The documentation is in `markdown` format and is available in the directory specified using the `-d` flag.
310
311eg. To generate documentation in `./doc` for all scripts in `./scripts`:
312```bash
313$ ciao -d doc scripts
314```
315
316An example generated documentation file can be found here:
317[Github API Example - Documentation](https://github.com/missinglink/ciao/blob/master/doc/scripts/examples/github-api.md)
318
319---
320
321## How it works
322
323When parsing `script` & `config` files ciao launches child processes to excute the coffee-script source.
324This isolates the main thread from malicious code and ensures the fastest execution of tests.
325
326All the requests are launched asyncronously using `http.request`.
327
328After a `response` comes back from the target server; all `#? assertion` blocks are fired asyncronously in a seperate child process.
329
330## NPM Module
331
332The `ciao` npm module can be found here:
333[https://npmjs.org/package/ciao](https://npmjs.org/package/ciao)
334
335## Github Pages
336
337A prettier version of this readme is available here:
338[http://missinglink.github.com/ciao/](http://missinglink.github.com/ciao/)
339
340## Contributing
341
342Please fork and pull request against upstream master on a feature branch.
343
344Pretty please; provide unit tests and script fixtures in the `test` and `fixtures` directories.
345
346### Getting Set Up
347
348```bash
349$ git clone git@github.com:missinglink/ciao.git ciao
350$ cd ciao
351$ npm install
352$ npm test
353$ ./bin/ciao scripts/examples
354```
355
356### Running Unit Tests
357
358The unit test suite is run using `mocha`
359
360```bash
361$ npm test
362```
363
364### Continuous Integration
365
366Travis tests every release against node versions `0.6` `0.8` & `0.10`
367
368[![Build Status](https://travis-ci.org/missinglink/ciao.png?branch=master)](https://travis-ci.org/missinglink/ciao)
369
370### Running Ciao test scripts
371
372This will execute all tests in the `./scripts` directory and write documentation in the `./doc` directory.
373
374```bash
375$ npm run ciao
376```
377
378### Known bugs
379
380It's early stages yet; there are a bunch of issues reported here:
381https://github.com/missinglink/ciao/issues
382
383Please report everything as it comes up, no matter how small.
384
385### Code review
386
387If you would like a code review or to open a feature discussion, please fork and pull request against upstream master.
388
389## Project goals
390
391### Short term
392
393* Stability
394* Cool Functionality
395* Ease of use
396
397### Mid term
398
399* Improved reporters
400* Improved documentors
401* Web interface
402
403### Long term
404
405* Scheduled builds
406* Hosted CI solution
407
408[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/missinglink/ciao/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
409