mechanize-2.7.5/ 0000755 0000041 0000041 00000000000 12772546476 013544 5 ustar www-data www-data mechanize-2.7.5/Rakefile 0000644 0000041 0000041 00000002117 12772546476 015212 0 ustar www-data www-data require 'rubygems'
begin
require "bundler/gem_tasks"
rescue LoadError
end
require 'rdoc/task'
require 'rake/testtask'
task :prerelease => [:clobber_rdoc, :test]
desc "Update SSL Certificate"
task('ssl_cert') do |p|
sh "openssl genrsa -des3 -out server.key 1024"
sh "openssl req -new -key server.key -out server.csr"
sh "cp server.key server.key.org"
sh "openssl rsa -in server.key.org -out server.key"
sh "openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt"
sh "cp server.key server.pem"
sh "mv server.key server.csr server.crt server.pem test/data/"
sh "rm server.key.org"
end
RDoc::Task.new do |rdoc|
rdoc.main = "README.rdoc"
rdoc.rdoc_dir = 'doc'
rdoc.rdoc_files.include( "CHANGELOG.rdoc", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.rdoc", "README.rdoc", "lib/**/*.rb")
end
desc "Run tests"
Rake::TestTask.new { |t|
t.test_files = Dir['test/**/test*.rb']
t.verbose = true
}
task publish_docs: %w[rdoc] do
sh 'rsync', '-avzO', '--delete', 'doc/', 'docs-push.seattlerb.org:/data/www/docs.seattlerb.org/mechanize/'
end
task default: :test
mechanize-2.7.5/EXAMPLES.rdoc 0000644 0000041 0000041 00000012077 12772546476 015642 0 ustar www-data www-data = Mechanize examples
Note: Several examples show methods chained to the end of do/end blocks.
do...end
is the same as curly braces ({...}
). For
example, do ... end.submit
is the same as { ...
}.submit
.
== Google
require 'rubygems'
require 'mechanize'
a = Mechanize.new { |agent|
agent.user_agent_alias = 'Mac Safari'
}
a.get('http://google.com/') do |page|
search_result = page.form_with(:id => 'gbqf') do |search|
search.q = 'Hello world'
end.submit
search_result.links.each do |link|
puts link.text
end
end
== Rubyforge
require 'rubygems'
require 'mechanize'
a = Mechanize.new
a.get('http://rubyforge.org/') do |page|
# Click the login link
login_page = a.click(page.link_with(:text => /Log In/))
# Submit the login form
my_page = login_page.form_with(:action => '/account/login.php') do |f|
f.form_loginname = ARGV[0]
f.form_pw = ARGV[1]
end.click_button
my_page.links.each do |link|
text = link.text.strip
next unless text.length > 0
puts text
end
end
== File Upload
Upload a file to flickr.
require 'rubygems'
require 'mechanize'
abort "#{$0} login passwd filename" if (ARGV.size != 3)
a = Mechanize.new { |agent|
# Flickr refreshes after login
agent.follow_meta_refresh = true
}
a.get('http://flickr.com/') do |home_page|
signin_page = a.click(home_page.link_with(:text => /Sign In/))
my_page = signin_page.form_with(:name => 'login_form') do |form|
form.login = ARGV[0]
form.passwd = ARGV[1]
end.submit
# Click the upload link
upload_page = a.click(my_page.link_with(:text => /Upload/))
# We want the basic upload page.
upload_page = a.click(upload_page.link_with(:text => /basic Uploader/))
# Upload the file
upload_page.form_with(:method => 'POST') do |upload_form|
upload_form.file_uploads.first.file_name = ARGV[2]
end.submit
end
== Pluggable Parsers
Let's say you want HTML pages to automatically be parsed with Rubyful Soup.
This example shows you how:
require 'rubygems'
require 'mechanize'
require 'rubyful_soup'
class SoupParser < Mechanize::Page
attr_reader :soup
def initialize(uri = nil, response = nil, body = nil, code = nil)
@soup = BeautifulSoup.new(body)
super(uri, response, body, code)
end
end
agent = Mechanize.new
agent.pluggable_parser.html = SoupParser
Now all HTML pages will be parsed with the SoupParser class, and automatically
give you access to a method called 'soup' where you can get access to the
Beautiful Soup for that page.
== Using a proxy
require 'rubygems'
require 'mechanize'
agent = Mechanize.new
agent.set_proxy 'localhost', 8000
page = agent.get(ARGV[0])
puts page.body
== The transact method
Mechanize#transact runs the given block and then resets the page history. I.e.
after the block has been executed, you're back at the original page; no need
to count how many times to call the back method at the end of a loop (while
accounting for possible exceptions).
This example also demonstrates subclassing Mechanize.
require 'rubygems'
require 'mechanize'
class TestMech < Mechanize
def process
get 'http://rubyforge.org/'
search_form = page.forms.first
search_form.words = 'WWW'
submit search_form
page.links_with(:href => %r{/projects/} ).each do |link|
next if link.href =~ %r{/projects/support/}
puts 'Loading %-30s %s' % [link.href, link.text]
begin
transact do
click link
# Do stuff, maybe click more links.
end
# Now we're back at the original page.
rescue => e
$stderr.puts "#{e.class}: #{e.message}"
end
end
end
end
TestMech.new.process
== Client Certificate Authentication (Mutual Auth)
In most cases a client certificate is created as an additional layer of
security for certain websites. The specific case that this was initially
tested on was for automating the download of archived images from a banks
(Wachovia) lockbox system. Once the certificate is installed into your
browser you will have to export it and split the certificate and private key
into separate files.
require 'rubygems'
require 'mechanize'
# create Mechanize instance
agent = Mechanize.new
# set the path of the certificate file
agent.cert = 'example.cer'
# set the path of the private key file
agent.key = 'example.key'
# get the login form & fill it out with the username/password
login_form = agent.get("http://example.com/login_page").form('Login')
login_form.Userid = 'TestUser'
login_form.Password = 'TestPassword'
# submit login form
agent.submit(login_form, login_form.buttons.first)
Exported files are usually in .p12 format (IE 7 & Firefox 2.0) which stands
for PKCS #12. You can convert them from p12 to pem format by using the
following commands:
openssl pkcs12 -in input_file.p12 -clcerts -out example.key -nocerts -nodes
openssl pkcs12 -in input_file.p12 -clcerts -out example.cer -nokeys
mechanize-2.7.5/Gemfile 0000644 0000041 0000041 00000000047 12772546476 015040 0 ustar www-data www-data source 'https://rubygems.org'
gemspec
mechanize-2.7.5/examples/ 0000755 0000041 0000041 00000000000 12772546476 015362 5 ustar www-data www-data mechanize-2.7.5/examples/flickr_upload.rb 0000644 0000041 0000041 00000001006 12772546476 020522 0 ustar www-data www-data require 'rubygems'
require 'mechanize'
agent = Mechanize.new
# Get the flickr sign in page
page = agent.get 'http://flickr.com/signin/flickr/'
# Fill out the login form
form = page.form_with :name => 'flickrloginform'
form.email = ARGV[0]
form.password = ARGV[1]
form.submit
# Go to the upload page
page = page.link_with(:text => 'Upload').click
# Fill out the form
form = page.forms.action('/photos_upload_process.gne').first
form.file_uploads.name('file1').first.file_name = ARGV[2]
form.submit
mechanize-2.7.5/examples/wikipedia_links_to_philosophy.rb 0000644 0000041 0000041 00000006177 12772546476 024050 0 ustar www-data www-data require 'mechanize'
require 'tsort'
##
# This example implements the alt-text of http://xkcd.com/903/ which states:
#
# Wikipedia trivia: if you take any article, click on the first link in the
# article text not in parentheses or italics, and then repeat, you will
# eventually end up at "Philosophy".
class WikipediaLinksToPhilosophy
def initialize
@agent = Mechanize.new
@agent.user_agent_alias = 'Mac Safari' # Wikipedia blocks "mechanize"
@history = @agent.history
@wiki_url = URI 'http://en.wikipedia.org'
@search_url = @wiki_url + '/w/index.php'
@random_url = @wiki_url + '/wiki/Special:Random'
@title = nil
@seen = nil
end
##
# Retrieves the title of the current page
def extract_title
@page.title =~ /(.*) - Wikipedia/
@title = $1
end
##
# Retrieves the initial page. If +query+ is not given a random page is
# chosen
def fetch_first_page query
if query then
search query
else
random
end
end
##
# The search is finished if we've seen the page before or we've reached
# Philosophy
def finished?
@seen or @title == 'Philosophy'
end
##
# Follows the first non-parenthetical, non-italic link in the main body of
# the article.
def follow_first_link
puts @title
# > p > a rejects italics
links = @page.root.css('.mw-content-ltr > p > a[href^="/wiki/"]')
# reject disambiguation and special pages, images and files
links = links.reject do |link_node|
link_node['href'] =~ %r%/wiki/\w+:|\(disambiguation\)%
end
links = links.reject do |link_node|
in_parenthetical? link_node
end
link = links.first
unless link then
# disambiguation page? try the first item in the list
link =
@page.root.css('.mw-content-ltr > ul > li > a[href^="/wiki/"]').first
end
# convert a Nokogiri HTML element back to a mechanize link
link = Mechanize::Page::Link.new link, @agent, @page
return if @seen = @agent.visited?(link)
@page = link.click
extract_title
end
##
# Is +link_node+ in an open parenthetical section?
def in_parenthetical? link_node
siblings = link_node.parent.children
seen = false
before = siblings.reject do |node|
seen or (seen = node == link_node)
end
preceding_text = before.map { |node| node.text }.join
open = preceding_text.count '('
close = preceding_text.count ')'
open > close
end
##
# Prints the result of the search
def print_result
if @seen then
puts "[Loop detected]"
else
puts @title
end
puts
# subtract initial search or Special:Random
puts "After #{@agent.history.length - 1} pages"
end
##
# Retrieves a random page from wikipedia
def random
@page = @agent.get @random_url
extract_title
end
##
# Entry point
def run query = nil
fetch_first_page query
follow_first_link until finished?
print_result
end
##
# Searches for +query+ on wikipedia
def search query
@page = @agent.get @search_url, search: query
extract_title
end
end
WikipediaLinksToPhilosophy.new.run ARGV.shift if $0 == __FILE__
mechanize-2.7.5/examples/spider.rb 0000644 0000041 0000041 00000000725 12772546476 017201 0 ustar www-data www-data require 'rubygems'
require 'mechanize'
agent = Mechanize.new
agent.max_history = nil # unlimited history
stack = agent.get(ARGV[0]).links
while l = stack.pop
next unless l.uri
host = l.uri.host
next unless host.nil? or host == agent.history.first.uri.host
next if agent.visited? l.href
puts "crawling #{l.uri}"
begin
page = l.click
next unless Mechanize::Page === page
stack.push(*page.links)
rescue Mechanize::ResponseCodeError
end
end
mechanize-2.7.5/examples/proxy_req.rb 0000644 0000041 0000041 00000000214 12772546476 017734 0 ustar www-data www-data require 'rubygems'
require 'mechanize'
agent = Mechanize.new
agent.set_proxy('localhost', '8000')
page = agent.get(ARGV[0])
puts page.body
mechanize-2.7.5/examples/mech-dump.rb 0000644 0000041 0000041 00000000136 12772546476 017566 0 ustar www-data www-data require 'rubygems'
require 'mechanize'
agent = Mechanize.new
puts agent.get(ARGV[0]).inspect
mechanize-2.7.5/examples/rubygems.rb 0000644 0000041 0000041 00000001233 12772546476 017543 0 ustar www-data www-data # This example logs a user in to rubyforge and prints out the body of the
# page after logging the user in.
require 'rubygems'
require 'mechanize'
require 'logger'
# Create a new mechanize object
mech = Mechanize.new
mech.log = Logger.new $stderr
mech.agent.http.debug_output = $stderr
# Load the rubyforge website
page = mech.get('https://rubygems.org/')
page = mech.click page.link_with(:text => /Sign in/) # Click the login link
form = page.forms[1] # Select the first form
form["session[who]"] = ARGV[0]
form["session[password]"] = ARGV[1]
form["commit"] = "Sign in"
# Submit the form
page = form.submit form.buttons.first
puts page.body # Print out the body
mechanize-2.7.5/.autotest 0000644 0000041 0000041 00000000151 12772546476 015412 0 ustar www-data www-data require 'autotest/restart'
Autotest.add_hook :initialize do |at|
at.testlib = 'minitest/autorun'
end
mechanize-2.7.5/CHANGELOG.rdoc 0000644 0000041 0000041 00000122372 12772546476 015713 0 ustar www-data www-data = Mechanize CHANGELOG
=== 2.7.5
* New Features
* All 4xx responses and RedirectLimitReachedError when fetching robots.txt are treated as full allow just like Googlebot does.
* Enable support for mime-types > 3.
* Bug fix
* Don't cause infinite loop when `GET /robots.txt` redirects. (#457)
* Fix basic authentication for a realm that contains uppercase characters. (#458, #459)
* Fix encoding error when uploading a file which name is non-ASCII. (#333)
=== 2.7.4
* New Features
* Accept array-like and hash-like values as query/parameter value.
A new utility method Mechanize::Util.each_parameter is added, and Mechanize::Util.build_query_string is enhanced
for this feature.
* Allow passing a `Form::FileUpload` instance to `#post`. #350 by Sam
Rawlins.
* Capture link when scheme is unsupported. #362 by Jon Rowe.
* Pre-defined User-Agent stings are updated to those of more recent versions, and new aliases for IE 10/11 and Edge are added.
* Support for mime-types 1.x is restored while keeping compatible with mime-types 2.x.
* Mechanize::Page now responds to #xpath, #css, #at_xpath, #at_css, and #%.
* element(s)_with methods now accept :xpath and :css options for doing xpath/css
selector searching.
* Pass URI information to Nokogiri where applicable. #405 @lulalala
* Bug fix
* Don't raise an exception if a connection has set a {read,open}_timeout and
a `file://` request is made. (#397)
* Fix whitespace bug in WWW-Authenticate. #451, #450, by Rasmus Bergholdt
* Don't allow redirect from a non-file URL to a file URL for security reasons. (#455)
=== 2.7.3
* New Features
* Allow net-http-persistent instance to be named. #324, John Weir.
* #save and #save! return filename #340
* Updated mime-types requirement to 2.x versions. #348 by Jeff Nyman.
* Bug fix
* Ensure Download#save! defaults back to original filename if
none is provided (#300)
=== 2.7.2
* Bug fix
* API compatibility issues with Mechanize::CookieJar cookies has been
addressed. https://github.com/sparklemotion/http-cookie/issues/2 #326
=== 2.7.1
* Bug fix
* Ensure images with no "src" attribute still return correct URLs. #317
* Fixes Mechanize::Parser#extract_filename where an empty string filename
in the response caused unhandled exception. #318
=== 2.7.0
* New Features
* Mechanize::Agent#response_read will now raise a
Mechanize::ResponseReadError instead of an EOFError and avoid losing
requested content. #296.
* Depend on http-cookie, add backwards compatible deprecations.
#257 Akinori MUSHA.
* Added `Download#save!` for overwriting existing files. #300 Sean Kim.
* Bug fix
* Ensure page URLs with whitespace in them are escaped #313 @pacop.
* Added a workaround for a bug of URI#+ that led to failure in resolving a relative path containing double slash like "/../http://.../". #304
=== 2.6.0
* New Features
* Mechanize#start and Mechanize#shutdown (Thanks, Damian Janowski!)
* Added Mechanize::Agent#allowed_error_codes for setting an Array
of status codes which should not raise an error. #248 Laurence Rowe.
* Added `File.save!` for overwriting existing files #219.
* DirectorySaver::save_to now accepts an option to decode filename. #262
* element(s)_with methods now accept a :search option for doing xpath/css
selector searching. #287 Philippe Bourgau
* Added httponly option for Mechanize::Cookie #242 by Paolo Perego.
* Added Mechanize::XmlFile as a default pluggable parser for handling
XML responses. #289
* Minor enhancements
* Added Mechanize::Download#save_as as an alias to #save. #246
* Fix documentation for `Mechanize::Page` element matchers. #269
* Added Mechanize::Form::Field#raw_value for fetching a fields value
before it's sent through Mechanize::Util.html_unescape. #283
* Added iPad and Android user agents. #277 by sambit, #278 by seansay.
* Bug fix
* Mechanize#cert and Mechanize#key now return the values set by
#cert= and #key=. #244, #245 (Thanks, Robert Gogolok!)
* Mechanize no longer submits disabled form fields. #276 by Bogdan Gusiev,
#279 by Ricardo Valeriano.
* Mechanize::File#save now behaves like Mechanize::Download#save in
that it will create the parent directory before saving.
#272, #280 by Ryan Kowalick
* Ensure `application/xml` is registered as an XML parser in
`PluggableParser`, not just `text/xml`. #266 James Gregory
* Mechanize now writes cookiestxt with a prefixed dot for wildcard domain
handling. #295 by Mike Morearty.
=== 2.5.2
* New Features
* Mechanize::CookieJar#save_as takes a keyword option "session" to say
that session cookies should be saved. Based on #230 by Jim Jones.
* Minor enhancements
* Added Mechanize#follow_redirect= as an alias to redirect_ok=.
* Bug fix
* Fixed casing of the Mac Firefox user-agent alias to match Linux Firefox.
In mechanize 3 the old "Mac FireFox" user-agent alias will be removed.
Pull request #231 by Gavin Miller.
* Mechanize now authenticates using the raw challenge, not a reconstructed
one, to avoid dealing with quoting rules of RFC 2617. Fixes failures in
#231 due to net-http-digest_auth 1.2.1
* Fixed Content-Disposition parameter parser to be case insensitive. #233
* Fixed redirection counting in following meta refresh. #240
=== 2.5.1
* Bug fix
* Mechanize no longer copies POST requests during a redirect which was
introduced by #215. Pull request #229 by Godfrey Chan.
=== 2.5
* Minor enhancements
* Added Mechanize#ignore_bad_chunking for working around servers that don't
terminate chunked transfer-encoding properly. Enabling this may cause
data loss. Issue #116
* Removed content-type check from Mechanize::Page allowing forced parsing
of incorrect or missing content-types. Issue #221 by GarthSnyder
* Bug fixes
* Fixed typos in EXAMPLES and GUIDES. Pull Request #213 by Erkan Yilmaz.
* Fixed handling of a quoted content-disposition size. Pull Request #220 by
Jason Rust
* Mechanize now ignores a missing gzip footer like browsers do. Issue #224
by afhbl
* Mechanize handles saving of files with the same name better now. Pull
Request #223 by Godfrey Chan, Issue #219 by Jon Hart
* Mechanize now sends headers across redirects. Issue #215 by Chris Gahan
* Mechanize now raises Mechanize::ResponseReadError when the server does not
terminate chunked transfer-encoding properly. Issue #116
* Mechanize no longer raises an exception when multiple identical
radiobuttons are checked. Issue #214 by Matthias Guenther
* Fixed documentation for pre_connect_hooks and post_connect_hooks. Issue
#226 by Robert Poor
* Worked around ruby 1.8 run with -Ku and ISO-8859-1 encoded characters in
URIs. Issue #228 by Stanislav O.Pogrebnyak
=== 2.4
* Security fix:
Mechanize#auth and Mechanize#basic_auth allowed disclosure of passwords to
malicious servers and have been deprecated.
In prior versions of mechanize only one set of HTTP authentication
credentials were allowed for all connections. If a mechanize instance
connected to more than one server then a malicious server detecting
mechanize could ask for HTTP Basic authentication. This would expose the
username and password intended only for one server.
Mechanize#auth and Mechanize#basic_auth now warn when used.
To fix the warning switch to Mechanize#add_auth which requires the URI
the credentials are intended for, the username and the password.
Optionally an HTTP authentication realm or NTLM domain may be provided.
* Minor enhancement
* Improved exception messages for 401 Unauthorized responses. Mechanize now
tells you if you were missing credentials, had an incorrect password, etc.
=== 2.3 / 2012-02-20
* Minor enhancements
* Add support for the Max-Age attribute in the Set-Cookie header.
* Added Mechanize::Download#body for compatibility with Mechanize::File when
using Mechanize#get_file with Mechanize::Image or other Download-based
pluggable parser. Issue #202 by angas
* Mechanize#max_file_buffer may be set to nil to disable creation of
Tempfiles.
* Bug fixes
* Applied Mechanize#max_file_buffer to the Content-Encoding handlers as well
to prevent extra Tempfiles for small gzip or deflate response
* Increased the default Mechanize#max_file_buffer to 100,000 bytes. This
gives ~5MB of response bodies in memory with the default history setting
of 50 pages (depending on GC behavior).
* Ignore empty path/domain attributes.
* Cookies with an empty Expires attribute value were stored as session
cookies but cookies without the Expires attribute were not. Issue #78
=== 2.2.1 / 2012-02-13
* Bug fixes
* Add missing file to the gem, ensure that missing files won't cause
failures again. Issue #201 by Alex
* Fix minor grammar issue in README. Issue #200 by Shane Becker.
=== 2.2 / 2012-02-12
* API changes
* MetaRefresh#href is not normalized to an absolute URL, but set to the
original value and resolved later. It is even set to nil when the
Refresh URL is unspecified or empty.
* Minor enhancements
* Expose ssl_version from net-http-persistent. Patch by astera.
* SSL parameters and proxy may now be set at any time. Issue #194 by
dsisnero.
* Improved Mechanize::Page with #image_with and #images_with and
Mechanize::Page::Image various img element attribute accessors, #caption,
#extname, #mime_type and #fetch. Pull request #173 by kitamomonga
* Added MIME type parsing for content-types in Mechanize::PluggableParser
for fine-grained parser choices. Parsers will be chosen based on exact
match, simplified type or media type in that order. See
Mechanize::PluggableParser#[]=.
* Added Mechanize#download which downloads a response body to an IO-like or
filename.
* Added Mechanize::DirectorySaver which saves responses in a single
directory. Issue #187 by yoshie902a.
* Added Mechanize::Page::Link#noreferrer?
* The documentation for Mechanize::Page#search and #at now show that both
XPath and CSS expressions are allowed. Issue #199 by Shane Becker.
* Bug fixes
* Fixed handling of a HEAD request with Accept-Encoding: gzip. Issue #198
by Oleg Dashevskii
* Use #resolve for resolving a Location header value. fixes #197
* A Refresh value can have whitespaces around the semicolon and equal sign.
* MetaRefresh#click no longer sends out Referer.
* A link with an empty href is now resolved correctly where previously the
query part was dropped.
=== 2.1.1 / 2012-02-03
* Bug fixes
* Set missing idle_timeout default. Issue #196
* Meta refresh URIs are now escaped (excluding %). Issue #177
* Fix charset name extraction. Issue #180
* A Referer URI sent on request no longer includes user information
or fragment part.
* Tempfiles for storing response bodies are unlinked upon creation to avoid
possible lack of finalization. Issue #183
* The default maximum history size is now 50 pages to avoid filling up a
disk with tempfiles accidentally. Related to Issue #183
* Errors in bodies with deflate and gzip responses now result in a
Mechanize::Error instead of silently being ignored and causing future
errors. Issue #185
* Mechanize now raises an UnauthorizedError instead of crashing when a 403
response does not contain a www-authenticate header. Issue #181
* Mechanize gives a useful exception when attempting to click buttons across
pages. Issue #186
* Added note to Mechanize#cert_store describing how to add certificates in
case your system does not come with a default set. Issue #179
* Invalid content-disposition headers are now ignored. Issue #191
* Fix NTLM by recognizing the "Negotiation" challenge instead of endlessly
looping. Issue #192
* Allow specification of the NTLM domain through Mechanize#auth. Issue #193
* Documented how to convert a Mechanize::ResponseReadError into a File or
Page, along with a new method #force_parse. Issue #176
=== 2.1 / 2011-12-20
* Deprecations
* Mechanize#get no longer accepts an options hash.
* Mechanize::Util::to_native_charset has been removed.
* Minor enhancements
* Mechanize now depends on net-http-persistent 2.3+. This new version
brings idle timeouts to help with the dreaded "too many connection resets"
issue when POSTing to a closed connection. Issue #123
* SSL connections will be verified against the system certificate store by
default.
* Added Mechanize#retry_change_requests to allow mechanize to retry POST and
other non-idempotent requests when you know it is safe to do so. Issue
#123
* Mechanize can now stream files directly to disk without loading them into
memory first through Mechanize::Download, a pluggable parser for
downloading files.
All responses larger than Mechanize#max_file_buffer are downloaded to a
Tempfile. For backwards compatibility Mechanize::File subclasses still
load the response body into memory.
To force all unknown content types to download to disk instead of memory
set:
agent.pluggable_parser.default = Mechanize::Download
* Added Mechanize#content_encoding_hooks which allow handling of
non-standard content encodings like "agzip". Patch #125 by kitamomonga
* Added dom_class to elements and the element matcher like dom_id. Patch
#156 by Dan Hansen.
* Added support for the HTML5 keygen form element. See
http://dev.w3.org/html5/spec/Overview.html#the-keygen-element Patch #157
by Victor Costan.
* Mechanize no longer follows meta refreshes that have no "url=" in the
content attribute to avoid infinite loops. To follow a meta refresh to
the same page set Mechanize#follow_meta_refresh_self to true. Issue #134
by Jo Hund.
* Updated 'Mac Safari' User-Agent alias to Safari 5.1.1. 'Mac Safari 4' can
be used for the old 'Mac Safari' alias.
* When given multiple HTTP authentication options mechanize now picks the
strongest method.
* Improvements to HTTP authorization:
* mechanize raises Mechanize::UnathorizedError for 401 responses which is
a sublcass of Mechanize::ResponseCodeError.
* Added support for NTLM authentication, but this has not been tested.
* Mechanize::Cookie.new accepts attributes in a hash.
* Mechanize::CookieJar#<<(cookie) (alias: add!) is added. Issue #139
* Different mechanize instances may now have different loggers. Issue #122
* Mechanize now accepts a proxy port as a service name or number string.
Issue #167
* Bug fixes
* Mechanize now handles cookies just as most modern browsers do,
roughly based on RFC 6265.
* domain=.example.com (which is invalid) is considered identical to
domain=example.com.
* A cookie with domain=example.com is sent to host.sub.example.com
as well as host.example.com and example.com.
* A cookie with domain=TLD (no dots) is accepted and sent if the
host name is TLD, and rejected otherwise. To retain compatibility
and convention, host/domain names starting with "local" are exempt
from this rule.
* A cookie with no domain attribute is only sent to the original
host.
* A cookie with an Effective TLD is rejected based on the public
suffix list. (cf. http://publicsuffix.org/)
* "Secure" cookies are not sent via non-https connection.
* Subdomain match is not performed against an IP address.
* It is recommended that you clear out existing cookie jars for
regeneration because previously saved cookies may not have been
parsed correctly.
* Mechanize takes more care to avoid saving files with certain unsafe names.
You should still take care not to use mechanize to save files directly
into your home directory ($HOME). Issue #163.
* Mechanize#cookie_jar= works again. Issue #126
* The original Referer value persists on redirection. Issue #150
* Do not send a referer on a Refresh header based redirection.
* Fixed encoding error in tests when LANG=C. Patch #142 by jinschoi.
* The order of items in a form submission now match the DOM order. Patch
#129 by kitamomonga
* Fixed proxy example in EXAMPLE. Issue #146 by NielsKSchjoedt
=== 2.0.1 / 2011-06-28
Mechanize now uses minitest to avoid 1.9 vs 1.8 assertion availability in
test/unit
* Bug Fixes
* Restored Mechanize#set_proxy. Issue #117, #118, #119
* Mechanize::CookieJar#load now lazy-loads YAML. Issue #118
* Mechanize#keep_alive_time no longer crashes but does nothing as
net-http-persistent does not support HTTP/1.0 keep-alive extensions.
=== 2.0 / 2011-06-27
Mechanize is now under the MIT license
* API changes
* WWW::Mechanize has been removed. Use Mechanize.
* Pre connect hooks are now called with the agent and the request. See
Mechanize#pre_connect_hooks.
* Post connect hooks are now called with the agent and the response. See
Mechanize#post_connect_hooks.
* Mechanize::Chain is gone, as an internal API this should cause no problems.
* Mechanize#fetch_page no longer accepts an options Hash.
* Mechanize#put now accepts headers instead of an options Hash as the last
argument
* Mechanize#delete now accepts headers instead of an options Hash as the
last argument
* Mechanize#request_with_entity now accepts headers instead of an options
Hash as the last argument
* Mechanize no longer raises RuntimeError directly, Mechanize::Error or
ArgumentError are raised instead.
* The User-Agent header has changed. It no longer includes the WWW- prefix
and now includes the ruby version. The URL has been updated as well.
* Mechanize now requires ruby 1.8.7 or newer.
* Hpricot support has been removed as webrobots requires nokogiri.
* Mechanize#get no longer accepts the referer as the second argument.
* Mechanize#get no longer allows the HTTP method to be changed (:verb
option).
* Mechanize::Page::Meta is now Mechanize::Page::MetaRefresh to accurately
depict its responsibilities.
* Mechanize::Page#meta is now Mechanize::Page#meta_refresh as it only
contains meta elements with http-equiv of "refresh"
* Mechanize::Page#charset is now Mechanize::Page::charset. GH #112, patch
by Godfrey Chan.
* Deprecations
* Mechanize#get with an options hash is deprecated and will be removed after
October, 2011.
* Mechanize::Util::to_native_charset is deprecated as it is no longer used
by Mechanize.
* New Features
* Add header reference methods to Mechanize::File so that a reponse
object gets compatible with Net::HTTPResponse.
* Mechanize#click accepts a regexp or string to click a button/link in the
current page. It works as expected when not passed a string or regexp.
* Provide a way to only follow permanent redirects (301)
automatically: agent.redirect_ok = :permanent GH #73
* Mechanize now supports HTML5 meta charset. GH #113
* Documented various Mechanize accessors. GH #66
* Mechanize now uses net-http-digest_auth. GH #31
* Mechanize now implements session cookies. GH #78
* Mechanize now implements deflate decoding. GH #40
* Mechanize now allows a certificate and key to be passed directly. GH #71
* Mechanize::Form::MultiSelectList now implements #option_with and
#options_with. GH #42
* Add Mechanize::Page::Link#rel and #rel?(kind) to read and test the rel
attribute.
* Add Mechanize::Page#canonical_uri to read a tag.
* Add support for Robots Exclusion Protocol (i.e. robots.txt) and
nofollow/noindex in meta tags and the rel attribute. Automatic
exclusion can be turned on by setting:
agent.robots = true
* Manual robots.txt test can be performed with
Mechanize#robots_allowed? and #robots_disallowed?.
* Mechanize::Form now supports the accept-charset attribute. GH #96
* Mechanize::ResponseReadError is raised if there is an exception while
reading the response body. This allows recovery from broken HTTP servers
(or connections). GH #90
* Mechanize#follow_meta_refresh set to :anywhere will follow meta refresh
found outside of a document's head. GH #99
* Add support for HTML5's rel="noreferrer" attribute which indicates
no "Referer" information should be sent when following the link.
* A frame will now load its content when #content is called. GH #111
* Added Mechanize#default_encoding to provide a default for pages with no
encoding specified. GH #104
* Added Mechanize#force_default_encoding which only uses
Mechanize#default_encoding for parsing HTML. GH #104
* Bug Fixes:
* Fixed a bug where Referer is not sent when accessing a relative
URI starting with "http".
* Fix handling of Meta Refresh with relative paths. GH #39
* Mechanize::CookieJar now supports RFC 2109 correctly. GH #85
* Fixed typo in EXAMPLES.rdoc. GH #74
* The base element is now handled correctly for images. GH #72
* Image buttons with no name attribute are now included in the form's button
list. GH#56
* Improved handling of non ASCII-7bit compatible characters in links (only
an issue on ruby 1.8). GH #36, GH #75
* Loading cookies.txt is faster. GH #38
* Mechanize no longer sends cookies for a.b.example to axb.example. GH #41
* Mechanize no longer sends the button name as a form field for image
buttons. GH #45
* Blank cookie values are now skipped. GH #80
* Mechanize now adds a '.' to cookie domains if no '.' was sent. This is
not allowed by RFC 2109 but does appear in RFC 2965. GH #86
* file URIs are now read in binary mode. GH #83
* Content-Encoding: x-gzip is now treated like gzip per RFC 2616.
* Mechanize now unescapes URIs for meta refresh. GH #68
* Mechanize now has more robust HTML charset detection. GH #43
* Mechanize::Form::Textarea is now created from a textarea element. GH #94
* A meta content-type now overrides the HTTP content type. GH #114
* Mechanize::Page::Link#uri now handles both escaped and unescaped hrefs.
GH #107
=== 1.0.0
* New Features:
* An optional verb may be passed to Mechanize#get GH #26
* The WWW constant is deprecated. Switch to the top level constant Mechanize
* SelectList#option_with and options_with for finding options
* Bug Fixes:
* Rescue errors from bogus encodings
* 7bit content-encoding support. Thanks sporkmonger! GH #2
* Fixed a bug with iconv conversion. Thanks awesomeman! GH #9
* meta redirects outside the head are not followed. GH #13
* Form submissions work with nil page encodings. GH #25
* Fixing default values with serialized cookies. GH #3
* Checkboxes and fields are sorted by page appearance before submitting. #11
=== 0.9.3
* Bug Fixes:
* Do not apply encoding if encoding equals 'none' Thanks Akinori MUSHA!
* Fixed Page#encoding= when changing the value from or to nil. Made
it return the assigned value while at it. (Akinori MUSHA)
* Custom request headers may be supplied WWW::Mechanize#request_headers
RF #24516
* HTML Parser may be set on a per instance level WWW::Mechanize#html_parser
RF #24693
* Fixed string encoding in ruby 1.9. RF #2433
* Rescuing Zlib::DataErrors (Thanks Kelley Reynolds)
* Fixing a problem with frozen SSL objects. RF #24950
* Do not send a referer on meta refresh. RF #24945
* Fixed a bug with double semi-colons in Content-Disposition headers
* Properly handling cookies that specify a path. RF #25259
=== 0.9.2 / 2009/03/05
* New Features:
* Mechanize#submit and Form#submit take arbitrary headers(thanks penguincoder)
* Bug Fixes:
* Fixed a bug with bad cookie parsing
* Form::RadioButton#click unchecks other buttons (RF #24159)
* Fixed problems with Iconv (RF #24190, RF #24192, RF #24043)
* POST parameters should be CGI escaped
* Made Content-Type match case insensitive (Thanks Kelly Reynolds)
* Non-string form parameters work
=== 0.9.1 2009/02/23
* New Features:
* Encoding may be specified for a page: Page#encoding=
* Bug Fixes:
* m17n fixes. ありがとう konn!
* Fixed a problem with base tags. ありがとう Keisuke
* HEAD requests do not record in the history
* Default encoding to ISO-8859-1 instead of ASCII
* Requests with URI instances should not be polluted RF #23472
* Nonce count fixed for digest auth requests. Thanks Adrian Slapa!
* Fixed a referer issue with requests using a uri. RF #23472
* WAP content types will now be parsed
* Rescued poorly formatted cookies. Thanks Kelley Reynolds!
=== 0.9.0
* Deprecations
* WWW::Mechanize::List is gone!
* Mechanize uses Nokogiri as it's HTML parser but you may switch to
Hpricot by using WWW::Mechanize.html_parser = Hpricot
* Bug Fixes:
* Nil check on page when base tag is used #23021
=== 0.8.5
* Deprecations
* WWW::Mechanize::List will be deprecated in 0.9.0, and warnings have
been added to help you upgrade.
* Bug Fixes:
* Stopped raising EOF exceptions on HEAD requests. ありがとう:HIRAKU Kuroda
* Fixed exceptions when a logger is set and file:// requests are made.
* Made Mechanize 1.9 compatible
* Not setting the port in the host header for SSL sites.
* Following refresh headers. Thanks Tim Connor!
* Cookie Jar handles cookie domains containing ports, like
'mydomain.com:443' (Thanks Michal Ochman!)
* Fixing strange uri escaping problems [#22604]
* Making content-type determintation more robust. (thanks Han Holl!)
* Dealing with links that are query string only. [#22402]
* Nokogiri may be dropped in as a replacement.
WWW::Mechanize.html_parser = Nokogiri::HTML
* Making sure the correct page is added to the history on meta refresh.
[#22708]
* Mechanize#get requests no longer send a referer unless they are relative
requests.
=== 0.8.4
* Bug Fixes:
* Setting the port number on the host header.
* Fixing Authorization headers for picky servers
=== 0.8.3
* Bug Fixes:
* Making sure logger is set during SSL connections.
=== 0.8.2
* Bug Fixes:
* Doh! I was accidentally setting headers twice.
=== 0.8.1
* Bug Fixes:
* Fixed problem with nil pointer when logger is set
=== 0.8.0
* New Features:
* Lifecycle hooks. Mechanize#pre_connect_hooks, Mechanize#post_connect_hooks
* file:/// urls are now supported
* Added Mechanize::Page#link_with, frame_with for searching for links using
+criteria+.
* Implementing PUT, DELETE, and HEAD requests
* Bug Fixes:
* Fixed an infinite loop when content-length and body length don't match.
* Only setting headers once
* Adding IIS authentication support
=== 0.7.8
* Bug Fixes:
* Fixed bug when receiving a 304 response (HTTPNotModified) on a page not
cached in history.
* #21428 Default to HTML parser for 'application/xhtml+xml' content-type.
* Fixed an issue where redirects were resending posted data
=== 0.7.7
* New Features:
* Page#form_with takes a +criteria+ hash.
* Page#form is changed to Page#form_with
* Mechanize#get takes custom http headers. Thanks Mike Dalessio!
* Form#click_button submits a form defaulting to the current button.
* Form#set_fields now takes a hash. Thanks Tobi!
* Mechanize#redirection_limit= for setting the max number of redirects.
* Bug Fixes:
* Added more examples. Thanks Robert Jackson.
* #20480 Making sure the Host header is set.
* #20672 Making sure cookies with weird semicolons work.
* Fixed bug with percent signs in urls.
http://d.hatena.ne.jp/kitamomonga/20080410/ruby_mechanize_percent_url_bug
* #21132 Not checking for EOF errors on redirect
* Fixed a weird gzipping error.
* #21233 Smarter multipart boundry. Thanks Todd Willey!
* #20097 Supporting meta tag cookies.
=== 0.7.6
* New Features:
* Added support for reading Mozilla cookie jars. Thanks Chris Riddoch!
* Moving text, password, hidden, int to default. Thanks Tim Harper!
* Mechanize#history_added callback for page loads. Thanks Tobi Reif!
* Mechanize#scheme_handlers callbacks for handling unsupported schemes on
links.
* Bug Fixes:
* Ignoring scheme case
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=470642
* Not encoding tildes in uris. Thanks Bruno. [#19380]
* Resetting request bodys when retrying form posts. Thanks Bruno. [#19379]
* Throwing away keep alive connections on EPIPE and ECONNRESET.
* Duplicating request headers when retrying a 401. Thanks Hiroshi Ichikawa.
* Simulating an EOF error when a response length is bad. Thanks Tobias Gruetzmacher.
http://rubyforge.org/tracker/index.php?func=detail&aid=19178&group_id=1453&atid=5711
* Defaulting option tags to the inner text.
http://rubyforge.org/tracker/index.php?func=detail&aid=19976&group_id=1453&atid=5709
* Supporting blank strings for option values.
http://rubyforge.org/tracker/index.php?func=detail&aid=19975&group_id=1453&atid=5709
=== 0.7.5
* Fixed a bug when fetching files and not pages. Thanks Mat Schaffer!
=== 0.7.4
* doh!
=== 0.7.3
* Pages are now yielded to a blocks given to WWW::Mechanize#get
* WWW::Mechanize#get now takes hash arguments for uri parameters.
* WWW::Mechanize#post takes an IO object as a parameter and posts correctly.
* Fixing a strange zlib inflate problem on windows
=== 0.7.2
* Handling gzipped responses with no Content-Length header
=== 0.7.1
* Added iPhone to the user agent aliases. [#17572]
* Fixed a bug with EOF errors in net/http. [#17570]
* Handling 0 length gzipped responses. [#17471]
=== 0.7.0
* Removed Ruby 1.8.2 support
* Changed parser to lazily parse links
* Lazily parsing document
* Adding verify_callback for SSL requests. Thanks Mike Dalessio!
* Fixed a bug with Accept-Language header. Thanks Bill Siggelkow.
=== 0.6.11
* Detecting single quotes in meta redirects.
* Adding pretty inspect for ruby versions > 1.8.4 (Thanks Joel Kociolek)
http://rubyforge.org/tracker/index.php?func=detail&aid=13150&group_id=1453&atid=5709
* Fixed bug with file name in multipart posts
http://rubyforge.org/tracker/?func=detail&aid=15594&group_id=1453&atid=5709
* Posting forms relative to the originating page. Thanks Mortee.
* Added a FAQ
http://rubyforge.org/tracker/?func=detail&aid=15772&group_id=1453&atid=5709
=== 0.6.10
* Made digest authentication work with POSTs.
* Made sure page was HTML before following meta refreshes.
http://rubyforge.org/tracker/index.php?func=detail&aid=12260&group_id=1453&atid=5709
* Made sure that URLS with a host and no path would default to '/' for history
purposes.
http://rubyforge.org/tracker/index.php?func=detail&aid=12368&group_id=1453&atid=5709
* Avoiding memory leaks with transact. Thanks Tobias Gruetzmacher!
http://rubyforge.org/tracker/index.php?func=detail&aid=12057&group_id=1453&atid=5711
* Fixing a problem with # signs in the file name. Thanks Tobias Gruetzmacher!
http://rubyforge.org/tracker/index.php?func=detail&aid=12510&group_id=1453&atid=5711
* Made sure that blank form values are submitted.
http://rubyforge.org/tracker/index.php?func=detail&aid=12505&group_id=1453&atid=5709
* Mechanize now respects the base tag. Thanks Stephan Dale.
http://rubyforge.org/tracker/index.php?func=detail&aid=12468&group_id=1453&atid=5709
* Aliasing inspect to pretty_inspect. Thanks Eric Promislow.
http://rubyforge.org/pipermail/mechanize-users/2007-July/000157.html
=== 0.6.9
* Updating UTF-8 support for urls
* Adding AREA tags to the links list.
http://rubyforge.org/pipermail/mechanize-users/2007-May/000140.html
* WWW::Mechanize#follow_meta_refresh will allow you to automatically follow
meta refresh tags. [#10032]
* Adding x-gzip to accepted content-encoding. Thanks Simon Strandgaard
http://rubyforge.org/tracker/index.php?func=detail&aid=11167&group_id=1453&atid=5711
* Added Digest Authentication support. Thanks to Ryan Davis and Eric Hodel,
you get a gold star!
=== 0.6.8
* Keep alive can be shut off now with WWW::Mechanize#keep_alive
* Conditional requests can be shut off with WWW::Mechanize#conditional_requests
* Monkey patched Net::HTTP#keep_alive?
* [#9877] Moved last request time. Thanks Max Stepanov
* Added WWW::Mechanize::File#save
* Defaulting file name to URI or Content-Disposition
* Updating compatability with hpricot
* Added more unit tests
=== 0.6.7
* Fixed a bug with keep-alive requests
* [#9549] fixed problem with cookie paths
=== 0.6.6
* Removing hpricot overrides
* Fixed a bug where alt text can be nil. Thanks Yannick!
* Unparseable expiration dates in cookies are now treated as session cookies
* Caching connections
* Requests now default to keep alive
* [#9434] Fixed bug where html entities weren't decoded
* [#9150] Updated mechanize history to deal with redirects
=== 0.6.5
* Copying headers to a hash to prevent memory leaks
* Speeding up page parsing
* Aliased fields to elements
* Adding If-Modified-Since header
* Added delete_field! to form. Thanks to Sava Chankov
* Updated uri escaping to support high order characters. Thanks to Henrik Nyh.
* Better handling relative URIs. Thanks to Henrik Nyh
* Now handles pipes in URLs
http://rubyforge.org/tracker/?func=detail&aid=7140&group_id=1453&atid=5709
* Now escaping html entities in form fields.
http://rubyforge.org/tracker/?func=detail&aid=7563&group_id=1453&atid=5709
* Added MSIE 7.0 user agent string
=== 0.6.4
* Adding the "redirect_ok" method to Mechanize to stop mechanize from
following redirects.
http://rubyforge.org/tracker/index.php?func=detail&aid=6571&group_id=1453&atid=5712
* Added protected method Mechanize#set_headers so that subclasses can set
custom headers.
http://rubyforge.org/tracker/?func=detail&aid=7208&group_id=1453&atid=5712
* Aliased Page#referer to Page#page
* Fixed a bug when clicking relative urls
http://rubyforge.org/pipermail/mechanize-users/2006-November/000035.html
* Fixing a bug when bad version or max age is passed to Cookie::parse
http://rubyforge.org/pipermail/mechanize-users/2006-November/000033.html
* Fixing a bug with response codes. [#6526]
* Fixed bug [#6548]. Input type of 'button' was not being added as a button.
* Fixed bug [#7139]. REXML parser calls hpricot parser by accident
=== 0.6.3
* Added keys and values methods to Form
* Added has_value? to Form
* Added a has_field? method to Form
* The add_field! method on Form now creates a field for you on the form.
Thanks to Mat Schaffer for the patch.
http://rubyforge.org/pipermail/mechanize-users/2006-November/000025.html
* Fixed a bug when form actions have html ecoded entities in them.
http://rubyforge.org/pipermail/mechanize-users/2006-October/000019.html
* Fixed a bug when links or frame sources have html encoded entities in the
href or src.
* Fixed a bug where '#' symbols are encoded
http://rubyforge.org/forum/message.php?msg_id=14747
=== 0.6.2
* Added a yield to Page#form so that dealing with forms can be more DSL like.
* Added the parsed page to the ResponseCodeError so that the parsed results
can be accessed even in the event of an error.
http://rubyforge.org/pipermail/mechanize-users/2006-September/000007.html
* Updated documentation (Thanks to Paul Smith)
=== 0.6.1
* Added a method to Form called "submit". Now forms can be submitted by
calling a method on the form.
* Added a click method to links
* Added an REXML pluggable parser for backwards compatability. To use it,
just do this:
agent.pluggable_parser.html = WWW::Mechanize::REXMLPage
* Fixed a bug with referrers by adding a page attribute to forms and links.
* Fixed a bug where domain names were case sensitive.
http://tenderlovemaking.com/2006/09/04/road-to-ruby-mechanize-060/#comment-53
* Fixed a bug with URI escaped links.
http://rubyforge.org/pipermail/mechanize-users/2006-September/000002.html
* Fixed a bug when options in select lists don't have a value. Thanks Dan Higham
[#5837] Code in lib/mechanize/form_elements.rb is incorrect.
* Fixed a bug with loading text in to links.
http://rubyforge.org/pipermail/mechanize-users/2006-September/000000.html
=== 0.6.0
* Changed main parser to use hpricot
* Made WWW::Mechanize::Page class searchable like hpricot
* Updated WWW::Mechanize#click to support hpricot links like this:
@agent.click (page/"a").first
* Clicking a Frame is now possible:
@agent.click (page/"frame").first
* Removed deprecated attr_finder
* Removed REXML helper methods since the main parser is now hpricot
* Overhauled cookie parser to use WEBrick::Cookie
=== 0.5.4
* Added WWW::Mechanize#trasact for saving history state between in a
transaction. See the EXAMPLES file. Thanks Johan Kiviniemi.
* Added support for gzip compressed pages
* Forms can now be accessed like a hash. For example, to set the value
of an input field named 'name' to "Aaron", you can do this:
form['name'] = "Aaron"
Or to get the value of a field named 'name', do this:
puts form['name']
* File uploads will now read the file specified in FileUpload#file_name
* FileUpload can use an IO object in FileUpload#file_data
* Fixed a bug with saving files on windows
* Fixed a bug with the filename being set in forms
=== 0.5.3
* Mechanize#click will now act on the first element of an array. So if an
array of links is passed to WWW::Mechanize#click, the first link is clicked.
That means the syntax for clicking links is shortened and still supports
selecting a link. The following are equivalent:
agent.click page.links.first
agent.click page.links
* Fixed a bug with spaces in href's and get's
* Added a tick, untick, and click method to radio buttons so that
radiobuttons can be "clicked"
* Added a tick, untick, and click method to check boxes so that
checkboxes can be "clicked"
* Options on Select lists can now be "tick"ed, and "untick"ed.
* Fixed a potential bug conflicting with rails. Thanks Eric Kolve
* Updated log4r support for a speed increase. Thanks Yinon Bentor
* Added inspect methods and pretty printing
=== 0.5.2
* Fixed a bug with input names that are nil
* Added a warning when using attr_finder because attr_finder will be deprecated
in 0.6.0 in favor of method calls. So this syntax:
@agent.links(:text => 'foo')
should be changed to this:
@agent.links.text('foo')
* Added support for selecting multiple options in select tags that support
multiple options. See WWW::Mechanize::MultiSelectList.
* New select list methods have been added, select_all, select_none.
* Options for select lists can now be "clicked" which toggles their selection,
they can be "selected" and "unselected". See WWW::Mechanize::Option
* Added a method to set multiple fields at the same time,
WWW::Mechanize::Form#set_fields. Which can be used like so:
form.set_fields( :foo => 'bar', :name => 'Aaron' )
=== 0.5.1
* Fixed bug with file uploads
* Added performance tweaks to the cookie class
=== 0.5.0
* Added pluggable parsers. (Thanks to Eric Kolve for the idea)
* Changed namespace so all classes are under WWW::Mechanize.
* Updating Forms so that fields can be used as accessors (Thanks Gregory Brown)
* Added WWW::Mechanize::File as default object used for unknown content types.
* Added 'save_as' method to Mechanize::File, so any page can be saved.
* Adding 'save_as' and 'load' to CookieJar so that cookies can be saved
between sessions.
* Added WWW::Mechanize::FileSaver pluggable parser to automatically save files.
* Added WWW::Mechanize::Page#title for page titles
* Added OpenSSL certificate support (Thanks Mike Dalessio)
* Removed support for body filters in favor of pluggable parsers.
* Fixed cookie bug adding a '/' when the url is missing one (Thanks Nick Dainty)
=== 0.4.7
* Fixed bug with no action in forms. Thanks to Adam Wiggins
* Setting a default user-agent string
* Added house cleaning to the cookie jar so expired cookies don't stick around.
* Added new method WWW::Form#field to find the first field with a given name.
(thanks to Gregory Brown)
* Added WWW::Mechanize#get_file for fetching non text/html files
=== 0.4.6
* Added support for proxies
* Added a uri field to WWW::Link
* Added a error class WWW::Mechanize::ContentTypeError
* Added image alt text to link text
* Added an visited? method to WWW::Mechanize
* Added Array#value= which will set the first value to the argument. That
allows syntax as such: form.fields.name('q').value = 'xyz'
Before it was like this: form.fields.name('q').first.value = 'xyz'
=== 0.4.5
* Added support for multiple values of the same name
* Updated build_query_string to take an array of arrays (Thanks Michal Janeczek)
* Added WWW::Mechanize#body_filter= so that response bodies can be preprocessed
* Added WWW::Page#body_filter= so that response bodies can be preprocessed
* Added support for more date formats in the cookie parser
* Fixed a bug with empty select lists
* Fixing a problem with cookies not handling no spaces after semicolons
=== 0.4.4
* Fixed error in method signature, basic_authetication is now basic_auth
* Fixed bug with encoding names in file uploads (Big thanks to Alex Young)
* Added options to the select list
=== 0.4.3
* Added syntactic sugar for finding things
* Fixed bug with HttpOnly option in cookies
* Fixed a bug with cookie date parsing
* Defaulted dropdown lists to the first element
* Added unit tests
=== 0.4.2
* Added support for iframes
* Made mechanize dependant on ruby-web rather than narf
* Added unit tests
* Fixed a bunch of warnings
=== 0.4.1
* Added support for file uploading
* Added support for frames (Thanks Gabriel[mailto:leerbag@googlemail.com])
* Added more unit tests
* Fixed some bugs
=== 0.4.0
* Added more unit tests
* Added a cookie jar with better cookie support, included expiration of cookies
and general cookie security.
* Updated mechanize to use built in net/http if ruby version is new enough.
* Added support for meta refresh tags
* Defaulted form actions to 'GET'
* Fixed various bugs
* Added more unit tests
* Added a response code exception
* Thanks to Brian Ellin (brianellin@gmail.com) for:
Added support for CA files, and support for 301 response codes
mechanize-2.7.5/README.rdoc 0000644 0000041 0000041 00000004545 12772546476 015362 0 ustar www-data www-data = Mechanize {}[http://travis-ci.org/sparklemotion/mechanize]
* http://docs.seattlerb.org/mechanize
* https://github.com/sparklemotion/mechanize
== Description
The Mechanize library is used for automating interaction with websites.
Mechanize automatically stores and sends cookies, follows redirects,
and can follow links and submit forms. Form fields can be populated and
submitted. Mechanize also keeps track of the sites that you have visited as
a history.
== Dependencies
* ruby 1.9.2 or newer
* nokogiri[https://github.com/sparklemotion/nokogiri]
== Support:
The bug tracker is available here:
* https://github.com/sparklemotion/mechanize/issues
== Examples
If you are just starting, check out the GUIDE[http://docs.seattlerb.org/mechanize/GUIDE_rdoc.html] or
the EXAMPLES[http://docs.seattlerb.org/mechanize/EXAMPLES_rdoc.html] file.
== Developers
Use bundler to install dependencies:
bundle install
Run all tests with:
rake test
You can also use +autotest+ from the ZenTest gem to run tests.
See also Mechanize::TestCase to read about the built-in testing
infrastructure.
== Authors
Copyright (c) 2005 by Michael Neumann (mneumann@ntecs.de)
Copyright (c) 2006-2011:
* {Aaron Patterson}[http://tenderlovemaking.com] (aaronp@rubyforge.org)
* {Mike Dalessio}[http://mike.daless.io] (mike@csa.net)
Copyright (c) 2011-2015:
* {Eric Hodel}[http://blog.segment7.net] (drbrain@segment7.net)
* {Akinori MUSHA}[http://blog.akinori.org] (knu@idaemons.org)
* {Lee Jarvis}[http://twitter.com/lee_jarvis] (ljjarvis@gmail.com)
This library comes with a shameless plug for employing me
(Aaron[http://tenderlovemaking.com/]) programming Ruby, my favorite language!
== Acknowledgments
This library was heavily influenced by its namesake in the Perl world. A big
thanks goes to {Andy Lester}[http://petdance.com],
the author of the original Perl module WWW::Mechanize which is available
here[http://search.cpan.org/dist/WWW-Mechanize/]. Ruby Mechanize would not be around without you!
Thank you to Michael Neumann for starting the Ruby version. Thanks to everyone
who's helped out in various ways. Finally, thank you to the people using this
library!
== License
This library is distributed under the MIT license. Please see the LICENSE[http://docs.seattlerb.org/mechanize/LICENSE_rdoc.html] file.
mechanize-2.7.5/.travis.yml 0000644 0000041 0000041 00000001111 12772546476 015647 0 ustar www-data www-data ---
language: ruby
notifications:
email:
- drbrain@segment7.net
- ljjarvis@gmail.com
- knu@idaemons.org
sudo: false
# bundler is missing for jruby-head in travis-ci
# https://github.com/travis-ci/travis-ci/issues/5861
before_install: gem query -i -n ^bundler$ >/dev/null || gem install bundler
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2
- 2.3.1
- ruby-head
- jruby-1.7.25
- jruby-9.1.2.0
- jruby-head
- rbx-19mode
script: rake test
matrix:
allow_failures:
- rvm: 2.3
- rvm: ruby-head
- rvm: jruby-1.7.25
- rvm: jruby-9.1.2.0
- rvm: jruby-head
- rvm: rbx-19mode
mechanize-2.7.5/lib/ 0000755 0000041 0000041 00000000000 12772546476 014312 5 ustar www-data www-data mechanize-2.7.5/lib/mechanize/ 0000755 0000041 0000041 00000000000 12772546476 016255 5 ustar www-data www-data mechanize-2.7.5/lib/mechanize/headers.rb 0000644 0000041 0000041 00000000612 12772546476 020214 0 ustar www-data www-data class Mechanize::Headers < Hash
def [](key)
super(key.downcase)
end
def []=(key, value)
super(key.downcase, value)
end
def key?(key)
super(key.downcase)
end
def canonical_each
block_given? or return enum_for(__method__)
each { |key, value|
key = key.capitalize
key.gsub!(/-([a-z])/) { "-#{$1.upcase}" }
yield [key, value]
}
end
end
mechanize-2.7.5/lib/mechanize/page/ 0000755 0000041 0000041 00000000000 12772546476 017171 5 ustar www-data www-data mechanize-2.7.5/lib/mechanize/page/meta_refresh.rb 0000644 0000041 0000041 00000004016 12772546476 022163 0 ustar www-data www-data ##
# This class encapsulates a meta element with a refresh http-equiv. Mechanize
# treats meta refresh elements just like 'a' tags. MetaRefresh objects will
# contain links, but most likely will have no text.
class Mechanize::Page::MetaRefresh < Mechanize::Page::Link
##
# Time to wait before next refresh
attr_reader :delay
##
# This MetaRefresh links did not contain a url= in the content attribute and
# links to itself.
attr_reader :link_self
##
# Matches the content attribute of a meta refresh element. After the match:
#
# $1:: delay
# $3:: url
CONTENT_REGEXP = /^\s*(\d+\.?\d*)\s*(?:;(?:\s*url\s*=\s*(['"]?)(\S*)\2)?\s*)?$/i
##
# Regexp of unsafe URI characters that excludes % for Issue #177
UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/?:@&%=+$,\[\]]/
##
# Parses the delay and url from the content attribute of a meta
# refresh element.
#
# Returns an array of [delay, url, link_self], where the first two
# are strings containing the respective parts of the refresh value,
# and link_self is a boolean value that indicates whether the url
# part is missing or empty. If base_uri, the URI of the current
# page is given, the value of url becomes an absolute URI.
def self.parse content, base_uri = nil
m = CONTENT_REGEXP.match(content) or return
delay, url = m[1], m[3]
url &&= url.empty? ? nil : Mechanize::Util.uri_escape(url, UNSAFE)
link_self = url.nil?
if base_uri
url = url ? base_uri + url : base_uri
end
return delay, url, link_self
end
def self.from_node node, page, uri = nil
http_equiv = node['http-equiv'] and
/\ARefresh\z/i =~ http_equiv or return
delay, uri, link_self = parse node['content'], uri
return unless delay
new node, page, delay, uri, link_self
end
def initialize node, page, delay, href, link_self = false
super node, page.mech, page
@delay = delay.include?(?.) ? delay.to_f : delay.to_i
@href = href
@link_self = link_self
end
def noreferrer?
true
end
end
mechanize-2.7.5/lib/mechanize/page/link.rb 0000644 0000041 0000041 00000004635 12772546476 020463 0 ustar www-data www-data ##
# This class encapsulates links. It contains the text and the URI for
# 'a' tags parsed out of an HTML page. If the link contains an image,
# the alt text will be used for that image.
#
# For example, the text for the following links with both be 'Hello World':
#
# Hello World
#
class Mechanize::Page::Link
attr_reader :node
attr_reader :href
attr_reader :attributes
attr_reader :page
alias :referer :page
def initialize(node, mech, page)
@node = node
@attributes = node
@href = node['href']
@mech = mech
@page = page
@text = nil
@uri = nil
end
# Click on this link
def click
@mech.click self
end
# This method is a shorthand to get link's DOM id.
# Common usage:
# page.link_with(:dom_id => "links_exact_id")
def dom_id
node['id']
end
# This method is a shorthand to get a link's DOM class
# Common usage:
# page.link_with(:dom_class => "links_exact_class")
def dom_class
node['class']
end
def pretty_print(q) # :nodoc:
q.object_group(self) {
q.breakable; q.pp text
q.breakable; q.pp href
}
end
alias inspect pretty_inspect # :nodoc:
# A list of words in the rel attribute, all lower-cased.
def rel
@rel ||= (val = attributes['rel']) ? val.downcase.split(' ') : []
end
# Test if the rel attribute includes +kind+.
def rel? kind
rel.include? kind
end
# Test if this link should not be traced.
def noreferrer?
rel?('noreferrer')
end
# The text content of this link
def text
return @text if @text
@text = @node.inner_text
# If there is no text, try to find an image and use it's alt text
if (@text.nil? or @text.empty?) and imgs = @node.search('img') then
@text = imgs.map do |e|
e['alt']
end.join
end
@text
end
alias :to_s :text
# A URI for the #href for this link. The link is first parsed as a raw
# link. If that fails parsing an escaped link is attepmted.
def uri
@uri ||= if @href then
begin
URI.parse @href
rescue URI::InvalidURIError
URI.parse WEBrick::HTTPUtils.escape @href
end
end
end
# A fully resolved URI for the #href for this link.
def resolved_uri
@mech.resolve uri
end
end
mechanize-2.7.5/lib/mechanize/page/label.rb 0000644 0000041 0000041 00000000500 12772546476 020570 0 ustar www-data www-data ##
# A form label on an HTML page
class Mechanize::Page::Label
attr_reader :node
attr_reader :text
attr_reader :page
alias :to_s :text
def initialize(node, page)
@node = node
@text = node.inner_text
@page = page
end
def for
(id = @node['for']) && page.search("##{id}") || nil
end
end
mechanize-2.7.5/lib/mechanize/page/frame.rb 0000644 0000041 0000041 00000001231 12772546476 020605 0 ustar www-data www-data # A Frame object wraps a frame HTML element. Frame objects can be treated
# just like Link objects. They contain #src, the #link they refer to and a
# #name, the name of the frame they refer to. #src and #name are aliased to
# #href and #text respectively so that a Frame object can be treated just like
# a Link.
class Mechanize::Page::Frame < Mechanize::Page::Link
alias :src :href
attr_reader :text
alias :name :text
def initialize(node, mech, referer)
super(node, mech, referer)
@node = node
@text = node['name']
@href = node['src']
@content = nil
end
def content
@content ||= @mech.get @href, [], page
end
end
mechanize-2.7.5/lib/mechanize/page/base.rb 0000644 0000041 0000041 00000000326 12772546476 020431 0 ustar www-data www-data ##
# A base element on an HTML page. Mechanize treats base tags just like 'a'
# tags. Base objects will contain links, but most likely will have no text.
class Mechanize::Page::Base < Mechanize::Page::Link
end
mechanize-2.7.5/lib/mechanize/page/image.rb 0000644 0000041 0000041 00000006405 12772546476 020605 0 ustar www-data www-data ##
# An image element on an HTML page
class Mechanize::Page::Image
attr_reader :node
attr_accessor :page
attr_accessor :mech
##
# Creates a new Mechanize::Page::Image from an image +node+ and source
# +page+.
def initialize node, page
@node = node
@page = page
@mech = page.mech
end
##
# The alt attribute of the image
def alt
node['alt']
end
##
# The caption of the image. In order of preference, the #title, #alt, or
# empty string "".
def caption
title || alt || ''
end
alias :text :caption
##
# The class attribute of the image
def dom_class
node['class']
end
##
# The id attribute of the image
def dom_id
node['id']
end
##
# The suffix of the #url. The dot is a part of suffix, not a delimiter.
#
# p image.url # => "http://example/test.jpg"
# p image.extname # => ".jpg"
#
# Returns an empty string if #url has no suffix:
#
# p image.url # => "http://example/sampleimage"
# p image.extname # => ""
def extname
return nil unless src
File.extname url.path
end
##
# Downloads the image.
#
# agent.page.image_with(:src => /logo/).fetch.save
#
# The referer is:
#
# #page("parent") ::
# all images on http html, relative #src images on https html
# (no referer) ::
# absolute #src images on https html
# user specified ::
# img.fetch(nil, my_referer_uri_or_page)
def fetch parameters = [], referer = nil, headers = {}
mech.get src, parameters, referer || image_referer, headers
end
##
# The height attribute of the image
def height
node['height']
end
def image_referer # :nodoc:
http_page = page.uri && page.uri.scheme == 'http'
https_page = page.uri && page.uri.scheme == 'https'
case
when http_page then page
when https_page && relative? then page
else
Mechanize::File.new(nil, { 'content-type' => 'text/plain' }, '', 200)
end
end
##
# MIME type guessed from the image url suffix
#
# p image.extname # => ".jpg"
# p image.mime_type # => "image/jpeg"
# page.images_with(:mime_type => /gif|jpeg|png/).each do ...
#
# Returns nil if url has no (well-known) suffix:
#
# p image.url # => "http://example/sampleimage"
# p image.mime_type # => nil
def mime_type
suffix_without_dot = extname ? extname.sub(/\A\./){''}.downcase : nil
Mechanize::Util::DefaultMimeTypes[suffix_without_dot]
end
def pretty_print(q) # :nodoc:
q.object_group(self) {
q.breakable; q.pp url
q.breakable; q.pp caption
}
end
alias inspect pretty_inspect # :nodoc:
def relative? # :nodoc:
%r{^https?://} !~ src
end
##
# The src attribute of the image
def src
node['src']
end
##
# The title attribute of the image
def title
node['title']
end
##
# The URL string of this image
def to_s
url.to_s
end
##
# URI for this image
def url
if relative? then
if page.bases[0] then
page.bases[0].href + src.to_s
else
page.uri + Mechanize::Util.uri_escape(src.to_s)
end
else
URI Mechanize::Util.uri_escape(src)
end
end
alias uri url
##
# The width attribute of the image
def width
node['width']
end
end
mechanize-2.7.5/lib/mechanize/history.rb 0000644 0000041 0000041 00000002346 12772546476 020310 0 ustar www-data www-data ##
# This class manages history for your mechanize object.
class Mechanize::History < Array
attr_accessor :max_size
def initialize(max_size = nil)
@max_size = max_size
@history_index = {}
end
def initialize_copy(orig)
super
@history_index = orig.instance_variable_get(:@history_index).dup
end
def inspect # :nodoc:
uris = map(&:uri).join ', '
"[#{uris}]"
end
def push(page, uri = nil)
super page
index = uri ? uri : page.uri
@history_index[index.to_s] = page
shift while length > @max_size if @max_size
self
end
alias :<< :push
def visited? uri
page = @history_index[uri.to_s]
return page if page # HACK
uri = uri.dup
uri.path = '/' if uri.path.empty?
@history_index[uri.to_s]
end
alias visited_page visited?
def clear
@history_index.clear
super
end
def shift
return nil if length == 0
page = self[0]
self[0] = nil
super
remove_from_index(page)
page
end
def pop
return nil if length == 0
page = super
remove_from_index(page)
page
end
private
def remove_from_index(page)
@history_index.each do |k,v|
@history_index.delete(k) if v == page
end
end
end
mechanize-2.7.5/lib/mechanize/directory_saver.rb 0000644 0000041 0000041 00000003775 12772546476 022022 0 ustar www-data www-data ##
# Unlike Mechanize::FileSaver, the directory saver places all downloaded files
# in a single pre-specified directory.
#
# You must register the directory to save to before using the directory saver:
#
# agent.pluggable_parser['image'] = \
# Mechanize::DirectorySaver.save_to 'images'
class Mechanize::DirectorySaver < Mechanize::Download
@directory = nil
@options = {}
##
# Creates a DirectorySaver subclass that will save responses to the given
# +directory+. If +options+ includes a +decode_filename+ value set to +true+
# then the downloaded filename will be ran through +CGI.unescape+ before
# being saved. If +options+ includes a +overwrite+ value set to +true+ then
# downloaded file will be overwritten if two files with the same names exist.
def self.save_to directory, options = {}
directory = File.expand_path directory
Class.new self do |klass|
klass.instance_variable_set :@directory, directory
klass.instance_variable_set :@options, options
end
end
##
# The directory downloaded files will be saved to.
def self.directory
@directory
end
##
# True if downloaded files should have their names decoded before saving.
def self.decode_filename?
@options[:decode_filename]
end
##
# Checks if +overwrite+ parameter is set to true
def self.overwrite?
@options[:overwrite]
end
##
# Saves the +body_io+ into the directory specified for this DirectorySaver
# by save_to. The filename is chosen by Mechanize::Parser#extract_filename.
def initialize uri = nil, response = nil, body_io = nil, code = nil
directory = self.class.directory
raise Mechanize::Error,
'no save directory specified - ' \
'use Mechanize::DirectorySaver.save_to ' \
'and register the resulting class' unless directory
super
@filename = CGI.unescape(@filename) if self.class.decode_filename?
path = File.join directory, @filename
if self.class.overwrite?
save! path
else
save path
end
end
end
mechanize-2.7.5/lib/mechanize/test_case.rb 0000644 0000041 0000041 00000016411 12772546476 020557 0 ustar www-data www-data require 'mechanize'
require 'logger'
require 'tempfile'
require 'tmpdir'
require 'webrick'
require 'zlib'
require 'rubygems'
begin
gem 'minitest'
rescue Gem::LoadError
end
require 'minitest/autorun'
begin
require 'minitest/pride'
rescue LoadError
end
##
# A generic test case for testing mechanize. Using a subclass of
# Mechanize::TestCase for your tests will create an isolated mechanize
# instance that won't pollute your filesystem or other tests.
#
# Once Mechanize::TestCase is loaded no HTTP requests will be made outside
# mechanize itself. All requests are handled via WEBrick servlets.
#
# Mechanize uses WEBrick servlets to test some functionality. You can run
# other HTTP clients against the servlets using:
#
# ruby -rmechanize/test_case/server -e0
#
# Which will launch a test server at http://localhost:8000
class Mechanize::TestCase < Minitest::Test
TEST_DIR = File.expand_path '../../../test', __FILE__
REQUESTS = []
##
# Creates a clean mechanize instance +@mech+ for use in tests.
def setup
super
REQUESTS.clear
@mech = Mechanize.new
@ssl_private_key = nil
@ssl_certificate = nil
end
##
# Creates a fake page with URI http://fake.example and an empty, submittable
# form.
def fake_page agent = @mech
uri = URI 'http://fake.example/'
html = <<-END
You can POST anything to this endpoint, though
BODY end end mechanize-2.7.5/lib/mechanize/test_case/http_refresh_servlet.rb 0000644 0000041 0000041 00000000500 12772546476 025010 0 ustar www-data www-data class HttpRefreshServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) res['Content-Type'] = req.query['ct'] || "text/html" refresh_time = req.query['refresh_time'] || 0 refresh_url = req.query['refresh_url'] || '/' res['Refresh'] = " #{refresh_time};url=#{refresh_url}\r\n"; end end mechanize-2.7.5/lib/mechanize/test_case/content_type_servlet.rb 0000644 0000041 0000041 00000000324 12772546476 025032 0 ustar www-data www-data class ContentTypeServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) ct = req.query['ct'] || "text/html; charset=utf-8" res['Content-Type'] = ct res.body = "Hello World" end end mechanize-2.7.5/lib/mechanize/test_case/infinite_redirect_servlet.rb 0000644 0000041 0000041 00000000557 12772546476 026015 0 ustar www-data www-data class InfiniteRedirectServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) res['Content-Type'] = req.query['ct'] || "text/html" res.status = req.query['code'] ? req.query['code'].to_i : '302' number = req.query['q'] ? req.query['q'].to_i : 0 res['Location'] = "/infinite_redirect?q=#{number + 1}" end alias :do_POST :do_GET end mechanize-2.7.5/lib/mechanize/test_case/basic_auth_servlet.rb 0000644 0000041 0000041 00000001127 12772546476 024423 0 ustar www-data www-data class BasicAuthServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req,res) htpd = nil Tempfile.open 'dot.htpasswd' do |io| htpd = WEBrick::HTTPAuth::Htpasswd.new(io.path) htpd.set_passwd('Blah', 'user', 'pass') end authenticator = WEBrick::HTTPAuth::BasicAuth.new({ :UserDB => htpd, :Realm => 'Blah', :Logger => Logger.new(nil) }) begin authenticator.authenticate(req,res) res.body = 'You are authenticated' rescue WEBrick::HTTPStatus::Unauthorized res.status = 401 end end alias :do_POST :do_GET end mechanize-2.7.5/lib/mechanize/test_case/referer_servlet.rb 0000644 0000041 0000041 00000000422 12772546476 023750 0 ustar www-data www-data class RefererServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) res['Content-Type'] = "text/html" res.body = req['Referer'] || '' end def do_POST(req, res) res['Content-Type'] = "text/html" res.body = req['Referer'] || '' end end mechanize-2.7.5/lib/mechanize/test_case/redirect_servlet.rb 0000644 0000041 0000041 00000000566 12772546476 024130 0 ustar www-data www-data class RedirectServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) res['Content-Type'] = req.query['ct'] || 'text/html' res.status = req.query['code'] ? req.query['code'].to_i : '302' res['Location'] = req['X-Location'] || '/verb' end alias :do_POST :do_GET alias :do_HEAD :do_GET alias :do_PUT :do_GET alias :do_DELETE :do_GET end mechanize-2.7.5/lib/mechanize/test_case/many_cookies_as_string_servlet.rb 0000644 0000041 0000041 00000002247 12772546476 027056 0 ustar www-data www-data class ManyCookiesAsStringServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) cookies = [] name_cookie = WEBrick::Cookie.new("name", "Aaron") name_cookie.path = "/" name_cookie.expires = Time.now + 86400 name_cookie.domain = 'localhost' cookies << name_cookie cookies << name_cookie cookies << name_cookie cookies << "#{name_cookie}; HttpOnly" expired_cookie = WEBrick::Cookie.new("expired", "doh") expired_cookie.path = "/" expired_cookie.expires = Time.now - 86400 cookies << expired_cookie different_path_cookie = WEBrick::Cookie.new("a_path", "some_path") different_path_cookie.path = "/some_path" different_path_cookie.expires = Time.now + 86400 cookies << different_path_cookie no_path_cookie = WEBrick::Cookie.new("no_path", "no_path") no_path_cookie.expires = Time.now + 86400 cookies << no_path_cookie no_exp_path_cookie = WEBrick::Cookie.new("no_expires", "nope") no_exp_path_cookie.path = "/" cookies << no_exp_path_cookie res['Set-Cookie'] = cookies.join(', ') res['Content-Type'] = "text/html" res.body = "hello" end end mechanize-2.7.5/lib/mechanize/test_case/digest_auth_servlet.rb 0000644 0000041 0000041 00000001366 12772546476 024626 0 ustar www-data www-data require 'logger' class DigestAuthServlet < WEBrick::HTTPServlet::AbstractServlet htpd = nil Tempfile.open 'digest.htpasswd' do |io| htpd = WEBrick::HTTPAuth::Htdigest.new(io.path) htpd.set_passwd('Blah', 'user', 'pass') end @@authenticator = WEBrick::HTTPAuth::DigestAuth.new({ :UserDB => htpd, :Realm => 'Blah', :Algorithm => 'MD5', :Logger => Logger.new(nil) }) def do_GET req, res def req.request_time; Time.now; end def req.request_uri; '/digest_auth'; end def req.request_method; 'GET'; end begin @@authenticator.authenticate req, res res.body = 'You are authenticated' rescue WEBrick::HTTPStatus::Unauthorized res.status = 401 end end alias :do_POST :do_GET end mechanize-2.7.5/lib/mechanize/test_case/server.rb 0000644 0000041 0000041 00000001655 12772546476 022071 0 ustar www-data www-data require 'webrick' require 'mechanize/test_case/servlets' server = WEBrick::HTTPServer.new :Port => 8000 server.mount_proc '/' do |req, res| res.content_type = 'text/html' servlets = MECHANIZE_TEST_CASE_SERVLETS.map do |path, servlet| "This server allows you to test various mechanize behavior against other HTTP clients. Some endpoints may require headers be set to have a reasonable function, or may respond diffently to POST vs GET requests. Please see the servlet implementation and mechanize tests for further details.
Here are the servlet endpoints available:
/robots.txt
files be obeyed?
def robots
@agent.robots
end
##
# When +enabled+ mechanize will retrieve and obey robots.txt
# files
def robots= enabled
@agent.robots = enabled
end
##
# The handlers for HTTP and other URI protocols.
def scheme_handlers
@agent.scheme_handlers
end
##
# Replaces the URI scheme handler table with +scheme_handlers+
def scheme_handlers= scheme_handlers
@agent.scheme_handlers = scheme_handlers
end
##
# The identification string for the client initiating a web request
def user_agent
@agent.user_agent
end
##
# Sets the User-Agent used by mechanize to +user_agent+. See also
# user_agent_alias
def user_agent= user_agent
@agent.user_agent = user_agent
end
##
# Set the user agent for the Mechanize object based on the given +name+.
#
# See also AGENT_ALIASES
def user_agent_alias= name
self.user_agent = AGENT_ALIASES[name] ||
raise(ArgumentError, "unknown agent alias #{name.inspect}")
end
##
# The value of watch_for_set is passed to pluggable parsers for retrieved
# content
attr_accessor :watch_for_set
# :section: SSL
#
# SSL settings for mechanize. These must be set in the block given to
# Mechanize.new
##
# Path to an OpenSSL server certificate file
def ca_file
@agent.ca_file
end
##
# Sets the certificate file used for SSL connections
def ca_file= ca_file
@agent.ca_file = ca_file
end
##
# An OpenSSL client certificate or the path to a certificate file.
def cert
@agent.certificate
end
##
# Sets the OpenSSL client certificate +cert+ to the given path or
# certificate instance
def cert= cert
@agent.certificate = cert
end
##
# An OpenSSL certificate store for verifying server certificates. This
# defaults to the default certificate store for your system.
#
# If your system does not ship with a default set of certificates you can
# retrieve a copy of the set from Mozilla here:
# http://curl.haxx.se/docs/caextract.html
#
# (Note that this set does not have an HTTPS download option so you may
# wish to use the firefox-db2pem.sh script to extract the certificates
# from a local install to avoid man-in-the-middle attacks.)
#
# After downloading or generating a cacert.pem from the above link you
# can create a certificate store from the pem file like this:
#
# cert_store = OpenSSL::X509::Store.new
# cert_store.add_file 'cacert.pem'
#
# And have mechanize use it with:
#
# agent.cert_store = cert_store
def cert_store
@agent.cert_store
end
##
# Sets the OpenSSL certificate store to +store+.
#
# See also #cert_store
def cert_store= cert_store
@agent.cert_store = cert_store
end
##
# What is this?
#
# Why is it different from #cert?
def certificate # :nodoc:
@agent.certificate
end
##
# An OpenSSL private key or the path to a private key
def key
@agent.private_key
end
##
# Sets the OpenSSL client +key+ to the given path or key instance. If a
# path is given, the path must contain an RSA key file.
def key= key
@agent.private_key = key
end
##
# OpenSSL client key password
def pass
@agent.pass
end
##
# Sets the client key password to +pass+
def pass= pass
@agent.pass = pass
end
##
# SSL version to use.
def ssl_version
@agent.ssl_version
end
##
# Sets the SSL version to use to +version+ without client/server
# negotiation.
def ssl_version= ssl_version
@agent.ssl_version = ssl_version
end
##
# A callback for additional certificate verification. See
# OpenSSL::SSL::SSLContext#verify_callback
#
# The callback can be used for debugging or to ignore errors by always
# returning +true+. Specifying nil uses the default method that was valid
# when the SSLContext was created
def verify_callback
@agent.verify_callback
end
##
# Sets the OpenSSL certificate verification callback
def verify_callback= verify_callback
@agent.verify_callback = verify_callback
end
##
# the OpenSSL server certificate verification method. The default is
# OpenSSL::SSL::VERIFY_PEER and certificate verification uses the default
# system certificates. See also cert_store
def verify_mode
@agent.verify_mode
end
##
# Sets the OpenSSL server certificate verification method.
def verify_mode= verify_mode
@agent.verify_mode = verify_mode
end
# :section: Utilities
attr_reader :agent # :nodoc:
##
# Parses the +body+ of the +response+ from +uri+ using the pluggable parser
# that matches its content type
def parse uri, response, body
content_type = nil
unless response['Content-Type'].nil?
data, = response['Content-Type'].split ';', 2
content_type, = data.downcase.split ',', 2 unless data.nil?
end
parser_klass = @pluggable_parser.parser content_type
unless parser_klass <= Mechanize::Download then
body = case body
when IO, Tempfile, StringIO then
body.read
else
body
end
end
parser_klass.new uri, response, body, response.code do |parser|
parser.mech = self if parser.respond_to? :mech=
parser.watch_for_set = @watch_for_set if
@watch_for_set and parser.respond_to?(:watch_for_set=)
end
end
def pretty_print(q) # :nodoc:
q.object_group(self) {
q.breakable
q.pp cookie_jar
q.breakable
q.pp current_page
}
end
##
# Sets the proxy +address+ at +port+ with an optional +user+ and +password+
def set_proxy address, port, user = nil, password = nil
@proxy_addr = address
@proxy_port = port
@proxy_user = user
@proxy_pass = password
@agent.set_proxy address, port, user, password
end
##
# Clears history and cookies.
def reset
@agent.reset
end
##
# Shuts down this session by clearing browsing state and closing all
# persistent connections.
def shutdown
reset
@agent.shutdown
end
private
##
# Posts +form+ to +uri+
def post_form(uri, form, headers = {})
cur_page = form.page || current_page ||
Page.new
request_data = form.request_data
log.debug("query: #{ request_data.inspect }") if log
headers = {
'Content-Type' => form.enctype,
'Content-Length' => request_data.size.to_s,
}.merge headers
# fetch the page
page = @agent.fetch uri, :post, headers, [request_data], cur_page
add_to_history(page)
page
end
##
# Adds +page+ to the history
def add_to_history(page)
@agent.history.push(page, @agent.resolve(page.uri))
@history_added.call(page) if @history_added
end
end
require 'mechanize/element_not_found_error'
require 'mechanize/response_read_error'
require 'mechanize/chunked_termination_error'
require 'mechanize/content_type_error'
require 'mechanize/cookie'
require 'mechanize/cookie_jar'
require 'mechanize/parser'
require 'mechanize/download'
require 'mechanize/directory_saver'
require 'mechanize/file'
require 'mechanize/file_connection'
require 'mechanize/file_request'
require 'mechanize/file_response'
require 'mechanize/form'
require 'mechanize/history'
require 'mechanize/http'
require 'mechanize/http/agent'
require 'mechanize/http/auth_challenge'
require 'mechanize/http/auth_realm'
require 'mechanize/http/content_disposition_parser'
require 'mechanize/http/www_authenticate_parser'
require 'mechanize/image'
require 'mechanize/page'
require 'mechanize/pluggable_parsers'
require 'mechanize/redirect_limit_reached_error'
require 'mechanize/redirect_not_get_or_head_error'
require 'mechanize/response_code_error'
require 'mechanize/robots_disallowed_error'
require 'mechanize/unauthorized_error'
require 'mechanize/unsupported_scheme_error'
require 'mechanize/util'
mechanize-2.7.5/mechanize.gemspec 0000644 0000041 0000041 00000004443 12772546476 017061 0 ustar www-data www-data # coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'mechanize/version'
Gem::Specification.new do |spec|
spec.name = "mechanize"
spec.version = Mechanize::VERSION
spec.homepage = "http://docs.seattlerb.org/mechanize/"
spec.summary = %q{The Mechanize library is used for automating interaction with websites}
spec.description =
[
"The Mechanize library is used for automating interaction with websites.",
"Mechanize automatically stores and sends cookies, follows redirects,",
"and can follow links and submit forms. Form fields can be populated and",
"submitted. Mechanize also keeps track of the sites that you have visited as",
"a history."
].join("\n")
spec.authors =
[
'Eric Hodel',
'Aaron Patterson',
'Mike Dalessio',
'Akinori MUSHA',
'Lee Jarvis'
]
spec.email =
[
'drbrain@segment7.net',
'aaronp@rubyforge.org',
'mike.dalessio@gmail.com',
'knu@idaemons.org',
'ljjarvis@gmail.com'
]
spec.license = "MIT"
spec.require_paths = ["lib"]
spec.files = `git ls-files`.split($/)
spec.test_files = spec.files.grep(%r{^test/})
spec.extra_rdoc_files += Dir['*.rdoc']
spec.rdoc_options = ["--main", "README.rdoc"]
spec.required_ruby_version = ">= 1.9.2"
spec.add_runtime_dependency "net-http-digest_auth", [ ">= 1.1.1", "~> 1.1" ]
spec.add_runtime_dependency "net-http-persistent", [ ">= 2.5.2", "~> 2.5" ]
if RUBY_VERSION >= "2.0"
spec.add_runtime_dependency "mime-types", [ ">= 1.17.2" ]
else
spec.add_runtime_dependency "mime-types", [ ">= 1.17.2", "< 3" ]
end
spec.add_runtime_dependency "http-cookie", [ "~> 1.0" ]
spec.add_runtime_dependency "nokogiri", [ "~> 1.6" ]
spec.add_runtime_dependency "ntlm-http", [ ">= 0.1.1", "~> 0.1" ]
spec.add_runtime_dependency "webrobots", [ "< 0.2", ">= 0.0.9" ]
spec.add_runtime_dependency "domain_name", [ ">= 0.5.1", "~> 0.5" ]
spec.add_development_dependency "rake"
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rdoc", "~> 4.0"
spec.add_development_dependency "minitest", "~> 5.0"
end
mechanize-2.7.5/test/ 0000755 0000041 0000041 00000000000 12772546476 014523 5 ustar www-data www-data mechanize-2.7.5/test/data/ 0000755 0000041 0000041 00000000000 12772546476 015434 5 ustar www-data www-data mechanize-2.7.5/test/data/server.pem 0000644 0000041 0000041 00000001567 12772546476 017456 0 ustar www-data www-data -----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqZ5iOGOLQc90ibB0dvEKFK+yGMZKmw/Ko6oCDdC1zrJchcohs
zSnGuS59gLvAmS8groLf77rY31fhKtG5dB8GynaOh4z+kcZhl+hCll+zTq7KH/rP
eg4S5iWllm7b6j/HssvTzSJyo1+p/+8LFXrULrY4Tcv3AJK4elDrI8ghrwIDAQAB
AoGAC+iZfLS4hSDTv2gW0NErROtA6E/mk8j12GArAwTHeGIDXc8HQbNEzCJ84UBx
3o/V/06yzruOL0HMfmvjpDY9RLsH02xZb2F/lruw4MJLu50i/Zu8Sjmb1YPSfCh/
3+8lREA3Uznlq+wHC3yPxQzMBy5jaEdH4IKxT0Bq8TeF0AECQQDSpL47YpRVRsLn
sS00ndEgQQmT5AJWJJtPpbHk6AA0a+zdNeuDRbdF42zG483YEqU7meZbPKR8QbkK
ZQPEBuevAkEAzxjGcz6NZesmN/NQOtOpylewEs1bdIJyBIBmcnmkimLBtdxd0t34
wUKVHLDSj2aemuAHHwsyn/BNXs6F+obmAQJBALpbkAXAAFW1xefvo3vih8sOXyfd
WIfX2SRNBqbq7otyVFudQaChBDUrsOgBUPLyBAdH8DoV27wm9UuR9RPvu/cCQFRr
WgICXqtMFtE56tuACreD1S9k7MHqpsW0/Y3ujicnKKWUhd5+Q3esR5JhdgOkpkSl
y+FYtDNERpW+BBliwgECQA+Vc7pnxwDIOP8kFumdAUmRmhEZjuwArFcywPzrCUn9
4/KBOp5wDN7kanBwNGZCZ/eQtkb6thAS8C9pufHD1lw=
-----END RSA PRIVATE KEY-----
mechanize-2.7.5/test/data/server.crt 0000644 0000041 0000041 00000001704 12772546476 017456 0 ustar www-data www-data -----BEGIN CERTIFICATE-----
MIICmzCCAgQCCQDq2kM3TCIM0DANBgkqhkiG9w0BAQQFADCBkTELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEjAQBgNV
BAoTCU1lY2hhbml6ZTESMBAGA1UECxMJTWVjaGFuaXplMQ4wDAYDVQQDEwVBYXJv
bjEjMCEGCSqGSIb3DQEJARYUYWFyb25wQHJ1Ynlmb3JnZS5vcmcwHhcNMDYwODIz
MDU0NTMwWhcNMDcwODIzMDU0NTMwWjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
Cldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEjAQBgNVBAoTCU1lY2hhbml6
ZTESMBAGA1UECxMJTWVjaGFuaXplMQ4wDAYDVQQDEwVBYXJvbjEjMCEGCSqGSIb3
DQEJARYUYWFyb25wQHJ1Ynlmb3JnZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
MIGJAoGBAKpnmI4Y4tBz3SJsHR28QoUr7IYxkqbD8qjqgIN0LXOslyFyiGzNKca5
Ln2Au8CZLyCugt/vutjfV+Eq0bl0HwbKdo6HjP6RxmGX6EKWX7NOrsof+s96DhLm
JaWWbtvqP8eyy9PNInKjX6n/7wsVetQutjhNy/cAkrh6UOsjyCGvAgMBAAEwDQYJ
KoZIhvcNAQEEBQADgYEAGtqgxn1fh0X5MxDG1yMp5aGcZ6HhtEtlm5S0ZsRnMsqU
Hh6Bd57+zUQ66XnLCbQN2cwNeeSoqtI16Ccc1I5cAhQnIZESMsPG21i1BnpEhKph
HfNFNpWI/upT2EXNUM6Vx2Kk2aCw2ysrD2pHpsTo5bCOly00uK1ZkoJVQMTL4gU=
-----END CERTIFICATE-----
mechanize-2.7.5/test/data/server.key 0000644 0000041 0000041 00000001567 12772546476 017465 0 ustar www-data www-data -----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqZ5iOGOLQc90ibB0dvEKFK+yGMZKmw/Ko6oCDdC1zrJchcohs
zSnGuS59gLvAmS8groLf77rY31fhKtG5dB8GynaOh4z+kcZhl+hCll+zTq7KH/rP
eg4S5iWllm7b6j/HssvTzSJyo1+p/+8LFXrULrY4Tcv3AJK4elDrI8ghrwIDAQAB
AoGAC+iZfLS4hSDTv2gW0NErROtA6E/mk8j12GArAwTHeGIDXc8HQbNEzCJ84UBx
3o/V/06yzruOL0HMfmvjpDY9RLsH02xZb2F/lruw4MJLu50i/Zu8Sjmb1YPSfCh/
3+8lREA3Uznlq+wHC3yPxQzMBy5jaEdH4IKxT0Bq8TeF0AECQQDSpL47YpRVRsLn
sS00ndEgQQmT5AJWJJtPpbHk6AA0a+zdNeuDRbdF42zG483YEqU7meZbPKR8QbkK
ZQPEBuevAkEAzxjGcz6NZesmN/NQOtOpylewEs1bdIJyBIBmcnmkimLBtdxd0t34
wUKVHLDSj2aemuAHHwsyn/BNXs6F+obmAQJBALpbkAXAAFW1xefvo3vih8sOXyfd
WIfX2SRNBqbq7otyVFudQaChBDUrsOgBUPLyBAdH8DoV27wm9UuR9RPvu/cCQFRr
WgICXqtMFtE56tuACreD1S9k7MHqpsW0/Y3ujicnKKWUhd5+Q3esR5JhdgOkpkSl
y+FYtDNERpW+BBliwgECQA+Vc7pnxwDIOP8kFumdAUmRmhEZjuwArFcywPzrCUn9
4/KBOp5wDN7kanBwNGZCZ/eQtkb6thAS8C9pufHD1lw=
-----END RSA PRIVATE KEY-----
mechanize-2.7.5/test/data/htpasswd 0000644 0000041 0000041 00000000023 12772546476 017207 0 ustar www-data www-data mech:44E/qORekFV0E
mechanize-2.7.5/test/data/server.csr 0000644 0000041 0000041 00000001304 12772546476 017451 0 ustar www-data www-data -----BEGIN CERTIFICATE REQUEST-----
MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
MRAwDgYDVQQHEwdTZWF0dGxlMRIwEAYDVQQKEwlNZWNoYW5pemUxEjAQBgNVBAsT
CU1lY2hhbml6ZTEOMAwGA1UEAxMFQWFyb24xIzAhBgkqhkiG9w0BCQEWFGFhcm9u
cEBydWJ5Zm9yZ2Uub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqZ5iO
GOLQc90ibB0dvEKFK+yGMZKmw/Ko6oCDdC1zrJchcohszSnGuS59gLvAmS8groLf
77rY31fhKtG5dB8GynaOh4z+kcZhl+hCll+zTq7KH/rPeg4S5iWllm7b6j/HssvT
zSJyo1+p/+8LFXrULrY4Tcv3AJK4elDrI8ghrwIDAQABoAAwDQYJKoZIhvcNAQEE
BQADgYEAT7SPe71NQvT2BYGEmbWb7FlSQrPh+rDQMHt/Akb8+r91NLkxZtbD1e/F
iyI9JloPCEwJXxHBl0VVRpFCRuJNN0z0E/G4NUWu6n+ZkihtnmV6uazzAQmD4pTl
SjoiyVLWU+r4Q4yXWXtJ9GR8Attv32fL3PcP+GGLeurXJAn0MNU=
-----END CERTIFICATE REQUEST-----
mechanize-2.7.5/test/test_mechanize_page_frame.rb 0000644 0000041 0000041 00000000567 12772546476 022230 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizePageFrame < Mechanize::TestCase
def test_content
page = page 'http://example/referer'
frame = node 'frame', 'name' => 'frame1', 'src' => 'http://example/'
frame = Mechanize::Page::Frame.new frame, @mech, page
frame.content
assert_equal 'http://example/referer', requests.first['Referer']
end
end
mechanize-2.7.5/test/test_mechanize_form_check_box.rb 0000644 0000041 0000041 00000001335 12772546476 023104 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFormCheckBox < Mechanize::TestCase
def setup
super
@page = @mech.get('http://localhost/tc_checkboxes.html')
end
def test_check
form = @page.forms.first
form.checkbox_with(:name => 'green').check
assert(form.checkbox_with(:name => 'green').checked)
%w{ red blue yellow brown }.each do |color|
assert_equal(false, form.checkbox_with(:name => color).checked)
end
end
def test_uncheck
form = @page.forms.first
checkbox = form.checkbox_with(:name => 'green')
checkbox.check
assert form.checkbox_with(:name => 'green').checked
checkbox.uncheck
assert !form.checkbox_with(:name => 'green').checked
end
end
mechanize-2.7.5/test/test_mechanize_form_textarea.rb 0000644 0000041 0000041 00000003047 12772546476 022776 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFormTextarea < Mechanize::TestCase
def setup
super
@page = @mech.get("http://localhost/tc_textarea.html")
end
def test_empty_text_area
form = @page.forms_with(:name => 'form1').first
assert_equal('', form.field_with(:name => 'text1').value)
form.text1 = 'Hello World'
assert_equal('Hello World', form.field_with(:name => 'text1').value)
page = @mech.submit(form)
assert_equal(1, page.links.length)
assert_equal('text1:Hello World', page.links[0].text)
end
def test_non_empty_textfield
form = @page.forms_with(:name => 'form2').first
assert_equal('sample text', form.field_with(:name => 'text1').value)
page = @mech.submit(form)
assert_equal(1, page.links.length)
assert_equal('text1:sample text', page.links[0].text)
end
def test_multi_textfield
form = @page.form_with(:name => 'form3')
assert_equal(2, form.fields_with(:name => 'text1').length)
assert_equal('', form.fields_with(:name => 'text1')[0].value)
assert_equal('sample text', form.fields_with(:name => 'text1')[1].value)
form.text1 = 'Hello World'
assert_equal('Hello World', form.fields_with(:name => 'text1')[0].value)
assert_equal('sample text', form.fields_with(:name => 'text1')[1].value)
page = @mech.submit(form)
assert_equal(2, page.links.length)
link = page.links_with(:text => 'text1:sample text')
assert_equal(1, link.length)
link = page.links_with(:text => 'text1:Hello World')
assert_equal(1, link.length)
end
end
mechanize-2.7.5/test/test_mechanize_file_connection.rb 0000644 0000041 0000041 00000000610 12772546476 023265 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFileConnection < Mechanize::TestCase
def test_request
uri = URI.parse "file://#{File.expand_path __FILE__}"
conn = Mechanize::FileConnection.new
body = ''
conn.request uri, nil do |response|
response.read_body do |part|
body << part
end
end
assert_equal File.read(__FILE__), body
end
end
mechanize-2.7.5/test/test_mechanize_history.rb 0000644 0000041 0000041 00000003226 12772546476 021636 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeHistory < Mechanize::TestCase
def setup
super
@uri = URI 'http://example/'
@uri2 = @uri + '/a'
@history = Mechanize::History.new
end
def test_initialize
assert_empty @history
end
def test_clear
@history.push :page, @uri
@history.clear
assert_empty @history
end
def test_pop
assert_nil @history.pop
@history.push :page1, @uri
@history.push :page2, @uri2
assert_equal :page2, @history.pop
refute_empty @history
end
def test_push
p1 = page @uri
obj = @history.push p1
assert_same @history, obj
assert_equal 1, @history.length
p2 = page @uri2
@history.push p2
assert_equal 2, @history.length
end
def test_push_max_size
@history = Mechanize::History.new 2
@history.push :page1, @uri
assert_equal 1, @history.length
@history.push :page2, @uri
assert_equal 2, @history.length
@history.push :page3, @uri
assert_equal 2, @history.length
end
def test_push_uri
obj = @history.push :page, @uri
assert_same @history, obj
assert_equal 1, @history.length
@history.push :page2, @uri
assert_equal 2, @history.length
end
def test_shift
assert_nil @history.shift
@history.push :page1, @uri
@history.push :page2, @uri2
page = @history.shift
assert_equal :page1, page
refute_empty @history
@history.shift
assert_empty @history
end
def test_visited_eh
refute @history.visited? @uri
@history.push page @uri
assert @history.visited? URI('http://example')
assert @history.visited? URI('http://example/')
end
end
mechanize-2.7.5/test/test_mechanize_http_auth_challenge.rb 0000644 0000041 0000041 00000002546 12772546476 024143 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeHttpAuthChallenge < Mechanize::TestCase
def setup
super
@uri = URI 'http://example/'
@AR = Mechanize::HTTP::AuthRealm
@AC = Mechanize::HTTP::AuthChallenge
@challenge = @AC.new 'Digest', { 'realm' => 'r' }, 'Digest realm=r'
end
def test_realm_basic
@challenge.scheme = 'Basic'
expected = @AR.new 'Basic', @uri, 'r'
assert_equal expected, @challenge.realm(@uri + '/foo')
end
def test_realm_digest
expected = @AR.new 'Digest', @uri, 'r'
assert_equal expected, @challenge.realm(@uri + '/foo')
end
def test_realm_digest_case
challenge = @AC.new 'Digest', { 'realm' => 'R' }, 'Digest realm=R'
expected = @AR.new 'Digest', @uri, 'R'
assert_equal expected, challenge.realm(@uri + '/foo')
end
def test_realm_unknown
@challenge.scheme = 'Unknown'
e = assert_raises Mechanize::Error do
@challenge.realm(@uri + '/foo')
end
assert_equal 'unknown HTTP authentication scheme Unknown', e.message
end
def test_realm_name
assert_equal 'r', @challenge.realm_name
end
def test_realm_name_case
challenge = @AC.new 'Digest', { 'realm' => 'R' }, 'Digest realm=R'
assert_equal 'R', challenge.realm_name
end
def test_realm_name_ntlm
challenge = @AC.new 'Negotiate, NTLM'
assert_nil challenge.realm_name
end
end
mechanize-2.7.5/test/test_mechanize_image.rb 0000644 0000041 0000041 00000000162 12772546476 021213 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeImage < Mechanize::TestCase
# empty subclass, no tests
end
mechanize-2.7.5/test/test_multi_select.rb 0000644 0000041 0000041 00000010214 12772546476 020576 0 ustar www-data www-data require 'mechanize/test_case'
class MultiSelectTest < Mechanize::TestCase
def setup
super
@page = @mech.get("http://localhost/form_multi_select.html")
@form = @page.forms.first
end
def test_option_with
o = @form.field_with(:name => 'list').option_with(:value => '1')
assert_equal '1', o.value
end
def test_options_with
os = @form.field_with(:name => 'list').options_with(:value => /1|2/)
assert_equal ['1', '2'].sort, os.map { |x| x.value }.sort
end
def test_select_none
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.field_with(:name => 'list').select_none
page = @mech.submit(form)
assert_equal(0, page.links.length)
end
def test_select_all
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.field_with(:name => 'list').select_all
page = @mech.submit(form)
assert_equal(6, page.links.length)
assert_equal(1, page.links_with(:text => 'list:1').length)
assert_equal(1, page.links_with(:text => 'list:2').length)
assert_equal(1, page.links_with(:text => 'list:3').length)
assert_equal(1, page.links_with(:text => 'list:4').length)
assert_equal(1, page.links_with(:text => 'list:5').length)
assert_equal(1, page.links_with(:text => 'list:6').length)
end
def test_click_all
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.field_with(:name => 'list').options.each { |o| o.click }
page = @mech.submit(form)
assert_equal(5, page.links.length)
assert_equal(1, page.links_with(:text => 'list:1').length)
assert_equal(1, page.links_with(:text => 'list:3').length)
assert_equal(1, page.links_with(:text => 'list:4').length)
assert_equal(1, page.links_with(:text => 'list:5').length)
assert_equal(1, page.links_with(:text => 'list:6').length)
end
def test_select_default
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
page = @mech.submit(form)
assert_equal(1, page.links.length)
assert_equal(1, page.links_with(:text => 'list:2').length)
end
def test_select_one
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.list = 'Aaron'
assert_equal(['Aaron'], form.list)
page = @mech.submit(form)
assert_equal(1, page.links.length)
assert_equal('list:Aaron', page.links.first.text)
end
def test_select_two
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.list = ['1', 'Aaron']
page = @mech.submit(form)
assert_equal(2, page.links.length)
assert_equal(1, page.links_with(:text => 'list:1').length)
assert_equal(1, page.links_with(:text => 'list:Aaron').length)
end
def test_select_three
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.list = ['1', '2', '3']
page = @mech.submit(form)
assert_equal(3, page.links.length)
assert_equal(1, page.links_with(:text => 'list:1').length)
assert_equal(1, page.links_with(:text => 'list:2').length)
assert_equal(1, page.links_with(:text => 'list:3').length)
end
def test_select_three_twice
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.list = ['1', '2', '3']
form.list = ['1', '2', '3']
page = @mech.submit(form)
assert_equal(3, page.links.length)
assert_equal(1, page.links_with(:text => 'list:1').length)
assert_equal(1, page.links_with(:text => 'list:2').length)
assert_equal(1, page.links_with(:text => 'list:3').length)
end
def test_select_with_click
page = @mech.get("http://localhost/form_multi_select.html")
form = page.forms.first
form.list = ['1', 'Aaron']
form.field_with(:name => 'list').options[3].tick
assert_equal(['1', 'Aaron', '4'].sort, form.list.sort)
page = @mech.submit(form)
assert_equal(3, page.links.length)
assert_equal(1, page.links_with(:text => 'list:1').length)
assert_equal(1, page.links_with(:text => 'list:Aaron').length)
assert_equal(1, page.links_with(:text => 'list:4').length)
end
end
mechanize-2.7.5/test/test_mechanize_form_option.rb 0000644 0000041 0000041 00000002042 12772546476 022463 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFormOption < Mechanize::TestCase
def setup
super
page = html_page <<-BODY
BODY
form = page.forms.first
@select = form.fields.first
@option1 = @select.options.first
@option2 = @select.options.last
end
def test_inspect
assert_match "value: 2", @select.inspect
end
def test_value_missing_value
option = node 'option'
option.inner_html = 'blah'
option = Mechanize::Form::Option.new option, nil
assert_equal 'blah', option.value
end
def test_click
@option1.click
assert @option1.selected?
end
def test_select
@option1.select
assert @option1.selected?
end
def test_unselect
@option2.unselect
refute @option2.selected?
end
def test_selected_eh
refute @option1.selected?
assert @option2.selected?
end
end
mechanize-2.7.5/test/test_mechanize_file_request.rb 0000644 0000041 0000041 00000000746 12772546476 022630 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFileRequest < Mechanize::TestCase
def setup
@uri = URI.parse 'file:///nonexistent'
@r = Mechanize::FileRequest.new @uri
end
def test_initialize
assert_equal @uri, @r.uri
assert_equal '/nonexistent', @r.path
assert_respond_to @r, :[]=
assert_respond_to @r, :add_field
assert_respond_to @r, :each_header
end
def test_response_body_permitted_eh
assert @r.response_body_permitted?
end
end
mechanize-2.7.5/test/test_mechanize_form_encoding.rb 0000644 0000041 0000041 00000006265 12772546476 022754 0 ustar www-data www-data # coding: utf-8
require 'mechanize/test_case'
class TestMechanizeFormEncoding < Mechanize::TestCase
# See also: tests of Util.from_native_charset
# Encoding test should do with non-utf-8 characters
INPUTTED_VALUE = "テスト" # "test" in Japanese UTF-8 encoding
CONTENT_ENCODING = 'Shift_JIS' # one of Japanese encoding
encoded_value = "\x83\x65\x83\x58\x83\x67".force_encoding(::Encoding::SHIFT_JIS) # "test" in Japanese Shift_JIS encoding
EXPECTED_QUERY = "first_name=#{CGI.escape(encoded_value)}&first_name=&gender=&green%5Beggs%5D="
ENCODING_ERRORS = [EncodingError, Encoding::ConverterNotFoundError] # and so on
ENCODING_LOG_MESSAGE = /INFO -- : form encoding: Shift_JIS/
INVALID_ENCODING = 'UTF-eight'
def set_form_with_encoding(enc)
page = @mech.get("http://localhost/form_set_fields.html")
form = page.forms.first
form.encoding = enc
form['first_name'] = INPUTTED_VALUE
form
end
def test_form_encoding_returns_accept_charset
page = @mech.get("http://localhost/rails_3_encoding_hack_form_test.html")
form = page.forms.first
accept_charset = form.form_node['accept-charset']
assert accept_charset
assert_equal accept_charset, form.encoding
refute_equal page.encoding, form.encoding
end
def test_form_encoding_returns_page_encoding_when_no_accept_charset
page = @mech.get("http://localhost/form_set_fields.html")
form = page.forms.first
accept_charset = form.form_node['accept-charset']
assert_nil accept_charset
refute_equal accept_charset, form.encoding
assert_equal page.encoding, form.encoding
end
def test_form_encoding_equals_sets_new_encoding
page = @mech.get("http://localhost/form_set_fields.html")
form = page.forms.first
refute_equal CONTENT_ENCODING, form.encoding
form.encoding = CONTENT_ENCODING
assert_equal CONTENT_ENCODING, form.encoding
end
def test_form_encoding_returns_nil_when_no_page_in_initialize
# this sequence is seen at Mechanize#post(url, query_hash)
node = {}
# Create a fake form
class << node
def search(*args); []; end
end
node['method'] = 'POST'
node['enctype'] = 'application/x-www-form-urlencoded'
form = Mechanize::Form.new(node)
assert_equal nil, form.encoding
end
def test_post_form_with_form_encoding
form = set_form_with_encoding CONTENT_ENCODING
form.submit
# we can not use "links.find{|l| l.text == 'key:val'}" assertion here
# because the link text encoding is always UTF-8 regaredless of html encoding
assert EXPECTED_QUERY, @mech.page.at('div#query').inner_text
end
def test_post_form_with_problematic_encoding
form = set_form_with_encoding INVALID_ENCODING
assert_raises(*ENCODING_ERRORS){ form.submit }
end
def test_form_ignore_encoding_error_is_true
form = set_form_with_encoding INVALID_ENCODING
form.ignore_encoding_error = true
form.submit
# HACK no assertions
end
def test_post_form_logs_form_encoding
sio = StringIO.new
@mech.log = Logger.new(sio)
@mech.log.level = Logger::INFO
form = set_form_with_encoding CONTENT_ENCODING
form.submit
assert_match ENCODING_LOG_MESSAGE, sio.string
@mech.log = nil
end
end
mechanize-2.7.5/test/test_mechanize_cookie_jar.rb 0000644 0000041 0000041 00000042745 12772546476 022253 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeCookieJar < Mechanize::TestCase
def setup
super
@jar = Mechanize::CookieJar.new
end
def cookie_values(options = {})
{
:name => 'Foo',
:value => 'Bar',
:path => '/',
:expires => Time.now + (10 * 86400),
:for_domain => true,
:domain => 'rubyforge.org'
}.merge(options)
end
def test_two_cookies_same_domain_and_name_different_paths
url = URI 'http://rubyforge.org/'
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
@jar.add(url, Mechanize::Cookie.new(cookie_values(:path => '/onetwo')))
assert_equal(1, @jar.cookies(url).length)
assert_equal 2, @jar.cookies(URI('http://rubyforge.org/onetwo')).length
end
def test_domain_case
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
@jar.add(url, Mechanize::Cookie.new(
cookie_values(:domain => 'RuByForge.Org', :name => 'aaron')))
assert_equal(2, @jar.cookies(url).length)
url2 = URI 'http://RuByFoRgE.oRg/'
assert_equal(2, @jar.cookies(url2).length)
end
def test_host_only
url = URI.parse('http://rubyforge.org/')
@jar.add(url, Mechanize::Cookie.new(
cookie_values(:domain => 'rubyforge.org', :for_domain => false)))
assert_equal(1, @jar.cookies(url).length)
assert_equal(1, @jar.cookies(URI('http://RubyForge.org/')).length)
assert_equal(1, @jar.cookies(URI('https://RubyForge.org/')).length)
assert_equal(0, @jar.cookies(URI('http://www.rubyforge.org/')).length)
end
def test_empty_value
values = cookie_values(:value => "")
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
@jar.add url, Mechanize::Cookie.new(values.merge(:domain => 'RuByForge.Org',
:name => 'aaron'))
assert_equal(2, @jar.cookies(url).length)
url2 = URI 'http://RuByFoRgE.oRg/'
assert_equal(2, @jar.cookies(url2).length)
end
def test_add_future_cookies
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
# Add the same cookie, and we should still only have one
@jar.add(url, Mechanize::Cookie.new(cookie_values))
assert_equal(1, @jar.cookies(url).length)
# Make sure we can get the cookie from different paths
assert_equal(1, @jar.cookies(URI('http://rubyforge.org/login')).length)
# Make sure we can't get the cookie from different domains
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
end
def test_add_multiple_cookies
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
# Add the same cookie, and we should still only have one
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(2, @jar.cookies(url).length)
# Make sure we can get the cookie from different paths
assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
# Make sure we can't get the cookie from different domains
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
end
def test_add_rejects_cookies_that_do_not_contain_an_embedded_dot
url = URI 'http://rubyforge.org/'
tld_cookie = Mechanize::Cookie.new(cookie_values(:domain => '.org'))
@jar.add(url, tld_cookie)
# single dot domain is now treated as no domain
# single_dot_cookie = Mechanize::Cookie.new(cookie_values(:domain => '.'))
# @jar.add(url, single_dot_cookie)
assert_equal(0, @jar.cookies(url).length)
end
def test_fall_back_rules_for_local_domains
url = URI 'http://www.example.local'
tld_cookie = Mechanize::Cookie.new(cookie_values(:domain => '.local'))
@jar.add(url, tld_cookie)
assert_equal(0, @jar.cookies(url).length)
sld_cookie = Mechanize::Cookie.new(cookie_values(:domain => '.example.local'))
@jar.add(url, sld_cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_add_makes_exception_for_localhost
url = URI 'http://localhost'
tld_cookie = Mechanize::Cookie.new(cookie_values(:domain => 'localhost'))
@jar.add(url, tld_cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_add_cookie_for_the_parent_domain
url = URI 'http://x.foo.com'
cookie = Mechanize::Cookie.new(cookie_values(:domain => '.foo.com'))
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_add_does_not_reject_cookies_from_a_nested_subdomain
url = URI 'http://y.x.foo.com'
cookie = Mechanize::Cookie.new(cookie_values(:domain => '.foo.com'))
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_cookie_without_leading_dot_does_not_cause_substring_match
url = URI 'http://arubyforge.org/'
cookie = Mechanize::Cookie.new(cookie_values(:domain => 'rubyforge.org'))
@jar.add(url, cookie)
assert_equal(0, @jar.cookies(url).length)
end
def test_cookie_without_leading_dot_matches_subdomains
url = URI 'http://admin.rubyforge.org/'
cookie = Mechanize::Cookie.new(cookie_values(:domain => 'rubyforge.org'))
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_cookies_with_leading_dot_match_subdomains
url = URI 'http://admin.rubyforge.org/'
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
assert_equal(1, @jar.cookies(url).length)
end
def test_cookies_with_leading_dot_match_parent_domains
url = URI 'http://rubyforge.org/'
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
assert_equal(1, @jar.cookies(url).length)
end
def test_cookies_with_leading_dot_match_parent_domains_exactly
url = URI 'http://arubyforge.org/'
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
assert_equal(0, @jar.cookies(url).length)
end
def test_cookie_for_ipv4_address_matches_the_exact_ipaddress
url = URI 'http://192.168.0.1/'
cookie = Mechanize::Cookie.new(cookie_values(:domain => '192.168.0.1'))
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_cookie_for_ipv4_address_does_not_cause_subdomain_match
url = URI 'http://192.168.0.1/'
cookie = Mechanize::Cookie.new(cookie_values(:domain => '.0.1'))
@jar.add(url, cookie)
assert_equal(0, @jar.cookies(url).length)
end
def test_cookie_for_ipv6_address_matches_the_exact_ipaddress
url = URI 'http://[fe80::0123:4567:89ab:cdef]/'
cookie = Mechanize::Cookie.new(cookie_values(:domain => '[fe80::0123:4567:89ab:cdef]'))
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
end
def test_cookies_dot
url = URI 'http://www.host.example/'
@jar.add(url,
Mechanize::Cookie.new(cookie_values(:domain => 'www.host.example')))
url = URI 'http://wwwxhost.example/'
assert_equal(0, @jar.cookies(url).length)
end
def test_clear_bang
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(2, @jar.cookies(url).length)
@jar.clear!
assert_equal(0, @jar.cookies(url).length)
end
def test_save_cookies_yaml
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
s_cookie = Mechanize::Cookie.new(cookie_values(:name => 'Bar',
:expires => nil,
:session => true))
@jar.add(url, cookie)
@jar.add(url, s_cookie)
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(3, @jar.cookies(url).length)
in_tmpdir do
value = @jar.save_as("cookies.yml")
assert_same @jar, value
jar = Mechanize::CookieJar.new
jar.load("cookies.yml")
assert_equal(2, jar.cookies(url).length)
end
assert_equal(3, @jar.cookies(url).length)
end
def test_save_session_cookies_yaml
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
s_cookie = Mechanize::Cookie.new(cookie_values(:name => 'Bar',
:expires => nil,
:session => true))
@jar.add(url, cookie)
@jar.add(url, s_cookie)
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(3, @jar.cookies(url).length)
in_tmpdir do
@jar.save_as("cookies.yml", :format => :yaml, :session => true)
jar = Mechanize::CookieJar.new
jar.load("cookies.yml")
assert_equal(3, jar.cookies(url).length)
end
assert_equal(3, @jar.cookies(url).length)
end
def test_save_cookies_cookiestxt
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
s_cookie = Mechanize::Cookie.new(cookie_values(:name => 'Bar',
:expires => nil,
:session => true))
@jar.add(url, cookie)
@jar.add(url, s_cookie)
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(3, @jar.cookies(url).length)
in_tmpdir do
@jar.save_as("cookies.txt", :cookiestxt)
assert_match(/\A# (?:Netscape )?HTTP Cookie File$/, File.read("cookies.txt"))
jar = Mechanize::CookieJar.new
jar.load("cookies.txt", :cookiestxt)
assert_equal(2, jar.cookies(url).length)
end
in_tmpdir do
@jar.save_as("cookies.txt", :cookiestxt, :session => true)
assert_match(/\A# (?:Netscape )?HTTP Cookie File$/, File.read("cookies.txt"))
jar = Mechanize::CookieJar.new
jar.load("cookies.txt", :cookiestxt)
assert_equal(3, jar.cookies(url).length)
end
assert_equal(3, @jar.cookies(url).length)
end
def test_expire_cookies
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
# Add a second cookie
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(2, @jar.cookies(url).length)
# Make sure we can get the cookie from different paths
assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
# Expire the first cookie
@jar.add(url, Mechanize::Cookie.new(
cookie_values(:expires => Time.now - (10 * 86400))))
assert_equal(1, @jar.cookies(url).length)
# Expire the second cookie
@jar.add(url, Mechanize::Cookie.new(
cookie_values( :name => 'Baz', :expires => Time.now - (10 * 86400))))
assert_equal(0, @jar.cookies(url).length)
end
def test_session_cookies
values = cookie_values(:expires => nil)
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
# Add a second cookie
@jar.add(url, Mechanize::Cookie.new(values.merge(:name => 'Baz')))
assert_equal(2, @jar.cookies(url).length)
# Make sure we can get the cookie from different paths
assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
# Expire the first cookie
@jar.add(url, Mechanize::Cookie.new(values.merge(:expires => Time.now - (10 * 86400))))
assert_equal(1, @jar.cookies(url).length)
# Expire the second cookie
@jar.add(url, Mechanize::Cookie.new(
values.merge(:name => 'Baz', :expires => Time.now - (10 * 86400))))
assert_equal(0, @jar.cookies(url).length)
# When given a URI with a blank path, CookieJar#cookies should return
# cookies with the path '/':
url = URI 'http://rubyforge.org'
assert_equal '', url.path
assert_equal(0, @jar.cookies(url).length)
# Now add a cookie with the path set to '/':
@jar.add(url, Mechanize::Cookie.new(values.merge( :name => 'has_root_path',
:path => '/')))
assert_equal(1, @jar.cookies(url).length)
end
def test_paths
values = cookie_values(:path => "/login", :expires => nil)
url = URI 'http://rubyforge.org/login'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length)
# Add a second cookie
@jar.add(url, Mechanize::Cookie.new(values.merge( :name => 'Baz' )))
assert_equal(2, @jar.cookies(url).length)
# Make sure we don't get the cookie in a different path
assert_equal(0, @jar.cookies(URI('http://rubyforge.org/hello')).length)
assert_equal(0, @jar.cookies(URI('http://rubyforge.org/')).length)
# Expire the first cookie
@jar.add(url, Mechanize::Cookie.new(values.merge( :expires => Time.now - (10 * 86400))))
assert_equal(1, @jar.cookies(url).length)
# Expire the second cookie
@jar.add(url, Mechanize::Cookie.new(values.merge( :name => 'Baz',
:expires => Time.now - (10 * 86400))))
assert_equal(0, @jar.cookies(url).length)
end
def test_save_and_read_cookiestxt
url = URI 'http://rubyforge.org/'
# Add one cookie with an expiration date in the future
cookie = Mechanize::Cookie.new(cookie_values)
@jar.add(url, cookie)
@jar.add(url, Mechanize::Cookie.new(cookie_values(:name => 'Baz')))
assert_equal(2, @jar.cookies(url).length)
in_tmpdir do
@jar.save_as("cookies.txt", :cookiestxt)
@jar.clear!
@jar.load("cookies.txt", :cookiestxt)
end
assert_equal(2, @jar.cookies(url).length)
end
def test_save_and_read_cookiestxt_with_session_cookies
url = URI 'http://rubyforge.org/'
@jar.add(url, Mechanize::Cookie.new(cookie_values(:expires => nil)))
in_tmpdir do
@jar.save_as("cookies.txt", :cookiestxt)
@jar.clear!
@jar.load("cookies.txt", :cookiestxt)
end
assert_equal(0, @jar.cookies(url).length)
end
def test_save_and_read_expired_cookies
url = URI 'http://rubyforge.org/'
@jar.jar['rubyforge.org'] = {}
@jar.add url, Mechanize::Cookie.new(cookie_values)
# HACK no asertion
end
def test_ssl_cookies
# thanks to michal "ocher" ochman for reporting the bug responsible for this test.
values = cookie_values(:expires => nil)
values_ssl = values.merge(:name => 'Baz', :domain => "#{values[:domain]}:443")
url = URI 'https://rubyforge.org/login'
cookie = Mechanize::Cookie.new(values)
@jar.add(url, cookie)
assert_equal(1, @jar.cookies(url).length, "did not handle SSL cookie")
cookie = Mechanize::Cookie.new(values_ssl)
@jar.add(url, cookie)
assert_equal(2, @jar.cookies(url).length, "did not handle SSL cookie with :443")
end
def test_secure_cookie
nurl = URI 'http://rubyforge.org/login'
surl = URI 'https://rubyforge.org/login'
ncookie = Mechanize::Cookie.new(cookie_values(:name => 'Foo1'))
scookie = Mechanize::Cookie.new(cookie_values(:name => 'Foo2', :secure => true))
@jar.add(nurl, ncookie)
@jar.add(nurl, scookie)
@jar.add(surl, ncookie)
@jar.add(surl, scookie)
assert_equal('Foo1', @jar.cookies(nurl).map { |c| c.name }.sort.join(' ') )
assert_equal('Foo1 Foo2', @jar.cookies(surl).map { |c| c.name }.sort.join(' ') )
end
def test_save_cookies_cookiestxt_subdomain
top_url = URI 'http://rubyforge.org/'
subdomain_url = URI 'http://admin.rubyforge.org/'
# cookie1 is for *.rubyforge.org; cookie2 is only for rubyforge.org, no subdomains
cookie1 = Mechanize::Cookie.new(cookie_values)
cookie2 = Mechanize::Cookie.new(cookie_values(:name => 'Boo', :for_domain => false))
@jar.add(top_url, cookie1)
@jar.add(top_url, cookie2)
assert_equal(2, @jar.cookies(top_url).length)
assert_equal(1, @jar.cookies(subdomain_url).length)
in_tmpdir do
@jar.save_as("cookies.txt", :cookiestxt)
jar = Mechanize::CookieJar.new
jar.load("cookies.txt", :cookiestxt) # HACK test the format
assert_equal(2, jar.cookies(top_url).length)
assert_equal(1, jar.cookies(subdomain_url).length)
# Check that we actually wrote the file correctly (not just that we were
# able to read what we wrote):
#
# * Cookies that only match exactly the domain specified must not have a
# leading dot, and must have FALSE as the second field.
# * Cookies that match subdomains may have a leading dot, and must have
# TRUE as the second field.
cookies_txt = File.readlines("cookies.txt")
assert_equal(1, cookies_txt.grep( /^rubyforge\.org\tFALSE/ ).length)
assert_equal(1, cookies_txt.grep( /^\.rubyforge\.org\tTRUE/ ).length)
end
assert_equal(2, @jar.cookies(top_url).length)
assert_equal(1, @jar.cookies(subdomain_url).length)
end
end
mechanize-2.7.5/test/test_mechanize_util.rb 0000644 0000041 0000041 00000007654 12772546476 021123 0 ustar www-data www-data # coding: utf-8
require 'mechanize/test_case'
class TestMechanizeUtil < Mechanize::TestCase
INPUTTED_VALUE = "テスト" # "test" in Japanese UTF-8 encoding
CONTENT_ENCODING = 'Shift_JIS' # one of Japanese encoding
ENCODED_VALUE = "\x83\x65\x83\x58\x83\x67".force_encoding(::Encoding::SHIFT_JIS) # "test" in Japanese Shift_JIS encoding
ENCODING_ERRORS = [EncodingError, Encoding::ConverterNotFoundError] # and so on
ERROR_LOG_MESSAGE = /from_native_charset: Encoding::ConverterNotFoundError: form encoding: "UTF-eight"/
INVALID_ENCODING = 'UTF-eight'
def setup
super
@MU = Mechanize::Util
@result = "not set"
end
def test_from_native_charset
@result = @MU.from_native_charset(INPUTTED_VALUE, CONTENT_ENCODING)
assert_equal ENCODED_VALUE, @result
end
def test_from_native_charset_returns_nil_when_no_string
@result = @MU.from_native_charset(nil, CONTENT_ENCODING)
assert_equal nil, @result
end
def test_from_native_charset_doesnot_convert_when_no_encoding
@result = @MU.from_native_charset(INPUTTED_VALUE, nil)
refute_equal ENCODED_VALUE, @result
assert_equal INPUTTED_VALUE, @result
end
def test_from_native_charset_doesnot_convert_when_not_nokogiri
parser = Mechanize.html_parser
Mechanize.html_parser = 'Another HTML Parser'
@result = @MU.from_native_charset(INPUTTED_VALUE, CONTENT_ENCODING)
refute_equal ENCODED_VALUE, @result
assert_equal INPUTTED_VALUE, @result
ensure
Mechanize.html_parser = parser
end
def test_from_native_charset_raises_error_with_bad_encoding
assert_raises(*ENCODING_ERRORS) do
@MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING)
end
end
def test_from_native_charset_suppress_encoding_error_when_3rd_arg_is_true
@MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, true)
# HACK no assertion
end
def test_from_native_charset_doesnot_convert_when_encoding_error_raised_and_ignored
@result = @MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, true)
refute_equal ENCODED_VALUE, @result
assert_equal INPUTTED_VALUE, @result
end
def test_from_native_charset_logs_form_when_encoding_error_raised
sio = StringIO.new("")
log = Logger.new(sio)
log.level = Logger::DEBUG
assert_raises(*ENCODING_ERRORS) do
@MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, nil, log)
end
assert_match ERROR_LOG_MESSAGE, sio.string
end
def test_from_native_charset_logs_form_when_encoding_error_is_ignored
sio = StringIO.new("")
log = Logger.new(sio)
log.level = Logger::DEBUG
@MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, true, log)
assert_match ERROR_LOG_MESSAGE, sio.string
end
def test_self_html_unescape_entity
assert_equal '&', @MU::html_unescape('&')
assert_equal '&', @MU::html_unescape('&')
end
def test_uri_escape
assert_equal "%25", @MU.uri_escape("%")
assert_equal "%", @MU.uri_escape("%", /[^%]/)
end
def test_build_query_string_simple
input_params = [
[:ids, 1],
[:action, 'delete'],
[:ids, 5],
]
expected_params = [
['ids', '1'],
['action', 'delete'],
['ids', '5'],
]
query = @MU.build_query_string(input_params)
assert_equal expected_params, URI.decode_www_form(query)
end
def test_build_query_string_complex
input_params = {
number: 7,
name: "\u{6B66}\u{8005}",
"ids[]" => [1, 3, 5, 7],
words: ["Sing", "Now!"],
params: { x: "50%", y: "100%", t: [80, 160] },
}
expected_params = [
['number', '7'],
['name', "\u{6B66}\u{8005}"],
['ids[]', '1'], ['ids[]', '3'], ['ids[]', '5'], ['ids[]', '7'],
['words', 'Sing'], ['words', 'Now!'],
['params[x]', '50%'],
['params[y]', '100%'],
['params[t]', '80'], ['params[t]', '160'],
]
query = @MU.build_query_string(input_params)
assert_equal expected_params, URI.decode_www_form(query)
end
end
mechanize-2.7.5/test/test_mechanize_form_multi_select_list.rb 0000644 0000041 0000041 00000003664 12772546476 024712 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFormMultiSelectList < Mechanize::TestCase
def setup
super
page = html_page <<-BODY
BODY
form = page.forms.first
@select = form.fields.first
end
def test_inspect
assert_match "value: #{%w[2]}", @select.inspect
end
def test_inspect_select_all
@select.select_all
assert_match "value: #{%w[1 2 3 4 5 6]}", @select.inspect
end
def test_option_with
option = @select.option_with :value => '1'
assert_equal '1', option.value
end
def test_options_with
options = @select.options_with :value => /[12]/
assert_equal 2, options.length
end
def test_query_value
assert_equal [%w[select 2]], @select.query_value
@select.options.last.click
assert_equal [%w[select 2], %w[select 6]], @select.query_value
end
def test_query_value_empty
@select.options.last.click
@select.options.last.instance_variable_set :@value, ''
assert_equal [%w[select 2], ['select', '']], @select.query_value
end
def test_select_all
@select.select_all
assert_equal %w[1 2 3 4 5 6], @select.value
end
def test_select_none
@select.select_none
assert_empty @select.value
end
def test_selected_options
assert_equal [@select.options[1]], @select.selected_options
@select.options.last.click
assert_equal [@select.options[1], @select.options.last],
@select.selected_options
end
def test_value
assert_equal %w[2], @select.value
end
def test_value_equals
@select.value = %w[a 1 2]
assert_equal %w[a 1 2], @select.value
end
end
mechanize-2.7.5/test/test_mechanize_http_auth_realm.rb 0000644 0000041 0000041 00000002063 12772546476 023313 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeHttpAuthRealm < Mechanize::TestCase
def setup
super
@uri = URI 'http://example/'
@AR = Mechanize::HTTP::AuthRealm
@realm = @AR.new 'Digest', @uri, 'r'
end
def test_initialize
assert_equal 'r', @realm.realm
realm = @AR.new 'Digest', @uri, 'R'
refute_equal 'r', realm.realm
realm = @AR.new 'Digest', @uri, 'R'
assert_equal 'R', realm.realm
realm = @AR.new 'Digest', @uri, nil
assert_nil realm.realm
end
def test_equals2
other = @realm.dup
assert_equal @realm, other
other = @AR.new 'Basic', @uri, 'r'
refute_equal @realm, other
other = @AR.new 'Digest', URI('http://other.example/'), 'r'
refute_equal @realm, other
other = @AR.new 'Digest', @uri, 'R'
refute_equal @realm, other
other = @AR.new 'Digest', @uri, 's'
refute_equal @realm, other
end
def test_hash
h = {}
h[@realm] = 1
other = @realm.dup
assert_equal 1, h[other]
other = @AR.new 'Basic', @uri, 'r'
assert_nil h[other]
end
end
mechanize-2.7.5/test/test_mechanize_page_meta_refresh.rb 0000644 0000041 0000041 00000007732 12772546476 023603 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizePageMetaRefresh < Mechanize::TestCase
def setup
super
@MR = Mechanize::Page::MetaRefresh
@uri = URI 'http://example/here/'
end
def util_page delay, uri
body = <<-BODY
BODY
Mechanize::Page.new(@uri, nil, body, 200, @mech)
end
def util_meta_refresh page
node = page.search('meta').first
@MR.from_node node, page
end
def test_class_parse
delay, uri, link_self = @MR.parse "0; url=http://localhost:8080/path", @uri
assert_equal "0", delay
assert_equal "http://localhost:8080/path", uri.to_s
refute link_self
delay, uri, link_self =
@MR.parse "100.001; url=http://localhost:8080/path", @uri
assert_equal "100.001", delay
assert_equal "http://localhost:8080/path", uri.to_s
refute link_self
delay, uri, link_self =
@MR.parse "0; url='http://localhost:8080/path'", @uri
assert_equal "0", delay
assert_equal "http://localhost:8080/path", uri.to_s
refute link_self
delay, uri, link_self =
@MR.parse "0; url=\"http://localhost:8080/path\"", @uri
assert_equal "0", delay
assert_equal "http://localhost:8080/path", uri.to_s
refute link_self
delay, uri, link_self = @MR.parse "0; url=", @uri
assert_equal "0", delay
assert_equal "http://example/here/", uri.to_s
assert link_self
delay, uri, link_self = @MR.parse "0", @uri
assert_equal "0", delay
assert_equal "http://example/here/", uri.to_s
assert link_self
delay, uri, link_self = @MR.parse " 0; ", @uri
assert_equal "0", delay
assert_equal "http://example/here/", uri.to_s
assert link_self
delay, uri, link_self = @MR.parse " 0 ; ", @uri
assert_equal "0", delay
assert_equal "http://example/here/", uri.to_s
assert link_self
delay, uri, link_self = @MR.parse "0; UrL=http://localhost:8080/path", @uri
assert_equal "0", delay
assert_equal "http://localhost:8080/path", uri.to_s
refute link_self
delay, uri, link_self = @MR.parse "0 ; UrL = http://localhost:8080/path", @uri
assert_equal "0", delay
assert_equal "http://localhost:8080/path", uri.to_s
refute link_self
end
def test_class_parse_funky
delay, uri, link_self = @MR.parse "0; url=/funky?Welcome<%2Fb>", @uri
assert_equal "0", delay
assert_equal "http://example/funky?%3Cb%3EWelcome%3C%2Fb%3E",
uri.to_s
refute link_self
end
def test_class_from_node
page = util_page 5, 'http://b.example'
link = util_meta_refresh page
assert_equal 5, link.delay
assert_equal 'http://b.example', link.href
page = util_page 5, 'http://example/a'
link = util_meta_refresh page
assert_equal 5, link.delay
assert_equal 'http://example/a', link.href
page = util_page 5, 'test'
link = util_meta_refresh page
assert_equal 5, link.delay
assert_equal 'test', link.href
page = util_page 5, '/test'
link = util_meta_refresh page
assert_equal 5, link.delay
assert_equal '/test', link.href
page = util_page 5, nil
link = util_meta_refresh page
assert_equal 5, link.delay
assert_equal nil, link.href
page = util_page 5, @uri
link = util_meta_refresh page
assert_equal 5, link.delay
assert_equal 'http://example/here/', link.href
end
def test_class_from_node_no_content
body = <<-BODY
BODY
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
assert_nil util_meta_refresh page
end
def test_class_from_node_not_refresh
body = <<-BODY
BODY
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
assert_nil util_meta_refresh page
end
def test_meta_refresh_click_sends_no_referer
page = util_page 0, '/referer'
link = util_meta_refresh page
refreshed = link.click
assert_equal '', refreshed.body
end
end
mechanize-2.7.5/test/test_mechanize_file.rb 0000644 0000041 0000041 00000004654 12772546476 021062 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeFile < Mechanize::TestCase
def setup
super
@parser = Mechanize::File
end
def test_save
uri = URI 'http://example/name.html'
page = Mechanize::File.new uri, nil, '0123456789'
Dir.mktmpdir do |dir|
Dir.chdir dir do
filename = page.save 'test.html'
assert File.exist? 'test.html'
assert_equal '0123456789', File.read('test.html')
assert_equal "test.html", filename
filename = page.save 'test.html'
assert File.exist? 'test.html.1'
assert_equal '0123456789', File.read('test.html.1')
assert_equal "test.html.1", filename
filename = page.save 'test.html'
assert File.exist? 'test.html.2'
assert_equal '0123456789', File.read('test.html.2')
assert_equal "test.html.2", filename
end
end
end
def test_save_default
uri = URI 'http://example/test.html'
page = Mechanize::File.new uri, nil, ''
Dir.mktmpdir do |dir|
Dir.chdir dir do
filename = page.save
assert File.exist? 'test.html'
assert_equal "test.html", filename
filename = page.save
assert File.exist? 'test.html.1'
assert_equal "test.html.1", filename
filename = page.save
assert File.exist? 'test.html.2'
assert_equal "test.html.2", filename
end
end
end
def test_save_default_dots
uri = URI 'http://localhost/../test.html'
page = Mechanize::File.new uri, nil, ''
Dir.mktmpdir do |dir|
Dir.chdir dir do
filename = page.save
assert File.exist? 'test.html'
assert_equal "test.html", filename
filename = page.save
assert File.exist? 'test.html.1'
assert_equal "test.html.1", filename
end
end
end
def test_filename
uri = URI 'http://localhost/test.html'
page = Mechanize::File.new uri, nil, ''
assert_equal "test.html", page.filename
end
def test_save_overwrite
uri = URI 'http://example/test.html'
page = Mechanize::File.new uri, nil, ''
Dir.mktmpdir do |dir|
Dir.chdir dir do
filename = page.save 'test.html'
assert File.exist? 'test.html'
assert_equal "test.html", filename
filename = page.save! 'test.html'
assert File.exist? 'test.html'
refute File.exist? 'test.html.1'
assert_equal "test.html", filename
end
end
end
end
mechanize-2.7.5/test/test_mechanize_xml_file.rb 0000644 0000041 0000041 00000001077 12772546476 021736 0 ustar www-data www-data require 'mechanize/test_case'
class TestMechanizeXmlFile < Mechanize::TestCase
def setup
super
uri = URI 'http://example.com/foo.xml'
@xml = Mechanize::XmlFile.new uri, nil, <<-XML
Do not follow this or this! BODY page.links[0].click page.links[1].click @mech.robots = true assert_raises Mechanize::RobotsDisallowedError do page.links[0].click end assert_raises Mechanize::RobotsDisallowedError do page.links[1].click end end def test_click_link_noreferrer link = node 'a', 'href' => '/index.html', 'rel' => 'noreferrer' link = Mechanize::Page::Link.new link, @mech, fake_page @mech.click link assert_nil requests.first['referer'] end def test_click_link_rel_nofollow page = html_page <<-BODY
You can follow this link but not this! BODY page.links[0].click page.links[1].click @mech.robots = true page.links[0].click assert_raises Mechanize::RobotsDisallowedError do page.links[1].click end end def test_click_link_parent page = page URI 'http://example/a/index.html' link = node 'a', 'href' => '../index.html' link = Mechanize::Page::Link.new link, @mech, page @mech.click link assert_equal '/index.html', requests.first.path end def test_click_link_parent_extra page = page URI 'http://example/a/index.html' link = node 'a', 'href' => '../../index.html' link = Mechanize::Page::Link.new link, @mech, page @mech.click link assert_equal '/index.html', requests.first.path end def test_click_link_hpricot_style # HACK move to test_search in Page page = @mech.get("http://localhost/tc_encoded_links.html") page = @mech.click(page.search('a').first) assert_equal("http://localhost/form_post?a=b&b=c", page.uri.to_s) end def test_click_link_query page = @mech.get("http://localhost/tc_encoded_links.html") link = page.links.first assert_equal('/form_post?a=b&b=c', link.href) page = @mech.click(link) assert_equal("http://localhost/form_post?a=b&b=c", page.uri.to_s) end def test_click_link_space page = @mech.get("http://localhost/tc_bad_links.html") @mech.click page.links.first assert_match(/alt_text.html$/, @mech.history.last.uri.to_s) assert_equal(2, @mech.history.length) end def test_click_more @mech.get 'http://localhost/test_click.html' @mech.click 'A Button' assert_equal 'http://localhost/frame_test.html?words=nil', @mech.page.uri.to_s @mech.back @mech.click 'A Link' assert_equal 'http://localhost/index.html', @mech.page.uri.to_s @mech.back @mech.click @mech.page.link_with(:text => 'A Link') assert_equal 'http://localhost/index.html', @mech.page.uri.to_s end def test_cookies uri = URI 'http://example' jar = HTTP::CookieJar.new jar.parse 'a=b', uri @mech.cookie_jar = jar refute_empty @mech.cookies end def test_cookie_jar assert_kind_of Mechanize::CookieJar, @mech.cookie_jar jar = HTTP::CookieJar.new @mech.cookie_jar = jar assert_equal jar, @mech.cookie_jar end def test_delete page = @mech.delete('http://localhost/verb', { 'q' => 'foo' }) assert_equal 1, @mech.history.length assert_equal 'DELETE', page.header['X-Request-Method'] end def test_delete_redirect page = @mech.delete('http://localhost/redirect') assert_equal(page.uri.to_s, 'http://localhost/verb') assert_equal 'GET', page.header['X-Request-Method'] end def test_download page = nil in_tmpdir do open 'download', 'w' do |io| page = @mech.download 'http://example', io refute io.closed? end assert_operator 1, :<=, File.stat('download').size end assert_empty @mech.history assert_kind_of Mechanize::Page, page end def test_download_filename page = nil in_tmpdir do page = @mech.download 'http://example', 'download' assert_operator 1, :<=, File.stat('download').size end assert_empty @mech.history assert_kind_of Mechanize::Page, page end def test_download_filename_error in_tmpdir do assert_raises Mechanize::UnauthorizedError do @mech.download 'http://example/digest_auth', 'download' end refute File.exist? 'download' end end def test_get uri = URI 'http://localhost' page = @mech.get uri, { :q => 'h' }, 'http://example', { 'X-H' => 'v' } assert_equal URI('http://localhost/?q=h'), page.uri assert_equal URI('http://localhost'), uri end def test_get_HTTP page = @mech.get('HTTP://localhost/', { :q => 'hello' }) assert_kind_of URI::HTTP, page.uri assert_equal 'localhost', page.uri.host assert_equal 80, page.uri.port assert_equal '/?q=hello', page.uri.request_uri end def test_get_anchor page = @mech.get('http://localhost/?foo=bar"') assert_equal('http://localhost/?foo=bar%22', page.uri.to_s) end def test_get_bad_url assert_raises ArgumentError do @mech.get '/foo.html' end end def test_get_auth @mech.add_auth @uri, 'user', 'pass' page = @mech.get @uri + '/basic_auth' assert_equal 'You are authenticated', page.body end def test_get_auth_bad @mech.add_auth(@uri, 'aaron', 'aaron') e = assert_raises Mechanize::UnauthorizedError do @mech.get(@uri + '/basic_auth') end assert_equal("401", e.response_code) end def test_get_auth_none e = assert_raises Mechanize::UnauthorizedError do @mech.get(@uri + '/basic_auth') end assert_equal("401", e.response_code) end def test_get_auth_realm @mech.add_auth @uri, 'user', 'pass', 'Blah' page = @mech.get @uri + '/basic_auth' assert_equal 'You are authenticated', page.body end def test_get_conditional assert_empty @mech.history page = @mech.get 'http://localhost/if_modified_since' assert_match(/You did not send/, page.body) assert_equal 1, @mech.history.length page2 = @mech.get 'http://localhost/if_modified_since' assert_equal 2, @mech.history.length assert_equal page.object_id, page2.object_id end def test_get_digest_auth @mech.add_auth @uri, 'user', 'pass' page = @mech.get @uri + '/digest_auth' assert_equal 'You are authenticated', page.body end def test_get_follow_meta_refresh @mech.follow_meta_refresh = true page = @mech.get('http://localhost/tc_follow_meta.html') assert_equal(2, @mech.history.length) assert_equal('http://localhost/tc_follow_meta.html', @mech.history.first.uri.to_s) assert_equal('http://localhost/index.html', page.uri.to_s) assert_equal('http://localhost/index.html', @mech.history.last.uri.to_s) [5, 6].each { |limit| @mech.redirection_limit = limit begin @mech.get('http://localhost/tc_follow_meta_loop_1.html') rescue => e assert_instance_of Mechanize::RedirectLimitReachedError, e assert_equal limit, e.redirects if limit % 2 == 0 assert_equal '/tc_follow_meta_loop_1.html', e.page.uri.path else assert_equal '/tc_follow_meta_loop_2.html', e.page.uri.path end end } end def test_get_follow_meta_refresh_anywhere @mech.follow_meta_refresh = :anywhere @mech.get('http://localhost/tc_meta_in_body.html') assert_equal 2, requests.length end def test_get_follow_meta_refresh_disabled page = @mech.get('http://localhost/tc_follow_meta.html') assert_equal('http://localhost/tc_follow_meta.html', page.uri.to_s) assert_equal(1, page.meta_refresh.length) end def test_get_follow_meta_refresh_empty_url @mech.follow_meta_refresh = true @mech.follow_meta_refresh_self = true page = @mech.get('http://example/refresh_with_empty_url') assert_equal(3, @mech.history.length) assert_equal('http://example/refresh_with_empty_url', @mech.history[0].uri.to_s) assert_equal('http://example/refresh_with_empty_url', @mech.history[1].uri.to_s) assert_equal('http://example/', page.uri.to_s) assert_equal('http://example/', @mech.history.last.uri.to_s) end def test_get_follow_meta_refresh_in_body @mech.follow_meta_refresh = true @mech.get('http://localhost/tc_meta_in_body.html') assert_equal 1, requests.length end def test_get_follow_meta_refresh_no_url @mech.follow_meta_refresh = true @mech.follow_meta_refresh_self = true page = @mech.get('http://example/refresh_without_url') assert_equal(3, @mech.history.length) assert_equal('http://example/refresh_without_url', @mech.history[0].uri.to_s) assert_equal('http://example/refresh_without_url', @mech.history[1].uri.to_s) assert_equal('http://example/', page.uri.to_s) assert_equal('http://example/', @mech.history.last.uri.to_s) end def test_get_follow_meta_refresh_referer_not_sent @mech.follow_meta_refresh = true @mech.get('http://localhost/tc_follow_meta.html') assert_equal 2, @mech.history.length assert_nil requests.last['referer'] end def test_get_referer_download download = Mechanize::Download.new URI 'http://example/prev' uri = URI 'http://example' page = @mech.get uri, { :q => 'h' }, download, { 'X-H' => 'v' } assert_equal URI('http://example/?q=h'), page.uri assert_equal URI('http://example'), uri assert_equal 'http://example/prev', requests.first['referer'] end def test_get_robots @mech.robots = true assert_equal "Page Title", @mech.get("http://localhost/index.html").title assert_raises Mechanize::RobotsDisallowedError do @mech.get "http://localhost/norobots.html" end end def test_follow_meta_refresh_self refute @mech.agent.follow_meta_refresh_self @mech.follow_meta_refresh_self = true assert @mech.agent.follow_meta_refresh_self end def test_get_gzip page = @mech.get("http://localhost/gzip?file=index.html") assert_kind_of(Mechanize::Page, page) assert_match('Hello World', page.body) end def test_content_encoding_hooks_header h = {'X-ResponseContentEncoding' => 'agzip'} # test of X-ResponseContentEncoding feature assert_raises(Mechanize::Error, 'Unsupported Content-Encoding: agzip') do @mech.get("http://localhost/gzip?file=index.html", nil, nil, h) end @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io| response['content-encoding'] = 'gzip' if response['content-encoding'] == 'agzip'} page = @mech.get("http://localhost/gzip?file=index.html", nil, nil, h) assert_match('Hello World', page.body) end def external_cmd(io); Zlib::GzipReader.new(io).read; end def test_content_encoding_hooks_body_io h = {'X-ResponseContentEncoding' => 'unsupported_content_encoding'} @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io| if response['content-encoding'] == 'unsupported_content_encoding' response['content-encoding'] = 'none' response_body_io.string = external_cmd(response_body_io) end} page = @mech.get("http://localhost/gzip?file=index.html", nil, nil, h) assert_match('Hello World', page.body) end def test_get_http_refresh @mech.follow_meta_refresh = true page = @mech.get('http://example/http_refresh?refresh_time=0') assert_equal('http://example/', page.uri.to_s) assert_equal(2, @mech.history.length) assert_nil requests.last['referer'] end def test_get_http_refresh_delay @mech.follow_meta_refresh = true class << @mech.agent attr_accessor :slept def sleep *args @slept = args end end @mech.get('http://localhost/http_refresh?refresh_time=1') assert_equal [1], @mech.agent.slept end def test_get_http_refresh_disabled page = @mech.get('http://localhost/http_refresh?refresh_time=0') assert_equal('http://localhost/http_refresh?refresh_time=0', page.uri.to_s) end def test_get_query page = @mech.get('http://localhost/', { :q => 'hello' }) assert_equal('http://localhost/?q=hello', page.uri.to_s) page = @mech.get('http://localhost/', { :q => %w[hello world]}) assert_equal('http://localhost/?q=hello&q=world', page.uri.to_s) page = @mech.get('http://localhost/', { :paging => { start: 1, limit: 25 } }) assert_equal('http://localhost/?paging%5Bstart%5D=1&paging%5Blimit%5D=25', page.uri.to_s) end def test_get_redirect page = @mech.get('http://localhost/redirect') assert_equal(page.uri.to_s, 'http://localhost/verb') assert_equal 'GET', page.header['X-Request-Method'] end def test_get_redirect_found page = @mech.get('http://localhost/response_code?code=302&ct=test/xml') assert_equal('http://localhost/index.html', page.uri.to_s) assert_equal(2, @mech.history.length) end def test_get_redirect_infinite assert_raises(Mechanize::RedirectLimitReachedError) { @mech.get('http://localhost/infinite_refresh') } end def test_get_referer request = nil @mech.pre_connect_hooks << lambda { |_, req| request = req } @mech.get('http://localhost/', [], 'http://tenderlovemaking.com/') assert_equal 'http://tenderlovemaking.com/', request['Referer'] end def test_get_referer_file uri = URI 'http://tenderlovemaking.com/crossdomain.xml' file = Mechanize::File.new uri @mech.get('http://localhost', [], file) # HACK no assertion of behavior end def test_get_referer_none @mech.get('http://localhost/') @mech.get('http://localhost/') assert_equal(2, requests.length) requests.each do |request| assert_nil request['referer'] end end def test_get_scheme_unsupported assert_raises Mechanize::UnsupportedSchemeError do begin @mech.get('ftp://server.com/foo.html') rescue Mechanize::UnsupportedSchemeError => error assert_equal 'ftp', error.scheme assert_equal 'ftp://server.com/foo.html', error.uri.to_s raise end end end def test_get_space page = nil page = @mech.get("http://localhost/tc_bad_links.html ") assert_match(/tc_bad_links.html$/, @mech.history.last.uri.to_s) assert_equal(1, @mech.history.length) end def test_get_tilde page = @mech.get('http://localhost/?foo=~2') assert_equal('http://localhost/?foo=~2', page.uri.to_s) end def test_get_weird @mech.get('http://localhost/?action=bing&bang=boom=1|a=|b=|c=') @mech.get('http://localhost/?a=b&b=c&c=d') @mech.get("http://localhost/?a=#{[0xd6].pack('U')}") # HACK no assertion of behavior end def test_get_yield pages = nil @mech.get("http://localhost/file_upload.html") { |page| pages = page } assert pages assert_equal('File Upload Form', pages.title) end def test_get_file body = @mech.get_file 'http://localhost/frame_test.html' assert_kind_of String, body refute_empty body end def test_get_file_download # non-Mechanize::File body = @mech.get_file 'http://localhost/button.jpg' assert_kind_of String, body refute_empty body end def test_head page = @mech.head('http://localhost/verb', { 'q' => 'foo' }) assert_equal 0, @mech.history.length assert_equal 'HEAD', page.header['X-Request-Method'] end def test_head_redirect page = @mech.head('http://localhost/redirect') assert_equal(page.uri.to_s, 'http://localhost/verb') assert_equal 'HEAD', page.header['X-Request-Method'] end def test_history 2.times do |i| assert_equal(i, @mech.history.size) @mech.get("http://localhost/") end page = @mech.get("http://localhost/form_test.html") assert_equal("http://localhost/form_test.html", @mech.history.last.uri.to_s) assert_equal("http://localhost/", @mech.history[-2].uri.to_s) assert @mech.visited?("http://localhost/") assert @mech.visited?("/form_test.html"), 'relative' assert !@mech.visited?("http://google.com/") assert @mech.visited?(page.links.first) end def test_history_added_gets_called added_page = nil @mech.history_added = lambda { |page| added_page = page } assert_equal @mech.get('http://localhost/tc_blank_form.html'), added_page end def test_history_order @mech.max_history = 2 assert_equal(0, @mech.history.length) @mech.get('http://localhost/form_test.html') assert_equal(1, @mech.history.length) @mech.get('http://localhost/empty_form.html') assert_equal(2, @mech.history.length) @mech.get('http://localhost/tc_checkboxes.html') assert_equal(2, @mech.history.length) assert_equal('http://localhost/empty_form.html', @mech.history[0].uri.to_s) assert_equal('http://localhost/tc_checkboxes.html', @mech.history[1].uri.to_s) end def test_initialize mech = Mechanize.new assert_equal 50, mech.max_history end def test_html_parser_equals @mech.html_parser = {} assert_raises(NoMethodError) { @mech.get('http://localhost/?foo=~2').links } end def test_idle_timeout_default assert_equal 5, Mechanize.new.idle_timeout end def test_idle_timeout_equals @mech.idle_timeout = 15 assert_equal 15, @mech.idle_timeout end def test_keep_alive_equals assert @mech.keep_alive @mech.keep_alive = false refute @mech.keep_alive end def test_keep_alive_time assert_equal 0, @mech.keep_alive_time @mech.keep_alive_time = 1 assert_equal 1, @mech.keep_alive_time end def test_log assert_nil @mech.log end def test_log_equals @mech.log = Logger.new $stderr refute_nil @mech.log assert_nil Mechanize.log end def test_max_file_buffer_equals @mech.max_file_buffer = 1024 assert_equal 1024, @mech.agent.max_file_buffer end def test_max_history_equals @mech.max_history = 10 0.upto(10) do |i| assert_equal(i, @mech.history.size) @mech.get("http://localhost/") end 0.upto(10) do |i| assert_equal(10, @mech.history.size) @mech.get("http://localhost/") end end def test_open_timeout_equals @mech.open_timeout = 5 assert_equal 5, @mech.open_timeout end def test_parse_download @mech.pluggable_parser['application/octet-stream'] = Mechanize::Download response = Net::HTTPOK.allocate response.instance_variable_set(:@header, 'content-type' => ['application/octet-stream']) download = @mech.parse @uri, response, StringIO.new('raw') assert_kind_of Mechanize::Download, download assert_kind_of StringIO, download.content end def test_parse_html response = Net::HTTPOK.allocate response.instance_variable_set :@header, 'content-type' => ['text/html'] page = @mech.parse URI('http://example/'), response, '' assert_kind_of Mechanize::Page, page end def test_post @mech.post "http://example", 'gender' => 'female' assert_equal "gender=female", requests.first.body end def test_post_auth requests = [] @mech.pre_connect_hooks << proc { |agent, request| requests << request.class } @mech.add_auth(@uri, 'user', 'pass') page = @mech.post(@uri + '/basic_auth') assert_equal('You are authenticated', page.body) assert_equal(2, requests.length) r1 = requests[0] r2 = requests[1] assert_equal(r1, r2) end def test_post_entity @mech.post "http://localhost/form_post", 'json' => '["""]' assert_equal "json=%5B%22%22%22%5D", requests.first.body end def test_post_multiple_values @mech.post "http://localhost/form_post", [%w[gender female], %w[gender male]] assert_equal "gender=female&gender=male", requests.first.body end def test_post_multipart page = @mech.post('http://localhost/file_upload', { :name => 'Some file', :userfile1 => File.open(__FILE__) }) name = File.basename __FILE__ assert_match( "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"", page.body ) assert_send [page.body.bytesize, :>, File.size(__FILE__)] end def test_post_file_upload_nonascii name = 'ユーザファイル1' file_upload = Mechanize::Form::FileUpload.new({'name' => 'userfile1'}, name) file_upload.file_data = File.read(__FILE__) file_upload.mime_type = 'application/zip' page = @mech.post('http://localhost/file_upload', { :name => 'Some file', :userfile1 => file_upload }) assert_match( "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"".force_encoding(Encoding::ASCII_8BIT), page.body ) assert_match("Content-Type: application/zip", page.body) assert_send [page.body.bytesize, :>, File.size(__FILE__)] end def test_post_file_upload name = File.basename(__FILE__) file_upload = Mechanize::Form::FileUpload.new({'name' => 'userfile1'}, name) file_upload.file_data = File.read(__FILE__) file_upload.mime_type = 'application/zip' page = @mech.post('http://localhost/file_upload', { :name => 'Some file', :userfile1 => file_upload }) assert_match( "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"", page.body ) assert_match("Content-Type: application/zip", page.body) assert_send [page.body.bytesize, :>, File.size(__FILE__)] end def test_post_redirect page = @mech.post('http://localhost/redirect') assert_equal(page.uri.to_s, 'http://localhost/verb') assert_equal 'GET', page.header['X-Request-Method'] end def test_put page = @mech.put('http://localhost/verb', 'foo') assert_equal 1, @mech.history.length assert_equal 'PUT', page.header['X-Request-Method'] end def test_put_redirect page = @mech.put('http://localhost/redirect', 'foo') assert_equal(page.uri.to_s, 'http://localhost/verb') assert_equal 'GET', page.header['X-Request-Method'] end def test_read_timeout_equals @mech.read_timeout = 5 assert_equal 5, @mech.read_timeout end def test_timeouts_for_file_connection uri = URI.parse "file://#{File.expand_path __FILE__}" @mech.read_timeout = 5 @mech.open_timeout = 5 assert @mech.get(uri) end def test_referer host_path = "localhost/tc_referer.html?t=1" ['http', 'https'].each { |proto| referer = "#{proto}://#{host_path}" [ "", "@", "user1@", ":@", "user1:@", ":password1@", "user1:password1@", ].each { |userinfo| url = "#{proto}://#{userinfo}#{host_path}" [url, url + "#foo"].each { |furl| [ ['relative', true], ['insecure', proto == 'http'], ['secure', true], ['relative noreferrer', false], ['insecure noreferrer', false], ['secure noreferrer', false], ].each_with_index { |(type, bool), i| rpage = @mech.get(furl) page = rpage.links[i].click assert_equal bool ? referer : '', page.body, "%s link from %s" % [type, furl] } rpage = @mech.get(furl) page = rpage.forms.first.submit assert_equal referer, page.body, "post from %s" % furl } } } end def test_retry_change_requests_equals refute @mech.retry_change_requests @mech.retry_change_requests = true assert @mech.retry_change_requests end def test_set_proxy http = @mech.agent.http @mech.set_proxy 'localhost', 8080, 'user', 'pass' assert_equal 'localhost', @mech.proxy_addr assert_equal 8080, @mech.proxy_port assert_equal 'user', @mech.proxy_user assert_equal 'pass', @mech.proxy_pass assert_equal URI('http://user:pass@localhost:8080'), http.proxy_uri end def test_shutdown uri = URI 'http://localhost' jar = HTTP::CookieJar.new jar.parse 'a=b', uri @mech.cookie_jar = jar @mech.get("http://localhost/") assert_match(/Hello World/, @mech.current_page.body) refute_empty @mech.cookies refute_empty Thread.current[@mech.agent.http.request_key] @mech.shutdown assert_nil Thread.current[@mech.agent.http.request_key] assert_empty @mech.history assert_empty @mech.cookies end def test_start body, id = nil Mechanize.start do |m| body = m.get("http://localhost/").body id = m.agent.http.request_key end assert_match(/Hello World/, body) assert_nil Thread.current[id] end def test_submit_bad_form_method page = @mech.get("http://localhost/bad_form_test.html") assert_raises ArgumentError do @mech.submit(page.forms.first) end end def test_submit_check_one page = @mech.get('http://localhost/tc_checkboxes.html') form = page.forms.first form.checkboxes_with(:name => 'green')[1].check page = @mech.submit(form) assert_equal(1, page.links.length) assert_equal('green:on', page.links.first.text) end def test_submit_check_two page = @mech.get('http://localhost/tc_checkboxes.html') form = page.forms.first form.checkboxes_with(:name => 'green')[0].check form.checkboxes_with(:name => 'green')[1].check page = @mech.submit(form) assert_equal(2, page.links.length) assert_equal('green:on', page.links[0].text) assert_equal('green:on', page.links[1].text) end def test_submit_enctype page = @mech.get("http://localhost/file_upload.html") assert_equal('multipart/form-data', page.forms[0].enctype) form = page.forms.first form.file_uploads.first.file_name = __FILE__ form.file_uploads.first.mime_type = "text/plain" form.file_uploads.first.file_data = "Hello World\n\n" page = @mech.submit(form) basename = File.basename __FILE__ assert_match( "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{basename}\"", page.body ) assert_match( "Content-Disposition: form-data; name=\"name\"", page.body ) assert_match('Content-Type: text/plain', page.body) assert_match('Hello World', page.body) assert_match('foo[aaron]', page.body) end def test_submit_file_data page = @mech.get("http://localhost/file_upload.html") assert_equal('multipart/form-data', page.forms[1].enctype) form = page.forms[1] form.file_uploads.first.file_name = __FILE__ form.file_uploads.first.file_data = File.read __FILE__ page = @mech.submit(form) contents = File.binread __FILE__ basename = File.basename __FILE__ assert_match( "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"", page.body ) assert_match(contents, page.body) end def test_submit_file_name page = @mech.get("http://localhost/file_upload.html") assert_equal('multipart/form-data', page.forms[1].enctype) form = page.forms[1] form.file_uploads.first.file_name = __FILE__ page = @mech.submit(form) contents = File.binread __FILE__ basename = File.basename __FILE__ assert_match( "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"", page.body ) assert_match(contents, page.body) end def test_submit_get form = node 'form', 'method' => 'GET', 'action' => '/?a=b' form = Mechanize::Form.new form, @mech, fake_page @mech.submit form assert_equal '/', requests.first.path end def test_submit_headers page = @mech.get 'http://localhost:2000/form_no_action.html' assert form = page.forms.first form.action = '/http_headers' page = @mech.submit form, nil, 'foo' => 'bar' headers = page.body.split("\n").map { |x| x.split('|', 2) }.flatten headers = Hash[*headers] assert_equal 'bar', headers['foo'] end def test_submit_multipart page = @mech.get("http://localhost/file_upload.html") assert_equal('multipart/form-data', page.forms[1].enctype) form = page.forms[1] form.file_uploads.first.file_name = __FILE__ form.file_uploads.first.mime_type = "text/plain" form.file_uploads.first.file_data = "Hello World\n\n" page = @mech.submit(form) basename = File.basename __FILE__ assert_match( "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"", page.body ) end def test_submit_no_file page = @mech.get("http://localhost/file_upload.html") form = page.forms.first form.field_with(:name => 'name').value = 'Aaron' @page = @mech.submit(form) assert_match('Aaron', @page.body) assert_match( "Content-Disposition: form-data; name=\"userfile1\"; filename=\"\"", @page.body ) end def test_submit_post form = node 'form', 'method' => 'POST', 'action' => '/?a=b' form = Mechanize::Form.new form, @mech, fake_page @mech.submit form assert_equal '/?a=b', requests.first.path end def test_submit_post_pound form = node 'form', 'method' => 'POST', 'action' => '/#1' form = Mechanize::Form.new form, @mech, fake_page @mech.submit form assert_equal '/', requests.first.path end def test_submit_too_many_radiobuttons page = @mech.get("http://localhost/form_test.html") form = page.form_with(:name => 'post_form1') form.radiobuttons.each { |r| r.checked = true } assert_raises Mechanize::Error do @mech.submit(form) end end def test_transact @mech.get("http://localhost/frame_test.html") assert_equal(1, @mech.history.length) @mech.transact { |a| 5.times { @mech.get("http://localhost/frame_test.html") } assert_equal(6, @mech.history.length) } assert_equal(1, @mech.history.length) end def test_user_agent_alias_equals_unknown assert_raises ArgumentError do @mech.user_agent_alias = "Aaron's Browser" end end def test_verify_mode assert_equal OpenSSL::SSL::VERIFY_PEER, @mech.verify_mode @mech.verify_mode = OpenSSL::SSL::VERIFY_NONE assert_equal OpenSSL::SSL::VERIFY_NONE, @mech.verify_mode end def test_visited_eh @mech.get("http://localhost/content_type_test?ct=application/pdf") assert \ @mech.visited?("http://localhost/content_type_test?ct=application/pdf") assert \ !@mech.visited?("http://localhost/content_type_test") assert \ !@mech.visited?("http://localhost/content_type_test?ct=text/html") end def test_visited_eh_link @mech.get("http://example/index.html") page = page URI 'http://example' link = node 'a', 'href' => '/index.html' link = Mechanize::Page::Link.new link, page, @mech assert @mech.visited? link end def test_visited_eh_redirect @mech.get("http://localhost/response_code?code=302") assert_equal("http://localhost/index.html", @mech.current_page.uri.to_s) assert @mech.visited?('http://localhost/response_code?code=302') end def test_no_frames_exists page = @mech.get("http://localhost/empty_form.html"); assert_nil page.frame_with(:name => 'noframe') assert_raises Mechanize::ElementNotFoundError do page.frame_with!(:name => 'noframe') end end def assert_header(page, header) headers = {} page.body.split(/[\r\n]+/).each do |page_header| headers.[]=(*page_header.chomp.split(/\|/)) end header.each do |key, value| assert(headers.has_key?(key)) assert_equal(value, headers[key]) end end end mechanize-2.7.5/test/test_mechanize_form_select_list.rb 0000644 0000041 0000041 00000003042 12772546476 023466 0 ustar www-data www-data require 'mechanize/test_case' class TestMechanizeFormSelectList < Mechanize::TestCase def setup super page = html_page <<-BODY
BODY form = page.forms.first @select = form.fields.first end def test_inspect assert_match "value: 2", @select.inspect end def test_option_with option = @select.option_with :value => '1' assert_equal '1', option.value end def test_options_with options = @select.options_with :value => /[12]/ assert_equal 2, options.length end def test_query_value assert_equal [%w[select 2]], @select.query_value @select.select_all assert_equal [%w[select 6]], @select.query_value end def test_select_all @select.select_all assert_equal "6", @select.value end def test_select_none @select.select_none assert_equal "1", @select.value end def test_selected_options assert_equal [@select.options[1]], @select.selected_options @select.options.last.click assert_equal [@select.options.last], @select.selected_options end def test_value assert_equal "2", @select.value end def test_value_equals @select.value = %w[a 1 2] assert_equal "a", @select.value end end mechanize-2.7.5/test/test_mechanize_redirect_limit_reached_error.rb 0000644 0000041 0000041 00000000661 12772546476 026020 0 ustar www-data www-data require 'mechanize/test_case' class TestMechanizeRedirectLimitReachedError < Mechanize::TestCase def setup super @error = Mechanize::RedirectLimitReachedError.new fake_page, 10 end def test_message assert_equal 'Redirect limit of 10 reached', @error.message end def test_redirects assert_equal 10, @error.redirects end def test_response_code assert_equal 200, @error.response_code end end mechanize-2.7.5/test/test_mechanize_form_image_button.rb 0000644 0000041 0000041 00000000446 12772546476 023636 0 ustar www-data www-data require 'mechanize/test_case' class TestMechanizeFormImageButton < Mechanize::TestCase def test_query_value button = Mechanize::Form::ImageButton.new 'name' => 'image_button' assert_equal [%w[image_button.x 0], %w[image_button.y 0]], button.query_value end end mechanize-2.7.5/test/test_mechanize_directory_saver.rb 0000644 0000041 0000041 00000002420 12772546476 023334 0 ustar www-data www-data require 'mechanize/test_case' class TestMechanizeDirectorySaver < Mechanize::TestCase def setup super @uri = URI 'http://example/relative/tc_relative_links.html' @io = StringIO.new 'hello world' end def test_self_save_to in_tmpdir do saver = Mechanize::DirectorySaver.save_to 'dir' saver.new @uri, nil, @io, 200 assert File.exist? 'dir/tc_relative_links.html' refute File.exist? 'dir/relative' end end def test_self_save_to_cd in_tmpdir do saver = Mechanize::DirectorySaver.save_to 'dir' FileUtils.mkdir 'other' Dir.chdir 'other' do saver.new @uri, nil, @io, 200 end assert File.exist? 'dir/tc_relative_links.html' refute File.exist? 'dir/relative' end end def test_with_decode_filename in_tmpdir do saver = Mechanize::DirectorySaver.save_to 'dir', :decode_filename => true uri = URI 'http://example.com/foo+bar.html' saver.new uri, nil, @io, 200 assert File.exist? 'dir/foo bar.html' end end def test_initialize_no_save_dir in_tmpdir do e = assert_raises Mechanize::Error do Mechanize::DirectorySaver.new @uri, nil, @io, 200 end assert_match %r%no save directory specified%, e.message end end end mechanize-2.7.5/test/htdocs/ 0000755 0000041 0000041 00000000000 12772546476 016007 5 ustar www-data www-data mechanize-2.7.5/test/htdocs/form_no_input_name.html 0000644 0000041 0000041 00000000701 12772546476 022551 0 ustar www-data www-dataPersonalized Home | Sign in |
©2006 Google
This frameset document contains: