ucnv-chainsaw 0.0.0
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.
- data/README.rdoc +42 -0
- data/Rakefile +149 -0
- data/examples/01_google.rb +17 -0
- data/examples/02_twitter.rb +15 -0
- data/lib/chainsaw.rb +40 -0
- data/lib/chainsaw/browser.rb +262 -0
- data/lib/chainsaw/common.rb +87 -0
- data/lib/chainsaw/element.rb +62 -0
- data/lib/chainsaw/ext/httpclient.rb +27 -0
- data/lib/chainsaw/ext/nokogiri.rb +29 -0
- data/test/helper.rb +15 -0
- data/test/htdocs/01.html +17 -0
- data/test/htdocs/02.html +9 -0
- data/test/htdocs/03.html +25 -0
- data/test/htdocs/04.html +14 -0
- data/test/htdocs/05.html +14 -0
- data/test/htdocs/06.html +14 -0
- data/test/htdocs/cgi.rb +50 -0
- data/test/htdocs/img.gif +0 -0
- data/test/server.rb +20 -0
- data/test/test_browser.rb +274 -0
- data/test/test_chainsaw.rb +20 -0
- data/test/test_element.rb +32 -0
- data/test/test_ext.rb +31 -0
- data/test/test_m17n.rb +23 -0
- metadata +116 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
|
2
|
+
module Chainsaw
|
3
|
+
|
4
|
+
module Util
|
5
|
+
|
6
|
+
def is_xml_parsable?(content_type)
|
7
|
+
content_type =~ %r{(?:text|application)/x?(?:ht)?ml}
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_nth(num)
|
11
|
+
case num.to_i
|
12
|
+
when 1
|
13
|
+
'1st'
|
14
|
+
when 2
|
15
|
+
'2nd'
|
16
|
+
when 3
|
17
|
+
'3rd'
|
18
|
+
else
|
19
|
+
num.to_i.to_s + 'th'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def qq(str)
|
24
|
+
"\"#{str}\""
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Encoding
|
29
|
+
NKF_TO_LIBXML2 = {
|
30
|
+
NKF::ASCII => 10, #=> 22,
|
31
|
+
NKF::JIS => 19,
|
32
|
+
NKF::SJIS => 20,
|
33
|
+
NKF::EUC => 21,
|
34
|
+
NKF::UTF8 => 1,
|
35
|
+
NKF::UTF16 => 2,
|
36
|
+
NKF::UNKNOWN => 10,
|
37
|
+
NKF::BINARY => 10,
|
38
|
+
}
|
39
|
+
|
40
|
+
def self.guess(data)
|
41
|
+
nokogiri_consts = Nokogiri::XML::SAX::Parser::ENCODINGS
|
42
|
+
nkf_guessed = NKF.guess data
|
43
|
+
value = NKF_TO_LIBXML2[nkf_guessed]
|
44
|
+
value = NKF_TO_LIBXML2[NKF::UTF8] unless nokogiri_consts.value?(value)
|
45
|
+
c = nokogiri_consts.find do |k, v|
|
46
|
+
v == value
|
47
|
+
end
|
48
|
+
c.first
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module ErrorWrapper
|
53
|
+
APPLY_TESTUNIT_BACKTRACEFILTER = true
|
54
|
+
@@indent = '| '
|
55
|
+
@@tab = ' '
|
56
|
+
def set_backtrace(backtrace)
|
57
|
+
root_cause = $!
|
58
|
+
unless root_cause.nil?
|
59
|
+
backtrace = filter_backtrace(backtrace)
|
60
|
+
backtrace.push '............', 'root cause'
|
61
|
+
backtrace.push "#{@@indent}#{root_cause.class.name}: #{root_cause.to_s}"
|
62
|
+
backtrace.concat(filter_backtrace(root_cause.backtrace).map do |t|
|
63
|
+
"#{@@indent}#{@@tab}#{t}"
|
64
|
+
end)
|
65
|
+
end
|
66
|
+
super backtrace
|
67
|
+
end
|
68
|
+
|
69
|
+
def filter_backtrace(backtrace)
|
70
|
+
if APPLY_TESTUNIT_BACKTRACEFILTER
|
71
|
+
require 'test/unit/util/backtracefilter'
|
72
|
+
Test::Unit::Util::BacktraceFilter.module_eval do
|
73
|
+
module_function :filter_backtrace
|
74
|
+
end
|
75
|
+
Test::Unit::Util::BacktraceFilter.filter_backtrace backtrace
|
76
|
+
else
|
77
|
+
backtrace
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class RequestError < StandardError
|
83
|
+
include Chainsaw::ErrorWrapper
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Chainsaw
|
5
|
+
module Element
|
6
|
+
include Chainsaw::Util
|
7
|
+
|
8
|
+
def is_form?
|
9
|
+
name =~ /^form$/i
|
10
|
+
end
|
11
|
+
|
12
|
+
def serialize_form(clicked_button = nil, image_x = -1, image_y = -1)
|
13
|
+
return nil unless is_form?
|
14
|
+
form = []
|
15
|
+
if clicked_button.nil?
|
16
|
+
s = self.xpath('.//input[@type="submit"]')
|
17
|
+
unless s.empty?
|
18
|
+
form.push [s.first['name'], s.first['value']]
|
19
|
+
end
|
20
|
+
else
|
21
|
+
s = self.xpath(".//input[@name=#{qq clicked_button}]")
|
22
|
+
|
23
|
+
if s.size and ['submit', 'image'].include? s.first['type']
|
24
|
+
form.push [s.first['name'], s.first['value']]
|
25
|
+
form.push [s.first['name'] + '.x', image_x] if image_x > 0
|
26
|
+
form.push [s.first['name'] + '.y', image_y] if image_y > 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
self.xpath('.//input').each do |e|
|
30
|
+
next unless e['name']
|
31
|
+
case e['type']
|
32
|
+
when 'text', 'password', 'hidden', nil
|
33
|
+
form.push [e['name'], e['value']]
|
34
|
+
when 'radio', 'checkbox'
|
35
|
+
form.push [e['name'], e['value']] unless e['checked'].nil?
|
36
|
+
when 'file'
|
37
|
+
if self['enctype'] =~ %r{^multipart/form-data}i
|
38
|
+
f = Pathname.new e['value'].to_s
|
39
|
+
form.push [e['name'], f]
|
40
|
+
end
|
41
|
+
else
|
42
|
+
;
|
43
|
+
end
|
44
|
+
end
|
45
|
+
self.xpath('.//textarea').each do |e|
|
46
|
+
form.push [e['name'], e.text]
|
47
|
+
end
|
48
|
+
self.xpath('.//select').each do |e|
|
49
|
+
opt = e.xpath('.//option')
|
50
|
+
slctd = opt.reject do |o|
|
51
|
+
o['selected'].nil?
|
52
|
+
end
|
53
|
+
slctd = opt.first if e['multiple'].nil? and slctd.empty?
|
54
|
+
slctd.each {|s| form.push([e['name'], s['value']]) } unless slctd.nil?
|
55
|
+
end
|
56
|
+
form
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class HTTPClient
|
4
|
+
def get_r(uri, query = nil, extheader = {}, &block)
|
5
|
+
follow_redirect(:get, uri, query, nil, extheader, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def post_r(uri, body = nil, extheader = {}, &block)
|
9
|
+
follow_redirect(:post, uri, nil, body, extheader, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias do_get_header_original do_get_header
|
13
|
+
def do_get_header(req, res, sess)
|
14
|
+
# It is not a good way, but HTTPClient cannot keep requested URIs..
|
15
|
+
unless res.respond_to?(:uri)
|
16
|
+
HTTP::Message.module_eval do
|
17
|
+
attr_accessor :uri
|
18
|
+
end
|
19
|
+
end
|
20
|
+
res.uri = req.header.request_uri
|
21
|
+
do_get_header_original(req, res, sess)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
HTTP::Status::SUCCESSFUL_STATUS.push 404
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
class Node
|
6
|
+
def fix_xpath(*paths)
|
7
|
+
paths.map do |path|
|
8
|
+
if path.is_a? String
|
9
|
+
# fix for id() func
|
10
|
+
path.sub(/^id\(\s*["']([^"']*)["']\s*\)/, './/*[@id="\1"]')
|
11
|
+
else
|
12
|
+
path
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
alias original_search search
|
18
|
+
def search(*paths)
|
19
|
+
original_search(*fix_xpath(*paths))
|
20
|
+
end
|
21
|
+
|
22
|
+
alias original_xpath xpath
|
23
|
+
def xpath(*paths)
|
24
|
+
original_xpath(*fix_xpath(*paths))
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'chainsaw'
|
4
|
+
require 'open-uri'
|
5
|
+
require File.dirname(__FILE__) + '/server.rb'
|
6
|
+
|
7
|
+
unless defined? TEST_URL
|
8
|
+
TEST_URL = "http://#{TEST_SERVER_CONFIG[:BindAddress]}:#{TEST_SERVER_CONFIG[:Port]}/"
|
9
|
+
|
10
|
+
begin
|
11
|
+
open TEST_URL
|
12
|
+
rescue
|
13
|
+
raise 'Run test/server.rb before you test.'
|
14
|
+
end
|
15
|
+
end
|
data/test/htdocs/01.html
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>test 01</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<div id="links">
|
7
|
+
<ul>
|
8
|
+
<li><a href="01.html">1</a></li>
|
9
|
+
<li><a href="02.html">2</a></li>
|
10
|
+
<li><a href="/03.html">3</a></li>
|
11
|
+
<li><a href="/cgi.rb">4</a></li>
|
12
|
+
<li><a href="00.html">5</a></li>
|
13
|
+
</ul>
|
14
|
+
</div>
|
15
|
+
</body>
|
16
|
+
</html>
|
17
|
+
|
data/test/htdocs/02.html
ADDED
data/test/htdocs/03.html
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>test 03</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<div id="forms">
|
7
|
+
<form action="cgi.rb" method="get" id="get-form">
|
8
|
+
<input type="file" name="f" />
|
9
|
+
<input type="text" name="t" />
|
10
|
+
<input type="submit" name="s" value="go" />
|
11
|
+
</form>
|
12
|
+
<form action="cgi.rb" method="post" id="post-form">
|
13
|
+
<input type="text" name="t">
|
14
|
+
<input type="password" name="p">
|
15
|
+
|
16
|
+
<input type="submit" name="s" value="go" />
|
17
|
+
</form>
|
18
|
+
<form action="cgi.rb" method="post" enctype="multipart/form-data" id="upload-form">
|
19
|
+
<input type="file" name="f" />
|
20
|
+
<input type="submit" name="s" value="go" />
|
21
|
+
</form>
|
22
|
+
</div>
|
23
|
+
</body>
|
24
|
+
</html>
|
25
|
+
|
data/test/htdocs/04.html
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>test utf8</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<div id="links">
|
7
|
+
<ul>
|
8
|
+
<li><a name="ウェブ検索のサービス" href="http://www.google.co.jp/">グーグル・ジャパン</a></li>
|
9
|
+
<li><a name="ウェブ検索のサービス" href="http://www.yahoo.co.jp/">ヤフー・ジャパン</a></li>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
</body>
|
13
|
+
</html>
|
14
|
+
<!-- 上記の内容だけでは NKF#guess が NKF::ASCII を返すため失敗する... -->
|
data/test/htdocs/05.html
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>test sjis</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<div id="links">
|
7
|
+
<ul>
|
8
|
+
<li><a name="�E�F�u�����̃T�[�r�X" href="http://www.google.co.jp/">�O�[�O���E�W���p��</a></li>
|
9
|
+
<li><a name="�E�F�u�����̃T�[�r�X" href="http://www.yahoo.co.jp/">���t�[�E�W���p��</a></li>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
</body>
|
13
|
+
</html>
|
14
|
+
|
data/test/htdocs/06.html
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>test sjis</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<div id="links">
|
7
|
+
<ul>
|
8
|
+
<li><a name="�����ָ����Υ����ӥ�" href="http://www.google.co.jp/">�������롦����ѥ�</a></li>
|
9
|
+
<li><a name="�����ָ����Υ����ӥ�" href="http://www.yahoo.co.jp/">��ա�������ѥ�</a></li>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
</body>
|
13
|
+
</html>
|
14
|
+
|
data/test/htdocs/cgi.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'yaml'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
cgi = CGI.new
|
6
|
+
env = Hash[ENV.collect() { |k, v| [k, v] }]
|
7
|
+
res = {}
|
8
|
+
|
9
|
+
if cgi.has_key? 'redirect'
|
10
|
+
l = env['REQUEST_URI'].split('cgi.rb').first + '02.html'
|
11
|
+
cgi.print [
|
12
|
+
'Status: 302 Moved Temporarily',
|
13
|
+
'Location: ' + l,
|
14
|
+
"\n"
|
15
|
+
].join("\n")
|
16
|
+
exit 0
|
17
|
+
end
|
18
|
+
|
19
|
+
if cgi.has_key? 'auth'
|
20
|
+
auth = env['HTTP_AUTHORIZATION'] || ''
|
21
|
+
user_pass = Base64.decode64(auth.split.last || '').split(/:/, 2)
|
22
|
+
if user_pass.empty?
|
23
|
+
cgi.print [
|
24
|
+
'Status: 401 Unauthorized',
|
25
|
+
'WWW-Authenticate: Basic realm="test"',
|
26
|
+
"\n",
|
27
|
+
'Access denied.'
|
28
|
+
].join("\n")
|
29
|
+
exit 0
|
30
|
+
else
|
31
|
+
res['auth'] = user_pass.join(':')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if env['CONTENT_TYPE'] =~ %r{^multipart/form-data;}
|
36
|
+
upload = cgi.params['f'][0]
|
37
|
+
res['upload'] = {
|
38
|
+
'size' => upload.size,
|
39
|
+
'original_filename' => upload.original_filename,
|
40
|
+
'content_type' => upload.content_type
|
41
|
+
} if upload
|
42
|
+
end
|
43
|
+
|
44
|
+
res.update(
|
45
|
+
'params' => cgi.params,
|
46
|
+
'cookies' => cgi.cookies,
|
47
|
+
'env' => env
|
48
|
+
)
|
49
|
+
|
50
|
+
cgi.print "\n\n" + res.to_yaml
|
data/test/htdocs/img.gif
ADDED
Binary file
|
data/test/server.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
|
3
|
+
TEST_SERVER_CONFIG = {
|
4
|
+
:DocumentRoot => File.join(File.expand_path(File.dirname(__FILE__)), 'htdocs'),
|
5
|
+
:BindAddress => '127.0.0.1',
|
6
|
+
:Port => 3080,
|
7
|
+
:CGIInterpreter => WEBrick::HTTPServlet::CGIHandler::Ruby,
|
8
|
+
}
|
9
|
+
|
10
|
+
if __FILE__ == $0
|
11
|
+
s = WEBrick::HTTPServer.new(TEST_SERVER_CONFIG)
|
12
|
+
s.mount(
|
13
|
+
'/cgi.rb',
|
14
|
+
WEBrick::HTTPServlet::CGIHandler,
|
15
|
+
TEST_SERVER_CONFIG[:DocumentRoot] + '/cgi.rb'
|
16
|
+
)
|
17
|
+
Signal.trap(:INT) { s.shutdown }
|
18
|
+
Signal.trap(:TERM) { exit 0 }
|
19
|
+
s.start
|
20
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper.rb'
|
2
|
+
|
3
|
+
|
4
|
+
class TestBrowser < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@text_val = 'value for text field'
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def test_open
|
12
|
+
cs = Chainsaw.launch(TEST_URL + '01.html')
|
13
|
+
cs.open { |cs|
|
14
|
+
assert_equal cs.uri.to_s, TEST_URL + '01.html'
|
15
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
16
|
+
assert_equal 200, cs.res.status
|
17
|
+
assert_equal 'text/html', cs.res.contenttype
|
18
|
+
links = cs.doc.search('//a')
|
19
|
+
assert_equal links.length, 5
|
20
|
+
cs.set_next links[1]
|
21
|
+
}
|
22
|
+
cs.open { |cs|
|
23
|
+
assert_equal cs.uri.to_s, TEST_URL + '02.html'
|
24
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
25
|
+
links = cs.doc.search('//a')
|
26
|
+
cs.set_next links.last
|
27
|
+
}
|
28
|
+
cs.open { |cs|
|
29
|
+
assert_equal cs.uri.to_s, TEST_URL + '00.html'
|
30
|
+
assert_equal 404, cs.res.status
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_back
|
35
|
+
d = ''
|
36
|
+
cs = Chainsaw.launch(TEST_URL + '01.html').
|
37
|
+
open { |cs|
|
38
|
+
d = cs.doc.to_s
|
39
|
+
cs.set_next cs.doc.search('//a')[1]
|
40
|
+
}.open.back { |cs|
|
41
|
+
assert_equal TEST_URL + '01.html', cs.uri.to_s
|
42
|
+
assert_equal d, cs.doc.to_s
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_open_file
|
47
|
+
Chainsaw.launch(TEST_URL + 'img.gif').
|
48
|
+
open { |cs|
|
49
|
+
assert_equal 200, cs.res.status
|
50
|
+
assert_equal 'image/gif', cs.res.contenttype
|
51
|
+
assert_not_nil cs.file
|
52
|
+
assert_instance_of Tempfile, cs.file
|
53
|
+
|
54
|
+
original = File.stat(File.dirname(__FILE__) + '/htdocs/img.gif')
|
55
|
+
saved = File.stat(cs.file.path)
|
56
|
+
assert_equal saved.size, original.size
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_submit_get
|
61
|
+
Chainsaw.launch(TEST_URL + '03.html').
|
62
|
+
open { |cs|
|
63
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
64
|
+
form = cs.doc.search('id("get-form")').first
|
65
|
+
form.xpath('//input[@name="t"]').attr('value', @text_val)
|
66
|
+
cs.set_next form
|
67
|
+
}.
|
68
|
+
submit { |cs|
|
69
|
+
x = YAML.load cs.res.content
|
70
|
+
assert_equal @text_val, x['params']['t'][0]
|
71
|
+
assert_equal 'go', x['params']['s'][0]
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_submit_post
|
76
|
+
Chainsaw.launch(TEST_URL + '03.html').
|
77
|
+
open { |cs|
|
78
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
79
|
+
form = cs.doc.search('id("post-form")').first
|
80
|
+
form.xpath('//input[@name="t"]').attr('value', @text_val)
|
81
|
+
cs.set_next form
|
82
|
+
}.
|
83
|
+
submit { |cs|
|
84
|
+
x = YAML.load cs.res.content
|
85
|
+
assert_equal @text_val, x['params']['t'][0]
|
86
|
+
assert_equal 'go', x['params']['s'][0]
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def test_submit_process
|
92
|
+
Chainsaw.launch(TEST_URL + '03.html').
|
93
|
+
process { |cs|
|
94
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
95
|
+
form = cs.doc.search('id("post-form")').first
|
96
|
+
form.xpath('//input[@name="t"]').attr('value', @text_val)
|
97
|
+
cs.set_next form
|
98
|
+
}.
|
99
|
+
process { |cs|
|
100
|
+
x = YAML.load cs.res.content
|
101
|
+
assert_equal @text_val, x['params']['t'][0]
|
102
|
+
assert_equal 'go', x['params']['s'][0]
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_submit_file
|
107
|
+
file_path = File.dirname(__FILE__) + '/htdocs/01.html'
|
108
|
+
Chainsaw.launch(TEST_URL + '03.html').
|
109
|
+
open { |cs|
|
110
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
111
|
+
form = cs.doc.search('id("upload-form")').first
|
112
|
+
form.xpath('//input[@name="f"]').attr('value', file_path)
|
113
|
+
cs.set_next form
|
114
|
+
}.
|
115
|
+
submit { |cs|
|
116
|
+
stat = File.stat(file_path)
|
117
|
+
x = YAML.load cs.res.content
|
118
|
+
data = x['upload']
|
119
|
+
assert_equal stat.size, data['size'].to_i
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_each
|
124
|
+
count = 0
|
125
|
+
Chainsaw.launch(TEST_URL + '01.html').open { |cs|
|
126
|
+
cs.set_next cs.doc.xpath('//a')
|
127
|
+
}.each { |cs|
|
128
|
+
count += 1
|
129
|
+
cs.open { |cs|
|
130
|
+
if count == 4
|
131
|
+
x = YAML.load cs.res.content
|
132
|
+
assert_equal TEST_URL + '01.html', x['env']['HTTP_REFERER']
|
133
|
+
end
|
134
|
+
}
|
135
|
+
}
|
136
|
+
assert_equal 5, count
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_each_with_index
|
140
|
+
count = 0
|
141
|
+
Chainsaw.launch(TEST_URL + '01.html').open { |cs|
|
142
|
+
cs.set_next cs.doc.xpath('//a')
|
143
|
+
}.each_with_index { |cs, index|
|
144
|
+
assert_equal index, count
|
145
|
+
count += 1
|
146
|
+
cs.open { |cs|
|
147
|
+
if count == 4
|
148
|
+
x = YAML.load cs.res.content
|
149
|
+
assert_equal TEST_URL + '01.html', x['env']['HTTP_REFERER']
|
150
|
+
end
|
151
|
+
}
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_referer
|
156
|
+
Chainsaw.launch(TEST_URL + '01.html').
|
157
|
+
open { |cs|
|
158
|
+
cs.set_next cs.doc.search('//a[contains(@href,"cgi.rb")]')[0]
|
159
|
+
}.
|
160
|
+
open { |cs|
|
161
|
+
x = YAML.load cs.res.content
|
162
|
+
assert_equal TEST_URL + '01.html', x['env']['HTTP_REFERER']
|
163
|
+
}
|
164
|
+
|
165
|
+
Chainsaw.launch(TEST_URL + '01.html', {:hide_referer => true}).
|
166
|
+
open { |cs|
|
167
|
+
cs.set_next cs.doc.search('//a[contains(@href,"cgi.rb")]')[0]
|
168
|
+
}.
|
169
|
+
open { |cs|
|
170
|
+
x = YAML.load cs.res.content
|
171
|
+
assert_nil x['env']['HTTP_REFERER']
|
172
|
+
}
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
=begin
|
177
|
+
def test_auth
|
178
|
+
user_pass = 'testuser:testpass'
|
179
|
+
Chainsaw.launch(TEST_URL + 'cgi.rb?auth').
|
180
|
+
set_auth(*user_pass.split(':')).
|
181
|
+
open {|cs|
|
182
|
+
x = YAML.load cs.res.content
|
183
|
+
assert_equal user_pass, x['auth']
|
184
|
+
cs.set_next cs.uri
|
185
|
+
}.
|
186
|
+
open { |cs|
|
187
|
+
assert_equal 200, cs.res.status
|
188
|
+
cs.uri
|
189
|
+
}
|
190
|
+
|
191
|
+
# I want to fix this to return 401 status and content body...
|
192
|
+
assert_raise Chainsaw::RequestError do
|
193
|
+
Chainsaw.launch(TEST_URL + 'cgi.rb?auth').
|
194
|
+
open { |cs|
|
195
|
+
assert_equal 401, cs.res.status
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
assert_raise Chainsaw::RequestError do
|
200
|
+
Chainsaw.launch.
|
201
|
+
set_auth(*user_pass.split(':')).
|
202
|
+
set_next(TEST_URL + 'cgi.rb?auth').
|
203
|
+
open { |cs|
|
204
|
+
assert_equal 401, cs.res.status
|
205
|
+
}
|
206
|
+
end
|
207
|
+
end
|
208
|
+
=end
|
209
|
+
|
210
|
+
def test_redirect
|
211
|
+
Chainsaw.launch(TEST_URL + 'cgi.rb?redirect').
|
212
|
+
open { |cs|
|
213
|
+
assert_equal TEST_URL + '02.html', cs.uri.to_s
|
214
|
+
}
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_request_failed
|
218
|
+
x = begin
|
219
|
+
Chainsaw.launch(TEST_URL).open.
|
220
|
+
set_next('http://localhost/').open
|
221
|
+
rescue => e
|
222
|
+
e.message
|
223
|
+
end
|
224
|
+
assert_equal 'Error occured during 2nd request; url: "http://localhost/"', x
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_invalid_url
|
228
|
+
assert_raise(TypeError) { Chainsaw.launch('ppppppppppp').open.doc }
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_max_history_count
|
232
|
+
cs = Chainsaw.launch
|
233
|
+
cs.max_history_count = 3
|
234
|
+
6.times do |i|
|
235
|
+
cs.set_next("#{TEST_URL}0#{i+1}.html").open
|
236
|
+
end
|
237
|
+
|
238
|
+
assert_equal 3, cs.history.size
|
239
|
+
assert_equal TEST_URL + '06.html', cs.history.first[:location]
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_ignore_redirect
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_result
|
247
|
+
cs = Chainsaw.launch
|
248
|
+
6.times do |i|
|
249
|
+
cs.set_next("#{TEST_URL}0#{i+1}.html").open do |cs|
|
250
|
+
[i, cs.uri]
|
251
|
+
end
|
252
|
+
end
|
253
|
+
assert_equal 6, cs.results.size
|
254
|
+
assert_equal 2, cs.results[2][0]
|
255
|
+
assert_equal TEST_URL + '03.html', cs.results[2][1].to_s
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_aliases
|
260
|
+
Chainsaw.launch(TEST_URL + '03.html').> { |cs|
|
261
|
+
assert_instance_of Nokogiri::HTML::Document, cs.doc
|
262
|
+
form = cs.doc.search('id("post-form")').first
|
263
|
+
form.xpath('//input[@name="t"]').attr('value', @text_val)
|
264
|
+
cs.set_next form
|
265
|
+
}.> { |cs|
|
266
|
+
x = YAML.load cs.res.content
|
267
|
+
assert_equal @text_val, x['params']['t'][0]
|
268
|
+
assert_equal 'go', x['params']['s'][0]
|
269
|
+
}
|
270
|
+
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|