updated README.md to point at new documentation website
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 | ... | ... |
-
Please register or sign in to post a comment