Commit 0e6b9a67 0e6b9a67336077ebc3d5fc6fefb2b32a407fea01 by Nicolas Perriault

updated README.md to point at new documentation website

1 parent 11e2c9ff
Showing 1 changed file with 1 additions and 666 deletions
...@@ -13,669 +13,4 @@ Casper.js is a navigation utility for [PhantomJS](http://www.phantomjs.org/). It ...@@ -13,669 +13,4 @@ Casper.js is a navigation utility for [PhantomJS](http://www.phantomjs.org/). It
13 13
14 Feel free to browse our [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples). Don't hesitate to pull request for any cool example of yours as well! 14 Feel free to browse our [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples). Don't hesitate to pull request for any cool example of yours as well!
15 15
16 ## Quickstart 16 **Read the [full documentation](http://n1k0.github.com/casperjs/) on casperjs dedicated website.**
17
18 In the following example, we'll query google for two terms consecutively, `capserjs` and `phantomjs`, and aggregate the result links in a standard Array. Then we'll output the result to the console:
19
20 ``` javascript
21 phantom.injectJs('casper.js');
22
23 function getLinks() {
24 var links = document.querySelectorAll('h3.r a');
25 return Array.prototype.map.call(links, function(e) {
26 return {
27 title: e.innerText,
28 href: e.getAttribute('href')
29 };
30 });
31 }
32
33 var links = [];
34 var casper = new phantom.Casper({
35 logLevel: "info", // we only want "info" or higher level log messages
36 loadImages: false, // do not download images to save bandwidth
37 loadPlugins: false, // do not load plugins to save kitten
38 verbose: true // write log messages to the console
39 })
40 .start('http://google.fr/')
41 .then(function(self) {
42 // search for 'casperjs' from google form
43 self.fill('form[name=f]', {
44 q: 'casperjs'
45 }, true);
46 })
47 .then(function(self) {
48 // aggregate results for the 'casperjs' search
49 links = self.evaluate(getLinks);
50 // now search for 'phantomjs' by fillin the form again
51 self.fill('form[name=f]', {
52 q: 'phantomjs'
53 }, true);
54 })
55 .then(function(self) {
56 // aggregate results for the 'phantomjs' search
57 links = links.concat(self.evaluate(getLinks));
58 })
59 .run(function(self) {
60 // echo results in some pretty fashion
61 self.echo(links.map(function(i) {
62 return i.title + ' (' + i.href + ')';
63 }).join('\n')).exit();
64 })
65 ;
66 ```
67 **Hint:** Method chaining is not mandatory but provided as an alternative way to structure your code.
68
69 Run it:
70
71 $ phantomjs samples/googlelinks.js
72 [info] [phantom] Starting…
73 [info] [phantom] Running suite: 3 steps
74 [info] [phantom] Step 1/3: http://www.google.fr/ (HTTP 301)
75 [info] [remote] set "q" value to casperjs
76 [info] [remote] submitting form to /search, HTTP GET
77 [info] [phantom] Step 1/3: done in 1592ms.
78 [info] [phantom] Step 2/3: http://www.google.fr/search?sclient=psy-ab&hl=fr&site=&source=hp&q=casperjs&pbx=1&oq=&aq=&aqi=&aql=&gs_sm=&gs_upl= (HTTP 301)
79 [info] [remote] set "q" value to phantomjs
80 [info] [remote] submitting form to /search, HTTP GET
81 [info] [phantom] Step 2/3: done in 3091ms.
82 [info] [phantom] Step 3/3: http://www.google.fr/search?sclient=psy-ab&hl=fr&source=hp&q=phantomjs&pbx=1&oq=&aq=&aqi=&aql=&gs_sm=&gs_upl= (HTTP 301)
83 [info] [phantom] Step 3/3: done in 3862ms.
84 [info] [phantom] Done 3 steps in 4111ms.
85 n1k0/casperjs - GitHub (https://github.com/n1k0/casperjs)
86 #2: Some functionality has broken due to 1.3 update - Issues - n1k0 ... (https://github.com/n1k0/casperjs/issues/2)
87 Commit History for n1k0/casperjs - GitHub (https://github.com/n1k0/casperjs/commits/master)
88 #1: Way to step forward and backwards - Issues - n1k0/casperjs ... (https://github.com/n1k0/casperjs/issues/1)
89 Casper Js | Facebook (http://www.facebook.com/people/Casper-Js/100000337260665)
90 Casper Js Profiles | Facebook (http://www.facebook.com/public/Casper-Js)
91 hashtags.org - CasperJS (http://hashtags.org/tag/CasperJS/)
92 Zerotohundred.com - View Profile: Casper JS (http://www.zerotohundred.com/newforums/members/casper-js.html)
93 J S Enterprises in Casper, WY | Casper J S Enterprises - YP.com (http://www.yellowpages.com/casper-wy/j-s-enterprises)
94 Best Guitat Backing Traks Free Download: ICFMeister, Handy Backup ... (http://www.softwaregeek.com/guitat-backing-traks/p2.html)
95 PhantomJS: Headless WebKit with JavaScript API (http://www.phantomjs.org/)
96 phantomjs - headless WebKit with JavaScript API - Google Project ... (http://code.google.com/p/phantomjs/)
97 QuickStart - phantomjs - 5-Minute Guide - headless WebKit with ... (http://code.google.com/p/phantomjs/wiki/QuickStart)
98 Paris JS #10 : Introduction à PhantomJS, un navigateur webkit ... (http://svay.com/blog/index/post/2011/08/31/Paris-JS-10-%3A-Introduction-%C3%A0-PhantomJS,-un-navigateur-webkit-headless)
99 ariya/phantomjs - GitHub (https://github.com/ariya/phantomjs)
100 twitter.com/search/%23%23PhantomJS/grid (http://twitter.com/search/%23%23PhantomJS/grid)
101 Phantom.js | Pilvee blog (http://pilvee.com/blog/tag/phantom-js/)
102 don't code today what you can't debug tomorrow: PhantomJS ... (http://ariya.blogspot.com/2011/01/phantomjs-minimalistic-headless-webkit.html)
103 DailyJS: PhantomJS, load.js, Phantom Limb, OpenOdyssey (http://dailyjs.com/2011/01/28/phantoms/)
104 PhantomJS: The Power of WebKit but Without the Broswer (http://www.readwriteweb.com/hack/2011/03/phantomjs-the-power-of-webkit.php)
105
106 ## CoffeeScript
107
108 You can also write Casper scripts using the [CoffeeScript syntax](http://jashkenas.github.com/coffee-script/):
109
110 ``` coffeescript
111 phantom.injectJs "path/to/casper.js"
112
113 q = ->
114 document.querySelector('input[name="q"]').setAttribute "value", "%term%"
115 document.querySelector('form[name="f"]').submit()
116
117 getLinks = ->
118 links = document.querySelectorAll("h3.r a")
119 Array::map.call links, (e) -> e.getAttribute "href"
120
121 links = []
122
123 casper = new phantom.Casper verbose: true, logLevel: "debug"
124 casper.start "http://google.fr/"
125 casper.thenEvaluate q, term: "casper"
126 casper.then -> links = casper.evaluate getLinks
127 casper.thenEvaluate q, term: "homer"
128 casper.then -> links = links.concat casper.evaluate getLinks
129 casper.run ->
130 out =
131 result: casper.result
132 links: links
133 casper.echo JSON.stringify out, null, " "
134 casper.exit()
135 ```
136
137 Just remember to suffix your script with the `coffee` extension.
138
139 ## Casper.js API Documentation
140
141 Code is quite heavily documented using `jsdoc`, but below you'll find the whole API documentation with added sample code added.
142
143 ### Casper([Object options])
144
145 Casper constructor accepts a single `options` argument which is an object. Available options are:
146
147 ```
148 Name | Type | Default | Description
149 ——————————————————+——————————+—————————+————————————————————————————————————————————————————————————————————————
150 clientScripts | Array | [] | A collection of script filepaths to include to every page loaded
151 faultTolerant | Boolean | true | Catch and log exceptions when executing steps in a non-blocking fashion
152 logLevel | String | "error" | Logging level (see logLevels for available values)
153 onDie | function | null | A function to be called when Casper#die() is called
154 onError | function | null | A function to be called when an "error" level event occurs
155 onLoadError | function | null | A function to be called when a requested resource cannot be loaded
156 onPageInitialized | function | null | A function to be called after WebPage instance has been initialized
157 page | WebPage | null | An existing WebPage instance
158 pageSettings | Object | {} | PhantomJS's WebPage settings object
159 timeout | Number | null | Max timeout in milliseconds
160 verbose | Boolean | false | Realtime output of log messages
161 ```
162
163 Example:
164
165 ``` javascript
166 phantom.injectJs('path/to/casper.js');
167
168 var casper = new phantom.Casper({
169 clientScripts: [
170 'includes/jquery.js', // These two scripts will be injected in remote
171 'includes/underscore.js' // DOM on every request
172 ],
173 logLevel: "info", // Only "info" level messages will be logged
174 onError: function(self, m) { // Any "error" level message will be written
175 console.log('FATAL:' + m); // on the console output and PhantomJS will
176 self.exit(); // terminate
177 },
178 pageSettings: {
179 loadImages: false, // The WebPage instance used by Casper will
180 loadPlugins: false // use these settings
181 }
182 });
183 ```
184
185 But no worry, usually you'll just need to instantiate Casper using `new phantom.Casper()`.
186
187 ### Casper#base64encode(String url)
188
189 Encodes a resource using the base64 algorithm synchroneously using client-side XMLHttpRequest.
190
191 NOTE: we cannot use `window.btoa()` because it fails miserably in the version of WebKit shipping with PhantomJS.
192
193 Example: retrieving google logo image encoded in base64:
194
195 ``` javascript
196 var base64logo = null;
197 casper.start('http://www.google.fr/', function(self) {
198 base64logo = self.base64encode('http://www.google.fr/images/srpr/logo3w.png');
199 }).run(function(self) {
200 self.echo(base64logo).exit();
201 });
202 ```
203
204 ### Casper#click(String selector)
205
206 Emulates a click on the element from the provided selector, if possible. In case of success, `true` is returned.
207
208 Example:
209
210 ```javascript
211 casper.start('http://google.fr/')
212 .thenEvaluate(function() {
213 document.querySelector('input[name="q"]').setAttribute('value', '%term%');
214 document.querySelector('form[name="f"]').submit();
215 }, {
216 term: 'CasperJS'
217 })
218 .then(function(self) {
219 // Click on 1st result link
220 if (self.click('h3.r a')) {
221 console.log('clicked ok')
222 }
223 })
224 .run(function(self) {
225 self.debugPage();
226 })
227 ;
228 ```
229
230 ### Casper#capture(String targetFilepath, Object clipRect)
231
232 Proxy method for PhantomJS' `WebPage#render`. Adds a clipRect parameter for automatically setting page clipRect setting values and sets it back once done.
233
234 Example:
235
236 ``` javascript
237 casper.start('http://www.google.fr/', function(self) {
238 self.capture('google.png', {
239 top: 100,
240 left: 100,
241 width: 500,
242 height: 400
243 });
244 }).run(function(self) {
245 self.exit();
246 });
247 ```
248
249 ### Casper#captureSelector(String targetFile, String selector)
250
251 Captures the page area containing the provided selector.
252
253 Example:
254
255 ``` javascript
256 casper.start('http://www.weather.com/', function(self) {
257 self.captureSelector('weather.png', '.twc-story-block');
258 }).run(function(self) {
259 self.exit();
260 });
261 ```
262
263 ### Casper#debugHTML()
264
265 Logs the HTML code of the current page directly to the standard output, for debugging purpose.
266
267 Example:
268
269 ``` javascript
270 casper.start('http://www.google.fr/', function(self) {
271 self.debugHTML();
272 }).run(function(self) {
273 self.exit();
274 });
275 ```
276
277 ### Casper#debugPage()
278
279 Logs the textual contents of the current page directly to the standard output, for debugging purpose.
280
281 Example:
282
283 ``` javascript
284 casper.start('http://www.google.fr/', function(self) {
285 self.debugPage();
286 }).run(function(self) {
287 self.exit();
288 });
289 ```
290
291 ### Casper#die(String message[, int status])
292
293 Exits phantom with a logged error message and an optional exit status code.
294
295 Example:
296
297 ``` javascript
298 casper.start('http://www.google.fr/', function(self) {
299 self.die("Fail.", 1);
300 }).run(function(self) {
301 self.exit();
302 });
303 ```
304
305 ### Casper#echo(String message[, String style])
306
307 Prints something to stdout, optionnaly with some fancy color (see the `Colorizer` section of this document for more information).
308
309 Example:
310
311 ``` javascript
312 casper.start('http://www.google.fr/', function(self) {
313 self.echo('Page title is: ' + self.evaluate(function() {
314 return document.title;
315 }), 'INFO'); // Will be printed in green on the console
316 }).run(function(self) {
317 self.exit();
318 });
319 ```
320
321 ### Casper#evaluate(function fn[, Object replacements])
322
323 Evaluates an expression in the page context, a bit like what PhantomJS' `WebPage#evaluate` does, but can also replace values by their placeholer names.
324
325 Example:
326
327 ``` javascript
328 casper.evaluate(function() {
329 document.querySelector('#username').setAttribute('value', '%username%');
330 document.querySelector('#password').setAttribute('value', '%password%');
331 document.querySelector('#submit').click();
332 }, {
333 username: 'sheldon.cooper',
334 password: 'b4z1ng4'
335 });
336 ```
337
338 ### Casper#evaluateOrDie(function fn[, String message])
339
340 Evaluates an expression within the current page DOM and `die()` if it returns anything but `true`.
341
342 Example:
343
344 ``` javascript
345 casper.start('http://foo.bar/home', function(self) {
346 self.evaluateOrDie(function() {
347 return /logged in/.match(document.title);
348 }, 'not authenticated');
349 }).run(function(self) {
350 self.exit();
351 });
352 ```
353
354 ### Casper#exit([int status])
355
356 Exits PhantomJS with an optional exit status code.
357
358 ### Casper#log(String message[, String level, String space)
359
360 Logs a message with an optional level in an optional space. Available levels are `debug`, `info`, `warning` and `error`. A space is a kind of namespace you can set for filtering your logs. By default, Casper logs messages in two distinct spaces: `phantom` and `remote`, to distinguish what happens in the PhantomJS environment from the remote one.
361
362 Example:
363
364 ``` javascript
365 casper.start('http://www.google.fr/', function(self) {
366 self.log("I'm logging an error", "error");
367 }).run(function(self) {
368 self.exit();
369 });
370 ```
371
372 ### Casper#fill(String selector, Object values, Boolean submit)
373
374 Fills the fields of a form with given values and optionnaly submit it.
375
376 Example with this sample html form:
377
378 ``` html
379 <form action="/contact" id="contact-form" enctype="multipart/form-data">
380 <input type="text" name="subject"/>
381 <textearea name="content"></textearea>
382 <input type="radio" name="civility" value="Mr"/> Mr
383 <input type="radio" name="civility" value="Mrs"/> Mrs
384 <input type="text" name="name"/>
385 <input type="email" name="email"/>
386 <input type="file" name="attachment"/>
387 <input type="checkbox" name="cc"/> Receive a copy
388 <input type="submit"/>
389 </form>
390 ```
391
392 ```javascript
393 casper.start('http://some.tld/contact.form', function(self) {
394 self.fill('form#contact-form', {
395 'subject': 'I am watching you',
396 'content': 'So be careful.',
397 'civility': 'Mr',
398 'name': 'Chuck Norris',
399 'email': 'chuck@norris.com',
400 'cc': true,
401 'attachment': '/Users/chuck/roundhousekick.doc'
402 }, true);
403 }).then(function(self) {
404 self.evaluateOrDie(function() {
405 return /message sent/.test(document.body.innerText);
406 }, 'sending message failed');
407 }).run(function(self) {
408 self.echo('message sent').exit();
409 });
410 ```
411
412 **WARNING:** Please don't use CasperJS nor PhantomJS to send spam, or I'll be calling the Chuck. More seriously, please don't.
413
414 ### Casper#getCurrentUrl()
415
416 Retrieves current URL of current document. Note: the url will be url-decoded.
417
418 Example:
419
420 ``` javascript
421 casper.start('http://www.google.fr/', function(self) {
422 self.log(self.getCurrentUrl()); // "http://www.google.fr/"
423 }).run(function(self) {
424 self.exit();
425 });
426 ```
427
428 ### Casper#repeat(int times, function then)
429
430 Repeats a navigation step a given number of times.
431
432 Example:
433
434 ``` javascript
435 var i = 0;
436 casper.start('http://foo.bar/home', function(self) {
437 self.evaluateOrDie(function() {
438 return /logged in/.match(document.title);
439 }, 'not authenticated');
440 }).repeat(5, function(self) {
441 self.echo("I am step #" + ++i);
442 }).run(function(self) {
443 self.exit();
444 });
445 ```
446
447 ### Casper#run(fn onComplete[, int time])
448
449 Runs the whole suite of steps and optionally executes a callback when they've all been done. Obviously, **calling this method is mandatory** in order to run the Casper navigation suite.
450
451 Casper suite **won't run**:
452
453 ``` javascript
454 casper.start('http://foo.bar/home', function(self) {
455 // ...
456 }).then(function(self) {
457 // ...
458 });
459 ```
460
461 Casper suite **will run**:
462
463 ``` javascript
464 casper.start('http://foo.bar/home', function(self) {
465 // ...
466 }).then(function(self) {
467 // ...
468 }).run();
469 ```
470
471 ### Casper#start(String url[, function then])
472
473 Configures and starts Casper, then open the provided `url` and optionnaly adds the step provided by the `then` argument.
474
475 Example:
476
477 ``` javascript
478 casper.start('http://google.fr/', function(self) {
479 self.echo("I'm loaded.");
480 }).run(function() {
481 self.exit();
482 });
483 ```
484
485 Alternatively:
486
487 ``` javascript
488 casper.start('http://google.fr/');
489 casper.then(function(self) {
490 self.echo("I'm loaded.");
491 });
492 casper.run(function(self) {
493 self.exit();
494 });
495 ```
496
497 Or alternatively:
498
499 ``` javascript
500 casper.start('http://google.fr/');
501 casper.then(function() {
502 casper.echo("I'm loaded.");
503 });
504 casper.run(function() {
505 casper.exit();
506 });
507 ```
508
509 Matter of taste!
510
511 Please note that **you must call the `start()` method in order to be able to add navigation steps** and run the suite. If you don't you'll get an error message inviting you to do so anyway.
512
513 ### Casper#then(function fn)
514
515 The standard way to add a new navigation step to the Casper suite by provide a callback function which will be executed when the requested page is loaded.
516
517 Example:
518
519 ``` javascript
520 casper.start('http://google.fr/').then(function(self) {
521 self.echo("I'm in your google.");
522 }).run(function(self) {
523 self.exit();
524 });
525 ```
526
527 Please note that usage of the `self` argument is not mandatory, it's just pythonic-like syntaxic sugar. You can perfectly use this alternative:
528
529 ``` javascript
530 casper.start('http://google.fr/').then(function() {
531 casper.echo("I'm in your google.");
532 }).run(function(self) {
533 self.exit();
534 });
535 ```
536
537 If you want to open a page as a next step in your navigation scenario, please refer to the `Casper#thenOpen()` method documentation.
538
539 ### Casper#thenEvaluate(function fn[, Object replacements])
540
541 Adds a new navigation step to perform code evaluation within the current retrieved page DOM.
542
543 Example:
544
545 ``` javascript
546 // Querying for "Chuck Norris" on Google
547 casper.start('http://google.fr/').thenEvaluate(function() {
548 document.querySelector('input[name="q"]').setAttribute('value', '%term%');
549 document.querySelector('form[name="f"]').submit();
550 }, {
551 term: 'Chuck Norris'
552 }).run(function(self) {
553 self.exit();
554 });
555 ```
556
557 ### Casper#thenOpen(String location[, function then])
558
559 Adds a new navigation step for opening a new location, and optionnaly add a next step when its loaded.
560
561 Example:
562
563 ``` javascript
564 casper.start('http://google.fr/').then(function(self) {
565 self.echo("I'm in your google.");
566 }).thenOpen('http://yahoo.fr/', function(self) {
567 self.echo("Now I'm in your yahoo.")
568 }).run(function(self) {
569 self.exit();
570 });
571 ```
572
573 ### Casper#thenOpenAndEvaluate(String location[, function then, Object replacements])
574
575 Basically a shortcut for opening an url and evaluate code against remote DOM environment.
576
577 Example:
578
579 ``` javascript
580 casper.start('http://google.fr/').then(function(self) {
581 self.echo("I'm in your google.");
582 }).thenOpenAndEvaluate('http://yahoo.fr/', function() {
583 document.querySelector['form'].submit();
584 }).run(function(self) {
585 self.exit();
586 });
587 ```
588
589 ## Client-side utils
590
591 Casper ships with a few client-side utilitites which are injected in the remote DOM environement, and accessible from there through the `__utils__` object instance of the `phantom.Casper.ClientUtils` class.
592
593 ### CasperUtils#getBase64(String url)
594
595 This method will retrieved a base64 encoded version of any resource behind an url. For example, let's imagine we want to retrieve the base64 representation of some website's logo:
596
597 ``` javascript
598 var logo = null;
599 casper.start('http://foo.bar/', function(self) {
600 logo = self.evaluate(function() {
601 var imgUrl = document.querySelector('img.logo').getAttribute('src');
602 return__utils__.getBase64(imgUrl);
603 };
604 }).run(function(self) {
605 self.echo(logo).exit();
606 });
607 ```
608
609 ## Colorizer
610
611 Casper ships with a `Colorizer` object which can print stuff to the console output in color:
612
613 ``` javascript
614 casper.echo('this is an informative message', 'INFO'); // printed in green
615 casper.echo('this is an error message', 'ERROR'); // printed in red
616 ```
617
618 Available predefined styles are:
619
620 - `ERROR`: white text on red background
621 - `INFO`: green text
622 - `TRACE`: green text
623 - `PARAMETER`: cyan text
624 - `COMMENT`: yellow text
625 - `WARNING`: red text
626 - `GREEN_BAR`: green text on white background
627 - `RED_BAR`: white text on red background
628 - `INFO_BAR`: cyan text
629
630 Here's a sample output of what it can look like:
631
632 ![capture](http://cl.ly/2j0m1A3E2N2z3Q2o2N1q/Capture_d%E2%80%99e%CC%81cran_2011-10-11_a%CC%80_23.48.41.png)
633
634 ## Extending Casper
635
636 Sometimes it can be convenient to add your own methods to the `Casper` class; it's easily doable using the `Casper.extend()` method as illustrated below:
637
638 ``` javascript
639 phantom.injectJs("path/to/casper.js");
640
641 phantom.Casper.extend({
642 fetchTexts: function(selector) {
643 return this.evaluate(function() {
644 var elements = document.querySelectorAll('%selector%');
645 return Array.prototype.map.call(elements, function(e) {
646 return e.innerText;
647 });
648 }, {
649 selector: selector.replace("'", "\'")
650 });
651 },
652
653 renderJSON: function(what) {
654 return this.echo(JSON.stringify(what, null, ' ')).exit();
655 }
656 });
657
658 var articles = [];
659
660 new phantom.Casper().start('http://www.liberation.fr/', function(self) {
661 articles = self.fetchTexts('h3');
662 }).thenOpen('http://www.lemonde.fr/', function(self) {
663 articles.concat(self.fetchTexts('h2.article'));
664 }).run(function(self) {
665 self.renderJSON(articles);
666 });
667 ```
668
669 ## Testing
670
671 CasperJS has some unit and functional tests, located in the `tests` subfolder. More tests will be added in the future. To run the test suite, from the root of a checkout of the casperjs repository:
672
673 $ phantomjs tests/run.js
674
675 ## Licensing
676
677 `Casper.js` is released under the terms of the [MIT license](http://en.wikipedia.org/wiki/MIT_License).
678
679 ## Now what
680
681 Feel free to play with the code and [report an issue on github](https://github.com/n1k0/casperjs/issues). I'm also reachable [on twitter](https://twitter.com/n1k0).
...\ No newline at end of file ...\ No newline at end of file
......