casperjs 1.0.0.RC1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. data/CHANGELOG.md +179 -0
  2. data/LICENSE.md +19 -0
  3. data/README.md +30 -0
  4. data/bin/bootstrap.js +292 -0
  5. data/bin/usage.txt +10 -0
  6. data/casperjs.gemspec +21 -0
  7. data/modules/casper.js +1679 -0
  8. data/modules/cli.js +138 -0
  9. data/modules/clientutils.js +595 -0
  10. data/modules/colorizer.js +129 -0
  11. data/modules/events.js +247 -0
  12. data/modules/injector.js +93 -0
  13. data/modules/mouse.js +110 -0
  14. data/modules/querystring.js +187 -0
  15. data/modules/tester.js +807 -0
  16. data/modules/utils.js +429 -0
  17. data/modules/vendors/coffee-script.js +8 -0
  18. data/modules/xunit.js +123 -0
  19. data/package.json +35 -0
  20. data/rubybin/casperjs +57 -0
  21. data/samples/bbcshots.coffee +64 -0
  22. data/samples/bbcshots.js +80 -0
  23. data/samples/cliplay.coffee +19 -0
  24. data/samples/cliplay.js +21 -0
  25. data/samples/customevents.coffee +11 -0
  26. data/samples/customevents.js +13 -0
  27. data/samples/customlogging.coffee +33 -0
  28. data/samples/customlogging.js +42 -0
  29. data/samples/download.coffee +10 -0
  30. data/samples/download.js +11 -0
  31. data/samples/dynamic.coffee +60 -0
  32. data/samples/dynamic.js +65 -0
  33. data/samples/each.coffee +14 -0
  34. data/samples/each.js +17 -0
  35. data/samples/events.coffee +34 -0
  36. data/samples/events.js +41 -0
  37. data/samples/extends.coffee +29 -0
  38. data/samples/extends.js +37 -0
  39. data/samples/googlelinks.coffee +27 -0
  40. data/samples/googlelinks.js +33 -0
  41. data/samples/googlematch.coffee +47 -0
  42. data/samples/googlematch.js +65 -0
  43. data/samples/googlepagination.coffee +40 -0
  44. data/samples/googlepagination.js +51 -0
  45. data/samples/googletesting.coffee +17 -0
  46. data/samples/googletesting.js +23 -0
  47. data/samples/logcolor.coffee +10 -0
  48. data/samples/logcolor.js +11 -0
  49. data/samples/metaextract.coffee +23 -0
  50. data/samples/metaextract.js +29 -0
  51. data/samples/multirun.coffee +37 -0
  52. data/samples/multirun.js +56 -0
  53. data/samples/screenshot.coffee +28 -0
  54. data/samples/screenshot.js +33 -0
  55. data/samples/statushandlers.coffee +15 -0
  56. data/samples/statushandlers.js +19 -0
  57. data/samples/steptimeout.coffee +37 -0
  58. data/samples/steptimeout.js +45 -0
  59. data/samples/timeout.coffee +39 -0
  60. data/samples/timeout.js +47 -0
  61. data/tests/run.js +76 -0
  62. data/tests/site/alert.html +10 -0
  63. data/tests/site/click.html +40 -0
  64. data/tests/site/confirm.html +12 -0
  65. data/tests/site/elementattribute.html +6 -0
  66. data/tests/site/error.html +10 -0
  67. data/tests/site/form.html +26 -0
  68. data/tests/site/global.html +9 -0
  69. data/tests/site/images/phantom.png +0 -0
  70. data/tests/site/index.html +17 -0
  71. data/tests/site/mouse-events.html +47 -0
  72. data/tests/site/multiple-forms.html +16 -0
  73. data/tests/site/page1.html +8 -0
  74. data/tests/site/page2.html +8 -0
  75. data/tests/site/page3.html +8 -0
  76. data/tests/site/prompt.html +12 -0
  77. data/tests/site/resources.html +16 -0
  78. data/tests/site/result.html +11 -0
  79. data/tests/site/test.html +10 -0
  80. data/tests/site/visible.html +17 -0
  81. data/tests/site/waitFor.html +22 -0
  82. data/tests/suites/casper/agent.js +24 -0
  83. data/tests/suites/casper/capture.js +31 -0
  84. data/tests/suites/casper/click.js +61 -0
  85. data/tests/suites/casper/confirm.js +21 -0
  86. data/tests/suites/casper/elementattribute.js +8 -0
  87. data/tests/suites/casper/encode.js +20 -0
  88. data/tests/suites/casper/evaluate.js +27 -0
  89. data/tests/suites/casper/events.js +38 -0
  90. data/tests/suites/casper/exists.js +9 -0
  91. data/tests/suites/casper/fetchtext.js +9 -0
  92. data/tests/suites/casper/flow.coffee +38 -0
  93. data/tests/suites/casper/formfill.js +69 -0
  94. data/tests/suites/casper/global.js +9 -0
  95. data/tests/suites/casper/history.js +21 -0
  96. data/tests/suites/casper/hooks.js +41 -0
  97. data/tests/suites/casper/logging.js +38 -0
  98. data/tests/suites/casper/mouseevents.js +27 -0
  99. data/tests/suites/casper/onerror.js +19 -0
  100. data/tests/suites/casper/open.js +73 -0
  101. data/tests/suites/casper/prompt.js +17 -0
  102. data/tests/suites/casper/resources.coffee +24 -0
  103. data/tests/suites/casper/start.js +15 -0
  104. data/tests/suites/casper/steps.js +32 -0
  105. data/tests/suites/casper/viewport.js +11 -0
  106. data/tests/suites/casper/visible.js +17 -0
  107. data/tests/suites/casper/wait.js +27 -0
  108. data/tests/suites/casper/xpath.js +32 -0
  109. data/tests/suites/cli.js +125 -0
  110. data/tests/suites/clientutils.js +84 -0
  111. data/tests/suites/coffee.coffee +19 -0
  112. data/tests/suites/fs.js +36 -0
  113. data/tests/suites/http_status.js +28 -0
  114. data/tests/suites/injector.js +64 -0
  115. data/tests/suites/tester.js +121 -0
  116. data/tests/suites/utils.js +209 -0
  117. data/tests/suites/xunit.js +16 -0
  118. data/tests/testdir/01_a/abc.js +0 -0
  119. data/tests/testdir/01_a/def.js +0 -0
  120. data/tests/testdir/02_b/abc.js +0 -0
  121. data/tests/testdir/03_a.js +0 -0
  122. data/tests/testdir/03_b.js +0 -0
  123. data/tests/testdir/04/01_init.js +0 -0
  124. data/tests/testdir/04/02_do.js +0 -0
  125. metadata +192 -0
