diamond-mechanize 2.2 → 2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/Rakefile +49 -0
  2. data/lib/mechanize.rb +1079 -0
  3. data/lib/mechanize/content_type_error.rb +13 -0
  4. data/lib/mechanize/cookie.rb +232 -0
  5. data/lib/mechanize/cookie_jar.rb +194 -0
  6. data/lib/mechanize/download.rb +59 -0
  7. data/lib/mechanize/element_matcher.rb +36 -0
  8. data/lib/mechanize/file.rb +65 -0
  9. data/lib/mechanize/file_connection.rb +17 -0
  10. data/lib/mechanize/file_request.rb +26 -0
  11. data/lib/mechanize/file_response.rb +74 -0
  12. data/lib/mechanize/file_saver.rb +39 -0
  13. data/lib/mechanize/form.rb +543 -0
  14. data/lib/mechanize/form/button.rb +6 -0
  15. data/lib/mechanize/form/check_box.rb +12 -0
  16. data/lib/mechanize/form/field.rb +54 -0
  17. data/lib/mechanize/form/file_upload.rb +21 -0
  18. data/lib/mechanize/form/hidden.rb +3 -0
  19. data/lib/mechanize/form/image_button.rb +19 -0
  20. data/lib/mechanize/form/keygen.rb +34 -0
  21. data/lib/mechanize/form/multi_select_list.rb +94 -0
  22. data/lib/mechanize/form/option.rb +50 -0
  23. data/lib/mechanize/form/radio_button.rb +55 -0
  24. data/lib/mechanize/form/reset.rb +3 -0
  25. data/lib/mechanize/form/select_list.rb +44 -0
  26. data/lib/mechanize/form/submit.rb +3 -0
  27. data/lib/mechanize/form/text.rb +3 -0
  28. data/lib/mechanize/form/textarea.rb +3 -0
  29. data/lib/mechanize/headers.rb +23 -0
  30. data/lib/mechanize/history.rb +82 -0
  31. data/lib/mechanize/http.rb +8 -0
  32. data/lib/mechanize/http/agent.rb +1004 -0
  33. data/lib/mechanize/http/auth_challenge.rb +59 -0
  34. data/lib/mechanize/http/auth_realm.rb +31 -0
  35. data/lib/mechanize/http/content_disposition_parser.rb +188 -0
  36. data/lib/mechanize/http/www_authenticate_parser.rb +155 -0
  37. data/lib/mechanize/monkey_patch.rb +16 -0
  38. data/lib/mechanize/page.rb +440 -0
  39. data/lib/mechanize/page/base.rb +7 -0
  40. data/lib/mechanize/page/frame.rb +27 -0
  41. data/lib/mechanize/page/image.rb +30 -0
  42. data/lib/mechanize/page/label.rb +20 -0
  43. data/lib/mechanize/page/link.rb +98 -0
  44. data/lib/mechanize/page/meta_refresh.rb +68 -0
  45. data/lib/mechanize/parser.rb +173 -0
  46. data/lib/mechanize/pluggable_parsers.rb +144 -0
  47. data/lib/mechanize/redirect_limit_reached_error.rb +19 -0
  48. data/lib/mechanize/redirect_not_get_or_head_error.rb +21 -0
  49. data/lib/mechanize/response_code_error.rb +21 -0
  50. data/lib/mechanize/response_read_error.rb +27 -0
  51. data/lib/mechanize/robots_disallowed_error.rb +28 -0
  52. data/lib/mechanize/test_case.rb +663 -0
  53. data/lib/mechanize/unauthorized_error.rb +3 -0
  54. data/lib/mechanize/unsupported_scheme_error.rb +6 -0
  55. data/lib/mechanize/util.rb +101 -0
  56. data/test/data/htpasswd +1 -0
  57. data/test/data/server.crt +16 -0
  58. data/test/data/server.csr +12 -0
  59. data/test/data/server.key +15 -0
  60. data/test/data/server.pem +15 -0
  61. data/test/htdocs/alt_text.html +10 -0
  62. data/test/htdocs/bad_form_test.html +9 -0
  63. data/test/htdocs/button.jpg +0 -0
  64. data/test/htdocs/canonical_uri.html +9 -0
  65. data/test/htdocs/dir with spaces/foo.html +1 -0
  66. data/test/htdocs/empty_form.html +6 -0
  67. data/test/htdocs/file_upload.html +26 -0
  68. data/test/htdocs/find_link.html +41 -0
  69. data/test/htdocs/form_multi_select.html +16 -0
  70. data/test/htdocs/form_multival.html +37 -0
  71. data/test/htdocs/form_no_action.html +18 -0
  72. data/test/htdocs/form_no_input_name.html +16 -0
  73. data/test/htdocs/form_order_test.html +11 -0
  74. data/test/htdocs/form_select.html +16 -0
  75. data/test/htdocs/form_set_fields.html +14 -0
  76. data/test/htdocs/form_test.html +188 -0
  77. data/test/htdocs/frame_referer_test.html +10 -0
  78. data/test/htdocs/frame_test.html +30 -0
  79. data/test/htdocs/google.html +13 -0
  80. data/test/htdocs/index.html +6 -0
  81. data/test/htdocs/link with space.html +5 -0
  82. data/test/htdocs/meta_cookie.html +11 -0
  83. data/test/htdocs/no_title_test.html +6 -0
  84. data/test/htdocs/noindex.html +9 -0
  85. data/test/htdocs/rails_3_encoding_hack_form_test.html +27 -0
  86. data/test/htdocs/relative/tc_relative_links.html +21 -0
  87. data/test/htdocs/robots.html +8 -0
  88. data/test/htdocs/robots.txt +2 -0
  89. data/test/htdocs/tc_bad_charset.html +9 -0
  90. data/test/htdocs/tc_bad_links.html +5 -0
  91. data/test/htdocs/tc_base_link.html +8 -0
  92. data/test/htdocs/tc_blank_form.html +11 -0
  93. data/test/htdocs/tc_charset.html +6 -0
  94. data/test/htdocs/tc_checkboxes.html +19 -0
  95. data/test/htdocs/tc_encoded_links.html +5 -0
  96. data/test/htdocs/tc_field_precedence.html +11 -0
  97. data/test/htdocs/tc_follow_meta.html +8 -0
  98. data/test/htdocs/tc_form_action.html +48 -0
  99. data/test/htdocs/tc_links.html +19 -0
  100. data/test/htdocs/tc_meta_in_body.html +9 -0
  101. data/test/htdocs/tc_pretty_print.html +17 -0
  102. data/test/htdocs/tc_referer.html +16 -0
  103. data/test/htdocs/tc_relative_links.html +19 -0
  104. data/test/htdocs/tc_textarea.html +23 -0
  105. data/test/htdocs/test_click.html +11 -0
  106. data/test/htdocs/unusual______.html +5 -0
  107. data/test/test_mechanize.rb +1164 -0
  108. data/test/test_mechanize_cookie.rb +451 -0
  109. data/test/test_mechanize_cookie_jar.rb +483 -0
  110. data/test/test_mechanize_download.rb +43 -0
  111. data/test/test_mechanize_file.rb +61 -0
  112. data/test/test_mechanize_file_connection.rb +21 -0
  113. data/test/test_mechanize_file_request.rb +19 -0
  114. data/test/test_mechanize_file_saver.rb +21 -0
  115. data/test/test_mechanize_form.rb +875 -0
  116. data/test/test_mechanize_form_check_box.rb +38 -0
  117. data/test/test_mechanize_form_encoding.rb +114 -0
  118. data/test/test_mechanize_form_field.rb +63 -0
  119. data/test/test_mechanize_form_file_upload.rb +20 -0
  120. data/test/test_mechanize_form_image_button.rb +12 -0
  121. data/test/test_mechanize_form_keygen.rb +32 -0
  122. data/test/test_mechanize_form_multi_select_list.rb +84 -0
  123. data/test/test_mechanize_form_option.rb +55 -0
  124. data/test/test_mechanize_form_radio_button.rb +78 -0
  125. data/test/test_mechanize_form_select_list.rb +76 -0
  126. data/test/test_mechanize_form_textarea.rb +52 -0
  127. data/test/test_mechanize_headers.rb +35 -0
  128. data/test/test_mechanize_history.rb +103 -0
  129. data/test/test_mechanize_http_agent.rb +1225 -0
  130. data/test/test_mechanize_http_auth_challenge.rb +39 -0
  131. data/test/test_mechanize_http_auth_realm.rb +49 -0
  132. data/test/test_mechanize_http_content_disposition_parser.rb +118 -0
  133. data/test/test_mechanize_http_www_authenticate_parser.rb +146 -0
  134. data/test/test_mechanize_link.rb +80 -0
  135. data/test/test_mechanize_page.rb +118 -0
  136. data/test/test_mechanize_page_encoding.rb +182 -0
  137. data/test/test_mechanize_page_frame.rb +16 -0
  138. data/test/test_mechanize_page_link.rb +390 -0
  139. data/test/test_mechanize_page_meta_refresh.rb +127 -0
  140. data/test/test_mechanize_parser.rb +289 -0
  141. data/test/test_mechanize_pluggable_parser.rb +52 -0
  142. data/test/test_mechanize_redirect_limit_reached_error.rb +24 -0
  143. data/test/test_mechanize_redirect_not_get_or_head_error.rb +14 -0
  144. data/test/test_mechanize_subclass.rb +22 -0
  145. data/test/test_mechanize_util.rb +103 -0
  146. data/test/test_multi_select.rb +119 -0
  147. metadata +148 -71
