casperjs 1.0.0.RC1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +179 -0
- data/LICENSE.md +19 -0
- data/README.md +30 -0
- data/bin/bootstrap.js +292 -0
- data/bin/usage.txt +10 -0
- data/casperjs.gemspec +21 -0
- data/modules/casper.js +1679 -0
- data/modules/cli.js +138 -0
- data/modules/clientutils.js +595 -0
- data/modules/colorizer.js +129 -0
- data/modules/events.js +247 -0
- data/modules/injector.js +93 -0
- data/modules/mouse.js +110 -0
- data/modules/querystring.js +187 -0
- data/modules/tester.js +807 -0
- data/modules/utils.js +429 -0
- data/modules/vendors/coffee-script.js +8 -0
- data/modules/xunit.js +123 -0
- data/package.json +35 -0
- data/rubybin/casperjs +57 -0
- data/samples/bbcshots.coffee +64 -0
- data/samples/bbcshots.js +80 -0
- data/samples/cliplay.coffee +19 -0
- data/samples/cliplay.js +21 -0
- data/samples/customevents.coffee +11 -0
- data/samples/customevents.js +13 -0
- data/samples/customlogging.coffee +33 -0
- data/samples/customlogging.js +42 -0
- data/samples/download.coffee +10 -0
- data/samples/download.js +11 -0
- data/samples/dynamic.coffee +60 -0
- data/samples/dynamic.js +65 -0
- data/samples/each.coffee +14 -0
- data/samples/each.js +17 -0
- data/samples/events.coffee +34 -0
- data/samples/events.js +41 -0
- data/samples/extends.coffee +29 -0
- data/samples/extends.js +37 -0
- data/samples/googlelinks.coffee +27 -0
- data/samples/googlelinks.js +33 -0
- data/samples/googlematch.coffee +47 -0
- data/samples/googlematch.js +65 -0
- data/samples/googlepagination.coffee +40 -0
- data/samples/googlepagination.js +51 -0
- data/samples/googletesting.coffee +17 -0
- data/samples/googletesting.js +23 -0
- data/samples/logcolor.coffee +10 -0
- data/samples/logcolor.js +11 -0
- data/samples/metaextract.coffee +23 -0
- data/samples/metaextract.js +29 -0
- data/samples/multirun.coffee +37 -0
- data/samples/multirun.js +56 -0
- data/samples/screenshot.coffee +28 -0
- data/samples/screenshot.js +33 -0
- data/samples/statushandlers.coffee +15 -0
- data/samples/statushandlers.js +19 -0
- data/samples/steptimeout.coffee +37 -0
- data/samples/steptimeout.js +45 -0
- data/samples/timeout.coffee +39 -0
- data/samples/timeout.js +47 -0
- data/tests/run.js +76 -0
- data/tests/site/alert.html +10 -0
- data/tests/site/click.html +40 -0
- data/tests/site/confirm.html +12 -0
- data/tests/site/elementattribute.html +6 -0
- data/tests/site/error.html +10 -0
- data/tests/site/form.html +26 -0
- data/tests/site/global.html +9 -0
- data/tests/site/images/phantom.png +0 -0
- data/tests/site/index.html +17 -0
- data/tests/site/mouse-events.html +47 -0
- data/tests/site/multiple-forms.html +16 -0
- data/tests/site/page1.html +8 -0
- data/tests/site/page2.html +8 -0
- data/tests/site/page3.html +8 -0
- data/tests/site/prompt.html +12 -0
- data/tests/site/resources.html +16 -0
- data/tests/site/result.html +11 -0
- data/tests/site/test.html +10 -0
- data/tests/site/visible.html +17 -0
- data/tests/site/waitFor.html +22 -0
- data/tests/suites/casper/agent.js +24 -0
- data/tests/suites/casper/capture.js +31 -0
- data/tests/suites/casper/click.js +61 -0
- data/tests/suites/casper/confirm.js +21 -0
- data/tests/suites/casper/elementattribute.js +8 -0
- data/tests/suites/casper/encode.js +20 -0
- data/tests/suites/casper/evaluate.js +27 -0
- data/tests/suites/casper/events.js +38 -0
- data/tests/suites/casper/exists.js +9 -0
- data/tests/suites/casper/fetchtext.js +9 -0
- data/tests/suites/casper/flow.coffee +38 -0
- data/tests/suites/casper/formfill.js +69 -0
- data/tests/suites/casper/global.js +9 -0
- data/tests/suites/casper/history.js +21 -0
- data/tests/suites/casper/hooks.js +41 -0
- data/tests/suites/casper/logging.js +38 -0
- data/tests/suites/casper/mouseevents.js +27 -0
- data/tests/suites/casper/onerror.js +19 -0
- data/tests/suites/casper/open.js +73 -0
- data/tests/suites/casper/prompt.js +17 -0
- data/tests/suites/casper/resources.coffee +24 -0
- data/tests/suites/casper/start.js +15 -0
- data/tests/suites/casper/steps.js +32 -0
- data/tests/suites/casper/viewport.js +11 -0
- data/tests/suites/casper/visible.js +17 -0
- data/tests/suites/casper/wait.js +27 -0
- data/tests/suites/casper/xpath.js +32 -0
- data/tests/suites/cli.js +125 -0
- data/tests/suites/clientutils.js +84 -0
- data/tests/suites/coffee.coffee +19 -0
- data/tests/suites/fs.js +36 -0
- data/tests/suites/http_status.js +28 -0
- data/tests/suites/injector.js +64 -0
- data/tests/suites/tester.js +121 -0
- data/tests/suites/utils.js +209 -0
- data/tests/suites/xunit.js +16 -0
- data/tests/testdir/01_a/abc.js +0 -0
- data/tests/testdir/01_a/def.js +0 -0
- data/tests/testdir/02_b/abc.js +0 -0
- data/tests/testdir/03_a.js +0 -0
- data/tests/testdir/03_b.js +0 -0
- data/tests/testdir/04/01_init.js +0 -0
- data/tests/testdir/04/02_do.js +0 -0
- metadata +192 -0
data/package.json
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
"name": "casperjs",
|
3
|
+
"description": "Navigation scripting & testing utility for PhantomJS",
|
4
|
+
"version": "1.0.0-RC1",
|
5
|
+
"keywords": [
|
6
|
+
"phantomjs",
|
7
|
+
"javascript"
|
8
|
+
],
|
9
|
+
"maintainers": [
|
10
|
+
{
|
11
|
+
"name": "Nicolas Perriault",
|
12
|
+
"email": "nperriault@gmail.com",
|
13
|
+
"web": "http://www.akei.com"
|
14
|
+
}
|
15
|
+
],
|
16
|
+
"dependencies": {
|
17
|
+
"http://www.phantomjs.org/": "1.5"
|
18
|
+
},
|
19
|
+
"bugs": {
|
20
|
+
"url": "https://github.com/n1k0/casperjs/issues"
|
21
|
+
},
|
22
|
+
"repositories": [
|
23
|
+
{
|
24
|
+
"type": "git",
|
25
|
+
"url": "git://github.com/n1k0/casperjs.git"
|
26
|
+
}
|
27
|
+
],
|
28
|
+
"licenses": [
|
29
|
+
{
|
30
|
+
"name": "MIT",
|
31
|
+
"url": "http://www.opensource.org/licenses/mit-license.php"
|
32
|
+
}
|
33
|
+
],
|
34
|
+
"homepage": "http://casperjs.org"
|
35
|
+
}
|
data/rubybin/casperjs
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Ruby Wrapper for CasperJs
|
3
|
+
# by hannyu
|
4
|
+
|
5
|
+
|
6
|
+
CASPER_PATH = File.dirname(File.dirname(File.expand_path(__FILE__)))
|
7
|
+
|
8
|
+
PHANTOMJS_NATIVE_ARGS = [
|
9
|
+
'--cookies-file',
|
10
|
+
'--config',
|
11
|
+
'--debug',
|
12
|
+
'--disk-cache',
|
13
|
+
'--ignore-ssl-errors',
|
14
|
+
'--load-images',
|
15
|
+
'--load-plugins',
|
16
|
+
'--local-storage-path',
|
17
|
+
'--local-storage-quota',
|
18
|
+
'--local-to-remote-url-access',
|
19
|
+
'--max-disk-cache-size',
|
20
|
+
'--output-encoding',
|
21
|
+
'--proxy',
|
22
|
+
'--proxy-auth',
|
23
|
+
'--proxy-type',
|
24
|
+
'--remote-debugger-port',
|
25
|
+
'--remote-debugger-autorun',
|
26
|
+
'--script-encoding',
|
27
|
+
'--web-security',
|
28
|
+
]
|
29
|
+
|
30
|
+
CASPER_ARGS = []
|
31
|
+
PHANTOMJS_ARGS = []
|
32
|
+
ARGV.each do |arg|
|
33
|
+
is_found = false
|
34
|
+
PHANTOMJS_NATIVE_ARGS.each do |pna|
|
35
|
+
if arg.start_with? pna
|
36
|
+
PHANTOMJS_ARGS << arg
|
37
|
+
is_found = true
|
38
|
+
break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
CASPER_ARGS << arg if not is_found
|
42
|
+
end
|
43
|
+
|
44
|
+
CASPER_COMMAND = []
|
45
|
+
CASPER_COMMAND << (ENV["PHANTOMJS_EXECUTABLE"] || "phantomjs")
|
46
|
+
CASPER_COMMAND.concat PHANTOMJS_ARGS
|
47
|
+
CASPER_COMMAND << File.join(CASPER_PATH, "bin", "bootstrap.js")
|
48
|
+
CASPER_COMMAND << "--casper-path=#{CASPER_PATH}"
|
49
|
+
CASPER_COMMAND << "--cli"
|
50
|
+
CASPER_COMMAND.concat CASPER_ARGS
|
51
|
+
|
52
|
+
if system(CASPER_COMMAND.join(" ")).nil?
|
53
|
+
puts "Fatal: Did you install phantomjs?"
|
54
|
+
end
|
55
|
+
|
56
|
+
exit $?.exitstatus
|
57
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
###
|
2
|
+
Create a mosaic image from all headline photos on BBC homepage
|
3
|
+
###
|
4
|
+
|
5
|
+
casper = require("casper").create()
|
6
|
+
nbLinks = 0
|
7
|
+
currentLink = 1
|
8
|
+
images = []
|
9
|
+
|
10
|
+
# helper to hide some element from remote DOM
|
11
|
+
casper.hide = (selector) ->
|
12
|
+
@evaluate (selector) ->
|
13
|
+
document.querySelector(selector).style.display = "none"
|
14
|
+
, selector: selector
|
15
|
+
|
16
|
+
casper.start "http://www.bbc.co.uk/", ->
|
17
|
+
nbLinks = @evaluate ->
|
18
|
+
return __utils__.findAll('#promo2_carousel_items_items li').length
|
19
|
+
@echo "#{nbLinks} items founds"
|
20
|
+
# hide navigation arrows
|
21
|
+
@hide ".nav_left"
|
22
|
+
@hide ".nav_right"
|
23
|
+
@mouse.move "#promo2_carousel"
|
24
|
+
@waitUntilVisible ".autoplay.nav_pause", ->
|
25
|
+
@echo "Moving over pause button"
|
26
|
+
@mouse.move ".autoplay.nav_pause"
|
27
|
+
@click ".autoplay.nav_pause"
|
28
|
+
@echo "Clicked on pause button"
|
29
|
+
@waitUntilVisible ".autoplay.nav_play", ->
|
30
|
+
@echo "Carousel has been paused"
|
31
|
+
# hide play button
|
32
|
+
@hide ".autoplay"
|
33
|
+
|
34
|
+
# Capture carrousel area
|
35
|
+
next = ->
|
36
|
+
image = "bbcshot#{currentLink}.png"
|
37
|
+
images.push image
|
38
|
+
@echo "Processing image #{currentLink}"
|
39
|
+
@captureSelector image, '.carousel_viewport'
|
40
|
+
if currentLink < nbLinks
|
41
|
+
@click ".carousel_itemList_li[rel='#{currentLink}']"
|
42
|
+
@wait 1000, ->
|
43
|
+
@then next
|
44
|
+
currentLink++
|
45
|
+
else
|
46
|
+
@then buildPage
|
47
|
+
|
48
|
+
# Building resulting page and image
|
49
|
+
buildPage = ->
|
50
|
+
@echo "Build result page"
|
51
|
+
fs = require "fs"
|
52
|
+
@viewport 624, 400
|
53
|
+
pageHtml = "<html><body style='background:black;margin:0;padding:0'>"
|
54
|
+
images.forEach (image) ->
|
55
|
+
pageHtml += "<img src='file://#{fs.workingDirectory}/#{image}'><br>"
|
56
|
+
pageHtml += "</body></html>"
|
57
|
+
fs.write "result.html", pageHtml, 'w'
|
58
|
+
@thenOpen "file://#{fs.workingDirectory}/result.html", ->
|
59
|
+
@echo "Resulting image saved to result.png"
|
60
|
+
@capture "result.png"
|
61
|
+
|
62
|
+
casper.then next
|
63
|
+
|
64
|
+
casper.run()
|
data/samples/bbcshots.js
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
/*
|
2
|
+
* Create a mosaic image from all headline photos on BBC homepage
|
3
|
+
*/
|
4
|
+
|
5
|
+
var casper = require("casper").create();
|
6
|
+
var nbLinks = 0;
|
7
|
+
var currentLink = 1;
|
8
|
+
var images = [];
|
9
|
+
var buildPage, next;
|
10
|
+
|
11
|
+
// helper to hide some element from remote DOM
|
12
|
+
casper.hide = function(selector) {
|
13
|
+
this.evaluate(function(selector) {
|
14
|
+
document.querySelector(selector).style.display = "none";
|
15
|
+
}, {
|
16
|
+
selector: selector
|
17
|
+
});
|
18
|
+
};
|
19
|
+
|
20
|
+
casper.start("http://www.bbc.co.uk/", function() {
|
21
|
+
nbLinks = this.evaluate(function() {
|
22
|
+
return __utils__.findAll('#promo2_carousel_items_items li').length;
|
23
|
+
});
|
24
|
+
this.echo(nbLinks + " items founds");
|
25
|
+
// hide navigation arrows
|
26
|
+
this.hide(".nav_left");
|
27
|
+
this.hide(".nav_right");
|
28
|
+
this.mouse.move("#promo2_carousel");
|
29
|
+
this.waitUntilVisible(".autoplay.nav_pause", function() {
|
30
|
+
this.echo("Moving over pause button");
|
31
|
+
this.mouse.move(".autoplay.nav_pause");
|
32
|
+
this.click(".autoplay.nav_pause");
|
33
|
+
this.echo("Clicked on pause button");
|
34
|
+
this.waitUntilVisible(".autoplay.nav_play", function() {
|
35
|
+
this.echo("Carousel has been paused");
|
36
|
+
// hide play button
|
37
|
+
this.hide(".autoplay");
|
38
|
+
});
|
39
|
+
});
|
40
|
+
});
|
41
|
+
|
42
|
+
// Capture carrousel area
|
43
|
+
next = function() {
|
44
|
+
var image;
|
45
|
+
image = "bbcshot" + currentLink + ".png";
|
46
|
+
images.push(image);
|
47
|
+
this.echo("Processing image " + currentLink);
|
48
|
+
this.captureSelector(image, '.carousel_viewport');
|
49
|
+
if (currentLink < nbLinks) {
|
50
|
+
this.click(".carousel_itemList_li[rel='" + currentLink + "']");
|
51
|
+
this.wait(1000, function() {
|
52
|
+
this.then(next);
|
53
|
+
currentLink++;
|
54
|
+
});
|
55
|
+
} else {
|
56
|
+
this.then(buildPage);
|
57
|
+
}
|
58
|
+
};
|
59
|
+
|
60
|
+
// Building resulting page and image
|
61
|
+
buildPage = function() {
|
62
|
+
var fs, pageHtml;
|
63
|
+
this.echo("Build result page");
|
64
|
+
fs = require("fs");
|
65
|
+
this.viewport(624, 400);
|
66
|
+
pageHtml = "<html><body style='background:black;margin:0;padding:0'>";
|
67
|
+
images.forEach(function(image) {
|
68
|
+
pageHtml += "<img src='file://" + fs.workingDirectory + "/" + image + "'><br>";
|
69
|
+
});
|
70
|
+
pageHtml += "</body></html>";
|
71
|
+
fs.write("result.html", pageHtml, 'w');
|
72
|
+
this.thenOpen("file://" + fs.workingDirectory + "/result.html", function() {
|
73
|
+
this.echo("Resulting image saved to result.png");
|
74
|
+
this.capture("result.png");
|
75
|
+
});
|
76
|
+
};
|
77
|
+
|
78
|
+
casper.then(next);
|
79
|
+
|
80
|
+
casper.run();
|
@@ -0,0 +1,19 @@
|
|
1
|
+
casper = require("casper").create()
|
2
|
+
dump = require("utils").dump
|
3
|
+
|
4
|
+
# removing default options passed by the Python executable
|
5
|
+
casper.cli.drop "cli"
|
6
|
+
casper.cli.drop "casper-path"
|
7
|
+
|
8
|
+
if casper.cli.args.length is 0 and Object.keys(casper.cli.options).length is 0
|
9
|
+
casper
|
10
|
+
.echo("Pass some args and options to see how they are handled by CasperJS")
|
11
|
+
.exit(1)
|
12
|
+
|
13
|
+
casper.echo "Casper CLI passed args:"
|
14
|
+
dump casper.cli.args
|
15
|
+
|
16
|
+
casper.echo "Casper CLI passed options:"
|
17
|
+
dump casper.cli.options
|
18
|
+
|
19
|
+
casper.exit()
|
data/samples/cliplay.js
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
var casper = require("casper").create();
|
2
|
+
var dump = require("utils").dump;
|
3
|
+
|
4
|
+
// removing default options passed by the Python executable
|
5
|
+
casper.cli.drop("cli");
|
6
|
+
casper.cli.drop("casper-path");
|
7
|
+
|
8
|
+
if (casper.cli.args.length === 0 && Object.keys(casper.cli.options).length === 0) {
|
9
|
+
casper
|
10
|
+
.echo("Pass some args and options to see how they are handled by CasperJS")
|
11
|
+
.exit(1)
|
12
|
+
;
|
13
|
+
}
|
14
|
+
|
15
|
+
casper.echo("Casper CLI passed args:");
|
16
|
+
dump(casper.cli.args);
|
17
|
+
|
18
|
+
casper.echo("Casper CLI passed options:");
|
19
|
+
dump(casper.cli.options);
|
20
|
+
|
21
|
+
casper.exit();
|
@@ -0,0 +1,11 @@
|
|
1
|
+
casper = require("casper").create()
|
2
|
+
|
3
|
+
# listening to a custom event
|
4
|
+
casper.on "google.loaded", (title) ->
|
5
|
+
@echo "Google page title is #{title}"
|
6
|
+
|
7
|
+
casper.start "http://google.com/", ->
|
8
|
+
# emitting a custom event
|
9
|
+
@emit "google.loaded", @getTitle()
|
10
|
+
|
11
|
+
casper.run()
|
@@ -0,0 +1,13 @@
|
|
1
|
+
var casper = require("casper").create();
|
2
|
+
|
3
|
+
// listening to a custom event
|
4
|
+
casper.on("google.loaded", function(title) {
|
5
|
+
this.echo("Google page title is " + title);
|
6
|
+
});
|
7
|
+
|
8
|
+
casper.start("http://google.com/", function() {
|
9
|
+
// emitting a custom event
|
10
|
+
this.emit("google.loaded", this.getTitle());
|
11
|
+
});
|
12
|
+
|
13
|
+
casper.run();
|
@@ -0,0 +1,33 @@
|
|
1
|
+
###
|
2
|
+
A basic custom logging implementation. The idea is to (extremely) verbosely
|
3
|
+
log every received resource.
|
4
|
+
###
|
5
|
+
|
6
|
+
casper = require("casper").create
|
7
|
+
###
|
8
|
+
Every time a resource is received, a new log entry is added to the stack
|
9
|
+
at the 'verbose' level.
|
10
|
+
|
11
|
+
@param Object resource A phantomjs resource object
|
12
|
+
###
|
13
|
+
onResourceReceived: (self, resource) ->
|
14
|
+
infos = []
|
15
|
+
props = [
|
16
|
+
"url"
|
17
|
+
"status"
|
18
|
+
"statusText"
|
19
|
+
"redirectURL"
|
20
|
+
"bodySize"
|
21
|
+
]
|
22
|
+
infos.push resource[prop] for prop in props
|
23
|
+
infos.push "[#{header.name}: #{header.value}]" for header in resource.headers
|
24
|
+
@log infos.join(", "), "verbose"
|
25
|
+
verbose: true # we want to see the log printed out to the console
|
26
|
+
logLevel: "verbose" # of course we want to see logs to our new level :)
|
27
|
+
|
28
|
+
# add a new 'verbose' logging level at the lowest priority
|
29
|
+
casper.logLevels = ["verbose"].concat casper.logLevels
|
30
|
+
|
31
|
+
# test our new logger with google
|
32
|
+
casper.start("http://www.google.com/").run ->
|
33
|
+
@exit()
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/*
|
2
|
+
* A basic custom logging implementation. The idea is to (extremely) verbosely
|
3
|
+
* log every received resource.
|
4
|
+
*/
|
5
|
+
|
6
|
+
var casper = require("casper").create({
|
7
|
+
/*
|
8
|
+
Every time a resource is received, a new log entry is added to the stack at
|
9
|
+
the 'verbose' level.
|
10
|
+
*/
|
11
|
+
onResourceReceived: function(self, resource) {
|
12
|
+
var header, infos, prop, props, _i, _j, _len, _len1, _ref;
|
13
|
+
infos = [];
|
14
|
+
props = [
|
15
|
+
"url",
|
16
|
+
"status",
|
17
|
+
"statusText",
|
18
|
+
"redirectURL",
|
19
|
+
"bodySize"
|
20
|
+
];
|
21
|
+
for (_i = 0, _len = props.length; _i < _len; _i++) {
|
22
|
+
prop = props[_i];
|
23
|
+
infos.push(resource[prop]);
|
24
|
+
}
|
25
|
+
_ref = resource.headers;
|
26
|
+
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
27
|
+
header = _ref[_j];
|
28
|
+
infos.push("[" + header.name + ": " + header.value + "]");
|
29
|
+
}
|
30
|
+
this.log(infos.join(", "), "verbose");
|
31
|
+
},
|
32
|
+
verbose: true,
|
33
|
+
logLevel: "verbose"
|
34
|
+
});
|
35
|
+
|
36
|
+
// add a new 'verbose' logging level at the lowest priority
|
37
|
+
casper.logLevels = ["verbose"].concat(casper.logLevels);
|
38
|
+
|
39
|
+
// test our new logger with google
|
40
|
+
casper.start("http://www.google.com/").run(function() {
|
41
|
+
this.exit();
|
42
|
+
});
|
data/samples/download.js
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
/*
|
2
|
+
* download the google logo image onto the local filesystem
|
3
|
+
*/
|
4
|
+
|
5
|
+
var casper = require("casper").create();
|
6
|
+
|
7
|
+
casper.start("http://www.google.fr/", function() {
|
8
|
+
this.download("http://www.google.fr/images/srpr/logo3w.png", "logo.png");
|
9
|
+
});
|
10
|
+
|
11
|
+
casper.run();
|
@@ -0,0 +1,60 @@
|
|
1
|
+
casper = require("casper").create
|
2
|
+
verbose: true
|
3
|
+
|
4
|
+
# The base links array
|
5
|
+
links = [
|
6
|
+
"http://google.com/"
|
7
|
+
"http://yahoo.com/"
|
8
|
+
"http://bing.com/"
|
9
|
+
]
|
10
|
+
|
11
|
+
currentLink = 0;
|
12
|
+
|
13
|
+
# If we don't set a limit, it could go on forever
|
14
|
+
upTo = ~~casper.cli.get(0) || 10
|
15
|
+
|
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
|
+
###
|
20
|
+
addLinks = (link) ->
|
21
|
+
@then ->
|
22
|
+
found = @evaluate searchLinks
|
23
|
+
@echo "#{found.length} links found on #{link}"
|
24
|
+
links = links.concat found
|
25
|
+
|
26
|
+
###
|
27
|
+
Fetch all <a> elements from the page and return
|
28
|
+
the ones which contains a href starting with 'http://'
|
29
|
+
###
|
30
|
+
searchLinks = ->
|
31
|
+
filter = Array::filter
|
32
|
+
map = Array::map
|
33
|
+
map.call filter.call(document.querySelectorAll("a"), (a) ->
|
34
|
+
(/^http:\/\/.*/i).test a.getAttribute("href")
|
35
|
+
), (a) ->
|
36
|
+
a.getAttribute "href"
|
37
|
+
|
38
|
+
# Just opens the page and prints the title
|
39
|
+
start = (link) ->
|
40
|
+
@start link, ->
|
41
|
+
@echo "Page title: #{ @getTitle() }"
|
42
|
+
|
43
|
+
# As long as it has a next link, and is under the maximum limit, will keep running
|
44
|
+
check = ->
|
45
|
+
if links[currentLink] && currentLink < upTo
|
46
|
+
@echo "--- Link #{currentLink} ---"
|
47
|
+
start.call @, links[currentLink]
|
48
|
+
addLinks.call @, links[currentLink]
|
49
|
+
currentLink++
|
50
|
+
@run check
|
51
|
+
else
|
52
|
+
@echo "All done."
|
53
|
+
@exit()
|
54
|
+
|
55
|
+
casper.start()
|
56
|
+
|
57
|
+
casper.then ->
|
58
|
+
@echo "Starting"
|
59
|
+
|
60
|
+
casper.run check
|