@@ -0,0 +1,65 @@
1
+ var casper = require("casper").create({
2
+ verbose: true
3
+ });
4
+
5
+ // The base links array
6
+ var links = [
7
+ "http://google.com/",
8
+ "http://yahoo.com/",
9
+ "http://bing.com/"
10
+ ];
11
+
12
+ // If we don't set a limit, it could go on forever
13
+ var upTo = ~~casper.cli.get(0) || 10;
14
+
15
+ var currentLink = 0;
16
+
17
+ // Get the links, and add them to the links array
18
+ // (It could be done all in one step, but it is intentionally splitted)
19
+ function addLinks(link) {
20
+ this.then(function() {
21
+ var found = this.evaluate(searchLinks);
22
+ this.echo(found.length + " links found on " + link);
23
+ links = links.concat(found);
24
+ });
25
+ }
26
+
27
+ // Fetch all <a> elements from the page and return
28
+ // the ones which contains a href starting with 'http://'
29
+ function searchLinks() {
30
+ var filter, map;
31
+ filter = Array.prototype.filter;
32
+ map = Array.prototype.map;
33
+ return map.call(filter.call(document.querySelectorAll("a"), function(a) {
34
+ return (/^http:\/\/.*/i).test(a.getAttribute("href"));
35
+ }), function(a) {
36
+ return a.getAttribute("href");
37
+ });
38
+ }
39
+
40
+ // Just opens the page and prints the title
41
+ function start(link) {
42
+ this.start(link, function() {
43
+ this.echo('Page title: ' + this.getTitle());
44
+ });
45
+ }
46
+
47
+ // As long as it has a next link, and is under the maximum limit, will keep running
48
+ function check() {
49
+ if (links[currentLink] && currentLink < upTo) {
50
+ this.echo('--- Link ' + currentLink + ' ---');
51
+ start.call(this, links[currentLink]);
52
+ addLinks.call(this, links[currentLink]);
53
+ currentLink++;
54
+ this.run(check);
55
+ } else {
56
+ this.echo("All done.");
57
+ this.exit();
58
+ }
59
+ }
60
+
61
+ casper.start().then(function() {
62
+ this.echo("Starting");
63
+ });
64
+
65
+ casper.run(check);
@@ -0,0 +1,14 @@
1
+ casper = require("casper").create()
2
+
3
+ links = [
4
+ "http://google.com/"
5
+ "http://yahoo.com/"
6
+ "http://bing.com/"
7
+ ]
8
+
9
+ casper.start()
10
+
11
+ casper.each links, (self, link) ->
12
+ @thenOpen link, -> @echo "#{@getTitle()} - #{link}"
13
+
14
+ casper.run()
@@ -0,0 +1,17 @@
1
+ var casper = require("casper").create();
2
+
3
+ var links = [
4
+ "http://google.com/",
5
+ "http://yahoo.com/",
6
+ "http://bing.com/"
7
+ ];
8
+
9
+ casper.start();
10
+
11
+ casper.each(links, function(self, link) {
12
+ this.thenOpen(link, function() {
13
+ this.echo(this.getTitle() + " - " + link);
14
+ });
15
+ });
16
+
17
+ casper.run();
@@ -0,0 +1,34 @@
1
+ ###
2
+ This script will add a custom HTTP status code handler, here for 404 pages.
3
+ ###
4
+
5
+ casper = require("casper").create()
6
+
7
+ casper.on "http.status.200", (resource) ->
8
+ @echo "#{resource.url} is OK", "INFO"
9
+
10
+ casper.on "http.status.301", (resource) ->
11
+ @echo "#{resource.url} is permanently redirected", "PARAMETER"
12
+
13
+ casper.on "http.status.302", (resource) ->
14
+ @echo "#{resource.url} is temporarily redirected", "PARAMETER"
15
+
16
+ casper.on "http.status.404", (resource) ->
17
+ @echo "#{resource.url} is not found", "COMMENT"
18
+
19
+ casper.on "http.status.500", (resource) ->
20
+ @echo "#{resource.url} is in error", "ERROR"
21
+
22
+ links = [
23
+ "http://google.com/"
24
+ "http://www.google.com/"
25
+ "http://www.google.com/plop"
26
+ ]
27
+
28
+ casper.start()
29
+
30
+ casper.each links, (self, link) ->
31
+ self.thenOpen link, ->
32
+ @echo "#{link} loaded"
33
+
34
+ casper.run()
@@ -0,0 +1,41 @@
1
+ /*
2
+ * This script will add a custom HTTP status code handler, here for 404 pages.
3
+ */
4
+
5
+ var casper = require("casper").create();
6
+
7
+ casper.on("http.status.200", function(resource) {
8
+ this.echo(resource.url + " is OK", "INFO");
9
+ });
10
+
11
+ casper.on("http.status.301", function(resource) {
12
+ this.echo(resource.url + " is permanently redirected", "PARAMETER");
13
+ });
14
+
15
+ casper.on("http.status.302", function(resource) {
16
+ this.echo(resource.url + " is temporarily redirected", "PARAMETER");
17
+ });
18
+
19
+ casper.on("http.status.404", function(resource) {
20
+ this.echo(resource.url + " is not found", "COMMENT");
21
+ });
22
+
23
+ casper.on("http.status.500", function(resource) {
24
+ this.echo(resource.url + " is in error", "ERROR");
25
+ });
26
+
27
+ var links = [
28
+ "http://google.com/",
29
+ "http://www.google.com/",
30
+ "http://www.google.com/plop"
31
+ ];
32
+
33
+ casper.start();
34
+
35
+ casper.each(links, function(self, link) {
36
+ self.thenOpen(link, function() {
37
+ this.echo(link + " loaded");
38
+ });
39
+ });
40
+
41
+ casper.run();
@@ -0,0 +1,29 @@
1
+ casper = require("casper").create
2
+ loadImages: false
3
+ logLevel: "debug"
4
+ verbose: true
5
+
6
+ links =
7
+ "http://edition.cnn.com/": 0
8
+ "http://www.nytimes.com/": 0
9
+ "http://www.bbc.co.uk/": 0
10
+ "http://www.guardian.co.uk/": 0
11
+
12
+ fantomas = Object.create(casper)
13
+
14
+ fantomas.countLinks = ->
15
+ @evaluate ->
16
+ __utils__.findAll("a[href]").length
17
+
18
+ fantomas.renderJSON = (what) ->
19
+ @echo JSON.stringify(what, null, " ")
20
+
21
+ fantomas.start()
22
+
23
+ Object.keys(links).forEach (url) ->
24
+ fantomas.thenOpen url, ->
25
+ links[url] = @countLinks()
26
+
27
+ fantomas.run ->
28
+ @renderJSON(links)
29
+ @exit()
@@ -0,0 +1,37 @@
1
+ var casper = require("casper").create({
2
+ loadImages: false,
3
+ logLevel: "debug",
4
+ verbose: true
5
+ });
6
+
7
+ var links = {
8
+ "http://edition.cnn.com/": 0,
9
+ "http://www.nytimes.com/": 0,
10
+ "http://www.bbc.co.uk/": 0,
11
+ "http://www.guardian.co.uk/": 0
12
+ };
13
+
14
+ var fantomas = Object.create(casper);
15
+
16
+ fantomas.countLinks = function() {
17
+ return this.evaluate(function() {
18
+ return __utils__.findAll("a[href]").length;
19
+ });
20
+ };
21
+
22
+ fantomas.renderJSON = function(what) {
23
+ this.echo(JSON.stringify(what, null, " "));
24
+ };
25
+
26
+ fantomas.start();
27
+
28
+ Object.keys(links).forEach(function(url) {
29
+ fantomas.thenOpen(url, function() {
30
+ links[url] = this.countLinks();
31
+ });
32
+ });
33
+
34
+ fantomas.run(function() {
35
+ this.renderJSON(links);
36
+ this.exit();
37
+ });
@@ -0,0 +1,27 @@
1
+ links = []
2
+ casper = require("casper").create()
3
+
4
+ getLinks = ->
5
+ links = document.querySelectorAll("h3.r a")
6
+ Array::map.call links, (e) ->
7
+ e.getAttribute "href"
8
+
9
+ casper.start "http://google.fr/", ->
10
+ # search for 'casperjs' from google form
11
+ @fill "form[action=\"/search\"]", q: "casperjs", true
12
+
13
+ casper.then ->
14
+ # aggregate results for the 'casperjs' search
15
+ links = @evaluate(getLinks)
16
+ # now search for 'phantomjs' by fillin the form again
17
+ @fill "form[action=\"/search\"]", q: "phantomjs", true
18
+
19
+ casper.then ->
20
+ # aggregate results for the 'phantomjs' search
21
+ links = links.concat(@evaluate(getLinks))
22
+
23
+ casper.run ->
24
+ # echo results in some pretty fashion
25
+ @echo links.length + " links found:"
26
+ @echo " - " + links.join("\n - ")
27
+ @exit()
@@ -0,0 +1,33 @@
1
+ var links = [];
2
+ var casper = require("casper").create();
3
+
4
+ function getLinks() {
5
+ var links = document.querySelectorAll("h3.r a");
6
+ return Array.prototype.map.call(links, function(e) {
7
+ return e.getAttribute("href");
8
+ });
9
+ };
10
+
11
+ casper.start("http://google.fr/", function() {
12
+ // search for 'casperjs' from google form
13
+ this.fill('form[action="/search"]', { q: "casperjs" }, true);
14
+ });
15
+
16
+ casper.then(function() {
17
+ // aggregate results for the 'casperjs' search
18
+ links = this.evaluate(getLinks);
19
+ // now search for 'phantomjs' by fillin the form again
20
+ this.fill('form[action="/search"]', { q: "phantomjs" }, true);
21
+ });
22
+
23
+ casper.then(function() {
24
+ // aggregate results for the 'phantomjs' search
25
+ links = links.concat(this.evaluate(getLinks));
26
+ });
27
+
28
+ casper.run(function() {
29
+ // echo results in some pretty fashion
30
+ this.echo(links.length + " links found:");
31
+ this.echo(" - " + links.join("\n - "))
32
+ this.exit();
33
+ });
@@ -0,0 +1,47 @@
1
+ ###
2
+ Takes provided terms passed as arguments and query google for the number of
3
+ estimated results each have.
4
+
5
+ Usage:
6
+ $ casperjs googlematch.coffee nicolas chuck borris
7
+ nicolas: 69600000
8
+ chuck: 49500000
9
+ borris: 2370000
10
+ winner is "nicolas" with 69600000 results
11
+ ###
12
+
13
+ casper = require("casper").create verbose: true
14
+
15
+ casper.fetchScore = ->
16
+ @evaluate ->
17
+ result = document.querySelector('#resultStats').innerText
18
+ parseInt /Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, '')
19
+
20
+ terms = casper.cli.args # terms are passed through command-line arguments
21
+
22
+ if terms.length < 2
23
+ casper
24
+ .echo("Usage: $ casperjs googlematch.js term1 term2 [term3]...")
25
+ .exit(1)
26
+
27
+ scores = []
28
+
29
+ casper.echo "Let the match begin between \"#{terms.join '", "'}\"!"
30
+
31
+ casper.start "http://google.fr/"
32
+
33
+ casper.each terms, (self, term) ->
34
+ @then -> @fill 'form[action="/search"]', { q: term }, true
35
+ @then ->
36
+ score = @fetchScore()
37
+ scores.push term: term, score: score
38
+ @echo "#{term}: #{score}"
39
+
40
+ casper.run ->
41
+ if scores.length is 0
42
+ @echo "No result found"
43
+ else
44
+ scores.sort (a, b) -> b.score - a.score
45
+ winner = scores[0]
46
+ @echo "Winner is \"" + winner.term + "\" with " + winner.score + " results"
47
+ @exit()
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Takes provided terms passed as arguments and query google for the number of
3
+ * estimated results each have.
4
+ *
5
+ * Usage:
6
+ * $ casperjs googlematch.js nicolas chuck borris
7
+ * nicolas: 69600000
8
+ * chuck: 49500000
9
+ * borris: 2370000
10
+ * winner is "nicolas" with 69600000 results
11
+ */
12
+
13
+ var casper = require("casper").create({
14
+ verbose: true
15
+ });
16
+
17
+ casper.fetchScore = function() {
18
+ return this.evaluate(function() {
19
+ var result = document.querySelector('#resultStats').innerText;
20
+ return parseInt(/Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, ''), 10);
21
+ });
22
+ };
23
+
24
+ var terms = casper.cli.args;
25
+
26
+ if (terms.length < 2) {
27
+ casper
28
+ .echo("Usage: $ casperjs googlematch.js term1 term2 [term3]...")
29
+ .exit(1)
30
+ ;
31
+ }
32
+
33
+ var scores = [];
34
+
35
+ casper.echo("Let the match begin between \"" + (terms.join('", "')) + "\"!");
36
+
37
+ casper.start("http://google.fr/");
38
+
39
+ casper.each(terms, function(casper, term, i) {
40
+ this.echo('Fecthing score for ' + term);
41
+ this.then(function() {
42
+ this.fill('form[action="/search"]', {q: term}, true);
43
+ });
44
+ this.then(function() {
45
+ var score = this.fetchScore();
46
+ scores.push({
47
+ term: term,
48
+ score: score
49
+ });
50
+ this.echo(term + ': ' + score);
51
+ });
52
+ });
53
+
54
+ casper.run(function() {
55
+ if (scores.length === 0) {
56
+ this.echo("No result found");
57
+ } else {
58
+ scores.sort(function(a, b) {
59
+ return b.score - a.score;
60
+ });
61
+ var winner = scores[0];
62
+ this.echo("Winner is \"" + winner.term + "\" with " + winner.score + " results");
63
+ }
64
+ this.exit();
65
+ });
@@ -0,0 +1,40 @@
1
+ ###
2
+ Capture multiple pages of google search results
3
+
4
+ Usage: $ casperjs googlepagination.coffee my search terms
5
+
6
+ (all arguments will be used as the query)
7
+ ###
8
+
9
+ casper = require("casper").create()
10
+ currentPage = 1
11
+
12
+ if casper.cli.args.length is 0
13
+ casper
14
+ .echo("Usage: $ casperjs googlepagination.coffee my search terms")
15
+ .exit(1)
16
+
17
+ processPage = ->
18
+ @echo "capturing page #{currentPage}"
19
+ @capture "google-results-p#{currentPage}.png"
20
+
21
+ # don't go too far down the rabbit hole
22
+ return if currentPage >= 5
23
+
24
+ if @exists "#pnnext"
25
+ currentPage++
26
+ @echo "requesting next page: #{currentPage}"
27
+ url = @getCurrentUrl()
28
+ @thenClick("#pnnext").then ->
29
+ @waitFor (->
30
+ url isnt @getCurrentUrl()
31
+ ), processPage
32
+ else
33
+ @echo "that's all, folks."
34
+
35
+ casper.start "http://google.fr/", ->
36
+ @fill 'form[action="/search"]', q: casper.cli.args.join(" "), true
37
+
38
+ casper.then processPage
39
+
40
+ casper.run()