@@ -0,0 +1,39 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeHttpAuthChallenge < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ @uri = URI 'http://example/'
9
+ @AR = Mechanize::HTTP::AuthRealm
10
+ @AC = Mechanize::HTTP::AuthChallenge
11
+ @challenge = @AC.new 'Digest', 'realm' => 'r'
12
+ end
13
+
14
+ def test_realm_basic
15
+ @challenge.scheme = 'Basic'
16
+
17
+ expected = @AR.new 'Basic', @uri, 'r'
18
+
19
+ assert_equal expected, @challenge.realm(@uri + '/foo')
20
+ end
21
+
22
+ def test_realm_digest
23
+ expected = @AR.new 'Digest', @uri, 'r'
24
+
25
+ assert_equal expected, @challenge.realm(@uri + '/foo')
26
+ end
27
+
28
+ def test_realm_unknown
29
+ @challenge.scheme = 'Unknown'
30
+
31
+ e = assert_raises Mechanize::Error do
32
+ @challenge.realm(@uri + '/foo')
33
+ end
34
+
35
+ assert_equal 'unknown HTTP authentication scheme Unknown', e.message
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,49 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeHttpAuthRealm < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ @uri = URI 'http://example/'
9
+ @AR = Mechanize::HTTP::AuthRealm
10
+ @realm = @AR.new 'Digest', @uri, 'r'
11
+ end
12
+
13
+ def test_initialize
14
+ assert_equal 'r', @realm.realm
15
+
16
+ realm = @AR.new 'Digest', @uri, 'R'
17
+ assert_equal 'r', realm.realm
18
+
19
+ realm = @AR.new 'Digest', @uri, nil
20
+ assert_nil realm.realm
21
+ end
22
+
23
+ def test_equals2
24
+ other = @realm.dup
25
+ assert_equal @realm, other
26
+
27
+ other = @AR.new 'Basic', @uri, 'r'
28
+ refute_equal @realm, other
29
+
30
+ other = @AR.new 'Digest', URI('http://other.example/'), 'r'
31
+ refute_equal @realm, other
32
+
33
+ other = @AR.new 'Digest', @uri, 's'
34
+ refute_equal @realm, other
35
+ end
36
+
37
+ def test_hash
38
+ h = {}
39
+ h[@realm] = 1
40
+
41
+ other = @realm.dup
42
+ assert_equal 1, h[other]
43
+
44
+ other = @AR.new 'Basic', @uri, 'r'
45
+ assert_nil h[other]
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,118 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeHttpContentDispositionParser < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ @parser = Mechanize::HTTP::ContentDispositionParser.new
9
+ end
10
+
11
+ def test_parse
12
+ now = Time.at Time.now.to_i
13
+
14
+ content_disposition = @parser.parse \
15
+ 'attachment;' \
16
+ 'filename=value;' \
17
+ "creation-date=\"#{now.rfc822}\";" \
18
+ "modification-date=\"#{(now + 1).rfc822}\";" \
19
+ "read-date=\"#{(now + 2).rfc822}\";" \
20
+ 'size=5;' \
21
+ 'arbitrary=value'
22
+
23
+ assert_equal 'attachment', content_disposition.type
24
+ assert_equal 'value', content_disposition.filename
25
+ assert_equal now, content_disposition.creation_date
26
+ assert_equal((now + 1), content_disposition.modification_date)
27
+ assert_equal((now + 2), content_disposition.read_date)
28
+ assert_equal 5, content_disposition.size
29
+ expected = { 'arbitrary' => 'value' }
30
+ assert_equal expected, content_disposition.parameters
31
+ end
32
+
33
+ def test_parse_header
34
+ content_disposition = @parser.parse \
35
+ 'content-disposition: attachment;filename=value', true
36
+
37
+ assert_equal 'attachment', content_disposition.type
38
+ assert_equal 'value', content_disposition.filename
39
+ end
40
+
41
+ def test_parse_no_type
42
+ content_disposition = @parser.parse 'filename=value'
43
+
44
+ assert_nil content_disposition.type
45
+ assert_equal 'value', content_disposition.filename
46
+ end
47
+
48
+ def test_parse_semicolons
49
+ content_disposition = @parser.parse 'attachment;;filename=value'
50
+
51
+ assert_equal 'attachment', content_disposition.type
52
+ assert_equal 'value', content_disposition.filename
53
+ end
54
+
55
+ def test_rfc_2045_quoted_string
56
+ @parser.scanner = StringScanner.new '"text"'
57
+
58
+ string = @parser.rfc_2045_quoted_string
59
+
60
+ assert_equal 'text', string
61
+ end
62
+
63
+ def test_rfc_2045_quoted_string_bad
64
+ @parser.scanner = StringScanner.new '"text'
65
+
66
+ assert_nil @parser.rfc_2045_quoted_string
67
+ end
68
+
69
+ def test_rfc_2045_quoted_string_crlf
70
+ @parser.scanner = StringScanner.new "\"multiline\\\r\n\ttext\""
71
+
72
+ string = @parser.rfc_2045_quoted_string
73
+
74
+ assert_equal "multiline\r\n\ttext", string
75
+ end
76
+
77
+ def test_rfc_2045_quoted_string_escape
78
+ @parser.scanner = StringScanner.new "\"escape\\ text\""
79
+
80
+ string = @parser.rfc_2045_quoted_string
81
+
82
+ assert_equal 'escape text', string
83
+ end
84
+
85
+ def test_rfc_2045_quoted_string_escape_bad
86
+ @parser.scanner = StringScanner.new '"escape\\'
87
+
88
+ string = @parser.rfc_2045_quoted_string
89
+
90
+ assert_nil string
91
+ end
92
+
93
+ def test_rfc_2045_quoted_string_folded
94
+ @parser.scanner = StringScanner.new "\"multiline\r\n\ttext\""
95
+
96
+ string = @parser.rfc_2045_quoted_string
97
+
98
+ assert_equal 'multiline text', string
99
+ end
100
+
101
+ def test_rfc_2045_quoted_string_quote
102
+ @parser.scanner = StringScanner.new '"escaped \\" here"'
103
+
104
+ string = @parser.rfc_2045_quoted_string
105
+
106
+ assert_equal 'escaped " here', string
107
+ end
108
+
109
+ def test_rfc_2045_quoted_string_quote_end
110
+ @parser.scanner = StringScanner.new '"end \\""'
111
+
112
+ string = @parser.rfc_2045_quoted_string
113
+
114
+ assert_equal 'end "', string
115
+ end
116
+
117
+ end
118
+
@@ -0,0 +1,146 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeHttpWwwAuthenticateParser < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ @parser = Mechanize::HTTP::WWWAuthenticateParser.new
9
+ end
10
+
11
+ def test_auth_param
12
+ @parser.scanner = StringScanner.new 'realm=here'
13
+
14
+ param = @parser.auth_param
15
+
16
+ assert_equal %w[realm here], param
17
+ end
18
+
19
+ def test_auth_param_bad_no_value
20
+ @parser.scanner = StringScanner.new 'realm='
21
+
22
+ assert_nil @parser.auth_param
23
+ end
24
+
25
+ def test_auth_param_bad_token
26
+ @parser.scanner = StringScanner.new 'realm'
27
+
28
+ assert_nil @parser.auth_param
29
+ end
30
+
31
+ def test_auth_param_bad_value
32
+ @parser.scanner = StringScanner.new 'realm="this '
33
+
34
+ assert_nil @parser.auth_param
35
+ end
36
+
37
+ def test_auth_param_quoted
38
+ @parser.scanner = StringScanner.new 'realm="this site"'
39
+
40
+ param = @parser.auth_param
41
+
42
+ assert_equal ['realm', 'this site'], param
43
+ end
44
+
45
+ def test_parse
46
+ expected = [
47
+ challenge('Basic', { 'realm' => 'foo' }),
48
+ ]
49
+
50
+ assert_equal expected, @parser.parse('Basic realm=foo')
51
+ end
52
+
53
+ def test_parse_multiple
54
+ expected = [
55
+ challenge('Basic', { 'realm' => 'foo' }),
56
+ challenge('Digest', { 'realm' => 'foo' }),
57
+ ]
58
+
59
+ assert_equal expected, @parser.parse('Basic realm=foo, Digest realm=foo')
60
+ end
61
+
62
+ def test_parse_multiple_blank
63
+ expected = [
64
+ challenge('Basic', { 'realm' => 'foo' }),
65
+ challenge('Digest', { 'realm' => 'foo' }),
66
+ ]
67
+
68
+ assert_equal expected, @parser.parse('Basic realm=foo,, Digest realm=foo')
69
+ end
70
+
71
+ def test_parse_ntlm_init
72
+ expected = [
73
+ challenge('NTLM', nil),
74
+ ]
75
+
76
+ assert_equal expected, @parser.parse('NTLM')
77
+ end
78
+
79
+ def test_parse_ntlm_type_2_3
80
+ expected = [
81
+ challenge('NTLM', 'foo='),
82
+ ]
83
+
84
+ assert_equal expected, @parser.parse('NTLM foo=')
85
+ end
86
+
87
+ def test_quoted_string
88
+ @parser.scanner = StringScanner.new '"text"'
89
+
90
+ string = @parser.quoted_string
91
+
92
+ assert_equal 'text', string
93
+ end
94
+
95
+ def test_quoted_string_bad
96
+ @parser.scanner = StringScanner.new '"text'
97
+
98
+ assert_nil @parser.quoted_string
99
+ end
100
+
101
+ def test_quoted_string_quote
102
+ @parser.scanner = StringScanner.new '"escaped \\" here"'
103
+
104
+ string = @parser.quoted_string
105
+
106
+ assert_equal 'escaped \\" here', string
107
+ end
108
+
109
+ def test_quoted_string_quote_end
110
+ @parser.scanner = StringScanner.new '"end \""'
111
+
112
+ string = @parser.quoted_string
113
+
114
+ assert_equal 'end \"', string
115
+ end
116
+
117
+ def test_token
118
+ @parser.scanner = StringScanner.new 'text'
119
+
120
+ string = @parser.token
121
+
122
+ assert_equal 'text', string
123
+ end
124
+
125
+ def test_token_space
126
+ @parser.scanner = StringScanner.new 't ext'
127
+
128
+ string = @parser.token
129
+
130
+ assert_equal 't', string
131
+ end
132
+
133
+ def test_token_special
134
+ @parser.scanner = StringScanner.new "t\text"
135
+
136
+ string = @parser.token
137
+
138
+ assert_equal 't', string
139
+ end
140
+
141
+ def challenge scheme, params
142
+ Mechanize::HTTP::AuthChallenge.new scheme, params
143
+ end
144
+
145
+ end
146
+
@@ -0,0 +1,80 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeLink < Mechanize::TestCase
4
+
5
+ def test_click
6
+ page = @mech.get("http://localhost/frame_test.html")
7
+ link = page.link_with(:text => "Form Test")
8
+
9
+ assert_equal('Form Test', link.text)
10
+ page = link.click
11
+ assert_equal("http://localhost/form_test.html",
12
+ @mech.history.last.uri.to_s)
13
+ end
14
+
15
+ def test_click_base
16
+ page = @mech.get("http://google.com/tc_base_link.html")
17
+ page = page.links.first.click
18
+ assert @mech.visited?("http://localhost/index.html")
19
+ end
20
+
21
+ def test_click_unsupported_scheme
22
+ page = @mech.get("http://google.com/tc_links.html")
23
+ link = page.link_with(:text => 'javascript link')
24
+ assert_raises Mechanize::UnsupportedSchemeError do
25
+ link.click
26
+ end
27
+
28
+ @mech.scheme_handlers['javascript'] = lambda { |my_link, my_page|
29
+ URI.parse('http://localhost/tc_links.html')
30
+ }
31
+
32
+ link.click
33
+
34
+ # HACK no assertion
35
+ end
36
+
37
+ def test_text_alt_text
38
+ page = @mech.get("http://localhost/alt_text.html")
39
+ assert_equal(5, page.links.length)
40
+ assert_equal(1, page.meta_refresh.length)
41
+
42
+ assert_equal '', page.meta_refresh.first.text
43
+ assert_equal 'alt text', page.link_with(:href => 'alt_text.html').text
44
+ assert_equal '', page.link_with(:href => 'no_alt_text.html').text
45
+ assert_equal 'no image', page.link_with(:href => 'no_image.html').text
46
+ assert_equal '', page.link_with(:href => 'no_text.html').text
47
+ assert_equal '', page.link_with(:href => 'nil_alt_text.html').text
48
+ end
49
+
50
+ def test_uri_escaped
51
+ doc = Nokogiri::HTML::Document.new
52
+
53
+ node = Nokogiri::XML::Node.new('foo', doc)
54
+ node['href'] = 'http://foo.bar/%20baz'
55
+
56
+ link = Mechanize::Page::Link.new(node, nil, nil)
57
+
58
+ assert_equal 'http://foo.bar/%20baz', link.uri.to_s
59
+ end
60
+
61
+ def test_uri_no_path
62
+ page = @mech.get("http://localhost/relative/tc_relative_links.html")
63
+ page = page.link_with(:text => 'just the query string').click
64
+ assert_equal('http://localhost/relative/tc_relative_links.html?a=b',
65
+ page.uri.to_s)
66
+ end
67
+
68
+ def test_uri_weird
69
+ doc = Nokogiri::HTML::Document.new
70
+
71
+ node = Nokogiri::XML::Node.new('foo', doc)
72
+ node['href'] = 'http://foo.bar/ baz'
73
+
74
+ link = Mechanize::Page::Link.new(node, nil, nil)
75
+
76
+ assert_equal 'http://foo.bar/%20baz', link.uri.to_s
77
+ end
78
+
79
+ end
80
+
@@ -0,0 +1,118 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizePage < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ @uri = URI 'http://example/'
9
+ end
10
+
11
+ def test_initialize_bad_content_type
12
+ e = assert_raises Mechanize::ContentTypeError do
13
+ Mechanize::Page.new(URI('http://example/'),
14
+ { 'content-type' => 'text/xml' }, 'hello', '200')
15
+ end
16
+
17
+ assert_equal('text/xml', e.content_type)
18
+ end
19
+
20
+ def test_frames
21
+ page = html_page <<-BODY
22
+ <TITLE>A simple frameset document</TITLE>
23
+ <FRAMESET cols="20%, 80%">
24
+ <FRAMESET rows="100, 200">
25
+ <FRAME name="frame1" src="/google.html">
26
+ <FRAME name="frame2" src="/form_test.html">
27
+ </FRAMESET>
28
+ <FRAMESET rows="100, 200">
29
+ <FRAME name="frame3" src="/file_upload.html">
30
+ <IFRAME src="http://google.com/" name="frame4"></IFRAME>
31
+ </FRAMESET>
32
+ </FRAMESET>
33
+ BODY
34
+
35
+ assert_equal 3, page.frames.size
36
+ assert_equal "frame1", page.frames[0].name
37
+ assert_equal "/google.html", page.frames[0].src
38
+ assert_equal "Google", page.frames[0].content.title
39
+
40
+ assert_equal "frame2", page.frames[1].name
41
+ assert_equal "/form_test.html", page.frames[1].src
42
+ assert_equal "Page Title", page.frames[1].content.title
43
+
44
+ assert_equal "frame3", page.frames[2].name
45
+ assert_equal "/file_upload.html", page.frames[2].src
46
+ assert_equal "File Upload Form", page.frames[2].content.title
47
+ end
48
+
49
+ def test_iframes
50
+ page = html_page <<-BODY
51
+ <TITLE>A simple frameset document</TITLE>
52
+ <FRAME name="frame1" src="/google.html">
53
+ <IFRAME src="/file_upload.html" name="frame4">
54
+ </IFRAME>
55
+ BODY
56
+
57
+ assert_equal 1, page.iframes.size
58
+
59
+ assert_equal "frame4", page.iframes.first.name
60
+ assert_equal "/file_upload.html", page.iframes.first.src
61
+ assert_equal "File Upload Form", page.iframes.first.content.title
62
+ end
63
+
64
+ def test_images
65
+ page = html_page <<-BODY
66
+ <img src="a.jpg">
67
+ BODY
68
+
69
+ assert_equal page.images.first.url, "http://example/a.jpg"
70
+ end
71
+
72
+ def test_images_base
73
+ page = html_page <<-BODY
74
+ <head>
75
+ <base href="http://other.example/">
76
+ </head>
77
+ <body>
78
+ <img src="a.jpg">
79
+ </body>
80
+ BODY
81
+
82
+ assert_equal page.images.first.url, "http://other.example/a.jpg"
83
+ end
84
+
85
+ def test_links
86
+ page = html_page <<-BODY
87
+ <a href="foo.html">
88
+ BODY
89
+
90
+ assert_equal page.links.first.href, "foo.html"
91
+ end
92
+
93
+ def test_parser_no_attributes
94
+ page = html_page <<-BODY
95
+ <html>
96
+ <meta>
97
+ <head><title></title>
98
+ <body>
99
+ <a>Hello</a>
100
+ <a><img /></a>
101
+ <form>
102
+ <input />
103
+ <select>
104
+ <option />
105
+ </select>
106
+ <textarea></textarea>
107
+ </form>
108
+ <frame></frame>
109
+ </body>
110
+ </html>
111
+ BODY
112
+
113
+ # HACK weak assertion
114
+ assert_kind_of Nokogiri::HTML::Document, page.root
115
+ end
116
+
117
+ end
118
+